|
25 | 25 | import shutil |
26 | 26 | from abc import ABC, abstractmethod |
27 | 27 |
|
| 28 | +from packaging.version import Version |
28 | 29 |
|
29 | 30 | from snakemake.exceptions import CreateCondaEnvironmentException, WorkflowError |
30 | 31 | from snakemake.logging import logger |
@@ -374,6 +375,21 @@ def execute_deployment_script(self, env_file, deploy_file): |
374 | 375 | text=True, |
375 | 376 | ) |
376 | 377 |
|
| 378 | + def _create_env_args(self, mode: str): |
| 379 | + args = [ |
| 380 | + "--quiet", |
| 381 | + "--no-shortcuts" if ON_WINDOWS else "", |
| 382 | + ] |
| 383 | + |
| 384 | + if mode != "yaml": |
| 385 | + args.append("--yes") |
| 386 | + if self.conda.frontend == "conda" or ( |
| 387 | + self.conda.frontend == "mamba" |
| 388 | + and self.conda.frontend_version < Version("2.0.0") |
| 389 | + ): |
| 390 | + args.append("--no-default-packages") |
| 391 | + return args |
| 392 | + |
377 | 393 | def create(self, dryrun=False): |
378 | 394 | """Create the conda environment.""" |
379 | 395 | from snakemake.shell import shell |
@@ -499,12 +515,9 @@ def create(self, dryrun=False): |
499 | 515 | [ |
500 | 516 | self.frontend, |
501 | 517 | "create", |
502 | | - "--quiet", |
503 | | - "--no-shortcuts" if ON_WINDOWS else "", |
504 | | - "--yes", |
505 | | - "--no-default-packages", |
506 | 518 | f"--prefix '{env_path}'", |
507 | 519 | ] |
| 520 | + + self._create_env_args(mode="archive") |
508 | 521 | + packages |
509 | 522 | ) |
510 | 523 | if self._container_img: |
@@ -534,22 +547,18 @@ def create_env(env_file, filetype="yaml"): |
534 | 547 | ) |
535 | 548 |
|
536 | 549 | subcommand = [self.frontend] |
537 | | - yes_flag = ["--yes"] |
538 | 550 | if filetype == "yaml": |
539 | 551 | subcommand.append("env") |
540 | | - yes_flag = [] |
541 | 552 |
|
542 | 553 | cmd = ( |
543 | 554 | strict_priority |
544 | 555 | + subcommand |
545 | 556 | + [ |
546 | 557 | "create", |
547 | | - "--quiet", |
548 | | - "--no-default-packages", |
549 | 558 | f'--file "{target_env_file}"', |
550 | 559 | f'--prefix "{env_path}"', |
551 | 560 | ] |
552 | | - + yes_flag |
| 561 | + + self._create_env_args(mode=filetype) |
553 | 562 | ) |
554 | 563 | cmd = " ".join(cmd) |
555 | 564 | if self._container_img: |
@@ -692,6 +701,8 @@ def __init__( |
692 | 701 | raise ValueError("Frontend must be specified if check is True.") |
693 | 702 | self._check() |
694 | 703 |
|
| 704 | + self.frontend_version = self._get_version(self.frontend) |
| 705 | + |
695 | 706 | @property |
696 | 707 | def is_initialized(self): |
697 | 708 | return hasattr(self, "prefix_path") |
@@ -766,21 +777,31 @@ def _check(self): |
766 | 777 | "Unable to check conda installation:\n" + e.stderr.decode() |
767 | 778 | ) |
768 | 779 |
|
769 | | - def _check_version(self): |
| 780 | + def _get_version(self, frontend: str) -> Version: |
770 | 781 | from snakemake.shell import shell |
771 | | - from packaging.version import Version |
772 | 782 |
|
773 | 783 | version = shell.check_output( |
774 | | - self._get_cmd("conda --version"), stderr=subprocess.PIPE, text=True |
| 784 | + self._get_cmd(f"{frontend} --version"), stderr=subprocess.PIPE, text=True |
775 | 785 | ) |
| 786 | + |
| 787 | + def parse_version(version_matches): |
| 788 | + return Version(version_matches[0]) |
| 789 | + |
776 | 790 | version_matches = re.findall(r"\d+.\d+.\d+", version) |
777 | 791 | if len(version_matches) != 1: |
| 792 | + if frontend == "mamba": |
| 793 | + version_matches = re.findall(r"mamba (\d+.\d+.\d+)", version) |
| 794 | + if len(version_matches) == 1: |
| 795 | + return parse_version(version_matches) |
778 | 796 | raise WorkflowError( |
779 | | - f"Unable to determine conda version. 'conda --version' returned {version}" |
| 797 | + f"Unable to determine conda version. '{frontend} --version' returned:\n{version}" |
780 | 798 | ) |
781 | 799 | else: |
782 | | - version = version_matches[0] |
783 | | - if Version(version) < Version("4.2"): |
| 800 | + return parse_version(version_matches) |
| 801 | + |
| 802 | + def _check_version(self): |
| 803 | + version = self._get_version("conda") |
| 804 | + if version < Version("4.2"): |
784 | 805 | raise CreateCondaEnvironmentException( |
785 | 806 | f"Conda must be version 4.2 or later, found version {version}." |
786 | 807 | ) |
|
0 commit comments