From 820b8677b6eb0e66a92ba7ebc6106eab46ab717a Mon Sep 17 00:00:00 2001
From: Michael Boniface <m.j.boniface@soton.ac.uk>
Date: Wed, 26 Feb 2025 21:52:32 +0000
Subject: [PATCH] feature: added -r option to connect to a remote repo on
 publication. This is a one off -r and the repo must be empty as there's no
 way to resolve merges without mamanual and this might as well be done with
 git itself. Essentailly this is the usecase where you have started locally
 but then want to publish to a remote repo at some later point. If there's an
 existing repo with commits then you must start the phen init from th
 eexisting repo. Closes #35

---
 acmc/main.py  |  5 ++++-
 acmc/phen.py  | 28 +++++++++++++++++++++-------
 docs/usage.md |  1 +
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/acmc/main.py b/acmc/main.py
index b702518..cf7ffbb 100644
--- a/acmc/main.py
+++ b/acmc/main.py
@@ -53,7 +53,7 @@ def phen_export(args):
 
 def phen_publish(args):
     """Handle the `phen publish` command."""
-    phen.publish(args.phen_dir)
+    phen.publish(args.phen_dir, args.remote_url)
 
 
 def phen_copy(args):
@@ -203,6 +203,9 @@ def main():
         default=str(phen.DEFAULT_PHEN_PATH.resolve()),
         help="Phenotype workspace directory",
     )
+    phen_publish_parser.add_argument(
+        "-r", "--remote_url", help="URL to remote git repository"
+    )
     phen_publish_parser.set_defaults(func=phen_publish)
 
     # phen copy
diff --git a/acmc/phen.py b/acmc/phen.py
index a9131b5..50b166b 100644
--- a/acmc/phen.py
+++ b/acmc/phen.py
@@ -285,6 +285,9 @@ def init(phen_dir, remote_url):
 # Ignore SQLite journal and metadata files
 *.db-journal
 *.sqlite3-journal
+
+# python
+.ipynb_checkpoints
  """
     ignore_path = phen_path / ".gitignore"
     with open(ignore_path, "w") as file:
@@ -749,7 +752,7 @@ def map_target_code_type(phen_path, phenotype, target_code_type):
     logger.info(f"Phenotype processed target code type {target_code_type}")
 
 
-def publish(phen_dir):
+def publish(phen_dir, remote_url):
     """Publishes updates to the phenotype by commiting all changes to the repo directory"""
 
     # Validate config
@@ -801,13 +804,24 @@ def publish(phen_dir):
     logger.info(f"New version: {version}")
 
     # push to origin if a remote repo
+    if remote_url is not None and "origin" not in repo.remotes:
+        repo.create_remote("origin", remote_url)
+
     try:
-        origin = repo.remotes.origin
-        origin.push("main")
-        origin.push(tags=True)
-        logger.debug("Changes pushed to 'origin'.")
-    except AttributeError:
-        logger.debug("No remote named 'origin' found, local repo.")
+        if "origin" in repo.remotes:
+            logger.debug(f"Remote 'origin' is already set {repo.remotes.origin.url}")
+            origin = repo.remotes.origin
+            logger.info(f"Pushing main branch to {repo.remotes.origin.url}")
+            origin.push("main")
+            logger.info(f"Pushing tags to {repo.remotes.origin.url}")
+            origin.push(tags=True)
+            logger.debug("Changes pushed to 'origin'")
+        else:
+            logger.debug("Remote 'origin' is not set")
+    except Exception as e:
+        repo.delete_tag(version)
+        repo.git.reset("--soft", "HEAD~1")
+        raise e
 
     logger.info(f"Phenotype published successfully")
 
diff --git a/docs/usage.md b/docs/usage.md
index 57271cf..29c1ba7 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -108,6 +108,7 @@ The `phen` command is used phenotype-related operations.
   ```
 
   - `-d`, `--phen-dir`: (Optional) Directory of phenotype configuration (the default is ./build/phen).
+  - `-r`, `--remote_url`: (Optional) URL to a remote git repository, only supports an empty repo without existing commits
 
 - **Copy Phenotype Configuration**
 
-- 
GitLab