diff --git a/docs/snk_config_file.md b/docs/snk_config_file.md index 95aa966..f25613e 100644 --- a/docs/snk_config_file.md +++ b/docs/snk_config_file.md @@ -32,6 +32,7 @@ The following options are available for configuration in `snk.yaml`: | `additional_snakemake_args`| A list of additional arguments to pass to snakemake. | List | `[]` | | `skip_missing` | Skip any missing CLI options (i.e. those in config but not in the snk file). | Boolean | `False` | | `commands` | A list of subcommands to include in the CLI. | List | `["run", "script", "env", "profile", "info", "config"]` | +| `min_snk_cli_version` | The minimum version of the Snk CLI required to run the workflow. | String or `null` | `null` | | `cli` | Annotations for the workflow CLI parameters (see [CLI section](https://snk.wytamma.com/snk_config_file/#cli) below). | Object | None | @@ -60,6 +61,7 @@ conda: True additional_snakemake_args: - "--reason" skip_missing: True +min_snk_cli_version: "0.6.1" cli: input: type: Path @@ -81,6 +83,7 @@ In this example: - The `conda` flag is enabled (True), indicating that the workflow should utilise Conda environments for executing tasks, provided the conda command is accessible in the system environment. - Additional Snakemake arguments are specified under `additional_snakemake_args`, including --reason which will display the reasons for rule execution. - The `skip_missing` option is enabled (True), which means that only config defined in the `snk.yaml` file, will be included in the dynamically generate CLI. +- The `min_snk_cli_version` is set to "0.6.1", indicating that the workflow requires at least version 0.6.1 of the Snk CLI to run. - An annotation is provided for the `input` parameter, which is of type `str` and comes with a help message "Path to the input file". ## CLI diff --git a/pyproject.toml b/pyproject.toml index 07dff24..f801642 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ classifiers = [ ] dependencies = [ "GitPython~=3.1.0", - "snk-cli>=0.6.1", + "snk-cli>=0.7.0", ] dynamic = ["version"] diff --git a/snk/nest.py b/snk/nest.py index 35a3f9b..d79f63b 100644 --- a/snk/nest.py +++ b/snk/nest.py @@ -220,11 +220,18 @@ def handle_force_installation(name: str): snakemake_min_version = self.check_for_snakemake_min_version(workflow_path, snakefile) if snakemake_version is not None: snakemake_version_to_install_in_venv = snakemake_version - elif parse_version(self._current_snakemake_version) < parse_version( - snakemake_min_version - ): - # The current version of Snakemake is less than the minimum version required by the workflow - snakemake_version_to_install_in_venv = f">={snakemake_min_version}" + if parse_version(self._current_snakemake_version) < parse_version( + snakemake_min_version + ): + # The current version of Snakemake is less than the minimum version required by the workflow + snakemake_version_to_install_in_venv = f">={snakemake_min_version}" + min_snk_cli_version = self.check_for_snk_cli_min_version(workflow_path) + if min_snk_cli_version is not None: + if parse_version(self._current_snk_cli_version) < parse_version( + min_snk_cli_version + ): + # The current version of Snakemake is less than the minimum version required by the workflow + dependencies.append(f"snk_cli>={min_snk_cli_version}") if snakemake_version_to_install_in_venv is not None or dependencies: isolate = True if isolate: @@ -606,8 +613,11 @@ def _install_snk_cli_in_venv(self, venv_path: Path, snakemake_version=None, depe else: snakemake_version = "snakemake" try: + snk_cli_in_deps = len([dep for dep in dependencies if "snk_cli" in dep]) > 0 + if not snk_cli_in_deps: + dependencies.append("snk_cli") subprocess.run( - [pip_path, "install", snakemake_version, "snk_cli", "setuptools"] + dependencies, + [pip_path, "install", snakemake_version, "setuptools"] + dependencies, check=True, ) except subprocess.CalledProcessError as e: @@ -725,6 +735,40 @@ def _current_snakemake_version(self): return __version__ + def check_for_snk_cli_min_version(self, workflow_path: Path): + """ + Check if the workflow has a minimum version of snk_cli. + + Args: + workflow_path (Path): The path to the workflow directory. + + Returns: + str: The minimum version of snk_cli. + + Examples: + >>> nest.check_for_snk_cli_min_version(Path("/path/to/workflow")) + """ + snk_config = SnkConfig.from_workflow_dir(workflow_path, create_if_not_exists=True) + try: + return snk_config.min_snk_cli_version + except AttributeError: + return None + + @property + def _current_snk_cli_version(self): + """ + Get the current version of snk_cli. + + Returns: + str: The current version of snk_cli. + + Examples: + >>> nest.get_current_current_snk_cli_version() + """ + from snk_cli.__about__ import __version__ + + return __version__ + def validate_Snakemake_repo(self, repo: Repo): """ Validates a Snakemake repository. diff --git a/tests/data/workflow/snk.yaml b/tests/data/workflow/snk.yaml index 1896c58..fb82c64 100644 --- a/tests/data/workflow/snk.yaml +++ b/tests/data/workflow/snk.yaml @@ -1,5 +1,6 @@ additional_snakemake_args: [] art: null +min_snk_cli_version: 0.6.2 cli: hidden: hidden: true