diff --git a/.gitignore b/.gitignore index bdecffe1d54acd670993aeb7b5d36424f03f797e..f476726deaa61419d99bf9bcfaf0d5a547da68b6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ dev-23a/ dist/ build/ *.egg-info/ +.mpsd-software-root diff --git a/src/mpsd_software_manager/mpsd_software.py b/src/mpsd_software_manager/mpsd_software.py index fe2f99d646d7b86612651e899237c0eacbf1d7ea..7121469e5cc6cddd09edfe2e0a1b0487fb68cc25 100755 --- a/src/mpsd_software_manager/mpsd_software.py +++ b/src/mpsd_software_manager/mpsd_software.py @@ -82,6 +82,7 @@ config_vars = { "metadata_tag_open": "!<meta>", "metadata_tag_close": "</meta>!", "spack_environments_repo": "https://gitlab.gwdg.de/mpsd-cs/spack-environments.git", + "init_file": ".mpsd-software-root", } @@ -1081,6 +1082,39 @@ def environment_status(mpsd_release: str, root_dir: Union[str, Path]) -> dict: return toolchain_map +def initialize_environment(root_dir: Path) -> None: + """Initialize the software environment. + + This creates a hidden file ``.mpsd-software-root`` to tag the location for + as the root of the installation. All compiled files, logs etc are written in + or below this subdirectory. + + Parameters + ---------- + root_dir : pathlib.Path + A Path object pointing to the current directory where the script was called. + + """ + # check if the root_dir is not already initialized + init_file = root_dir / config_vars["init_file"] + if init_file.exists(): + logging.getLogger("print").info( + f"Error: Directory {str(root_dir)} is already initialized." + ) + sys.exit(1) + else: + # create the init file + init_file.touch() + # note the execution in the execution summary log + # create the log file and fill it with the headers + record_script_execution_summary(root_dir=root_dir) + # record the msg in the log file + record_script_execution_summary( + root_dir=root_dir, + msg=f"Initialising MPSD software instance at {root_dir}.", + ) + + def main(): """Execute main entry point.""" parser = argparse.ArgumentParser( @@ -1104,6 +1138,7 @@ def main(): ) subparsers.required = True list_of_cmds = [ + ("init", "Initialise the MPSD software instance in the current directory"), ("available", "What is available for installation?"), ("install", "Install a software environment"), # ("reinstall", "Reinstall a package_set"), @@ -1132,11 +1167,13 @@ def main(): ) else: - subp.add_argument( - "release", - type=str, - help="Release version to prepare, install, reinstall or remove", - ) + # all commands except init need a release version + if cmd != "init": + subp.add_argument( + "release", + type=str, + help="Release version to prepare, install, reinstall or remove", + ) if cmd in ["install", "reinstall", "remove"]: # "install" command needs additional documentation package_set_help = ( @@ -1166,21 +1203,29 @@ def main(): # root dir is the place where this script is called from root_dir = Path(os.getcwd()) + # set up logging for all actions except init + if args.action != "init": + log_file = get_installer_log_file_path(args.release, args.action, root_dir) + else: + log_file = None set_up_logging( args.loglevel, - get_installer_log_file_path(args.release, args.action, root_dir), + log_file, ) # sanity check for common mistakes in command line arguments - if args.release.endswith("/"): # happens easily with autocompletion - logging.error( - f"You provided mpsd-release='{args.release}'. " - f"Did you mean '{args.release.removesuffix('/')}'?" - ) - sys.exit(1) + if args.action != "init": + if args.release.endswith("/"): # happens easily with autocompletion + logging.error( + f"You provided mpsd-release='{args.release}'. " + f"Did you mean '{args.release.removesuffix('/')}'?" + ) + sys.exit(1) # Check the command and run related function - if args.action == "remove": + if args.action == "init": + initialize_environment(root_dir) + elif args.action == "remove": remove_environment(args.release, root_dir, args.package_set) elif args.action == "start-new": start_new_environment(args.from_release, args.to_release, root_dir) diff --git a/tests/test_mpsd_software.py b/tests/test_mpsd_software.py index 514c8e5fabd8817fe693ed19e2c50d0ca60abc15..3ebd1fd69982ebb3883ac1ebd99eca4c3a46e8ed 100644 --- a/tests/test_mpsd_software.py +++ b/tests/test_mpsd_software.py @@ -520,6 +520,25 @@ def test_remove_environment(tmp_path): # done in test_install_environment_zlib +def test_initialize_environment(tmp_path): + """Test that init_file is created as expected.""" + # test that the init file is created as expected + mod.initialize_environment(tmp_path) + init_file = tmp_path / mod.config_vars["init_file"] + + assert init_file.exists() + # ensure "Initialising MPSD software ..." is in the log file + log_file = tmp_path / mod.config_vars["cmd_log_file"] + with open(log_file, "r") as f: + assert (f"Initialising MPSD software instance at {tmp_path}") in f.read() + + # test that calling again results in warning and exit code 1 + with pytest.raises(SystemExit) as pytest_wrapped_e: + mod.initialize_environment(tmp_path) + assert pytest_wrapped_e.type == SystemExit + assert pytest_wrapped_e.value.code == 1 + + def test_interface(tmp_path): """Test other things (not implemented yet).""" pass