snakemake-software-deployment-plugin-container 0.6.3__tar.gz → 0.7.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (11) hide show
  1. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/CHANGELOG.md +21 -0
  2. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/PKG-INFO +3 -3
  3. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/pyproject.toml +3 -3
  4. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/src/snakemake_software_deployment_plugin_container/__init__.py +85 -2
  5. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/tests/test_plugin.py +10 -1
  6. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/.github/workflows/ci.yml +0 -0
  7. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/.github/workflows/conventional-prs.yml +0 -0
  8. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/.github/workflows/release-please.yml +0 -0
  9. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/.gitignore +0 -0
  10. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/LICENSE +0 -0
  11. {snakemake_software_deployment_plugin_container-0.6.3 → snakemake_software_deployment_plugin_container-0.7.2}/README.md +0 -0
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.2](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.7.1...v0.7.2) (2026-09-08)
4
+
5
+
6
+ ### Performance Improvements
7
+
8
+ * explicit handling of deployment ([#25](https://github.com/snakemake/snakemake-software-deployment-plugin-container/issues/25)) ([127dff9](https://github.com/snakemake/snakemake-software-deployment-plugin-container/commit/127dff9b49f81a0fd55504676e1385b1dea977f7))
9
+
10
+ ## [0.7.1](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.7.0...v0.7.1) (2026-09-07)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * bump twine ([6a5fcdf](https://github.com/snakemake/snakemake-software-deployment-plugin-container/commit/6a5fcdf33ff93101266551449e090f3a13d569b7))
16
+
17
+ ## [0.7.0](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.6.3...v0.7.0) (2026-09-07)
18
+
19
+
20
+ ### Features
21
+
22
+ * auto-pass workflow environment variables into container ([#21](https://github.com/snakemake/snakemake-software-deployment-plugin-container/issues/21)) ([3083669](https://github.com/snakemake/snakemake-software-deployment-plugin-container/commit/3083669e9e250053508099d26cfef93ec4fa8432))
23
+
3
24
  ## [0.6.3](https://github.com/snakemake/snakemake-software-deployment-plugin-container/compare/v0.6.2...v0.6.3) (2026-07-24)
4
25
 
5
26
 
@@ -1,13 +1,13 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: snakemake-software-deployment-plugin-container
3
- Version: 0.6.3
3
+ Version: 0.7.2
4
4
  Project-URL: repository, https://github.com/snakemake/snakemake-software-deployment-plugin-container
5
5
  Project-URL: documentation, https://snakemake.github.io/snakemake-plugin-catalog/plugins/software-deployment/container.html
6
6
  Author-email: Ben Carrillo <ben.uzh@pm.me>, Johannes Köster <johannes.koester@uni-due.de>
7
7
  License-File: LICENSE
8
8
  Requires-Python: <4.0,>=3.11
9
9
  Requires-Dist: snakemake-interface-common<2.0.0,>=1.23.0
10
- Requires-Dist: snakemake-interface-software-deployment-plugins<1.0,>=0.16.0
10
+ Requires-Dist: snakemake-interface-software-deployment-plugins<1.0,>=0.19.2
11
11
  Requires-Dist: udocker<2.0.0,>=1.3.17
12
12
  Description-Content-Type: text/markdown
13
13
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "snakemake-software-deployment-plugin-container"
3
- version = "0.6.3"
3
+ version = "0.7.2"
4
4
  authors = [
5
5
  { name = "Ben Carrillo", email = "ben.uzh@pm.me" },
6
6
  { name = "Johannes Köster", email = "johannes.koester@uni-due.de" }
@@ -10,7 +10,7 @@ readme = "README.md"
10
10
  requires-python = ">=3.11,<4.0"
11
11
  dependencies = [
12
12
  "snakemake-interface-common (>=1.23.0,<2.0.0)",
13
- "snakemake-interface-software-deployment-plugins (>=0.16.0,<1.0)",
13
+ "snakemake-interface-software-deployment-plugins (>=0.19.2,<1.0)",
14
14
  "udocker (>=1.3.17,<2.0.0)",
15
15
  ]
16
16
 
@@ -63,7 +63,7 @@ exclude_lines = ["pass", "\\.\\.\\."]
63
63
  fail_under = 86.0
64
64
 
65
65
  [tool.pixi.feature.publish.pypi-dependencies]
66
- twine = ">=6.1.0,<7"
66
+ twine = ">=7.0,<8"
67
67
  build = ">=1.2.2,<2"
68
68
 
69
69
 
@@ -1,3 +1,6 @@
1
+ from pathlib import Path
2
+ from abc import abstractmethod
3
+ from snakemake_interface_software_deployment_plugins import DeployableEnvBase
1
4
  import re
2
5
 
3
6
  __author__ = "ben carrillo"
@@ -91,7 +94,7 @@ class EnvSpec(EnvSpecBase):
91
94
 
92
95
 
93
96
  # All errors should be wrapped with snakemake-interface-common.errors.WorkflowError
94
- class Env(EnvBase):
97
+ class Env(DeployableEnvBase, EnvBase):
95
98
  # image_repo is the de-referenced repository from where the image was obtained
96
99
  image_repo: str
97
100
  settings: Settings
@@ -159,11 +162,62 @@ class Env(EnvBase):
159
162
  # Return an empty tuple () if no software can be reported.
160
163
  return [SoftwareReport(name=self.spec.image_uri)]
161
164
 
165
+ def is_deployment_path_portable(self) -> bool:
166
+ """Return whether the deployment path matters for the environment, i.e.
167
+ whether the environment is portable. If this returns False, the deployment
168
+ path is considered for the deployment hash. For example, conda environments are not
169
+ portable because they hardcode the path in binaries, while containers are
170
+ portable.
171
+ """
172
+ return True
173
+
174
+ async def deploy(self) -> None:
175
+ """Deploy the environment to self.deployment_path.
176
+
177
+ When issuing shell commands, the environment should use
178
+ self.run_cmd(cmd: str) in order to ensure that it runs within eventual
179
+ parent environments (e.g. a container or an env module).
180
+ """
181
+ deploy_cmd = self.runtime_manager.deploy_cmd()
182
+ assert deploy_cmd is not None
183
+ self.deployment_path.mkdir(parents=True, exist_ok=True)
184
+ self.run_cmd(
185
+ deploy_cmd,
186
+ check=True,
187
+ )
188
+
189
+ def remove(self) -> None:
190
+ """Remove the deployed environment."""
191
+ if (
192
+ self.is_deployable()
193
+ and self.runtime_manager.deployed_image_path() is not None
194
+ ):
195
+ self.runtime_manager.deployed_image_path.unlink(missing_ok=True)
196
+
197
+ def is_deployable(self) -> bool:
198
+ return (
199
+ self.settings.runtime is Runtime.UDOCKER
200
+ or self.settings.runtime is Runtime.APPTAINER
201
+ )
202
+
162
203
 
163
204
  @dataclass
164
205
  class RuntimeManager:
165
206
  env: Env
166
207
 
208
+ def deployed_image_name(self) -> str:
209
+ return (
210
+ self.env.spec.image_uri.replace("/", "_")
211
+ .replace(":", "_")
212
+ .replace("#", "_")
213
+ )
214
+
215
+ @abstractmethod
216
+ def deployed_image_path(self) -> Path | None: ...
217
+
218
+ @abstractmethod
219
+ def deploy_cmd(self) -> str | None: ...
220
+
167
221
  def options(self) -> str:
168
222
  return "--rm"
169
223
 
@@ -217,7 +271,11 @@ class RuntimeManagerApptainer(RuntimeManager):
217
271
  return "exec"
218
272
 
219
273
  def options(self) -> str:
220
- return ""
274
+ options = ""
275
+ envvars = [f"{env_var}={os.environ[env_var]}" for env_var in self.env.envvars]
276
+ if envvars:
277
+ options += f" --env {','.join(envvars)}"
278
+ return options
221
279
 
222
280
  def workdir_option(self) -> str:
223
281
  return "--cwd"
@@ -230,6 +288,14 @@ class RuntimeManagerApptainer(RuntimeManager):
230
288
  return super().image_uri()
231
289
  return f"docker://{super().image_uri()}"
232
290
 
291
+ def deployed_image_path(self) -> Path | None:
292
+ return (self.env.deployment_path / self.deployed_image_name()).with_suffix(
293
+ ".sif"
294
+ )
295
+
296
+ def deploy_cmd(self) -> str | None:
297
+ return f"apptainer pull {self.deployed_image_path()} {self.image_uri()}"
298
+
233
299
 
234
300
  class RuntimeManagerDocker(RuntimeManager):
235
301
  def options(self) -> str:
@@ -240,11 +306,28 @@ class RuntimeManagerDocker(RuntimeManager):
240
306
  uid = os.getuid()
241
307
  gid = os.getgid()
242
308
  options += f" --user {uid}:{gid}"
309
+ for env_var in self.env.envvars:
310
+ options += f" --env {env_var}"
243
311
  return options
244
312
 
313
+ def deployed_image_path(self) -> Path | None:
314
+ return None
315
+
316
+ def deploy_cmd(self) -> str | None:
317
+ # No need to deploy anything in docker, the daemon handles that on the fly.
318
+ return None
319
+
245
320
 
246
321
  class RuntimeManagerUdocker(RuntimeManager):
247
322
  def options(self) -> str:
248
323
  options = super().options()
249
324
  options += " --nobanner --env TINI_SUBREAPER=1"
325
+ for env_var in self.env.envvars:
326
+ options += f" --env {env_var}={os.environ[env_var]}"
250
327
  return options
328
+
329
+ def deployed_image_path(self) -> Path | None:
330
+ return None
331
+
332
+ def deploy_cmd(self) -> str | None:
333
+ return f"UDOCKER_DIR={self.env.deployment_path} udocker pull {self.image_uri()}"
@@ -1,7 +1,9 @@
1
+ from collections.abc import Set
1
2
  from typing import Optional, Type
3
+ import shutil
4
+ import os
2
5
 
3
6
  import pytest
4
- import shutil
5
7
 
6
8
  from snakemake_interface_software_deployment_plugins.tests import (
7
9
  TestSoftwareDeploymentBase,
@@ -22,6 +24,10 @@ from snakemake_software_deployment_plugin_container import (
22
24
  )
23
25
 
24
26
 
27
+ os.environ["TESTVAR1"] = "testvalue"
28
+ os.environ["TESTVAR2"] = "testvalue2"
29
+
30
+
25
31
  class TestBase(TestSoftwareDeploymentBase):
26
32
  test_container = "quay.io/biocontainers/samtools:1.23.1--ha83d96e_0"
27
33
 
@@ -47,6 +53,9 @@ class TestBase(TestSoftwareDeploymentBase):
47
53
  # with exit code 0 (i.e. without error).
48
54
  return "samtools --version"
49
55
 
56
+ def get_envvars(self) -> Set[str]:
57
+ return {"TESTVAR1", "TESTVAR2"}
58
+
50
59
 
51
60
  class TestApptainerContainer(TestBase):
52
61
  __test__ = True