Source code for ecpi.scripts.ecpi_checkout

#!/usr/bin/env python3
# -*-coding:utf-8 -*
"""

cmd = 'git clone -b <branch> --sparse https://drf-gitlab.cea.fr/svom/ECLAIRs.git'

"""
import os.path as osp
import os
import argparse
import sys

from pathlib import Path
from distutils.version import LooseVersion as l_ver
import git
from git.repo import Repo
from git import RemoteProgress

# We assume ECPI_TOKEN and ECPI_USER are well defined
# TODO: Discuss if this information must be protected in 0600 mode files
ECPI_TOKEN = os.getenv('ECPI_TOKEN')
ECPI_USER = os.getenv('ECPI_USER')
ecpi_repo_url = f'https://{ECPI_USER}:{ECPI_TOKEN}@drf-gitlab.cea.fr/svom/ECLAIRs.git'


# NOTE: git configuration uses posix paths!! The following lines do not work in windows:
# ECPI_MODULES = {
#     'dpco': osp.join("src", "ecpi", "process", "dpco"),
#     'cali': osp.join("src", "ecpi", "process", "cali"),
#     'bube': osp.join("src", "ecpi", "process", "bube"),
#     'imag': osp.join("src", "ecpi", "process", "imag"),
#     'mosa': osp.join("src", "ecpi", "process", "mosa"),
#     'spex': osp.join("src", "ecpi", "process", "spex"),
#     'simu': osp.join("src", "ecpi", "simu")
# }
ECPI_MODULES = {
    'dpco': ["src/ecpi/process/dpco"],
    'cali': ["src/ecpi/process/cali"],
    'bube': ["src/ecpi/process/bube"],
    'imag': ["src/ecpi/process/imag"],
    'mosa': ["src/ecpi/process/mosa"],
    'spex': ["src/ecpi/process/spex"],
    'simu': ["src/ecpi/simu", "src/ecpi/extras/simu"]
}


# We implement update method
[docs]class EcpiProgress(RemoteProgress):
[docs] def update(self, op_code, cur_count, max_count=None, message=''): if message: print(message)
[docs]def add_args(): """Retrieve command line options.""" parser = argparse.ArgumentParser( add_help=True, usage="ecpi_co ecpi_module git_branch", description="Retrieves a ECLAIRs submodule for local development in CWD (default ECPI_HOME).", ) parser.add_argument( "ecpi_mod", help="Submodule tto be retrieved from the eclairs-gp gitlab repository.", ) parser.add_argument( "ecpi_branch", help="Existing branch into the eclairs-gp gitlab repository." ) return parser.parse_args()
[docs]def check_args(args): if args.ecpi_mod not in ECPI_MODULES: print(f"Module [{args.ecpi_mod}] is not a retrievable module in *eclair-gp*!") return False if args.ecpi_branch.find('dev') != 0: print("By convention ECPI development branches must start with 'dev[_-][0-9]{3,}'!") return False if args.ecpi_branch.lower() == 'dev': print("You cannot clone [dev] branch. This branch is protected!") return False return True
[docs]def check_env_var(env_var, lines): ecpi_dir_val = None for line in lines: # We avoid commented lines line = line.strip() if len(line) == 0 or line[0] in ['#', '!', ';']: continue if line.find(env_var) >= 0: print(f"Found variable [{env_var}] in line [{line}]") fields = line.split('=') if len(fields) > 1: ecpi_dir_val = fields[1] # print(ecpi_root_val, lines) ecpi_dir_val = ecpi_dir_val.replace('\n', '') if ecpi_dir_val is None: print('Corrupted ecpi configuration file!') return False env_ecpi_dir = os.getenv(env_var) if env_ecpi_dir is None: print('Inactive ECPI environment variables. Run "source .ect/ecpirc" in your ECPI_HOME dir!') return False if ecpi_dir_val.find(env_ecpi_dir) < 0: err_msg = f"""Your environment variables do not match your ECPI configuration! -->>> Environment variable {env_var} is [{env_ecpi_dir}] -->>> Local configuration for {env_var} is [{ecpi_dir_val}] """ print(err_msg) return False return True
[docs]def search_config_dir_in_parents(dir_name): pth_dir = Path(os.getcwd()) exist_dir = False local_dir = '' for path in pth_dir.parents: print(f"Looking for {dir_name} in directory: {path} ...", end="") local_dir = osp.join(path, dir_name) if osp.isdir(local_dir): print("Found!") exist_dir = True break print("Not found!") print("\nParsing parent folders... Done!\n") if not exist_dir: return None return local_dir
[docs]def check_ecpi_config(): config_file = osp.join('.ect', 'ecpirc') lines = [] abs_path_file = osp.join(os.getcwd(), config_file) if osp.isfile(abs_path_file): with open(abs_path_file, 'r') as f: lines = f.readlines() else: abs_path_file = osp.join(search_config_dir_in_parents('.ect'), config_file) if osp.isfile(abs_path_file): with open(abs_path_file, 'r') as f: lines = f.readlines() if not lines: print('It looks current working directory in not an ECPI_HOME subtree!') return False print("Checking environment variables to match with local ecpi configuration...") return check_env_var('ECPI_ROOT', lines) and check_env_var('ECPI_HOME', lines)
[docs]def has_git_dir(): has_git = False cwd = os.getcwd() if osp.isdir(osp.join(cwd, 'local')) or osp.isdir(osp.join(cwd, '.git')): print(f'Current directory has already a git directory. Skipping!') has_git = True elif search_config_dir_in_parents('.git') is not None: print(f'Current directory is in a git subtree directory. Skipping!') has_git = True return has_git
[docs]def update_ecpi_module_path(args, loc_dir): assert isinstance(loc_dir, str) ecpi_root = os.getenv('ECPI_ROOT') root_mod_dir = osp.dirname( osp.join(ecpi_root, loc_dir.replace('src'+osp.sep, '')) ) home_mod_dir = osp.dirname(osp.join(args.local_root, loc_dir)) path_string = f""" __path__ = [ '{home_mod_dir}', '{root_mod_dir}' ] """ try: with open(osp.join(root_mod_dir, '__init__.py'), 'a') as f: f.writelines(path_string) except: print(f'Error updating module file in {root_mod_dir}!') return False return True
# main function for an entry-point must be without arguments # arguments must be added with the add_args function
[docs]def main(): args = add_args() if not check_args(args): print('Bad arguments!') sys.exit(1) if not check_ecpi_config(): print('Current working directory is not configured or has a wrong configuration!') sys.exit(2) if has_git_dir(): print('A git repository already exists in this subtree. Skipping!') sys.exit(3) # Checking for git version >= 2.33 git_cmd = git.Git() git_ver = git_cmd.execute(['git', '--version']) git_ver = git_ver.replace('git', '').replace('version', '').strip() if l_ver(git_ver) < l_ver('2.33'): print(f'git version is {git_ver}. You need to install at least *git 2.33.0*. Skipping!') sys.exit(4) print('Everything looks ok. Trying to clone git repository!\n') try: repo = Repo.clone_from(ecpi_repo_url, 'local', sparse=True, branch=args.ecpi_branch, progress=EcpiProgress() ) except: print(f"Error cloning branch [{args.ecpi_branch}] into local repository. Maybe wrong name!") sys.exit(3) # Adding module access path to local git configuration (.git/info/sparse-checkout) git_root = osp.dirname(repo._get_config_path('repository')) args.__setattr__('local_root', osp.dirname(git_root)) info_file = osp.join(git_root, "info", "sparse-checkout") if osp.isfile(info_file): with open(info_file, 'a') as f: for line in ECPI_MODULES[args.ecpi_mod]: f.write(line+'\n') else: print(f"Error adding the submodule [{args.ecpi_mod}] into your sparse configuration file:") print(f"--->>> {args.ecpi_branch}") sys.exit(4) repo.git.execute(['git', 'sparse-checkout', 'reapply']) # Adding local module's path into global module's __path__ variable print(f"Adding [{args.ecpi_mod}]-subdirs into your sparse configuration file") rev = True for loc_dir in ECPI_MODULES[args.ecpi_mod]: print(f'Configuring {loc_dir} module') rev = rev and update_ecpi_module_path(args, loc_dir) if not rev: print(f"Error adding the submodule [{args.ecpi_mod}] into __path__ variable") sys.exit(5) sys.exit(0)
if __name__ == '__main__': main()