shipit-cli 0.21.0__tar.gz → 0.21.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 (55) hide show
  1. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/PKG-INFO +1 -1
  2. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/pyproject.toml +1 -1
  3. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/builders/docker.py +9 -4
  4. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/builders/local.py +9 -3
  5. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/cli.py +82 -15
  6. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/runners/local.py +8 -2
  7. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/runners/wasmer.py +19 -17
  8. shipit_cli-0.21.2/src/shipit/version.py +5 -0
  9. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/volumes.py +27 -13
  10. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_subdir.py +184 -4
  11. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_volumes.py +37 -0
  12. shipit_cli-0.21.0/src/shipit/version.py +0 -5
  13. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/.gitignore +0 -0
  14. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/README.md +0 -0
  15. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/__init__.py +0 -0
  16. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/assets/node/optimize-node-modules.sh +0 -0
  17. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/assets/php/php.ini +0 -0
  18. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/assets/wordpress/.htaccess +0 -0
  19. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/assets/wordpress/install.sh +0 -0
  20. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/assets/wordpress/start.php +0 -0
  21. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/assets/wordpress/wp-config.php +0 -0
  22. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/builders/__init__.py +0 -0
  23. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/builders/base.py +0 -0
  24. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/generator.py +0 -0
  25. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/procfile.py +0 -0
  26. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/base.py +0 -0
  27. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/go.py +0 -0
  28. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/hugo.py +0 -0
  29. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/install_context.py +0 -0
  30. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/jekyll.py +0 -0
  31. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/laravel.py +0 -0
  32. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/mkdocs.py +0 -0
  33. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/node.py +0 -0
  34. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/node_static.py +0 -0
  35. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/php.py +0 -0
  36. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/python.py +0 -0
  37. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/registry.py +0 -0
  38. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/staticfile.py +0 -0
  39. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/providers/wordpress.py +0 -0
  40. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/runners/__init__.py +0 -0
  41. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/runners/base.py +0 -0
  42. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/shipit_types.py +0 -0
  43. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/ui.py +0 -0
  44. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/src/shipit/utils.py +0 -0
  45. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_cli_after_deploy.py +0 -0
  46. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_e2e.py +0 -0
  47. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_generate_shipit_examples.py +0 -0
  48. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_install_context.py +0 -0
  49. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_node_provider.py +0 -0
  50. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_node_static_provider.py +0 -0
  51. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_php_provider.py +0 -0
  52. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_staticfile_provider.py +0 -0
  53. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_version.py +0 -0
  54. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_wasmer_annotations.py +0 -0
  55. {shipit_cli-0.21.0 → shipit_cli-0.21.2}/tests/test_wordpress_phpix.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shipit-cli
3
- Version: 0.21.0
3
+ Version: 0.21.2
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "shipit-cli"
3
- version = "0.21.0"
3
+ version = "0.21.2"
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"
@@ -45,12 +45,17 @@ class DockerBuildBackend:
45
45
  }
46
46
 
47
47
  def __init__(
48
- self, src_dir: Path, assets_path: Path, docker_client: Optional[str] = None,
49
- docker_opts: Optional[str] = None
48
+ self,
49
+ src_dir: Path,
50
+ assets_path: Path,
51
+ docker_client: Optional[str] = None,
52
+ docker_opts: Optional[str] = None,
53
+ shipit_dir: Optional[Path] = None,
50
54
  ) -> None:
51
55
  self.src_dir = src_dir
52
56
  self.assets_path = assets_path
53
- self.docker_path = self.src_dir / ".shipit" / "docker"
57
+ self.shipit_dir = shipit_dir or self.src_dir / ".shipit"
58
+ self.docker_path = self.shipit_dir / "docker"
54
59
  self.docker_path.mkdir(parents=True, exist_ok=True)
55
60
  self.docker_out_path = self.docker_path / "out"
56
61
  self.docker_file_path = self.docker_path / "Dockerfile"
@@ -77,7 +82,7 @@ class DockerBuildBackend:
77
82
  return self.docker_out_path / self.get_mount_path(name)
78
83
 
79
84
  def get_volume_path(self, name: str) -> Path:
80
- return self.src_dir / ".shipit" / "volumes" / name
85
+ return self.shipit_dir / "volumes" / name
81
86
 
82
87
  @property
83
88
  def is_depot(self) -> bool:
@@ -25,10 +25,16 @@ from shipit.utils import download_file
25
25
 
26
26
 
27
27
  class LocalBuildBackend:
28
- def __init__(self, src_dir: Path, assets_path: Path) -> None:
28
+ def __init__(
29
+ self,
30
+ src_dir: Path,
31
+ assets_path: Path,
32
+ shipit_dir: Optional[Path] = None,
33
+ ) -> None:
29
34
  self.src_dir = src_dir
30
35
  self.assets_path = assets_path
31
- self.local_path = self.src_dir / ".shipit" / "local"
36
+ self.shipit_dir = shipit_dir or self.src_dir / ".shipit"
37
+ self.local_path = self.shipit_dir / "local"
32
38
  self.build_path = self.local_path / "build"
33
39
  self.workdir = self.build_path
34
40
  self.runtime_path: Optional[str] = None
@@ -46,7 +52,7 @@ class LocalBuildBackend:
46
52
  return self.get_mount_path(name)
47
53
 
48
54
  def get_volume_path(self, name: str) -> Path:
49
- return self.src_dir / ".shipit" / "volumes" / name
55
+ return self.shipit_dir / "volumes" / name
50
56
 
51
57
  def execute_step(self, step: Step, env: Dict[str, str]) -> None:
52
58
  build_path = self.workdir
@@ -79,6 +79,13 @@ def default_shipit_path(project_paths: ProjectPaths) -> Path:
79
79
  )
80
80
 
81
81
 
82
+ def default_shipit_dir(project_paths: ProjectPaths) -> Path:
83
+ shipit_dir = project_paths.workspace_root / ".shipit"
84
+ if project_paths.subdir is None:
85
+ return shipit_dir
86
+ return shipit_dir / shipit_subdir_slug(project_paths.subdir)
87
+
88
+
82
89
  def resolve_project_paths(path: Path, subdir: Optional[Path] = None) -> ProjectPaths:
83
90
  workspace_root = path.resolve()
84
91
  if subdir is None:
@@ -673,6 +680,7 @@ def auto(
673
680
  ):
674
681
  run(
675
682
  project_paths.workspace_root,
683
+ subdir=Path(project_paths.subdir) if project_paths.subdir else None,
676
684
  wasmer=wasmer,
677
685
  wasmer_bin=wasmer_bin,
678
686
  docker=docker,
@@ -685,10 +693,11 @@ def auto(
685
693
  wasmer_registry=wasmer_registry,
686
694
  serve_port=serve_port,
687
695
  )
688
-
696
+
689
697
  if wasmer_deploy or wasmer_deploy_config:
690
698
  deploy(
691
699
  project_paths.workspace_root,
700
+ subdir=Path(project_paths.subdir) if project_paths.subdir else None,
692
701
  wasmer_deploy=wasmer_deploy,
693
702
  wasmer_deploy_config=wasmer_deploy_config,
694
703
  wasmer_bin=wasmer_bin,
@@ -809,6 +818,11 @@ def deploy(
809
818
  help="Project path (defaults to current directory).",
810
819
  show_default=False,
811
820
  ),
821
+ subdir: Optional[Path] = typer.Option(
822
+ None,
823
+ "--subdir",
824
+ help="App subdirectory relative to the project path.",
825
+ ),
812
826
  wasmer_deploy: bool = typer.Option(
813
827
  True,
814
828
  help="Deploy the project to Wasmer.",
@@ -840,14 +854,21 @@ def deploy(
840
854
  ) -> None:
841
855
  if not path.exists():
842
856
  raise Exception(f"The path {path} does not exist")
857
+ project_paths = resolve_project_paths(path, subdir)
858
+ shipit_dir = default_shipit_dir(project_paths)
843
859
 
844
- build_backend = LocalBuildBackend(path, ASSETS_PATH)
860
+ build_backend = LocalBuildBackend(
861
+ project_paths.workspace_root,
862
+ ASSETS_PATH,
863
+ shipit_dir=shipit_dir,
864
+ )
845
865
  runner = WasmerRunner(
846
866
  build_backend,
847
- path,
867
+ project_paths.workspace_root,
848
868
  registry=wasmer_registry,
849
869
  token=wasmer_token,
850
870
  bin=wasmer_bin,
871
+ shipit_dir=shipit_dir,
851
872
  )
852
873
 
853
874
  if wasmer_deploy_config:
@@ -863,6 +884,11 @@ def run(
863
884
  help="Project path (defaults to current directory).",
864
885
  show_default=False,
865
886
  ),
887
+ subdir: Optional[Path] = typer.Option(
888
+ None,
889
+ "--subdir",
890
+ help="App subdirectory relative to the project path.",
891
+ ),
866
892
  wasmer: bool = typer.Option(
867
893
  False,
868
894
  help="Use Wasmer to run the project.",
@@ -915,23 +941,38 @@ def run(
915
941
  ) -> None:
916
942
  if not path.exists():
917
943
  raise Exception(f"The path {path} does not exist")
944
+ project_paths = resolve_project_paths(path, subdir)
945
+ shipit_dir = default_shipit_dir(project_paths)
918
946
 
919
947
  if docker or docker_client:
920
948
  build_backend: BuildBackend = DockerBuildBackend(
921
- path, ASSETS_PATH, docker_client, docker_opts
949
+ project_paths.workspace_root,
950
+ ASSETS_PATH,
951
+ docker_client,
952
+ docker_opts,
953
+ shipit_dir=shipit_dir,
922
954
  )
923
955
  else:
924
- build_backend = LocalBuildBackend(path, ASSETS_PATH)
956
+ build_backend = LocalBuildBackend(
957
+ project_paths.workspace_root,
958
+ ASSETS_PATH,
959
+ shipit_dir=shipit_dir,
960
+ )
925
961
 
926
962
  if wasmer:
927
963
  runner: Runner = WasmerRunner(
928
964
  build_backend,
929
- path,
965
+ project_paths.workspace_root,
930
966
  registry=wasmer_registry,
931
967
  bin=wasmer_bin,
968
+ shipit_dir=shipit_dir,
932
969
  )
933
970
  else:
934
- runner = LocalRunner(build_backend, path)
971
+ runner = LocalRunner(
972
+ build_backend,
973
+ project_paths.workspace_root,
974
+ shipit_dir=shipit_dir,
975
+ )
935
976
 
936
977
  commands_to_run = resolve_run_commands(
937
978
  command_names=command_names,
@@ -941,11 +982,12 @@ def run(
941
982
 
942
983
  if commands_to_run:
943
984
  run_serve_commands(
944
- path,
985
+ project_paths.workspace_root,
945
986
  runner,
946
987
  commands_to_run,
947
988
  volume_specs=volume_specs,
948
989
  env=runtime_serve_env(serve_port),
990
+ shipit_dir=shipit_dir,
949
991
  )
950
992
  else:
951
993
  console.print("[bold]No commands specified. Use `--command` to run a command.[/bold]")
@@ -1066,13 +1108,21 @@ def plan(
1066
1108
  project_paths.workspace_root,
1067
1109
  read_shipit_subdir(shipit_file),
1068
1110
  )
1111
+ shipit_dir = default_shipit_dir(project_paths)
1069
1112
 
1070
1113
  if docker or docker_client:
1071
1114
  build_backend: BuildBackend = DockerBuildBackend(
1072
- project_paths.workspace_root, ASSETS_PATH, docker_client
1115
+ project_paths.workspace_root,
1116
+ ASSETS_PATH,
1117
+ docker_client,
1118
+ shipit_dir=shipit_dir,
1073
1119
  )
1074
1120
  else:
1075
- build_backend = LocalBuildBackend(project_paths.workspace_root, ASSETS_PATH)
1121
+ build_backend = LocalBuildBackend(
1122
+ project_paths.workspace_root,
1123
+ ASSETS_PATH,
1124
+ shipit_dir=shipit_dir,
1125
+ )
1076
1126
  if wasmer:
1077
1127
  runner: Runner = WasmerRunner(
1078
1128
  build_backend,
@@ -1080,9 +1130,14 @@ def plan(
1080
1130
  registry=wasmer_registry,
1081
1131
  token=wasmer_token,
1082
1132
  bin=wasmer_bin,
1133
+ shipit_dir=shipit_dir,
1083
1134
  )
1084
1135
  else:
1085
- runner = LocalRunner(build_backend, project_paths.workspace_root)
1136
+ runner = LocalRunner(
1137
+ build_backend,
1138
+ project_paths.workspace_root,
1139
+ shipit_dir=shipit_dir,
1140
+ )
1086
1141
 
1087
1142
  base_config = Config()
1088
1143
  base_config.commands.enrich_from_path(project_paths.app_path)
@@ -1244,6 +1299,7 @@ def build(
1244
1299
  path,
1245
1300
  read_shipit_subdir(shipit_file),
1246
1301
  )
1302
+ shipit_dir = default_shipit_dir(project_paths)
1247
1303
 
1248
1304
  if docker or docker_client:
1249
1305
  build_backend: BuildBackend = DockerBuildBackend(
@@ -1251,9 +1307,14 @@ def build(
1251
1307
  ASSETS_PATH,
1252
1308
  docker_client,
1253
1309
  docker_opts=docker_opts,
1310
+ shipit_dir=shipit_dir,
1254
1311
  )
1255
1312
  else:
1256
- build_backend = LocalBuildBackend(project_paths.workspace_root, ASSETS_PATH)
1313
+ build_backend = LocalBuildBackend(
1314
+ project_paths.workspace_root,
1315
+ ASSETS_PATH,
1316
+ shipit_dir=shipit_dir,
1317
+ )
1257
1318
  if wasmer:
1258
1319
  runner: Runner = WasmerRunner(
1259
1320
  build_backend,
@@ -1261,9 +1322,14 @@ def build(
1261
1322
  registry=wasmer_registry,
1262
1323
  token=wasmer_token,
1263
1324
  bin=wasmer_bin,
1325
+ shipit_dir=shipit_dir,
1264
1326
  )
1265
1327
  else:
1266
- runner = LocalRunner(build_backend, project_paths.workspace_root)
1328
+ runner = LocalRunner(
1329
+ build_backend,
1330
+ project_paths.workspace_root,
1331
+ shipit_dir=shipit_dir,
1332
+ )
1267
1333
 
1268
1334
  base_config = Config()
1269
1335
  base_config.commands.enrich_from_path(project_paths.app_path)
@@ -1344,7 +1410,7 @@ def build(
1344
1410
 
1345
1411
  # Build and serve
1346
1412
  build_backend.build(serve.name, env, serve.mounts or [], build_steps)
1347
- build_volumes(project_paths.workspace_root, serve)
1413
+ build_volumes(project_paths.workspace_root, serve, shipit_dir=shipit_dir)
1348
1414
  runner.build(serve)
1349
1415
  if serve.prepare and not skip_prepare:
1350
1416
  console.print("\n[bold]Running prepare step[/bold]")
@@ -1390,9 +1456,10 @@ def run_serve_commands(
1390
1456
  commands: List[str],
1391
1457
  volume_specs: Optional[List[str]] = None,
1392
1458
  env: Optional[Dict[str, str]] = None,
1459
+ shipit_dir: Optional[Path] = None,
1393
1460
  ) -> None:
1394
1461
  volume_mappings = merge_volume_mappings(
1395
- load_volume_mappings(path),
1462
+ load_volume_mappings(path, shipit_dir=shipit_dir),
1396
1463
  parse_cli_volume_mappings(volume_specs),
1397
1464
  )
1398
1465
  for command in commands:
@@ -18,10 +18,16 @@ if TYPE_CHECKING:
18
18
 
19
19
 
20
20
  class LocalRunner:
21
- def __init__(self, build_backend: BuildBackend, src_dir: Path) -> None:
21
+ def __init__(
22
+ self,
23
+ build_backend: BuildBackend,
24
+ src_dir: Path,
25
+ shipit_dir: Optional[Path] = None,
26
+ ) -> None:
22
27
  self.build_backend = build_backend
23
28
  self.src_dir = src_dir
24
- self.runner_path = self.src_dir / ".shipit" / "runner" / "local"
29
+ self.shipit_dir = shipit_dir or self.src_dir / ".shipit"
30
+ self.runner_path = self.shipit_dir / "runner" / "local"
25
31
  self.serve_bin_path = self.runner_path / "bin"
26
32
  self.prepare_bash_script = self.runner_path / "prepare" / "prepare.sh"
27
33
 
@@ -167,28 +167,28 @@ class WasmerRunner:
167
167
  },
168
168
  "phpix": {
169
169
  "dependencies": {
170
- "latest": "phpix/phpix-83-32bit@=0.2.0-rc.6",
171
- "8.3": "phpix/phpix-83-32bit@=0.2.0-rc.6",
172
- "8.3.29": "phpix/phpix-83-32bit@=0.2.0-rc.6",
173
- "8.2": "phpix/phpix-82-32bit@=0.2.0-rc.6",
174
- "8.1": "phpix/phpix-81-32bit@=0.2.0-rc.6",
170
+ "latest": "phpix/phpix-83-32bit@=0.2.0",
171
+ "8.3": "phpix/phpix-83-32bit@=0.2.0",
172
+ "8.3.29": "phpix/phpix-83-32bit@=0.2.0",
173
+ "8.2": "phpix/phpix-82-32bit@=0.2.0",
174
+ "8.1": "phpix/phpix-81-32bit@=0.2.0",
175
175
  "7.4": "php/php-32@=7.4.3301", # Note, we don't have PHPix + PHP 7.4 and never will
176
176
  },
177
177
  "architecture_dependencies": {
178
178
  "64-bit": {
179
- "latest": "phpix/phpix-83-64bit@=0.2.0-rc.6",
180
- "8.3": "phpix/phpix-83-64bit@=0.2.0-rc.6",
181
- "8.3.29": "phpix/phpix-83-64bit@=0.2.0-rc.6",
182
- "8.2": "phpix/phpix-82-64bit@=0.2.0-rc.6",
183
- "8.1": "phpix/phpix-81-64bit@=0.2.0-rc.6",
179
+ "latest": "phpix/phpix-83-64bit@=0.2.0",
180
+ "8.3": "phpix/phpix-83-64bit@=0.2.0",
181
+ "8.3.29": "phpix/phpix-83-64bit@=0.2.0",
182
+ "8.2": "phpix/phpix-82-64bit@=0.2.0",
183
+ "8.1": "phpix/phpix-81-64bit@=0.2.0",
184
184
  "7.4": "php/php-64@=7.4.3301",
185
185
  },
186
186
  "32-bit": {
187
- "latest": "phpix/phpix-83-32bit@=0.2.0-rc.6",
188
- "8.3": "phpix/phpix-83-32bit@=0.2.0-rc.6",
189
- "8.3.29": "phpix/phpix-83-32bit@=0.2.0-rc.6",
190
- "8.2": "phpix/phpix-82-32bit@=0.2.0-rc.6",
191
- "8.1": "phpix/phpix-81-32bit@=0.2.0-rc.6",
187
+ "latest": "phpix/phpix-83-32bit@=0.2.0",
188
+ "8.3": "phpix/phpix-83-32bit@=0.2.0",
189
+ "8.3.29": "phpix/phpix-83-32bit@=0.2.0",
190
+ "8.2": "phpix/phpix-82-32bit@=0.2.0",
191
+ "8.1": "phpix/phpix-81-32bit@=0.2.0",
192
192
  "7.4": "php/php-32@=7.4.3301",
193
193
  },
194
194
  },
@@ -224,10 +224,12 @@ class WasmerRunner:
224
224
  registry: Optional[str] = None,
225
225
  token: Optional[str] = None,
226
226
  bin: Optional[str] = None,
227
+ shipit_dir: Optional[Path] = None,
227
228
  ) -> None:
228
229
  self.build_backend = build_backend
229
230
  self.src_dir = src_dir
230
- self.wasmer_dir_path = self.src_dir / ".shipit" / "wasmer"
231
+ self.shipit_dir = shipit_dir or self.src_dir / ".shipit"
232
+ self.wasmer_dir_path = self.shipit_dir / "wasmer"
231
233
  self.wasmer_registry = registry
232
234
  self.wasmer_token = token
233
235
  self.bin = bin or "wasmer"
@@ -342,7 +344,7 @@ class WasmerRunner:
342
344
  self.run_serve_command(
343
345
  "bash /prepare/prepare.sh",
344
346
  volume_mappings={
345
- **load_volume_mappings(self.src_dir),
347
+ **load_volume_mappings(self.src_dir, shipit_dir=self.shipit_dir),
346
348
  "/prepare": prepare_dir,
347
349
  },
348
350
  )
@@ -0,0 +1,5 @@
1
+ __all__ = ["version", "version_info"]
2
+
3
+
4
+ version = "0.21.2"
5
+ version_info = (0, 21, 2, "final", 0)
@@ -1,22 +1,29 @@
1
1
  import json
2
2
  import shutil
3
3
  from pathlib import Path
4
- from typing import Dict
4
+ from typing import Dict, Optional
5
5
 
6
6
  from shipit.builders.base import BuildBackend
7
7
  from shipit.shipit_types import Serve, Volume
8
8
 
9
9
 
10
- def get_volumes_dir(src_dir: Path) -> Path:
11
- return src_dir / ".shipit" / "volumes"
10
+ def get_volumes_dir(src_dir: Path, shipit_dir: Optional[Path] = None) -> Path:
11
+ return (shipit_dir or src_dir / ".shipit") / "volumes"
12
12
 
13
13
 
14
- def get_volume_mappings_path(src_dir: Path) -> Path:
15
- return get_volumes_dir(src_dir) / "mappings.json"
14
+ def get_volume_mappings_path(
15
+ src_dir: Path,
16
+ shipit_dir: Optional[Path] = None,
17
+ ) -> Path:
18
+ return get_volumes_dir(src_dir, shipit_dir=shipit_dir) / "mappings.json"
16
19
 
17
20
 
18
- def build_volumes(src_dir: Path, serve: Serve) -> Dict[str, str]:
19
- volumes_dir = get_volumes_dir(src_dir)
21
+ def build_volumes(
22
+ src_dir: Path,
23
+ serve: Serve,
24
+ shipit_dir: Optional[Path] = None,
25
+ ) -> Dict[str, str]:
26
+ volumes_dir = get_volumes_dir(src_dir, shipit_dir=shipit_dir)
20
27
  volumes_dir.mkdir(parents=True, exist_ok=True)
21
28
 
22
29
  mappings = {
@@ -25,17 +32,20 @@ def build_volumes(src_dir: Path, serve: Serve) -> Dict[str, str]:
25
32
  }
26
33
  for volume in serve.volumes or []:
27
34
  volume.path.mkdir(parents=True, exist_ok=True)
28
- if _should_link_local_volume(src_dir, volume):
35
+ if _should_link_local_volume(src_dir, volume, shipit_dir=shipit_dir):
29
36
  _link_local_volume(volume)
30
37
 
31
- get_volume_mappings_path(src_dir).write_text(
38
+ get_volume_mappings_path(src_dir, shipit_dir=shipit_dir).write_text(
32
39
  json.dumps(mappings, indent=2, sort_keys=True) + "\n"
33
40
  )
34
41
  return mappings
35
42
 
36
43
 
37
- def load_volume_mappings(src_dir: Path) -> Dict[str, str]:
38
- mappings_path = get_volume_mappings_path(src_dir)
44
+ def load_volume_mappings(
45
+ src_dir: Path,
46
+ shipit_dir: Optional[Path] = None,
47
+ ) -> Dict[str, str]:
48
+ mappings_path = get_volume_mappings_path(src_dir, shipit_dir=shipit_dir)
39
49
  if not mappings_path.is_file():
40
50
  return {}
41
51
 
@@ -98,8 +108,12 @@ def _parse_volume_spec(spec: str) -> tuple[str, str]:
98
108
  return name, guest_path
99
109
 
100
110
 
101
- def _should_link_local_volume(src_dir: Path, volume: Volume) -> bool:
102
- shipit_dir = (src_dir / ".shipit").absolute()
111
+ def _should_link_local_volume(
112
+ src_dir: Path,
113
+ volume: Volume,
114
+ shipit_dir: Optional[Path] = None,
115
+ ) -> bool:
116
+ shipit_dir = (shipit_dir or src_dir / ".shipit").absolute()
103
117
  return volume.serve_path.is_absolute() and volume.serve_path.is_relative_to(
104
118
  shipit_dir
105
119
  )
@@ -52,20 +52,26 @@ def _patch_fake_build_runner(monkeypatch: pytest.MonkeyPatch):
52
52
  runner_instances = []
53
53
 
54
54
  class FakeBuildBackend:
55
- def __init__(self, src_dir: Path, assets_path: Path) -> None:
55
+ def __init__(
56
+ self,
57
+ src_dir: Path,
58
+ assets_path: Path,
59
+ shipit_dir: Path | None = None,
60
+ ) -> None:
56
61
  self.src_dir = src_dir
57
62
  self.assets_path = assets_path
63
+ self.shipit_dir = shipit_dir or src_dir / ".shipit"
58
64
  self.runtime_path = None
59
65
  build_backend_instances.append(self)
60
66
 
61
67
  def get_build_mount_path(self, name: str) -> Path:
62
- return self.src_dir / ".shipit" / "fake" / "build" / name
68
+ return self.shipit_dir / "fake" / "build" / name
63
69
 
64
70
  def get_artifact_mount_path(self, name: str) -> Path:
65
71
  return self.get_build_mount_path(name)
66
72
 
67
73
  def get_volume_path(self, name: str) -> Path:
68
- return self.src_dir / ".shipit" / "volumes" / name
74
+ return self.shipit_dir / "volumes" / name
69
75
 
70
76
  def get_runtime_path(self) -> str | None:
71
77
  return self.runtime_path
@@ -79,9 +85,16 @@ def _patch_fake_build_runner(monkeypatch: pytest.MonkeyPatch):
79
85
  }
80
86
 
81
87
  class FakeRunner:
82
- def __init__(self, build_backend, src_dir: Path) -> None:
88
+ def __init__(
89
+ self,
90
+ build_backend,
91
+ src_dir: Path,
92
+ shipit_dir: Path | None = None,
93
+ ) -> None:
83
94
  self.build_backend = build_backend
84
95
  self.src_dir = src_dir
96
+ self.shipit_dir = shipit_dir or src_dir / ".shipit"
97
+ self.calls = []
85
98
  runner_instances.append(self)
86
99
 
87
100
  def prepare_config(self, provider_config):
@@ -99,6 +112,23 @@ def _patch_fake_build_runner(monkeypatch: pytest.MonkeyPatch):
99
112
  def prepare(self, env, prepare) -> None:
100
113
  self.prepare_args = (env, prepare)
101
114
 
115
+ def has_serve_command(self, command: str) -> bool:
116
+ return True
117
+
118
+ def run_serve_command(
119
+ self,
120
+ command: str,
121
+ volume_mappings=None,
122
+ env=None,
123
+ ) -> None:
124
+ self.calls.append(
125
+ {
126
+ "command": command,
127
+ "volume_mappings": volume_mappings,
128
+ "env": env,
129
+ }
130
+ )
131
+
102
132
  monkeypatch.setattr(cli, "LocalBuildBackend", FakeBuildBackend)
103
133
  monkeypatch.setattr(cli, "LocalRunner", FakeRunner)
104
134
  return build_backend_instances, runner_instances
@@ -430,6 +460,12 @@ def test_build_recovers_subdir_from_generated_shipit(
430
460
 
431
461
  assert result.exit_code == 0, result.output
432
462
  assert build_backend_instances[-1].src_dir == tmp_path.resolve()
463
+ assert build_backend_instances[-1].shipit_dir == (
464
+ tmp_path.resolve() / ".shipit" / "apps-site"
465
+ )
466
+ assert runner_instances[-1].shipit_dir == (
467
+ tmp_path.resolve() / ".shipit" / "apps-site"
468
+ )
433
469
  serve = runner_instances[-1].serve
434
470
  assert serve.cwd.endswith("/app")
435
471
  install_step = next(
@@ -463,9 +499,107 @@ def test_build_subdir_uses_app_specific_shipit_by_default(
463
499
 
464
500
  assert result.exit_code == 0, result.output
465
501
  assert build_backend_instances[-1].src_dir == tmp_path.resolve()
502
+ assert build_backend_instances[-1].shipit_dir == (
503
+ tmp_path.resolve() / ".shipit" / "apps-site"
504
+ )
505
+ assert runner_instances[-1].shipit_dir == (
506
+ tmp_path.resolve() / ".shipit" / "apps-site"
507
+ )
466
508
  assert runner_instances[-1].serve.cwd.endswith("/app")
467
509
 
468
510
 
511
+ def test_run_subdir_uses_app_specific_shipit_dir(
512
+ tmp_path: Path,
513
+ monkeypatch: pytest.MonkeyPatch,
514
+ ) -> None:
515
+ _write_node_workspace(tmp_path)
516
+ build_backend_instances, runner_instances = _patch_fake_build_runner(
517
+ monkeypatch
518
+ )
519
+
520
+ result = runner.invoke(
521
+ cli.app,
522
+ ["run", str(tmp_path), "--subdir=apps/site", "--start"],
523
+ )
524
+
525
+ assert result.exit_code == 0, result.output
526
+ assert build_backend_instances[-1].shipit_dir == (
527
+ tmp_path.resolve() / ".shipit" / "apps-site"
528
+ )
529
+ assert runner_instances[-1].shipit_dir == (
530
+ tmp_path.resolve() / ".shipit" / "apps-site"
531
+ )
532
+ assert runner_instances[-1].calls == [
533
+ {
534
+ "command": "start",
535
+ "volume_mappings": {},
536
+ "env": {"PORT": "8080"},
537
+ }
538
+ ]
539
+
540
+
541
+ def test_deploy_subdir_uses_app_specific_shipit_dir(
542
+ tmp_path: Path,
543
+ monkeypatch: pytest.MonkeyPatch,
544
+ ) -> None:
545
+ _write_node_workspace(tmp_path)
546
+ build_backend_instances, _runner_instances = _patch_fake_build_runner(
547
+ monkeypatch
548
+ )
549
+ wasmer_runner_instances = []
550
+
551
+ class FakeWasmerRunner:
552
+ def __init__(
553
+ self,
554
+ build_backend,
555
+ src_dir: Path,
556
+ registry=None,
557
+ token=None,
558
+ bin=None,
559
+ shipit_dir: Path | None = None,
560
+ ) -> None:
561
+ self.build_backend = build_backend
562
+ self.src_dir = src_dir
563
+ self.registry = registry
564
+ self.token = token
565
+ self.bin = bin
566
+ self.shipit_dir = shipit_dir or src_dir / ".shipit"
567
+ self.deploy_calls = []
568
+ wasmer_runner_instances.append(self)
569
+
570
+ def deploy_config(self, config_path: Path) -> None:
571
+ self.deploy_config_path = config_path
572
+
573
+ def deploy(self, app_owner=None, app_name=None) -> None:
574
+ self.deploy_calls.append(
575
+ {
576
+ "app_owner": app_owner,
577
+ "app_name": app_name,
578
+ }
579
+ )
580
+
581
+ monkeypatch.setattr(cli, "WasmerRunner", FakeWasmerRunner)
582
+
583
+ result = runner.invoke(
584
+ cli.app,
585
+ ["deploy", str(tmp_path), "--subdir=apps/site"],
586
+ )
587
+
588
+ assert result.exit_code == 0, result.output
589
+ assert build_backend_instances[-1].shipit_dir == (
590
+ tmp_path.resolve() / ".shipit" / "apps-site"
591
+ )
592
+ assert wasmer_runner_instances[-1].shipit_dir == (
593
+ tmp_path.resolve() / ".shipit" / "apps-site"
594
+ )
595
+ assert wasmer_runner_instances[-1].deploy_calls == [
596
+ {
597
+ "app_owner": None,
598
+ "app_name": None,
599
+ }
600
+ ]
601
+
602
+
469
603
  def test_plan_accepts_subdir_and_reports_app_provider(tmp_path: Path) -> None:
470
604
  _write_node_workspace(tmp_path)
471
605
 
@@ -537,6 +671,52 @@ def test_auto_passes_subdir_to_generate_and_build(
537
671
  assert not (tmp_path / "Shipit").exists()
538
672
 
539
673
 
674
+ def test_auto_passes_subdir_to_run_and_deploy(
675
+ tmp_path: Path,
676
+ monkeypatch: pytest.MonkeyPatch,
677
+ ) -> None:
678
+ _write_node_workspace(tmp_path)
679
+ calls = {}
680
+
681
+ def fake_generate(path: Path, **kwargs) -> None:
682
+ calls["generate"] = (path, kwargs)
683
+ out = kwargs["out"] or cli.default_shipit_path(
684
+ cli.resolve_project_paths(path, kwargs["subdir"])
685
+ )
686
+ out.write_text('app_subdir = "apps/site"\n')
687
+
688
+ def fake_build(path: Path, **kwargs) -> None:
689
+ calls["build"] = (path, kwargs)
690
+
691
+ def fake_run(path: Path, **kwargs) -> None:
692
+ calls["run"] = (path, kwargs)
693
+
694
+ def fake_deploy(path: Path, **kwargs) -> None:
695
+ calls["deploy"] = (path, kwargs)
696
+
697
+ monkeypatch.setattr(cli, "generate", fake_generate)
698
+ monkeypatch.setattr(cli, "build", fake_build)
699
+ monkeypatch.setattr(cli, "run", fake_run)
700
+ monkeypatch.setattr(cli, "deploy", fake_deploy)
701
+
702
+ result = runner.invoke(
703
+ cli.app,
704
+ [
705
+ "auto",
706
+ str(tmp_path),
707
+ "--subdir=apps/site",
708
+ "--start",
709
+ "--wasmer-deploy",
710
+ ],
711
+ )
712
+
713
+ assert result.exit_code == 0, result.output
714
+ assert calls["run"][0] == tmp_path.resolve()
715
+ assert calls["run"][1]["subdir"] == Path("apps/site")
716
+ assert calls["deploy"][0] == tmp_path.resolve()
717
+ assert calls["deploy"][1]["subdir"] == Path("apps/site")
718
+
719
+
540
720
  @pytest.mark.parametrize(
541
721
  "subdir",
542
722
  [
@@ -89,6 +89,43 @@ def test_build_volumes_links_runtime_volume_to_host_directory(
89
89
  assert load_volume_mappings(tmp_path) == {"wp-content": str(target)}
90
90
 
91
91
 
92
+ def test_build_volumes_can_use_namespaced_shipit_directory(
93
+ tmp_path: Path,
94
+ ) -> None:
95
+ src_dir = tmp_path / "src"
96
+ src_dir.mkdir()
97
+ assets_path = tmp_path / "assets"
98
+ assets_path.mkdir()
99
+ shipit_dir = src_dir / ".shipit" / "apps-site"
100
+ build_backend = LocalBuildBackend(src_dir, assets_path, shipit_dir=shipit_dir)
101
+
102
+ target = build_backend.get_artifact_mount_path("app") / "wp-content"
103
+ target.mkdir(parents=True, exist_ok=True)
104
+
105
+ volume = Volume(
106
+ name="wp-content",
107
+ path=build_backend.get_volume_path("wp-content"),
108
+ serve_path=target,
109
+ )
110
+ serve = Serve(
111
+ name="wordpress",
112
+ provider="wordpress",
113
+ build=[],
114
+ deps=[],
115
+ commands={"start": "php -S localhost:8080 -t /app"},
116
+ volumes=[volume],
117
+ )
118
+
119
+ mappings = build_volumes(src_dir, serve, shipit_dir=shipit_dir)
120
+
121
+ assert volume.path == shipit_dir / "volumes" / "wp-content"
122
+ assert mappings == {"wp-content": str(target)}
123
+ assert load_volume_mappings(src_dir, shipit_dir=shipit_dir) == {
124
+ "wp-content": str(target)
125
+ }
126
+ assert not (src_dir / ".shipit" / "volumes" / "mappings.json").exists()
127
+
128
+
92
129
  def test_wasmer_runner_passes_volume_paths_into_wasmer_run(
93
130
  tmp_path: Path,
94
131
  monkeypatch: pytest.MonkeyPatch,
@@ -1,5 +0,0 @@
1
- __all__ = ["version", "version_info"]
2
-
3
-
4
- version = "0.21.0"
5
- version_info = (0, 21, 0, "final", 0)
File without changes
File without changes