From d6c124bbfca3202804fc1b0fd920870593d8b32d Mon Sep 17 00:00:00 2001
From: Filippo Cremonese <filippocremonese@rev.ng>
Date: Fri, 18 Sep 2020 17:16:30 +0200
Subject: [PATCH] Added update command

---
 orchestra/cmds/__init__.py | 10 ++++---
 orchestra/cmds/update.py   | 54 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 4 deletions(-)
 create mode 100644 orchestra/cmds/update.py

diff --git a/orchestra/cmds/__init__.py b/orchestra/cmds/__init__.py
index 45ac7b1..6156b0b 100644
--- a/orchestra/cmds/__init__.py
+++ b/orchestra/cmds/__init__.py
@@ -1,13 +1,14 @@
 import argparse
 
-from . import components
-from . import environment
 from . import clone
+from . import components
 from . import configure
-from . import install
-from . import uninstall
+from . import environment
 from . import graph
+from . import install
 from . import shell
+from . import uninstall
+from . import update
 
 
 class CustomArgumentParser(argparse.ArgumentParser):
@@ -26,6 +27,7 @@ def install_subcommands(argparser):
     components.install_subcommand(subparsers)
     environment.install_subcommand(subparsers)
     clone.install_subcommand(subparsers)
+    update.install_subcommand(subparsers)
     configure.install_subcommand(subparsers)
     install.install_subcommand(subparsers)
     uninstall.install_subcommand(subparsers)
diff --git a/orchestra/cmds/update.py b/orchestra/cmds/update.py
new file mode 100644
index 0000000..65da021
--- /dev/null
+++ b/orchestra/cmds/update.py
@@ -0,0 +1,54 @@
+import os.path
+import subprocess
+from glob import glob
+
+from loguru import logger
+
+from ..model.configuration import Configuration
+
+
+def install_subcommand(sub_argparser):
+    cmd_parser = sub_argparser.add_parser("update", handler=handle_update)
+
+
+def handle_update(args, config: Configuration):
+    logger.info("Updating binary archives")
+    os.makedirs(config.binary_archives_dir, exist_ok=True)
+    for name, url in config.binary_archives_remotes.items():
+        binary_archive_path = os.path.join(config.binary_archives_dir, name)
+        if os.path.exists(binary_archive_path):
+            pull_binary_archive(name, config)
+        else:
+            clone_binary_archive(name, url, config)
+
+    logger.info("Updating repositories")
+    for git_repo in glob(os.path.join(config.sources_dir, "**/.git"), recursive=True):
+        git_repo = os.path.dirname(git_repo)
+        logger.info(f"Pulling {git_repo}")
+        result = git_pull(git_repo)
+        if result.returncode:
+            logger.error(f"Could not pull repository {git_repo}")
+
+
+def pull_binary_archive(name, config):
+    binary_archive_path = os.path.join(config.binary_archives_dir, name)
+    logger.info(f"Pulling binary archive {binary_archive_path}")
+    result = git_pull(binary_archive_path)
+    if result.returncode:
+        logger.error(f"Could not pull binary archive {binary_archive_path}")
+
+
+def clone_binary_archive(name, url, config):
+    logger.info(f"Trying to clone binary archive from remote {name} ({url})")
+    binary_archive_path = os.path.join(config.binary_archives_dir, name)
+    env = os.environ
+    env["GIT_LFS_SKIP_SMUDGE"] = "1"
+    result = subprocess.run(["git", "clone", url, binary_archive_path], env=env)
+    if result.returncode:
+        logger.info(f"Could not clone binary archive from remote {name}!")
+
+
+def git_pull(directory):
+    env = os.environ
+    env["GIT_LFS_SKIP_SMUDGE"] = "1"
+    return subprocess.run(["git", "-C", directory, "pull", "--ff-only"], env=env)
-- 
GitLab