From 05469c904978f69629ec0850e806194b5b06725d Mon Sep 17 00:00:00 2001
From: "r.jaepel" <r.jaepel@fz-juelich.de>
Date: Thu, 16 Nov 2023 15:25:01 +0100
Subject: [PATCH] Add ability to convert existing git repos to cadet-rdm repos

---
 cadetrdm/initialize_repo.py | 29 ++++++++++++++++++-----------
 cadetrdm/repositories.py    |  7 +++++++
 tests/test_git_adapter.py   | 19 +++++++++++++++++++
 3 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/cadetrdm/initialize_repo.py b/cadetrdm/initialize_repo.py
index 335009e..ef5e282 100644
--- a/cadetrdm/initialize_repo.py
+++ b/cadetrdm/initialize_repo.py
@@ -15,7 +15,7 @@ def add_linebreaks(input_list):
     """
     Add linebreaks between each entry in the input_list
     """
-    return [line + "\n" for line in input_list]
+    return ["\n" + line for line in input_list]
 
 
 def init_lfs(lfs_filetypes: list, path: str = None):
@@ -102,17 +102,21 @@ def initialize_git_repo(path_to_repo: str, output_repo_name: (str | bool) = "out
     starting_directory = os.getcwd()
 
     if path_to_repo != ".":
-        if os.path.exists(path_to_repo) and len(os.listdir(path_to_repo)) > 0:
-            raise ValueError("Path to repository already exists and is not an empty directory.")
         os.makedirs(path_to_repo, exist_ok=True)
         os.chdir(path_to_repo)
 
-    os.system(f"git init")
+    try:
+        repo = git.Repo(".")
+        proceed = input(f'The target directory already contains a git repo.\n'
+                        f'Please back up or push all changes to the repo before continuing.'
+                        f'Proceed? Y/n \n')
+        if not (proceed.lower() == "y" or proceed == ""):
+            raise KeyboardInterrupt
+    except git.exc.InvalidGitRepositoryError:
+        os.system(f"git init")
 
-    init_lfs(lfs_filetypes)
-
-    write_lines_to_file(path=".gitattributes", lines=gitattributes)
-    write_lines_to_file(path=".gitignore", lines=gitignore)
+    write_lines_to_file(path=".gitattributes", lines=gitattributes, open_type="a")
+    write_lines_to_file(path=".gitignore", lines=gitignore, open_type="a")
 
     if output_repo_kwargs is None:
         output_repo_kwargs = {"gitattributes": ["logs/log.csv merge=union"]}
@@ -125,8 +129,11 @@ def initialize_git_repo(path_to_repo: str, output_repo_name: (str | bool) = "out
         # This instance of ProjectRepo is therefore the project repo
         repo = ProjectRepo(".", output_folder=output_repo_name)
     else:
-        create_output_readme()
         # If output_repo_name is False we are in the output_repo and should finish by committing the changes
+        init_lfs(lfs_filetypes)
+
+        create_output_readme()
+
         repo = ResultsRepo(".")
 
     repo.commit("initial commit")
@@ -147,7 +154,7 @@ def create_readme():
                     "Please update the environment.yml with your python environment requirements.", "", "",
                     "The output repository can be found at:",
                     "[output_repo]() (not actually set yet because no remote has been configured at this moment"]
-    write_lines_to_file("README.md", readme_lines, open_type="w")
+    write_lines_to_file("README.md", readme_lines, open_type="a")
 
 
 def create_output_readme():
@@ -155,7 +162,7 @@ def create_output_readme():
                     "- authors", "- project", "- things we will find interesting later", "", "",
                     "The project repository can be found at:",
                     "[project_repo]() (not actually set yet because no remote has been configured at this moment"]
-    write_lines_to_file("README.md", readme_lines, open_type="w")
+    write_lines_to_file("README.md", readme_lines, open_type="a")
 
 
 def initialize_from_remote(project_url, path_to_repo: str = None):
diff --git a/cadetrdm/repositories.py b/cadetrdm/repositories.py
index 78b364f..673cd3c 100644
--- a/cadetrdm/repositories.py
+++ b/cadetrdm/repositories.py
@@ -677,6 +677,12 @@ class ProjectRepo(BaseRepo):
         if os.path.exists(self.output_repo.working_dir + "_cached"):
             shutil.rmtree(self.output_repo.working_dir + "_cached")
 
+    def test_for_correct_repo_setup(self):
+        """
+        ToDo: implement
+        :return:
+        """
+
     def enter_context(self, ):
         """
         Enter the tracking context. This includes:
@@ -688,6 +694,7 @@ class ProjectRepo(BaseRepo):
         :return:
             The name of the newly created output branch.
         """
+        self.test_for_correct_repo_setup()
         self.test_for_uncommitted_changes()
         self._on_context_enter_commit_hash = self.current_commit_hash
         self._is_in_context_manager = True
diff --git a/tests/test_git_adapter.py b/tests/test_git_adapter.py
index 21c41fb..7389f2c 100644
--- a/tests/test_git_adapter.py
+++ b/tests/test_git_adapter.py
@@ -154,6 +154,25 @@ def try_initialize_from_remote():
     assert try_init_gitpython_repo("test_repo_from_remote")
 
 
+def test_init_over_existing_repo():
+    path_to_repo = "test_repo_2"
+    if os.path.exists(path_to_repo):
+        remove_dir(path_to_repo)
+    os.makedirs(path_to_repo)
+    os.chdir(path_to_repo)
+    os.system(f"git init")
+    with open("README.md", "w") as handle:
+        handle.write("Readme-line 1\n")
+    with open(".gitignore", "w") as handle:
+        handle.write("foo.bar.*")
+    repo = git.Repo(".")
+    repo.git.add(".")
+    repo.git.commit("-m", "Initial commit")
+    os.chdir("..")
+
+    initialize_git_repo(path_to_repo)
+
+
 def test_cadet_rdm(path_to_repo):
     # because these depend on one-another and there is no native support afaik for sequential tests
     # these tests are called sequentially here as try_ functions.
-- 
GitLab