From c7eb41091b9df6f08dbcaed38deca354fb797d50 Mon Sep 17 00:00:00 2001
From: davidovski <david@davidovski.xyz>
Date: Tue, 7 Dec 2021 18:55:10 +0000
Subject: added update command

---
 default.conf         |  2 +-
 src/options.py       |  2 +-
 src/util.py          |  2 +-
 src/verbs/install.py | 43 ++++++++++++++++++--------------------
 src/verbs/update.py  | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/xi.py            |  2 ++
 6 files changed, 83 insertions(+), 26 deletions(-)
 create mode 100644 src/verbs/update.py

diff --git a/default.conf b/default.conf
index 6fac4b2..717692d 100644
--- a/default.conf
+++ b/default.conf
@@ -1,7 +1,7 @@
 dir {
     packages    /var/lib/xipkg/packages
     keychain    /var/lib/xipkg/keychain
-    sources    /var/lib/xipkg/sources
+    sources     /var/lib/xipkg/sources
     installed   /var/lib/xipkg/installed
     cache       /var/cache/xipkg
 }
diff --git a/src/options.py b/src/options.py
index 011c039..f3f83d5 100644
--- a/src/options.py
+++ b/src/options.py
@@ -65,7 +65,7 @@ def parse_args():
 
             # is a named argument with a --
             if arg[1] == "-" and len(arg) > 2 and arg[2:].split("=")[0] in names:
-                option.appen(names[arg[2:].split("=")[0]])
+                option.append(names[arg[2:].split("=")[0]])
             # is a single letter argument with a -
             else:
                 for letter in arg[1:]:
diff --git a/src/util.py b/src/util.py
index 50b8ff8..fcc58f4 100644
--- a/src/util.py
+++ b/src/util.py
@@ -10,7 +10,7 @@ DEFAULT_BAR_COLOR = colors.BLACK + colors.BG_CYAN
 DEFAULT_BAR_COLOR_RESET = colors.BG_BLACK + colors.CYAN
 
 def extract_tar(package_path, destination):
-    tarfile.open(package_path).extractall(destination)
+    os.system(f"tar -h --no-overwrite-dir -xf {package_path} -C {destination}")
 
 def add_path(*argv):
     a = argv[0]
diff --git a/src/verbs/install.py b/src/verbs/install.py
index 6c8c9fd..2e63dd4 100644
--- a/src/verbs/install.py
+++ b/src/verbs/install.py
@@ -114,6 +114,7 @@ def retrieve_package(sources, package_info, package_name, config,
         package_dir = util.add_path(cache_dir, source)
 
         util.mkdir(package_dir)
+        # TODO if exists maybe just use cached version
         status, package_path = util.curl_to_file(package_url, util.add_path(package_dir, package_name + ".xipkg"), text=package_name + ".xipkg")
 
         if status == 200:
@@ -228,7 +229,7 @@ def install_package(package_name, package_path, package_info,
         config, root="/"):
 
     # TODO loading bar here
-    util.extract_tar(package_path, root)
+    files = util.extract_tar(package_path, root)
     save_installed_info(package_name, package_info, repo, source_url, key, config, root=root)
     # untar and move into root
     # then add entry in the config["dir"]["installed"]
@@ -262,6 +263,23 @@ def save_installed_info(package_name, package_info,
 
     pass
 
+def install_single(package, options, config, verbose=False, unsafe=False):
+
+        checksum, sources, repo = find_package(package, config["repos"],
+                config["dir"]["packages"], config["sources"])
+
+        info = retrieve_package_info(
+                    sources, checksum, package, config,
+                    verbose=verbose, skip_verification=unsafe
+                )
+
+        package_path, source, key = retrieve_package(sources, 
+                info, package, config, 
+                verbose=verbose, skip_verification=unsafe)
+
+        install_package(package, package_path, info, 
+                repo, sources[source], key,
+                config, root=options["r"])
 
 def install(args, options, config):
     if not options["l"]:
@@ -276,10 +294,7 @@ def install(args, options, config):
     packages_dir = config["dir"]["packages"]
     to_install = args if options["n"] else find_all_dependencies(args, options, config)
 
-
     if len(to_install) > 0:
-
-
         print(colors.CLEAR_LINE + colors.RESET, end="")
         print(colors.BLUE + "The following packages will be installed:")
         print(end="\t")
@@ -289,26 +304,8 @@ def install(args, options, config):
 
         if util.ask_confirmation(colors.BLUE + "Continue?", no_confirm=options["y"]):
 
-            downloaded = []
             for package in to_install:
-                checksum, sources, repo = find_package(package, config["repos"],
-                        config["dir"]["packages"], config["sources"])
-
-                info = retrieve_package_info(
-                            sources, checksum, package, config,
-                            verbose=v, skip_verification=unsafe
-                        )
-
-                package_path, source, key = retrieve_package(sources, 
-                        info, package, config, 
-                        verbose=v, skip_verification=unsafe)
-
-                downloaded.append(package, package_path, info, 
-                                repo, sources[source], key
-                        )
-                install_package(package, package_path, info, 
-                        repo, sources[source], key,
-                        config, root=options["r"])
+                install_single(package, options, config, verbose=v, unsafe=unsafe)
                 util.fill_line(f"Installed {package}", colors.BG_CYAN + colors.LIGHT_BLACK, end="\n")
 
         else:
diff --git a/src/verbs/update.py b/src/verbs/update.py
new file mode 100644
index 0000000..1cba192
--- /dev/null
+++ b/src/verbs/update.py
@@ -0,0 +1,58 @@
+import os
+import util
+import colors
+import time
+
+from verbs.install import find_package, install_single
+from verbs.sync import sync
+
+VERSION_COMPARED = "CHECKSUM"
+
+def get_installed_versions(config, root="/"):
+    packages = {}
+
+    installed_dir = util.add_path(root, config["dir"]["installed"])
+    if os.path.exists(installed_dir):
+        files = os.listdir(installed_dir)
+        for package in files:
+            with open(util.add_path(installed_dir, package, "info")) as file:
+                for line in file:
+                    if line.startswith(VERSION_COMPARED):
+                        packages[package] = line.strip().split("=")[-1]
+
+    return packages
+
+def get_available_version(package_name, config, root="/"):
+    repos = config["repos"]
+    packages_dir = config["dir"]["packages"]
+    sources = config["sources"]
+    checksum, found_sources, requested_repo = find_package(package_name, repos, packages_dir, sources)
+    return checksum
+    
+def update(args, options, config):
+    if not options["l"]:
+        sync(args, options, config)
+
+    v = options["v"]
+
+    updates = [package for package,checksum in get_installed_versions(config, options["r"]).items() if not checksum == get_available_version(package, config, options["r"])]
+
+    if len(args) > 0:
+        updates = [update for update in updates if update in args]
+
+    if len(updates) > 0:
+        print(colors.CLEAR_LINE + colors.RESET, end="")
+        print(colors.BLUE + "The following packages will be updated:")
+        print(end="\t")
+        for d in updates:
+            print(colors.BLUE if d in args else colors.LIGHT_BLUE, d, end="")
+        print()
+
+        if util.ask_confirmation(colors.BLUE + "Continue?", no_confirm=options["y"]):
+            for package in updates:
+                install_single(package, options, config, verbose=v, unsafe=options["u"])
+                util.fill_line(f"Updated {package}", colors.BG_CYAN + colors.LIGHT_BLACK, end="\n")
+    else:
+        print(colors.LIGHT_RED + "Nothing to do")
+
+    
diff --git a/src/xi.py b/src/xi.py
index aa819b4..cf03ecf 100644
--- a/src/xi.py
+++ b/src/xi.py
@@ -5,6 +5,7 @@ import colors
 
 from verbs.sync import sync
 from verbs.install import install
+from verbs.update import update
 
 def search():
     pass
@@ -13,6 +14,7 @@ def remove():
 
 verbs = { v: globals()[v] for v in [
                 "search",
+                "update",
                 "install",
                 "remove",
                 "sync"
-- 
cgit v1.2.1