diff --git a/snakemake/deployment/conda.py b/snakemake/deployment/conda.py index 59a91a556..8bb7327b9 100644 --- a/snakemake/deployment/conda.py +++ b/snakemake/deployment/conda.py @@ -62,8 +62,14 @@ def __init__( ): self.file = None self.name = None + self.post_deploy_file = None if env_file is not None: self.file = infer_source_file(env_file) + deploy_file = Path(self.file.get_path_or_uri()).with_suffix( + ".post-deploy.sh" + ) + if deploy_file.exists(): + self.post_deploy_file = infer_source_file(deploy_file) if env_name is not None: assert env_file is None, "bug: both env_file and env_name specified" self.name = env_name @@ -101,8 +107,9 @@ def _get_content(self): def _get_content_deploy(self): self.check_is_file_based() - deploy_file = Path(self.file).with_suffix(".post-deploy.sh") - return self.workflow.sourcecache.open(deploy_file, "rb").read() + if self.post_deploy_file: + return self.workflow.sourcecache.open(self.post_deploy_file, "rb").read() + return None @property def _env_archive_dir(self): @@ -139,6 +146,9 @@ def hash(self): md5hash.update(env_dir.encode()) if self._container_img: md5hash.update(self._container_img.url.encode()) + content_deploy = self.content_deploy + if content_deploy: + md5hash.update(content_deploy) md5hash.update(self.content) self._hash = md5hash.hexdigest() return self._hash @@ -148,6 +158,9 @@ def content_hash(self): if self._content_hash is None: md5hash = hashlib.md5() md5hash.update(self.content) + content_deploy = self.content_deploy + if content_deploy: + md5hash.update(content_deploy) self._content_hash = md5hash.hexdigest() return self._content_hash @@ -317,11 +330,7 @@ def create(self, dryrun=False): tmp.write(self.content) env_file = tmp.name tmp_env_file = tmp.name - if ( - Path(self.file.get_path_or_uri()) - .with_suffix(".post-deploy.sh") - .exists() - ): + if self.post_deploy_file: with tempfile.NamedTemporaryFile( delete=False, suffix=".post-deploy.sh" ) as tmp: @@ -331,8 +340,7 @@ def create(self, dryrun=False): tmp_deploy_file = tmp.name else: env_file = env_file.get_path_or_uri() - if Path(env_file).with_suffix(".post-deploy.sh").exists(): - deploy_file = Path(env_file).with_suffix(".post-deploy.sh") + deploy_file = self.post_deploy_file env_path = self.address diff --git a/tests/test_deploy_hashing/Snakefile b/tests/test_deploy_hashing/Snakefile new file mode 100644 index 000000000..9fe47395a --- /dev/null +++ b/tests/test_deploy_hashing/Snakefile @@ -0,0 +1,19 @@ +rule all: + input: + expand("{s}.txt", s=["a", "b"]) + +rule a: + output: + "a.txt" + conda: + "a.yaml" + shell: + "touch {output}" + +rule b: + output: + "b.txt" + conda: + "b.yaml" + shell: + "touch {output}" \ No newline at end of file diff --git a/tests/test_deploy_hashing/a.post-deploy.sh b/tests/test_deploy_hashing/a.post-deploy.sh new file mode 100644 index 000000000..ebca5bab2 --- /dev/null +++ b/tests/test_deploy_hashing/a.post-deploy.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +echo "test" > $CONDA_PREFIX/a.txt \ No newline at end of file diff --git a/tests/test_deploy_hashing/a.yaml b/tests/test_deploy_hashing/a.yaml new file mode 100644 index 000000000..50d99e291 --- /dev/null +++ b/tests/test_deploy_hashing/a.yaml @@ -0,0 +1,5 @@ +channels: + - bioconda + - conda-forge +dependencies: + - python =3.10 diff --git a/tests/test_deploy_hashing/b.yaml b/tests/test_deploy_hashing/b.yaml new file mode 100644 index 000000000..50d99e291 --- /dev/null +++ b/tests/test_deploy_hashing/b.yaml @@ -0,0 +1,5 @@ +channels: + - bioconda + - conda-forge +dependencies: + - python =3.10 diff --git a/tests/test_deploy_hashing/expected-results/a.txt b/tests/test_deploy_hashing/expected-results/a.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/test_deploy_hashing/expected-results/b.txt b/tests/test_deploy_hashing/expected-results/b.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/tests.py b/tests/tests.py index 2e54c4c2f..293c55747 100644 --- a/tests/tests.py +++ b/tests/tests.py @@ -434,6 +434,12 @@ def test_deploy_script(): run(dpath("test_deploy_script"), use_conda=True) +@skip_on_windows +def test_deploy_hashing(): + tmpdir = run(dpath("test_deploy_hashing"), use_conda=True, cleanup=False) + assert len(next(os.walk(os.path.join(tmpdir, ".snakemake/conda")))[1]) == 2 + + def test_conda_custom_prefix(): run( dpath("test_conda_custom_prefix"),