container-magic 4.2.2__tar.gz → 4.2.3__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 (35) hide show
  1. {container_magic-4.2.2/src/container_magic.egg-info → container_magic-4.2.3}/PKG-INFO +1 -1
  2. {container_magic-4.2.2 → container_magic-4.2.3}/pyproject.toml +1 -1
  3. container_magic-4.2.3/src/container_magic/__init__.py +5 -0
  4. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/cli/main.py +3 -5
  5. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/config.py +4 -0
  6. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/runner.py +9 -9
  7. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/run_script.py +13 -15
  8. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/templates/run.sh.j2 +2 -1
  9. {container_magic-4.2.2 → container_magic-4.2.3/src/container_magic.egg-info}/PKG-INFO +1 -1
  10. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/SOURCES.txt +0 -1
  11. container_magic-4.2.2/src/container_magic/__init__.py +0 -3
  12. container_magic-4.2.2/src/container_magic/templates/_macros.j2 +0 -7
  13. {container_magic-4.2.2 → container_magic-4.2.3}/LICENSE +0 -0
  14. {container_magic-4.2.2 → container_magic-4.2.3}/README.md +0 -0
  15. {container_magic-4.2.2 → container_magic-4.2.3}/setup.cfg +0 -0
  16. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/cli/__init__.py +0 -0
  17. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/__init__.py +0 -0
  18. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/builder.py +0 -0
  19. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/cache.py +0 -0
  20. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/registry.py +0 -0
  21. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/runtime.py +0 -0
  22. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/steps.py +0 -0
  23. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/symlinks.py +0 -0
  24. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/templates.py +0 -0
  25. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/core/volumes.py +0 -0
  26. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/__init__.py +0 -0
  27. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/build_script.py +0 -0
  28. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/generators/dockerfile.py +0 -0
  29. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/registry/__init__.py +0 -0
  30. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/templates/Dockerfile.j2 +0 -0
  31. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic/templates/build.sh.j2 +0 -0
  32. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/dependency_links.txt +0 -0
  33. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/entry_points.txt +0 -0
  34. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/requires.txt +0 -0
  35. {container_magic-4.2.2 → container_magic-4.2.3}/src/container_magic.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: container-magic
3
- Version: 4.2.2
3
+ Version: 4.2.3
4
4
  Summary: A tool for rapidly creating containerised development environments
5
5
  Author-email: Mark Hedley Jones <mark@hedleyjones.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "container-magic"
7
- version = "4.2.2"
7
+ version = "4.2.3"
8
8
  description = "A tool for rapidly creating containerised development environments"
9
9
  authors = [
10
10
  {name = "Mark Hedley Jones", email = "mark@hedleyjones.com"}
@@ -0,0 +1,5 @@
1
+ """Container-magic: Rapidly create containerised development environments."""
2
+
3
+ from importlib.metadata import version
4
+
5
+ __version__ = version("container-magic")
@@ -97,7 +97,7 @@ def cli():
97
97
  "--in-place",
98
98
  "in_place",
99
99
  is_flag=True,
100
- help="Initialize in current directory instead of creating new one",
100
+ help="Initialise in current directory instead of creating new one",
101
101
  )
102
102
  def init(
103
103
  template: str,
@@ -122,7 +122,7 @@ def init(
122
122
 
123
123
  # Determine project path
124
124
  if in_place:
125
- # Initialize in current directory
125
+ # Initialise in current directory
126
126
  path = Path.cwd()
127
127
  elif path is None:
128
128
  # Create new directory with project name
@@ -141,7 +141,7 @@ def init(
141
141
  click.echo(f"Creating project at {path}")
142
142
  path.mkdir(parents=True)
143
143
  else:
144
- click.echo(f"Initializing in {path}")
144
+ click.echo(f"Initialising in {path}")
145
145
 
146
146
  # Create default config with base, development, and production stages
147
147
  # If no tag specified, append :latest
@@ -323,8 +323,6 @@ def cache_list(path: Path):
323
323
  size_mb = asset["size"] / (1024 * 1024)
324
324
  click.echo(f" {asset['filename']} ({size_mb:.2f} MB)")
325
325
  click.echo(f" URL: {asset['url']}")
326
- if asset.get("dest"):
327
- click.echo(f" Dest: {asset['dest']}")
328
326
  click.echo(f" Hash: {asset['hash'][:16]}...")
329
327
 
330
328
 
@@ -395,6 +395,10 @@ class ContainerMagicConfig(BaseModel):
395
395
  with open(path) as f:
396
396
  data = yaml.safe_load(f)
397
397
 
398
+ if not isinstance(data, dict):
399
+ print("Error: cm.yaml must contain a YAML mapping", file=sys.stderr)
400
+ sys.exit(1)
401
+
398
402
  try:
399
403
  config = cls(**data)
400
404
  except ValidationError as e:
@@ -62,7 +62,7 @@ def _detect_shell(config: ContainerMagicConfig) -> str:
62
62
 
63
63
  Priority: runtime.shell > distro field > image-name detection.
64
64
  """
65
- runtime_shell = config.runtime.shell if config.runtime else None
65
+ runtime_shell = config.runtime.shell
66
66
  if runtime_shell:
67
67
  return runtime_shell
68
68
  dev_stage = "development" if "development" in config.stages else "base"
@@ -73,14 +73,14 @@ def _detect_shell(config: ContainerMagicConfig) -> str:
73
73
  return detect_shell(resolve_base_image(dev_stage_config.frm, config.stages))
74
74
 
75
75
 
76
- def _build_feature_flags(config: ContainerMagicConfig) -> Dict[str, bool]:
76
+ def build_feature_flags(config: ContainerMagicConfig) -> Dict[str, bool]:
77
77
  """Build feature flags dict from runtime config."""
78
- runtime_features = config.runtime.features if config.runtime else []
78
+ features = config.runtime.features
79
79
  return {
80
- "display": "display" in runtime_features,
81
- "gpu": "gpu" in runtime_features,
82
- "audio": "audio" in runtime_features,
83
- "aws_credentials": "aws_credentials" in runtime_features,
80
+ "display": "display" in features,
81
+ "gpu": "gpu" in features,
82
+ "audio": "audio" in features,
83
+ "aws_credentials": "aws_credentials" in features,
84
84
  }
85
85
 
86
86
 
@@ -301,7 +301,7 @@ def run_container(
301
301
  runtime_cmd = runtime.value
302
302
  shell = _detect_shell(config)
303
303
  container_home = _detect_container_home()
304
- features = _build_feature_flags(config)
304
+ features = build_feature_flags(config)
305
305
  image = f"{config.names.image}:development"
306
306
  container_name = f"{config.names.image}-development"
307
307
 
@@ -584,7 +584,7 @@ def stop_container(config: ContainerMagicConfig) -> int:
584
584
  )
585
585
 
586
586
  # xhost cleanup if display feature enabled with Docker
587
- features = _build_feature_flags(config)
587
+ features = build_feature_flags(config)
588
588
  if features["display"] and runtime == Runtime.DOCKER and os.environ.get("DISPLAY"):
589
589
  try:
590
590
  subprocess.run(["xhost", "-local:"], capture_output=True)
@@ -6,7 +6,12 @@ from pathlib import Path
6
6
  from jinja2 import Environment, PackageLoader
7
7
 
8
8
  from container_magic.core.config import ContainerMagicConfig
9
- from container_magic.core.templates import detect_shell, resolve_base_image, resolve_distro_shell
9
+ from container_magic.core.runner import build_feature_flags
10
+ from container_magic.core.templates import (
11
+ detect_shell,
12
+ resolve_base_image,
13
+ resolve_distro_shell,
14
+ )
10
15
  from container_magic.core.volumes import expand_volumes_for_script, label_volumes
11
16
 
12
17
 
@@ -38,7 +43,7 @@ def generate_run_script(config: ContainerMagicConfig, project_dir: Path) -> None
38
43
  workdir = f"/home/{production_user}"
39
44
 
40
45
  # Determine interactive shell: runtime.shell > distro > image-name detection
41
- runtime_shell = config.runtime.shell if config.runtime else None
46
+ runtime_shell = config.runtime.shell
42
47
  prod_stage = "production" if "production" in config.stages else "base"
43
48
  stage_config = config.stages[prod_stage]
44
49
  shell = (
@@ -55,17 +60,10 @@ def generate_run_script(config: ContainerMagicConfig, project_dir: Path) -> None
55
60
  cmd_copy.command = cmd_spec.command.replace("$", r"\$")
56
61
  commands_escaped[cmd_name] = cmd_copy
57
62
 
58
- # Build feature flags
59
- runtime_features = config.runtime.features if config.runtime else []
60
- features = {
61
- "display": "display" in runtime_features,
62
- "gpu": "gpu" in runtime_features,
63
- "audio": "audio" in runtime_features,
64
- "aws_credentials": "aws_credentials" in runtime_features,
65
- }
63
+ features = build_feature_flags(config)
66
64
 
67
65
  # Expand volume variables and apply SELinux labels for production context
68
- raw_volumes = config.runtime.volumes if config.runtime else []
66
+ raw_volumes = config.runtime.volumes
69
67
  expanded_volumes = expand_volumes_for_script(raw_volumes, workdir)
70
68
  expanded_volumes = label_volumes(expanded_volumes)
71
69
 
@@ -75,13 +73,13 @@ def generate_run_script(config: ContainerMagicConfig, project_dir: Path) -> None
75
73
  workdir=workdir,
76
74
  shell=shell,
77
75
  backend=backend,
78
- privileged=config.runtime.privileged if config.runtime else False,
79
- network=config.runtime.network_mode if config.runtime else None,
76
+ privileged=config.runtime.privileged,
77
+ network=config.runtime.network_mode,
80
78
  features=features,
81
79
  volumes=expanded_volumes,
82
- devices=config.runtime.devices if config.runtime else [],
80
+ devices=config.runtime.devices,
83
81
  commands=commands_escaped,
84
- ipc=config.runtime.ipc if config.runtime else None,
82
+ ipc=config.runtime.ipc,
85
83
  )
86
84
 
87
85
  run_script = project_dir / "run.sh"
@@ -18,7 +18,7 @@ if command -v docker >/dev/null 2>&1; then
18
18
  elif command -v podman >/dev/null 2>&1; then
19
19
  RUNTIME="podman"
20
20
  else
21
- echo "Error: Neither docker nor podman found in PATH"
21
+ echo "Error: Neither docker nor podman found in PATH" >&2
22
22
  exit 1
23
23
  fi
24
24
  {%- else %}
@@ -292,6 +292,7 @@ run_{{ command_name }}() {
292
292
  local _manifest=""
293
293
  if [[ ${#MANIFEST_LINES[@]} -gt 0 ]]; then
294
294
  _manifest=$(mktemp /tmp/cm-manifest-XXXXXX)
295
+ trap 'rm -f "$_manifest"' EXIT
295
296
  printf '%s\n' "${MANIFEST_LINES[@]}" >"$_manifest"
296
297
  RUN_ARGS+=("-v" "${_manifest}:/run/cm/mounts:ro,z")
297
298
  fi
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: container-magic
3
- Version: 4.2.2
3
+ Version: 4.2.3
4
4
  Summary: A tool for rapidly creating containerised development environments
5
5
  Author-email: Mark Hedley Jones <mark@hedleyjones.com>
6
6
  License: MIT
@@ -27,6 +27,5 @@ src/container_magic/generators/dockerfile.py
27
27
  src/container_magic/generators/run_script.py
28
28
  src/container_magic/registry/__init__.py
29
29
  src/container_magic/templates/Dockerfile.j2
30
- src/container_magic/templates/_macros.j2
31
30
  src/container_magic/templates/build.sh.j2
32
31
  src/container_magic/templates/run.sh.j2
@@ -1,3 +0,0 @@
1
- """Container-magic: Rapidly create containerised development environments."""
2
-
3
- __version__ = "0.1.0"
@@ -1,7 +0,0 @@
1
- {#- Shared macros for container-magic templates -#}
2
-
3
- {%- macro symlink_mounts(workspace_name, container_base, workspace_symlinks) -%}
4
- {% for rel_path in workspace_symlinks %}
5
- RUN_ARGS+=("-v" "$(pwd)/{{ workspace_name }}/{{ rel_path }}:{{ container_base }}/{{ workspace_name }}/{{ rel_path }}:z")
6
- {% endfor -%}
7
- {%- endmacro -%}
File without changes