diff --git a/acmc.py b/acmc.py index 22aed7441057f3cd9649aaa6e9b35715345ce9f6..6ecf0358c7d5d5c427ffa022057c17b1aec434af 100644 --- a/acmc.py +++ b/acmc.py @@ -26,7 +26,7 @@ def omop_delete(args): def phen_init(args): """Handle the `phen init` command.""" - phen.init(args.phen_dir) + phen.init(args.phen_dir, args.remote_url) def phen_validate(args): """Handle the `phen validate` command.""" @@ -99,6 +99,7 @@ def main(): # phen init phen_init_parser = phen_subparsers.add_parser("init", help="Initiatise phenotype directory") phen_init_parser.add_argument("-d", "--phen-dir", type=str, default=str(phen.DEFAULT_PHEN_PATH.resolve()), help="Phenotype directory") + phen_init_parser.add_argument("-r", "--remote_url", help="URL to remote git repository") phen_init_parser.set_defaults(func=phen_init) # phen validate @@ -109,7 +110,7 @@ def main(): # phen map phen_map_parser = phen_subparsers.add_parser("map", help="Process phen mapping") phen_map_parser.add_argument("-d", "--phen-dir", type=str, default=str(phen.DEFAULT_PHEN_PATH.resolve()), help="Phenotype directory") - phen_map_parser.add_argument("-t", "--target-coding", required=True, choices=['read2_code', 'read3_code', 'icd10_code', 'snomed_code', 'opcs4_code'], help="Specify the target coding (read2, read3, icd10, snomed, opcs4)") + phen_map_parser.add_argument("-t", "--target-coding", required=True, choices=['read2_code', 'read3_code', 'icd10_code', 'snomed_code', 'opcs4_code'], help="Specify the target coding (read2_code, read3_code, icd10_code, snomed_code, opcs4_code)") # phen map flags phen_map_parser.add_argument("-tr", "--translate", action="store_true", default=False, help="Translate code types") phen_map_parser.add_argument("-v", "--verify", action="store_true", default=False, help="Verify codes") diff --git a/phen.py b/phen.py index 9fa324f2ef1ea39d6f5459d2297e84aebb204742..216a73aa7941c53f71cc1a259d199cfd7cb95288 100644 --- a/phen.py +++ b/phen.py @@ -8,6 +8,7 @@ import sys import shutil import git import re +import requests from pathlib import Path import trud @@ -29,7 +30,8 @@ from omop import setup pd.set_option("mode.chained_assignment", None) -DEFAULT_PHEN_PATH = Path('build') / 'phen' +PHEN_DIR = 'phen' +DEFAULT_PHEN_PATH = Path('build') / PHEN_DIR CODES_DIR = 'codes' OUTPUT_DIR = 'output' CONFIG_FILE = 'config.json' @@ -47,15 +49,15 @@ class PhenValidationException(Exception): super().__init__(message) self.validation_errors = validation_errors -def init(phen_dir): +def init(phen_dir, remote_url): """Initial phenotype directory as git repo with standard structure""" print(f"Initialising Phenotype in directory: {phen_dir}") phen_path = Path(phen_dir) - + # check if directory already exists and ask user if they want to recreate it configure = False if phen_path.exists() and phen_path.is_dir(): # Check if it exists and is a directory - user_input = input(f"The phen directory '{phen_path}' already exists. Do you want to reinitialise, deleting all current configuration? (yes/no): ").strip().lower() + user_input = input(f"The phen directory '{phen_path}' already exists. Do you want to reinitialise? (yes/no): ").strip().lower() if user_input in ['yes', 'y']: shutil.rmtree(phen_path) configure = True; @@ -66,50 +68,67 @@ def init(phen_dir): # configure the phen directories if configure: - # create root phen directory - phen_path.mkdir(parents=True, exist_ok=True) - print(f"Phen directory '{phen_path}' has been created.") - # create codes directory - codes_path = phen_path / CODES_DIR - codes_path.mkdir(exist_ok=True) - keep_path = codes_path / '.gitkeep' - keep_path.touch(exist_ok=True) - # create maps directory - output_path = phen_path / OUTPUT_DIR - output_path.mkdir(exist_ok=True) - keep_path = output_path / '.gitkeep' - keep_path.touch(exist_ok=True) - # create empty config file - initial_version = "v1.0.1" - config = { - "concept_sets": { - "version": initial_version, - "omop": { - "vocabulary_id": "", - "vocabulary_name": "", - "vocabulary_reference": "" + repo = None + # remote then clone the repo + if remote_url != None: + try: + repo = git.cmd.Git() + repo.clone(remote_url, phen_path) + repo = git.Repo(phen_path) + except Exception: + raise Exception(f"Error: remote_url for the repo {remote_url} ") + else: + # local then create the directories and init + phen_path.mkdir(parents=True, exist_ok=True) + print(f"Phen directory '{phen_path}' has been created.") + repo = git.Repo.init(phen_path) + #repo.create_tag(initial_version, message=f"Release {initial_version}") + + + # check if the phen path has already been configured which would be the case for remote clones + config_path = phen_path / CONFIG_FILE + if not config_path.exists(): + print("Creating configuration files") + # create codes directory + codes_path = phen_path / CODES_DIR + codes_path.mkdir(exist_ok=True) + keep_path = codes_path / '.gitkeep' + keep_path.touch(exist_ok=True) + # create maps directory + output_path = phen_path / OUTPUT_DIR + output_path.mkdir(exist_ok=True) + keep_path = output_path / '.gitkeep' + keep_path.touch(exist_ok=True) + # create empty config file + initial_version = "v1.0.1" + config = { + "concept_sets": { + "version": initial_version, + "omop": { + "vocabulary_id": "", + "vocabulary_name": "", + "vocabulary_reference": "" + }, + "concept_set": [ + ] }, - "concept_set": [ + "codes": [ ] - }, - "codes": [ - ] - } - config_path = phen_path / CONFIG_FILE - # Write the JSON data to a file - with open(config_path, "w", encoding="utf-8") as f: - json.dump(config, f, indent=4) - - # initialise phen directory as a git repo includ .gitkeep to keep the codes dir - repo = git.Repo.init(phen_path) - repo.git.add(codes_path) - repo.git.add(output_path) - repo.git.add(all=True) - msg = "Initialized phen git repo." - repo.index.commit(msg) - repo.create_tag(initial_version, message=f"Release {initial_version}") - print(msg) - + } + config_path = phen_path / CONFIG_FILE + # Write the JSON data to a file + with open(config_path, "w", encoding="utf-8") as f: + json.dump(config, f, indent=4) + + # initialise phen directory as a git repo includ .gitkeep to keep the codes dir + repo.git.add(codes_path) + repo.git.add(output_path) + repo.git.add(all=True) + msg = "Initialized phen git repo." + repo.index.commit(msg) + print(msg) + else: + print(f"Phenotype configuration files already exist") print(f"Phenotype initialised") else: print(f"Phenotype not initiatised") @@ -520,6 +539,15 @@ def publish(phen_dir): repo.create_tag(version, message=f"Release {version}") print(f"Created tag: {version}") + # push to origin if a remote repo + try: + origin = repo.remotes.origin + print(f"Remote 'origin' exists: {origin.url}") + origin.push(tags=True) + print("Changes pushed to 'origin'.") + except AttributeError: + print("No remote named 'origin' found, local repo.") + def copy(phen_dir, target_dir, version=None): """Copys a phen repo at a specific tagged version into a target directory"""