shipit-cli 0.8.0__tar.gz → 0.9.0__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 (28) hide show
  1. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/PKG-INFO +3 -2
  2. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/pyproject.toml +4 -3
  3. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/cli.py +13 -5
  4. shipit_cli-0.9.0/src/shipit/providers/node_static.py +304 -0
  5. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/registry.py +1 -1
  6. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/staticfile.py +2 -0
  7. shipit_cli-0.9.0/src/shipit/version.py +5 -0
  8. shipit_cli-0.8.0/src/shipit/providers/node_static.py +0 -88
  9. shipit_cli-0.8.0/src/shipit/version.py +0 -5
  10. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/.gitignore +0 -0
  11. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/README.md +0 -0
  12. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/__init__.py +0 -0
  13. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/assets/php/php.ini +0 -0
  14. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/assets/wordpress/install.sh +0 -0
  15. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/assets/wordpress/wp-config.php +0 -0
  16. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/generator.py +0 -0
  17. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/procfile.py +0 -0
  18. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/base.py +0 -0
  19. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/gatsby.py +0 -0
  20. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/hugo.py +0 -0
  21. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/laravel.py +0 -0
  22. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/mkdocs.py +0 -0
  23. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/php.py +0 -0
  24. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/python.py +0 -0
  25. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/src/shipit/providers/wordpress.py +0 -0
  26. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/tests/test_e2e.py +0 -0
  27. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/tests/test_generate_shipit_examples.py +0 -0
  28. {shipit_cli-0.8.0 → shipit_cli-0.9.0}/tests/test_version.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shipit-cli
3
- Version: 0.8.0
4
- Summary: Add your description here
3
+ Version: 0.9.0
4
+ Summary: Shipit CLI is the best way to build, serve and deploy your projects anywhere.
5
5
  Project-URL: homepage, https://wasmer.io
6
6
  Project-URL: repository, https://github.com/wasmerio/shipit
7
7
  Project-URL: Changelog, https://github.com/wasmerio/shipit/changelog
@@ -10,6 +10,7 @@ Requires-Dist: dotenv>=0.9.9
10
10
  Requires-Dist: pyyaml>=6.0.2
11
11
  Requires-Dist: requests>=2.32.5
12
12
  Requires-Dist: rich>=14.1.0
13
+ Requires-Dist: semantic-version>=2.10.0
13
14
  Requires-Dist: sh>=2.2.2
14
15
  Requires-Dist: starlark-pyo3>=2025.1
15
16
  Requires-Dist: tomlkit>=0.13.3
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "shipit-cli"
3
- version = "0.8.0"
4
- description = "Add your description here"
3
+ version = "0.9.0"
4
+ description = "Shipit CLI is the best way to build, serve and deploy your projects anywhere."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
7
7
  dependencies = [
@@ -9,6 +9,7 @@ dependencies = [
9
9
  "pyyaml>=6.0.2",
10
10
  "requests>=2.32.5",
11
11
  "rich>=14.1.0",
12
+ "semantic-version>=2.10.0",
12
13
  "sh>=2.2.2",
13
14
  "starlark-pyo3>=2025.1",
14
15
  "tomlkit>=0.13.3",
@@ -36,7 +37,7 @@ only-include = ["src/shipit", "tests"]
36
37
  [tool.uv]
37
38
  dev-dependencies = [
38
39
  "aiohttp>=3.12.15",
39
- "pytest>=8.2",
40
+ "pytest>=8.4.1",
40
41
  "pytest-asyncio>=1.2.0",
41
42
  "pytest-rerunfailures>=16.0.1",
42
43
  "pytest-xdist>=3.8.0",
@@ -305,7 +305,7 @@ class DockerBuilder:
305
305
  image_name,
306
306
  command,
307
307
  *(extra_args or []),
308
- _env=os.environ, # Pass the current environment variables to the Docker client
308
+ _env={"DOCKER_BUILDKIT": "1", **os.environ}, # Pass the current environment variables to the Docker client
309
309
  _out=write_stdout,
310
310
  _err=write_stderr,
311
311
  )
@@ -370,7 +370,8 @@ RUN chmod {oct(mode)[2:]} {path.absolute()}
370
370
  base_path = self.docker_path
371
371
  shutil.rmtree(base_path, ignore_errors=True)
372
372
  base_path.mkdir(parents=True, exist_ok=True)
373
- self.docker_file_contents = "FROM debian:trixie-slim AS build\n"
373
+ self.docker_file_contents = "# syntax=docker/dockerfile:1.7-labs\n"
374
+ self.docker_file_contents += "FROM debian:trixie-slim AS build\n"
374
375
 
375
376
  self.docker_file_contents += """
376
377
  RUN apt-get update \\
@@ -378,6 +379,8 @@ RUN apt-get update \\
378
379
  build-essential gcc make autoconf libtool bison \\
379
380
  dpkg-dev pkg-config re2c locate \\
380
381
  libmariadb-dev libmariadb-dev-compat libpq-dev \\
382
+ libvips-dev default-libmysqlclient-dev libmagickwand-dev \\
383
+ libicu-dev libxml2-dev libxslt-dev \\
381
384
  sudo curl ca-certificates \\
382
385
  && rm -rf /var/lib/apt/lists/*
383
386
 
@@ -435,7 +438,11 @@ RUN curl https://mise.run | sh
435
438
  else:
436
439
  raise Exception(f"Asset {step.source} does not exist")
437
440
  else:
438
- self.docker_file_contents += f"COPY {step.source} {step.target}\n"
441
+ if step.ignore:
442
+ exclude = " \\\n" +" \\\n".join([f" --exclude={ignore}" for ignore in step.ignore]) + " \\\n "
443
+ else:
444
+ exclude = ""
445
+ self.docker_file_contents += f"COPY{exclude} {step.source} {step.target}\n"
439
446
  elif isinstance(step, EnvStep):
440
447
  env_vars = " ".join(
441
448
  [f"{key}={value}" for key, value in step.variables.items()]
@@ -538,9 +545,10 @@ class LocalBuilder:
538
545
  exe = shutil.which(program, path=PATH)
539
546
  if not exe:
540
547
  raise Exception(f"Program is not installed: {program}")
541
- cmd = sh.Command(exe) # "grep"
548
+ cmd = sh.Command("bash") # "grep"
542
549
  result = cmd(
543
- *parts[1:],
550
+ "-c",
551
+ command_line,
544
552
  _env={**env, "PATH": PATH},
545
553
  _cwd=build_path,
546
554
  _out=write_stdout,
@@ -0,0 +1,304 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import yaml
5
+ from pathlib import Path
6
+ from typing import Dict, Optional, Any, Set
7
+ from enum import Enum
8
+ from semantic_version import Version, NpmSpec
9
+
10
+
11
+ from .base import (
12
+ DetectResult,
13
+ DependencySpec,
14
+ Provider,
15
+ _exists,
16
+ MountSpec,
17
+ ServiceSpec,
18
+ VolumeSpec,
19
+ CustomCommands,
20
+ )
21
+ from .staticfile import StaticFileProvider
22
+
23
+
24
+ class PackageManager(Enum):
25
+ NPM = "npm"
26
+ PNPM = "pnpm"
27
+ YARN = "yarn"
28
+ BUN = "bun"
29
+
30
+ def as_dependency(self, path) -> DependencySpec:
31
+ dep_name = {
32
+ PackageManager.NPM: "npm",
33
+ PackageManager.PNPM: "pnpm",
34
+ PackageManager.YARN: "yarn",
35
+ PackageManager.BUN: "bun",
36
+ }[self]
37
+
38
+ default_version = None
39
+ if self == PackageManager.PNPM:
40
+ lockfile = path / self.lockfile()
41
+ lockfile_version = self.pnpm_lockfile_version(lockfile)
42
+ if lockfile_version:
43
+ if lockfile_version.startswith("5."):
44
+ default_version = "7"
45
+ elif lockfile_version.startswith("6."):
46
+ default_version = "8"
47
+
48
+ return DependencySpec(
49
+ dep_name,
50
+ env_var=f"SHIPIT_{dep_name.upper()}_VERSION",
51
+ default_version=default_version,
52
+ )
53
+
54
+ def lockfile(self) -> (str):
55
+ return {
56
+ PackageManager.NPM: "package-lock.json",
57
+ PackageManager.PNPM: "pnpm-lock.yaml",
58
+ PackageManager.YARN: "yarn.lock",
59
+ PackageManager.BUN: "bun.lockb",
60
+ }[self]
61
+
62
+ @classmethod
63
+ def pnpm_lockfile_version(cls, lockfile: Path) -> Optional[str]:
64
+ # Read line by line and return the lockfileVersion
65
+ with open(lockfile, "r") as f:
66
+ for line in f:
67
+ if "lockfileVersion" in line:
68
+ try:
69
+ config = yaml.safe_load(line)
70
+ version = config.get("lockfileVersion")
71
+ assert isinstance(version, (str, bytes))
72
+ return version
73
+ except:
74
+ pass
75
+ return None
76
+
77
+ def install_command(self, has_lockfile: bool = False) -> str:
78
+ return {
79
+ PackageManager.NPM: f"npm {'ci' if has_lockfile else 'install'}",
80
+ PackageManager.PNPM: f"pnpm install{' --frozen-lockfile' if has_lockfile else ''}",
81
+ PackageManager.YARN: f"yarn install{' --frozen-lockfile' if has_lockfile else ''}",
82
+ PackageManager.BUN: f"bun install{' --no-save' if has_lockfile else ''}",
83
+ }[self]
84
+
85
+ def run_command(self, command: str) -> str:
86
+ return {
87
+ PackageManager.NPM: f"npm run {command}",
88
+ PackageManager.PNPM: f"pnpm run {command}",
89
+ PackageManager.YARN: f"yarn run {command}",
90
+ PackageManager.BUN: f"bun run {command}",
91
+ }[self]
92
+
93
+ def run_execute_command(self, command: str) -> str:
94
+ return {
95
+ PackageManager.NPM: f"npx {command}",
96
+ PackageManager.PNPM: f"pnpx {command}",
97
+ PackageManager.YARN: f"ypx {command}",
98
+ PackageManager.BUN: f"bunx {command}",
99
+ }[self]
100
+
101
+
102
+ class StaticGenerator(Enum):
103
+ ASTRO = "astro"
104
+ VITE = "vite"
105
+ NEXT = "next"
106
+ GATSBY = "gatsby"
107
+ DOCUSAURUS = "docusaurus"
108
+ SVELTE = "svelte"
109
+ REMIX = "remix"
110
+ NUXT_OLD = "nuxt"
111
+ NUXT_V3 = "nuxt3"
112
+
113
+
114
+ class NodeStaticProvider(StaticFileProvider):
115
+ package_manager: PackageManager
116
+ package_json: Optional[Dict[str, Any]]
117
+ extra_dependencies: Set[str]
118
+
119
+ def __init__(self, path: Path, custom_commands: CustomCommands):
120
+ super().__init__(path, custom_commands)
121
+ if (path / "package-lock.json").exists():
122
+ self.package_manager = PackageManager.NPM
123
+ elif (path / "pnpm-lock.yaml").exists():
124
+ self.package_manager = PackageManager.PNPM
125
+ elif (path / "yarn.lock").exists():
126
+ self.package_manager = PackageManager.YARN
127
+ elif (path / "bun.lockb").exists():
128
+ self.package_manager = PackageManager.BUN
129
+ else:
130
+ self.package_manager = PackageManager.PNPM
131
+
132
+ self.package_json = self.parse_package_json(path)
133
+
134
+ if self.has_dependency(self.package_json, "gatsby"):
135
+ self.static_generator = StaticGenerator.GATSBY
136
+ elif self.has_dependency(self.package_json, "astro"):
137
+ self.static_generator = StaticGenerator.ASTRO
138
+ elif self.has_dependency(self.package_json, "@docusaurus/core"):
139
+ self.static_generator = StaticGenerator.DOCUSAURUS
140
+ elif self.has_dependency(self.package_json, "svelte"):
141
+ self.static_generator = StaticGenerator.SVELTE
142
+ elif self.has_dependency(self.package_json, "@remix-run/dev"):
143
+ self.static_generator = StaticGenerator.REMIX
144
+ elif self.has_dependency(self.package_json, "vite"):
145
+ self.static_generator = StaticGenerator.VITE
146
+ elif self.has_dependency(self.package_json, "next"):
147
+ self.static_generator = StaticGenerator.NEXT
148
+ elif self.has_dependency(self.package_json, "nuxt", "2") or self.has_dependency(
149
+ self.package_json, "nuxt", "1"
150
+ ):
151
+ self.static_generator = StaticGenerator.NUXT_OLD
152
+ elif self.has_dependency(self.package_json, "nuxt"):
153
+ self.static_generator = StaticGenerator.NUXT_V3
154
+
155
+ # if self.has_dependency(self.package_json, "sharp"):
156
+ # self.extra_dependencies.add("libvips")
157
+
158
+ @classmethod
159
+ def parse_package_json(cls, path: Path) -> Optional[Dict[str, Any]]:
160
+ package_json_path = path / "package.json"
161
+ if not package_json_path.exists():
162
+ return None
163
+ try:
164
+ package_json = json.loads(package_json_path.read_text())
165
+ assert isinstance(package_json, dict), (
166
+ "package.json must be a valid JSON object"
167
+ )
168
+ return package_json
169
+ except Exception:
170
+ return None
171
+
172
+ @classmethod
173
+ def has_dependency(
174
+ cls, package_json: Optional[Dict[str, Any]], dep: str, version: Optional[str] = None
175
+ ) -> bool:
176
+ if not package_json:
177
+ return False
178
+ for section in ("dependencies", "devDependencies", "peerDependencies"):
179
+ dep_section = package_json.get(section, {})
180
+ if dep in dep_section:
181
+ if version:
182
+ try:
183
+ constraint = NpmSpec(dep_section[dep])
184
+ return Version(version) in constraint
185
+ except Exception:
186
+ pass
187
+ else:
188
+ return True
189
+ return False
190
+
191
+ @classmethod
192
+ def name(cls) -> str:
193
+ return "node-static"
194
+
195
+ @classmethod
196
+ def detect(
197
+ cls, path: Path, custom_commands: CustomCommands
198
+ ) -> Optional[DetectResult]:
199
+ package_json = cls.parse_package_json(path)
200
+ if not package_json:
201
+ return None
202
+ static_generators = ["astro", "vite", "next", "nuxt", "gatsby", "svelte", "@docusaurus/core", "@remix-run/dev"]
203
+ if any(cls.has_dependency(package_json, dep) for dep in static_generators):
204
+ return DetectResult(cls.name(), 40)
205
+ return None
206
+
207
+ def initialize(self) -> None:
208
+ pass
209
+
210
+ def serve_name(self) -> str:
211
+ return self.path.name
212
+
213
+ def provider_kind(self) -> str:
214
+ return "staticsite"
215
+
216
+ def dependencies(self) -> list[DependencySpec]:
217
+ package_manager_dep = self.package_manager.as_dependency(self.path)
218
+ package_manager_dep.use_in_build = True
219
+ return [
220
+ DependencySpec(
221
+ "node",
222
+ env_var="SHIPIT_NODE_VERSION",
223
+ default_version="22",
224
+ use_in_build=True,
225
+ ),
226
+ package_manager_dep,
227
+ DependencySpec("static-web-server", use_in_serve=True),
228
+ ]
229
+
230
+ def declarations(self) -> Optional[str]:
231
+ return None
232
+
233
+ def get_output_dir(self) -> str:
234
+ if self.static_generator == StaticGenerator.NEXT:
235
+ return "out"
236
+ elif self.static_generator in [StaticGenerator.ASTRO, StaticGenerator.VITE, StaticGenerator.NUXT_OLD, StaticGenerator.NUXT_V3]:
237
+ return "dist"
238
+ elif self.static_generator in [StaticGenerator.GATSBY, StaticGenerator.REMIX]:
239
+ return "public"
240
+ elif self.static_generator in [StaticGenerator.DOCUSAURUS, StaticGenerator.SVELTE]:
241
+ return "build"
242
+ else:
243
+ return "dist"
244
+
245
+ def get_build_command(self) -> bool:
246
+ if not self.package_json:
247
+ return False
248
+ build_command = self.package_json.get("scripts", {}).get("build")
249
+ if build_command:
250
+ return self.package_manager.run_command("build")
251
+ if self.static_generator == StaticGenerator.GATSBY:
252
+ return self.package_manager.run_execute_command("gatsby build")
253
+ if self.static_generator == StaticGenerator.ASTRO:
254
+ return self.package_manager.run_execute_command("astro build")
255
+ elif self.static_generator == StaticGenerator.REMIX:
256
+ return self.package_manager.run_execute_command("remix-ssg build")
257
+ elif self.static_generator == StaticGenerator.DOCUSAURUS:
258
+ return self.package_manager.run_execute_command("docusaurus build")
259
+ elif self.static_generator == StaticGenerator.SVELTE:
260
+ return self.package_manager.run_execute_command("svelte-kit build")
261
+ elif self.static_generator == StaticGenerator.VITE:
262
+ return self.package_manager.run_execute_command("vite build")
263
+ elif self.static_generator == StaticGenerator.NEXT:
264
+ return self.package_manager.run_execute_command("next export")
265
+ elif self.static_generator == StaticGenerator.NUXT_V3:
266
+ return self.package_manager.run_execute_command("nuxi generate")
267
+ elif self.static_generator == StaticGenerator.NUXT_OLD:
268
+ return self.package_manager.run_execute_command("nuxt generate")
269
+ return False
270
+
271
+ def build_steps(self) -> list[str]:
272
+ output_dir = self.get_output_dir()
273
+ get_build_command = self.get_build_command()
274
+ lockfile = self.package_manager.lockfile()
275
+ has_lockfile = (self.path / lockfile).exists()
276
+ install_command = self.package_manager.install_command(has_lockfile=has_lockfile)
277
+ input_files = ["package.json"]
278
+ if has_lockfile:
279
+ input_files.append(lockfile)
280
+ inputs_install_files = ", ".join([f'"{file}"' for file in input_files])
281
+
282
+ return [
283
+ 'workdir(temp["build"])',
284
+ # 'run("npx corepack enable", inputs=["package.json"], group="install")',
285
+ f'run("{install_command}", inputs=[{inputs_install_files}], group="install")',
286
+ 'copy(".", ".", ignore=["node_modules", ".git"])',
287
+ f'run("{get_build_command}", outputs=["{output_dir}"], group="build")',
288
+ f'run("cp -R {output_dir}/* {{}}/".format(app["build"]))',
289
+ ]
290
+
291
+ def prepare_steps(self) -> Optional[list[str]]:
292
+ return None
293
+
294
+ def mounts(self) -> list[MountSpec]:
295
+ return [MountSpec("temp"), *super().mounts()]
296
+
297
+ def volumes(self) -> list[VolumeSpec]:
298
+ return []
299
+
300
+ def env(self) -> Optional[Dict[str, str]]:
301
+ return None
302
+
303
+ def services(self) -> list[ServiceSpec]:
304
+ return []
@@ -16,7 +16,7 @@ def providers() -> list[type[Provider]]:
16
16
  # Order matters: more specific providers first
17
17
  return [
18
18
  LaravelProvider,
19
- GatsbyProvider,
19
+ # GatsbyProvider,
20
20
  HugoProvider,
21
21
  MkdocsProvider,
22
22
  PythonProvider,
@@ -19,6 +19,8 @@ from .base import (
19
19
 
20
20
  class StaticFileProvider:
21
21
  config: Optional[dict] = None
22
+ path: Path
23
+ custom_commands: CustomCommands
22
24
 
23
25
  def __init__(self, path: Path, custom_commands: CustomCommands):
24
26
  self.path = path
@@ -0,0 +1,5 @@
1
+ __all__ = ["version", "version_info"]
2
+
3
+
4
+ version = "0.9.0"
5
+ version_info = (0, 9, 0, "final", 0)
@@ -1,88 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from pathlib import Path
4
- from typing import Dict, Optional
5
-
6
- from .base import (
7
- DetectResult,
8
- DependencySpec,
9
- Provider,
10
- _exists,
11
- _has_dependency,
12
- MountSpec,
13
- ServiceSpec,
14
- VolumeSpec,
15
- CustomCommands,
16
- )
17
-
18
-
19
- class NodeStaticProvider:
20
- def __init__(self, path: Path, custom_commands: CustomCommands):
21
- self.path = path
22
- self.custom_commands = custom_commands
23
-
24
- @classmethod
25
- def name(cls) -> str:
26
- return "node-static"
27
-
28
- @classmethod
29
- def detect(cls, path: Path, custom_commands: CustomCommands) -> Optional[DetectResult]:
30
- pkg = path / "package.json"
31
- if not pkg.exists():
32
- return None
33
- static_generators = ["astro", "vite", "next", "nuxt"]
34
- if any(_has_dependency(pkg, dep) for dep in static_generators):
35
- return DetectResult(cls.name(), 40)
36
- return None
37
-
38
- def initialize(self) -> None:
39
- pass
40
-
41
- def serve_name(self) -> str:
42
- return self.path.name
43
-
44
- def provider_kind(self) -> str:
45
- return "staticsite"
46
-
47
- def dependencies(self) -> list[DependencySpec]:
48
- return [
49
- DependencySpec(
50
- "node",
51
- env_var="SHIPIT_NODE_VERSION",
52
- default_version="22",
53
- use_in_build=True,
54
- ),
55
- DependencySpec("npm", use_in_build=True),
56
- DependencySpec("static-web-server", use_in_serve=True),
57
- ]
58
-
59
- def declarations(self) -> Optional[str]:
60
- return None
61
-
62
- def build_steps(self) -> list[str]:
63
- output_dir = "dist" if (self.path / "dist").exists() else "public"
64
- return [
65
- "run(\"npm install\", inputs=[\"package.json\", \"package-lock.json\"], group=\"install\")",
66
- "copy(\".\", \".\", ignore=[\"node_modules\", \".git\"])",
67
- f"run(\"npm run build\", outputs=[\"{output_dir}\"], group=\"build\")",
68
- f"run(\"cp -R {output_dir}/* {{}}/\".format(app[\"build\"]))",
69
- ]
70
-
71
- def prepare_steps(self) -> Optional[list[str]]:
72
- return None
73
-
74
- def commands(self) -> Dict[str, str]:
75
- output_dir = "dist" if (self.path / "dist").exists() else "public"
76
- return {"start": f'"static-web-server --root /app/{output_dir}"'}
77
-
78
- def mounts(self) -> list[MountSpec]:
79
- return [MountSpec("app")]
80
-
81
- def volumes(self) -> list[VolumeSpec]:
82
- return []
83
-
84
- def env(self) -> Optional[Dict[str, str]]:
85
- return None
86
-
87
- def services(self) -> list[ServiceSpec]:
88
- return []
@@ -1,5 +0,0 @@
1
- __all__ = ["version", "version_info"]
2
-
3
-
4
- version = "0.8.0"
5
- version_info = (0, 8, 0, "final", 0)
File without changes
File without changes
File without changes