shipit-cli 0.16.0__tar.gz → 0.17.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 (39) hide show
  1. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/PKG-INFO +2 -1
  2. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/pyproject.toml +2 -1
  3. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/assets/wordpress/wp-config.php +1 -1
  4. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/builders/docker.py +10 -3
  5. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/go.py +1 -1
  6. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/hugo.py +23 -2
  7. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/laravel.py +1 -1
  8. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/node_static.py +18 -5
  9. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/php.py +17 -2
  10. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/runners/wasmer.py +36 -15
  11. shipit_cli-0.17.0/src/shipit/version.py +5 -0
  12. shipit_cli-0.16.0/src/shipit/version.py +0 -5
  13. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/.gitignore +0 -0
  14. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/README.md +0 -0
  15. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/__init__.py +0 -0
  16. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/assets/php/php.ini +0 -0
  17. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/assets/wordpress/install.sh +0 -0
  18. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/builders/__init__.py +0 -0
  19. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/builders/base.py +0 -0
  20. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/builders/local.py +0 -0
  21. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/cli.py +0 -0
  22. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/generator.py +0 -0
  23. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/procfile.py +0 -0
  24. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/base.py +0 -0
  25. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/jekyll.py +0 -0
  26. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/mkdocs.py +0 -0
  27. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/python.py +0 -0
  28. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/registry.py +0 -0
  29. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/staticfile.py +0 -0
  30. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/providers/wordpress.py +0 -0
  31. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/runners/__init__.py +0 -0
  32. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/runners/base.py +0 -0
  33. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/runners/local.py +0 -0
  34. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/shipit_types.py +0 -0
  35. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/ui.py +0 -0
  36. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/src/shipit/utils.py +0 -0
  37. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/tests/test_e2e.py +0 -0
  38. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/tests/test_generate_shipit_examples.py +0 -0
  39. {shipit_cli-0.16.0 → shipit_cli-0.17.0}/tests/test_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shipit-cli
3
- Version: 0.16.0
3
+ Version: 0.17.0
4
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
@@ -12,6 +12,7 @@ Requires-Dist: pydantic>=2.12.4
12
12
  Requires-Dist: pyyaml>=6.0.2
13
13
  Requires-Dist: requests>=2.32.5
14
14
  Requires-Dist: rich>=14.1.0
15
+ Requires-Dist: ripgrep-python>=0.1.0
15
16
  Requires-Dist: semantic-version>=2.10.0
16
17
  Requires-Dist: sh>=2.2.2
17
18
  Requires-Dist: toml>=0.10.2
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "shipit-cli"
3
- version = "0.16.0"
3
+ version = "0.17.0"
4
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"
@@ -17,6 +17,7 @@ dependencies = [
17
17
  "tomlkit>=0.13.3",
18
18
  "typer>=0.16.1",
19
19
  "toml>=0.10.2",
20
+ "ripgrep-python>=0.1.0",
20
21
  ]
21
22
 
22
23
  [project.urls]
@@ -73,7 +73,7 @@ function get_env_var(string $name, string $default = '')
73
73
  }
74
74
 
75
75
  if ($default === '') {
76
- error_log("Configuration error: environment variable " . $name . " not provided.");
76
+ error_log("Warning: env var " . $name . " was not provided.");
77
77
  }
78
78
 
79
79
  return $default;
@@ -38,6 +38,9 @@ class DockerBuildBackend:
38
38
  "source": "ubi:composer/composer",
39
39
  "postinstall": """composer_dir=$(mise where ubi:composer/composer); ln -s "$composer_dir/composer.phar" /usr/local/bin/composer""",
40
40
  },
41
+ "hugo": {
42
+ "source": "ubi:gohugoio/hugo[matching=extended]",
43
+ },
41
44
  }
42
45
 
43
46
  def __init__(
@@ -135,7 +138,7 @@ RUN apt-get update \\
135
138
  libmariadb-dev libmariadb-dev-compat libpq-dev \\
136
139
  libvips-dev default-libmysqlclient-dev libmagickwand-dev \\
137
140
  libicu-dev libxml2-dev libxslt-dev libyaml-dev \\
138
- sudo curl ca-certificates \\
141
+ sudo curl ca-certificates unzip git \\
139
142
  && rm -rf /var/lib/apt/lists/*
140
143
 
141
144
  SHELL ["/bin/bash", "-o", "pipefail", "-c"]
@@ -212,14 +215,18 @@ RUN curl https://mise.run | sh
212
215
  if dependency.name == "pie":
213
216
  docker_file_contents += "RUN apt-get update && apt-get -y --no-install-recommends install gcc make autoconf libtool bison re2c pkg-config libpq-dev\n"
214
217
  docker_file_contents += "RUN curl -L --output /usr/bin/pie https://github.com/php/pie/releases/download/1.2.0/pie.phar && chmod +x /usr/bin/pie\n"
215
- return
218
+ continue
219
+ elif dependency.name == "composer":
220
+ version = dependency.version or "2.9.2"
221
+ docker_file_contents += f"RUN curl -L --output /usr/bin/composer https://github.com/composer/composer/releases/download/{version}/composer.phar && chmod +x /usr/bin/composer\n"
222
+ continue
216
223
  elif dependency.name == "static-web-server":
217
224
  if dependency.version:
218
225
  docker_file_contents += (
219
226
  f"ENV SWS_INSTALL_VERSION={dependency.version}\n"
220
227
  )
221
228
  docker_file_contents += "RUN curl --proto '=https' --tlsv1.2 -sSfL https://get.static-web-server.net | sh\n"
222
- return
229
+ continue
223
230
 
224
231
  mapped_dependency = self.mise_mapper.get(dependency.name, {})
225
232
  package_name = mapped_dependency.get("source", dependency.name)
@@ -89,7 +89,7 @@ class GoProvider(Provider):
89
89
  'copy(".", ".", ignore=[".git"])',
90
90
  'env(GOCACHE="/tmp/.cache/go-build", GOPATH=temp.path)',
91
91
  'run("go build -o {} {}".format(config.serve_binary, config.go_build_file), group="build")',
92
- 'copy("{}/{}".format(temp.path, config.serve_binary), "{}/{}".format(app.path, config.serve_binary))',
92
+ 'run("cp {}/{} {}/{}".format(temp.path, config.serve_binary, app.path, config.serve_binary))',
93
93
  ]
94
94
 
95
95
  def mounts(self) -> list[MountSpec]:
@@ -17,12 +17,27 @@ from pydantic_settings import SettingsConfigDict
17
17
  import toml
18
18
  import json
19
19
  import yaml
20
+ from pyripgrep import Grep
21
+
22
+
23
+ def is_old_hugo(src_dir: Path) -> dict:
24
+ rg = Grep()
25
+
26
+ # Hard-fail signal: old Hugo
27
+ if rg.search("resources.ToCSS", path=str(src_dir)):
28
+ return True
29
+
30
+ # Modern Hugo signal
31
+ if rg.search("css.Sass", path=str(src_dir)):
32
+ return False
33
+
34
+ return False
20
35
 
21
36
 
22
37
  class HugoConfig(StaticFileConfig):
23
38
  model_config = SettingsConfigDict(extra="ignore", env_prefix="SHIPIT_")
24
39
 
25
- hugo_version: Optional[str] = "0.149.0"
40
+ hugo_version: Optional[str] = None
26
41
  static_dir: Optional[str] = "public"
27
42
 
28
43
 
@@ -55,6 +70,12 @@ class HugoProvider(StaticFileProvider):
55
70
  hugo_publish_dir = hugo_publish_dir or "public"
56
71
  assert isinstance(hugo_publish_dir, str), "publishDir in hugo config must be a string"
57
72
  config.static_dir = hugo_publish_dir
73
+
74
+ if not config.hugo_version:
75
+ if is_old_hugo(path):
76
+ config.hugo_version = "0.139.0"
77
+ else:
78
+ config.hugo_version = "0.153.2"
58
79
  return config
59
80
 
60
81
  @classmethod
@@ -94,7 +115,7 @@ class HugoProvider(StaticFileProvider):
94
115
  return [
95
116
  'workdir(temp.path)',
96
117
  'copy(".", ".", ignore=[".git"])',
97
- 'run("hugo build", group="build")',
118
+ 'run("hugo build --gc --minify", group="build")',
98
119
  'run("cp -R {}/* {}/".format(config.static_dir, static_app.path))'
99
120
  ]
100
121
 
@@ -70,7 +70,7 @@ class LaravelProvider(PhpProvider):
70
70
 
71
71
  def build_steps(self) -> list[str]:
72
72
  return [
73
- 'env(COMPOSER_HOME="/tmp", COMPOSER_FUND="0")',
73
+ 'env(COMPOSER_HOME="/tmp", COMPOSER_FUND="0", COMPOSER_ALLOW_SUPERUSER="1")',
74
74
  'workdir(app.path)',
75
75
  # "run(\"pie install php/pdo_pgsql\")",
76
76
  'run("composer install --optimize-autoloader --no-scripts --no-interaction", inputs=["composer.json", "composer.lock", "artisan"], outputs=["."], group="install")',
@@ -1,3 +1,4 @@
1
+ from shipit.providers.base import _exists
1
2
  import json
2
3
  import yaml
3
4
  from pathlib import Path
@@ -113,6 +114,7 @@ class StaticGenerator(Enum):
113
114
  NUXT_V3 = "nuxt3"
114
115
  REMIX_OLD = "remix-old"
115
116
  REMIX_V2 = "remix-v2"
117
+ REMIX_V2_CLASSIC = "remix-v2-classic"
116
118
 
117
119
  def get_output_dir(self) -> str:
118
120
  if self == StaticGenerator.NEXT:
@@ -123,13 +125,18 @@ class StaticGenerator(Enum):
123
125
  StaticGenerator.ASTRO,
124
126
  StaticGenerator.VITE,
125
127
  StaticGenerator.NUXT_OLD,
126
- StaticGenerator.REMIX_V2,
127
128
  ]:
128
129
  return "dist"
129
130
  elif self == StaticGenerator.GATSBY:
130
131
  return "public"
131
- elif self == StaticGenerator.REMIX_OLD:
132
+ elif self in [
133
+ StaticGenerator.REMIX_OLD,
134
+ StaticGenerator.REMIX,
135
+ StaticGenerator.REMIX_V2,
136
+ ]:
132
137
  return "build/client"
138
+ elif self == StaticGenerator.REMIX_V2_CLASSIC:
139
+ return "public"
133
140
  elif self in [
134
141
  StaticGenerator.DOCUSAURUS,
135
142
  StaticGenerator.DOCUSAURUS_OLD,
@@ -145,7 +152,8 @@ class StaticGenerator(Enum):
145
152
  "gatsby": [StaticGenerator.GATSBY],
146
153
  "astro": [StaticGenerator.ASTRO],
147
154
  "remix-ssg": [StaticGenerator.REMIX_OLD],
148
- "vite": [StaticGenerator.VITE, StaticGenerator.REMIX_V2],
155
+ "remix": [StaticGenerator.REMIX_V2_CLASSIC, StaticGenerator.REMIX_V2],
156
+ "vite": [StaticGenerator.VITE],
149
157
  "docusaurus": [StaticGenerator.DOCUSAURUS, StaticGenerator.DOCUSAURUS_OLD],
150
158
  "next": [StaticGenerator.NEXT],
151
159
  "nuxi": [StaticGenerator.NUXT_V3],
@@ -164,6 +172,7 @@ class StaticGenerator(Enum):
164
172
  StaticGenerator.ASTRO: "astro build",
165
173
  StaticGenerator.REMIX_OLD: "remix-ssg build",
166
174
  StaticGenerator.REMIX_V2: "vite build",
175
+ StaticGenerator.REMIX_V2_CLASSIC: "remix build",
167
176
  StaticGenerator.DOCUSAURUS: "docusaurus build",
168
177
  StaticGenerator.DOCUSAURUS_OLD: "docusaurus build",
169
178
  StaticGenerator.SVELTE: "svelte-kit build",
@@ -171,7 +180,7 @@ class StaticGenerator(Enum):
171
180
  StaticGenerator.NEXT: "next export",
172
181
  StaticGenerator.NUXT_V3: "nuxi generate",
173
182
  StaticGenerator.NUXT_OLD: "nuxt generate",
174
- StaticGenerator.REMIX: "remix-ssg build",
183
+ StaticGenerator.REMIX: "remix build",
175
184
  }[self]
176
185
 
177
186
 
@@ -233,7 +242,11 @@ class NodeStaticProvider(StaticFileProvider):
233
242
  ) or cls.has_dependency(package_json, "@remix-run/dev", "0"):
234
243
  config.static_generator = StaticGenerator.REMIX_OLD
235
244
  elif cls.has_dependency(package_json, "@remix-run/dev"):
236
- config.static_generator = StaticGenerator.REMIX_V2
245
+ has_vite = cls.has_dependency(package_json, "@remix-run/vite") or cls.has_dependency(package_json, "vite") or _exists(path, "vite.config.js", "vite.config.ts", "vite.config.mjs", "vite.config.cjs")
246
+ if has_vite:
247
+ config.static_generator = StaticGenerator.REMIX_V2
248
+ else:
249
+ config.static_generator = StaticGenerator.REMIX_V2_CLASSIC
237
250
  elif cls.has_dependency(package_json, "vite"):
238
251
  config.static_generator = StaticGenerator.VITE
239
252
  elif cls.has_dependency(package_json, "next"):
@@ -12,12 +12,18 @@ from .base import (
12
12
  VolumeSpec,
13
13
  Config,
14
14
  )
15
+ from enum import Enum
15
16
  from pydantic_settings import SettingsConfigDict
16
17
 
18
+ class PhpFramework(Enum):
19
+ Laravel = "laravel"
20
+ Symfony = "symfony"
21
+
17
22
 
18
23
  class PhpConfig(Config):
19
24
  model_config = SettingsConfigDict(extra="ignore", env_prefix="SHIPIT_")
20
25
 
26
+ framework: Optional[PhpFramework] = None
21
27
  use_composer: bool = False
22
28
  composer_build_script: Optional[str] = None
23
29
  php_version: Optional[str] = "8.3"
@@ -48,6 +54,9 @@ class PhpProvider:
48
54
  if not composer_build_script and "post-install-cmd" in composer_config["scripts"]:
49
55
  composer_build_script = "post-install-cmd"
50
56
  config = PhpConfig(use_composer=use_composer, composer_build_script=composer_build_script, **base_config.model_dump())
57
+ if not config.framework:
58
+ if _exists(path, "symfony.lock"):
59
+ config.framework = PhpFramework.Symfony
51
60
  return config
52
61
 
53
62
  @classmethod
@@ -105,12 +114,18 @@ class PhpProvider:
105
114
  )
106
115
 
107
116
  if self.config.use_composer:
108
- steps.append('env(COMPOSER_HOME="/tmp", COMPOSER_FUND="0")')
117
+ steps.append('env(COMPOSER_HOME="/tmp", COMPOSER_FUND="0", COMPOSER_ALLOW_SUPERUSER="1")')
109
118
  steps.append(
110
119
  'run("composer install --optimize-autoloader --ignore-platform-reqs --no-scripts --no-interaction", inputs=["composer.json", "composer.lock"], outputs=["."], group="install")'
111
120
  )
112
121
 
113
- steps.append('copy(".", ".", ignore=[".git"])')
122
+ dirs_to_ignore = [".git"]
123
+ if self.config.use_composer:
124
+ dirs_to_ignore.append("vendor")
125
+ if self.config.framework == PhpFramework.Symfony:
126
+ dirs_to_ignore.append("var")
127
+
128
+ steps.append('copy(".", ".", ignore={})'.format(json.dumps(dirs_to_ignore)))
114
129
 
115
130
  # Since we don't run the scripts during the install step, we need to run them after the build step
116
131
  if self.config.use_composer and self.config.composer_build_script:
@@ -1,3 +1,4 @@
1
+ from functools import reduce
1
2
  from shipit.shipit_types import EnvStep
2
3
  from shipit.shipit_types import UseStep
3
4
  import hashlib
@@ -23,6 +24,7 @@ from shipit.version import version as shipit_version
23
24
  if TYPE_CHECKING:
24
25
  from shipit.shipit_types import Step
25
26
 
27
+
26
28
  class MapperItem(TypedDict, total=False):
27
29
  dependencies: Dict[str, str]
28
30
  scripts: Set[str]
@@ -169,10 +171,14 @@ class WasmerRunner:
169
171
  step = UseStep(dependencies=deps)
170
172
  new_build_steps.append(step)
171
173
  if found_go:
172
- new_build_steps.append(EnvStep(variables={
173
- "GOOS": "wasip1",
174
- "GOARCH": "wasm",
175
- }))
174
+ new_build_steps.append(
175
+ EnvStep(
176
+ variables={
177
+ "GOOS": "wasip1",
178
+ "GOARCH": "wasm",
179
+ }
180
+ )
181
+ )
176
182
  else:
177
183
  new_build_steps.append(step)
178
184
  return new_build_steps
@@ -244,9 +250,9 @@ class WasmerRunner:
244
250
  for mount in serve.mounts:
245
251
  if program.startswith(str(mount.serve_path.absolute())):
246
252
  module_path = program_path.relative_to(mount.serve_path).as_posix()
247
- full_module_path = self.build_backend.get_artifact_mount_path(
248
- mount.name
249
- ) / module_path
253
+ full_module_path = (
254
+ self.build_backend.get_artifact_mount_path(mount.name) / module_path
255
+ )
250
256
  return full_module_path
251
257
  return None
252
258
 
@@ -338,15 +344,19 @@ class WasmerRunner:
338
344
  # It's an executable
339
345
  full_module_path = self.find_file_in_mounts(serve, program)
340
346
  if not full_module_path:
341
- raise Exception(f"Could not find {program} in the mounts or in the binaries list")
347
+ raise Exception(
348
+ f"Could not find {program} in the mounts or in the binaries list"
349
+ )
342
350
  # Check if is a WebAssembly module by checking the contents
343
351
  if not full_module_path.read_bytes().startswith(b"\0asm"):
344
- raise Exception(f"Wasmer can only execute WebAssembly modules, binary {program} is not.")
345
-
352
+ raise Exception(
353
+ f"Wasmer can only execute WebAssembly modules, binary {program} is not."
354
+ )
355
+
346
356
  if not modules:
347
357
  modules = aot()
348
358
  doc.add("module", modules)
349
-
359
+
350
360
  module = table()
351
361
  modules.append(module)
352
362
  module_name = program.replace("/", "_").lower().lstrip("_")
@@ -356,11 +366,13 @@ class WasmerRunner:
356
366
  command_module = module_name
357
367
  else:
358
368
  raise Exception(f"Binary {program} not runable in Wasmer yet")
359
-
369
+
360
370
  if not command_module:
361
371
  program_binary = binaries.get(program)
362
372
  if not program_binary:
363
- raise Exception(f"Command {command_name} is trying to run {program} but it is not available (dependencies: {', '.join(dependencies.keys())}, programs: {', '.join(binaries.keys())})")
373
+ raise Exception(
374
+ f"Command {command_name} is trying to run {program} but it is not available (dependencies: {', '.join(dependencies.keys())}, programs: {', '.join(binaries.keys())})"
375
+ )
364
376
  command_module = program_binary["script"]
365
377
  command_env.update(program_binary.get("env") or {})
366
378
 
@@ -374,7 +386,9 @@ class WasmerRunner:
374
386
  if serve.env:
375
387
  command_env.update(serve.env)
376
388
  if command_env:
377
- arr = array([f"{k}={v}" for k, v in command_env.items()]).multiline(True)
389
+ arr = array([f"{k}={v}" for k, v in command_env.items()]).multiline(
390
+ True
391
+ )
378
392
  wasi_args.add("env", arr)
379
393
  title = string("annotations.wasi", literal=False)
380
394
  command.add(title, wasi_args)
@@ -430,7 +444,14 @@ class WasmerRunner:
430
444
  yaml_config["volumes"] = volumes_yaml
431
445
 
432
446
  has_php = any(dep.name == "php" for dep in serve.deps)
433
- if has_php:
447
+ build_deps = reduce(
448
+ lambda acc, dep: acc + dep.dependencies,
449
+ [step for step in serve.build if isinstance(step, UseStep)],
450
+ [],
451
+ )
452
+ is_built_with_go = any(dep.name in ["go", "go-wasix"] for dep in build_deps)
453
+
454
+ if has_php or is_built_with_go:
434
455
  scaling = yaml_config.get("scaling", {})
435
456
  scaling["mode"] = "single_concurrency"
436
457
  yaml_config["scaling"] = scaling
@@ -0,0 +1,5 @@
1
+ __all__ = ["version", "version_info"]
2
+
3
+
4
+ version = "0.17.0"
5
+ version_info = (0, 17, 0, "final", 0)
@@ -1,5 +0,0 @@
1
- __all__ = ["version", "version_info"]
2
-
3
-
4
- version = "0.16.0"
5
- version_info = (0, 16, 0, "final", 0)
File without changes
File without changes