shipit-cli 0.19.1__tar.gz → 0.19.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 (49) hide show
  1. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/PKG-INFO +22 -11
  2. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/README.md +21 -10
  3. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/pyproject.toml +1 -1
  4. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/cli.py +115 -94
  5. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/php.py +4 -0
  6. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/runners/local.py +1 -2
  7. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/runners/wasmer.py +36 -30
  8. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/ui.py +1 -1
  9. shipit_cli-0.19.2/src/shipit/version.py +5 -0
  10. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/volumes.py +38 -1
  11. shipit_cli-0.19.2/tests/test_cli_after_deploy.py +362 -0
  12. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_e2e.py +2 -2
  13. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_volumes.py +32 -3
  14. shipit_cli-0.19.1/src/shipit/version.py +0 -5
  15. shipit_cli-0.19.1/tests/test_cli_after_deploy.py +0 -159
  16. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/.gitignore +0 -0
  17. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/__init__.py +0 -0
  18. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/assets/php/php.ini +0 -0
  19. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/assets/wordpress/.htaccess +0 -0
  20. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/assets/wordpress/install.sh +0 -0
  21. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/assets/wordpress/start.php +0 -0
  22. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/assets/wordpress/wp-config.php +0 -0
  23. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/builders/__init__.py +0 -0
  24. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/builders/base.py +0 -0
  25. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/builders/docker.py +0 -0
  26. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/builders/local.py +0 -0
  27. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/generator.py +0 -0
  28. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/procfile.py +0 -0
  29. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/base.py +0 -0
  30. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/go.py +0 -0
  31. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/hugo.py +0 -0
  32. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/jekyll.py +0 -0
  33. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/laravel.py +0 -0
  34. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/mkdocs.py +0 -0
  35. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/node_static.py +0 -0
  36. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/python.py +0 -0
  37. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/registry.py +0 -0
  38. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/staticfile.py +0 -0
  39. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/providers/wordpress.py +0 -0
  40. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/runners/__init__.py +0 -0
  41. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/runners/base.py +0 -0
  42. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/shipit_types.py +0 -0
  43. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/src/shipit/utils.py +0 -0
  44. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_generate_shipit_examples.py +0 -0
  45. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_php_provider.py +0 -0
  46. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_staticfile_provider.py +0 -0
  47. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_version.py +0 -0
  48. {shipit_cli-0.19.1 → shipit_cli-0.19.2}/tests/test_wasmer_annotations.py +0 -0
  49. {shipit_cli-0.19.1 → shipit_cli-0.19.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.19.1
3
+ Version: 0.19.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
@@ -37,12 +37,13 @@ Install nothing globally; use `uvx shipit-cli` to run Shipit from anywhere.
37
37
  uvx shipit-cli .
38
38
  ```
39
39
 
40
- Running in `auto` mode will generate the `Shipit` file when needed, build the project, and can
41
- also serve it. Shipit picks the safest builder automatically and falls back to
42
- Docker or Wasmer when requested:
40
+ Running in `auto` mode will generate the `Shipit` file when needed, build the
41
+ project, and can also run it. Shipit picks the safest builder automatically
42
+ and falls back to Docker or Wasmer when requested:
43
43
 
44
- - `uvx shipit-cli . --wasmer` builds locally and serves inside Wasmer.
45
- - `uvx shipit-cli . --docker` builds it with Docker (you can customize the docker client as well, eg: `--docker-client depot`).
44
+ - `uvx shipit-cli . --wasmer` builds locally and runs inside Wasmer.
45
+ - `uvx shipit-cli . --docker` builds it with Docker (you can customize the
46
+ docker client as well, eg: `--docker-client depot`).
46
47
  - `uvx shipit-cli . --start` launches the app after building.
47
48
 
48
49
  You can combine them as needed:
@@ -56,8 +57,7 @@ uvx shipit-cli . --start --wasmer --skip-prepare
56
57
  ### Default `auto` mode
57
58
 
58
59
  Full pipeline in one command. Combine flags such as `--regenerate` to rewrite
59
- the `Shipit` file. Use
60
- `--wasmer` to run with Wasmer, or `--wasmer-deploy` to deploy to Wasmer Edge.
60
+ the `Shipit` file. Use `--wasmer` to run with Wasmer.
61
61
 
62
62
  ### `generate`
63
63
 
@@ -87,13 +87,24 @@ uvx shipit-cli build
87
87
  Run the build steps defined in `Shipit`. Append `--wasmer` to execute inside
88
88
  Wasmer, `--docker` to use Docker builds.
89
89
 
90
- ### `serve`
90
+ ### `run`
91
91
 
92
92
  ```bash
93
- uvx shipit-cli serve
93
+ uvx shipit-cli run
94
94
  ```
95
95
 
96
- Execute the start command for the project. Combine with `--wasmer` for WebAssembly execution, or `--wasmer-deploy` to deploy to Wasmer Edge.
96
+ Run explicit commands for the project. Use `--start` to run the start
97
+ command, or pass one or more `--command` values. Combine with `--wasmer`
98
+ for WebAssembly execution.
99
+
100
+ ### `deploy`
101
+
102
+ ```bash
103
+ uvx shipit-cli deploy
104
+ ```
105
+
106
+ Deploy a Wasmer package generated by `shipit build --wasmer`. Use
107
+ `--wasmer-deploy-config` to write deployment metadata instead of publishing.
97
108
 
98
109
  ## Supported Technologies
99
110
 
@@ -14,12 +14,13 @@ Install nothing globally; use `uvx shipit-cli` to run Shipit from anywhere.
14
14
  uvx shipit-cli .
15
15
  ```
16
16
 
17
- Running in `auto` mode will generate the `Shipit` file when needed, build the project, and can
18
- also serve it. Shipit picks the safest builder automatically and falls back to
19
- Docker or Wasmer when requested:
17
+ Running in `auto` mode will generate the `Shipit` file when needed, build the
18
+ project, and can also run it. Shipit picks the safest builder automatically
19
+ and falls back to Docker or Wasmer when requested:
20
20
 
21
- - `uvx shipit-cli . --wasmer` builds locally and serves inside Wasmer.
22
- - `uvx shipit-cli . --docker` builds it with Docker (you can customize the docker client as well, eg: `--docker-client depot`).
21
+ - `uvx shipit-cli . --wasmer` builds locally and runs inside Wasmer.
22
+ - `uvx shipit-cli . --docker` builds it with Docker (you can customize the
23
+ docker client as well, eg: `--docker-client depot`).
23
24
  - `uvx shipit-cli . --start` launches the app after building.
24
25
 
25
26
  You can combine them as needed:
@@ -33,8 +34,7 @@ uvx shipit-cli . --start --wasmer --skip-prepare
33
34
  ### Default `auto` mode
34
35
 
35
36
  Full pipeline in one command. Combine flags such as `--regenerate` to rewrite
36
- the `Shipit` file. Use
37
- `--wasmer` to run with Wasmer, or `--wasmer-deploy` to deploy to Wasmer Edge.
37
+ the `Shipit` file. Use `--wasmer` to run with Wasmer.
38
38
 
39
39
  ### `generate`
40
40
 
@@ -64,13 +64,24 @@ uvx shipit-cli build
64
64
  Run the build steps defined in `Shipit`. Append `--wasmer` to execute inside
65
65
  Wasmer, `--docker` to use Docker builds.
66
66
 
67
- ### `serve`
67
+ ### `run`
68
68
 
69
69
  ```bash
70
- uvx shipit-cli serve
70
+ uvx shipit-cli run
71
71
  ```
72
72
 
73
- Execute the start command for the project. Combine with `--wasmer` for WebAssembly execution, or `--wasmer-deploy` to deploy to Wasmer Edge.
73
+ Run explicit commands for the project. Use `--start` to run the start
74
+ command, or pass one or more `--command` values. Combine with `--wasmer`
75
+ for WebAssembly execution.
76
+
77
+ ### `deploy`
78
+
79
+ ```bash
80
+ uvx shipit-cli deploy
81
+ ```
82
+
83
+ Deploy a Wasmer package generated by `shipit build --wasmer`. Use
84
+ `--wasmer-deploy-config` to write deployment metadata instead of publishing.
74
85
 
75
86
  ## Supported Technologies
76
87
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "shipit-cli"
3
- version = "0.19.1"
3
+ version = "0.19.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"
@@ -36,7 +36,12 @@ from shipit.shipit_types import (
36
36
  )
37
37
  from shipit.ui import console
38
38
  from shipit.version import version as shipit_version
39
- from shipit.volumes import build_volumes, load_volume_mappings
39
+ from shipit.volumes import (
40
+ build_volumes,
41
+ load_volume_mappings,
42
+ merge_volume_mappings,
43
+ parse_cli_volume_mappings,
44
+ )
40
45
 
41
46
  app = typer.Typer(invoke_without_command=True)
42
47
 
@@ -347,7 +352,7 @@ def auto(
347
352
  ),
348
353
  wasmer: bool = typer.Option(
349
354
  False,
350
- help="Use Wasmer to build and serve the project.",
355
+ help="Use Wasmer to build and run the project.",
351
356
  ),
352
357
  wasmer_bin: Optional[str] = typer.Option(
353
358
  None,
@@ -373,18 +378,26 @@ def auto(
373
378
  False,
374
379
  help="Run the prepare command after building (defaults to True).",
375
380
  ),
376
- run_commands: Optional[List[str]] = typer.Option(
381
+ command_names: Optional[List[str]] = typer.Option(
382
+ None,
383
+ "-c",
384
+ "--command",
385
+ help="Run one or more commands after building. Can be passed multiple times.",
386
+ ),
387
+ volume_specs: Optional[List[str]] = typer.Option(
377
388
  None,
378
- "--run",
379
- help="Run one or more serve commands after building. Can be passed multiple times.",
389
+ "--volume",
390
+ help="Attach one or more volumes as NAME:/guest/path. Can be passed multiple times.",
380
391
  ),
381
392
  start: bool = typer.Option(
382
393
  False,
383
- help="Equivalent to `--run=start`.",
394
+ "--start/--no-start",
395
+ help="Equivalent to `--command=start`.",
384
396
  ),
385
397
  after_deploy: bool = typer.Option(
386
398
  False,
387
- help="Equivalent to `--run=after_deploy`.",
399
+ "--after-deploy/--no-after-deploy",
400
+ help="Equivalent to `--command=after_deploy`.",
388
401
  ),
389
402
  regenerate: bool = typer.Option(
390
403
  None,
@@ -398,30 +411,10 @@ def auto(
398
411
  False,
399
412
  help="Use a temporary Shipit file in the system temporary directory.",
400
413
  ),
401
- wasmer_deploy: Optional[bool] = typer.Option(
402
- False,
403
- help="Deploy the project to Wasmer.",
404
- ),
405
- wasmer_deploy_config: Optional[Path] = typer.Option(
406
- None,
407
- help="Save the output of the Wasmer build to a json file",
408
- ),
409
- wasmer_token: Optional[str] = typer.Option(
410
- None,
411
- help="Wasmer token.",
412
- ),
413
414
  wasmer_registry: Optional[str] = typer.Option(
414
415
  None,
415
416
  help="Wasmer registry.",
416
417
  ),
417
- wasmer_app_owner: Optional[str] = typer.Option(
418
- None,
419
- help="Owner of the Wasmer app.",
420
- ),
421
- wasmer_app_name: Optional[str] = typer.Option(
422
- None,
423
- help="Name of the Wasmer app.",
424
- ),
425
418
  install_command: Optional[str] = typer.Option(
426
419
  None,
427
420
  help="The install command to use (overwrites the default)",
@@ -451,9 +444,6 @@ def auto(
451
444
  help="The port to use (defaults to 8080).",
452
445
  ),
453
446
  ):
454
- # We assume wasmer as an active flag if we pass wasmer deploy or wasmer deploy config
455
- wasmer = wasmer or wasmer_deploy or (wasmer_deploy_config is not None)
456
-
457
447
  if not path.exists():
458
448
  raise Exception(f"The path {path} does not exist")
459
449
 
@@ -494,7 +484,6 @@ def auto(
494
484
  docker_opts=docker_opts,
495
485
  skip_docker_if_safe_build=skip_docker_if_safe_build,
496
486
  wasmer_registry=wasmer_registry,
497
- wasmer_token=wasmer_token,
498
487
  wasmer_bin=wasmer_bin,
499
488
  skip_prepare=skip_prepare,
500
489
  env_name=env_name,
@@ -502,24 +491,25 @@ def auto(
502
491
  provider=provider,
503
492
  config=config,
504
493
  )
505
- if run_commands or start or after_deploy or wasmer_deploy or wasmer_deploy_config:
506
- serve(
494
+ if (
495
+ command_names
496
+ or volume_specs
497
+ or start
498
+ or after_deploy
499
+ ):
500
+ run(
507
501
  path,
508
502
  wasmer=wasmer,
509
503
  wasmer_bin=wasmer_bin,
510
504
  docker=docker,
511
505
  docker_client=docker_client,
512
- run_commands=run_commands,
506
+ docker_opts=docker_opts,
507
+ command_names=command_names,
508
+ volume_specs=volume_specs,
513
509
  start=start,
514
510
  after_deploy=after_deploy,
515
- wasmer_token=wasmer_token,
516
511
  wasmer_registry=wasmer_registry,
517
- wasmer_deploy=wasmer_deploy,
518
- wasmer_app_owner=wasmer_app_owner,
519
- wasmer_app_name=wasmer_app_name,
520
- wasmer_deploy_config=wasmer_deploy_config,
521
512
  )
522
- # deploy(path)
523
513
 
524
514
 
525
515
  @app.command(name="generate")
@@ -602,7 +592,7 @@ def generate(
602
592
  context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
603
593
  )
604
594
  def _default(ctx: typer.Context) -> None:
605
- if ctx.invoked_subcommand in ["auto", "generate", "build", "serve", "deploy", None]:
595
+ if ctx.invoked_subcommand in ["auto", "generate", "build", "run", "deploy", None]:
606
596
  print_help()
607
597
 
608
598
 
@@ -613,12 +603,57 @@ def deploy(
613
603
  help="Project path (defaults to current directory).",
614
604
  show_default=False,
615
605
  ),
606
+ wasmer_deploy: bool = typer.Option(
607
+ True,
608
+ help="Deploy the project to Wasmer.",
609
+ ),
610
+ wasmer_bin: Optional[str] = typer.Option(
611
+ None,
612
+ help="The path to the Wasmer binary.",
613
+ ),
614
+ wasmer_token: Optional[str] = typer.Option(
615
+ None,
616
+ help="Wasmer token.",
617
+ ),
618
+ wasmer_registry: Optional[str] = typer.Option(
619
+ None,
620
+ help="Wasmer registry.",
621
+ ),
622
+ wasmer_app_owner: Optional[str] = typer.Option(
623
+ None,
624
+ help="Owner of the Wasmer app.",
625
+ ),
626
+ wasmer_app_name: Optional[str] = typer.Option(
627
+ None,
628
+ help="Name of the Wasmer app.",
629
+ ),
630
+ wasmer_deploy_config: Optional[Path] = typer.Option(
631
+ None,
632
+ help="Save the output of the Wasmer build to a json file",
633
+ ),
616
634
  ) -> None:
617
- pass
635
+ if not path.exists():
636
+ raise Exception(f"The path {path} does not exist")
637
+
638
+ build_backend = LocalBuildBackend(path, ASSETS_PATH)
639
+ runner = WasmerRunner(
640
+ build_backend,
641
+ path,
642
+ registry=wasmer_registry,
643
+ token=wasmer_token,
644
+ bin=wasmer_bin,
645
+ )
646
+
647
+ if wasmer_deploy_config:
648
+ runner.deploy_config(wasmer_deploy_config)
649
+ return
618
650
 
651
+ if wasmer_deploy:
652
+ runner.deploy(app_owner=wasmer_app_owner, app_name=wasmer_app_name)
619
653
 
620
- @app.command(name="serve")
621
- def serve(
654
+
655
+ @app.command(name="run")
656
+ def run(
622
657
  path: Path = typer.Argument(
623
658
  Path("."),
624
659
  help="Project path (defaults to current directory).",
@@ -626,7 +661,7 @@ def serve(
626
661
  ),
627
662
  wasmer: bool = typer.Option(
628
663
  False,
629
- help="Use Wasmer to build and serve the project.",
664
+ help="Use Wasmer to run the project.",
630
665
  ),
631
666
  wasmer_bin: Optional[str] = typer.Option(
632
667
  None,
@@ -644,47 +679,32 @@ def serve(
644
679
  None,
645
680
  help="Additional options to pass to the Docker client.",
646
681
  ),
647
- run_commands: Optional[List[str]] = typer.Option(
682
+ command_names: Optional[List[str]] = typer.Option(
648
683
  None,
649
- "--run",
650
- help="Run one or more serve commands. Can be passed multiple times.",
684
+ "-c",
685
+ "--command",
686
+ help="Run one or more commands. Can be passed multiple times.",
651
687
  ),
652
- start: Optional[bool] = typer.Option(
653
- True,
654
- help="Equivalent to `--run=start`.",
688
+ volume_specs: Optional[List[str]] = typer.Option(
689
+ None,
690
+ "--volume",
691
+ help="Attach one or more volumes as NAME:/guest/path. Can be passed multiple times.",
655
692
  ),
656
- after_deploy: bool = typer.Option(
693
+ start: bool = typer.Option(
657
694
  False,
658
- help="Equivalent to `--run=after_deploy`.",
695
+ "--start/--no-start",
696
+ help="Equivalent to `--command=start`.",
659
697
  ),
660
- wasmer_deploy: Optional[bool] = typer.Option(
698
+ after_deploy: bool = typer.Option(
661
699
  False,
662
- help="Deploy the project to Wasmer.",
663
- ),
664
- wasmer_token: Optional[str] = typer.Option(
665
- None,
666
- help="Wasmer token.",
700
+ "--after-deploy/--no-after-deploy",
701
+ help="Equivalent to `--command=after_deploy`.",
667
702
  ),
668
703
  wasmer_registry: Optional[str] = typer.Option(
669
704
  None,
670
705
  help="Wasmer registry.",
671
706
  ),
672
- wasmer_app_owner: Optional[str] = typer.Option(
673
- None,
674
- help="Owner of the Wasmer app.",
675
- ),
676
- wasmer_app_name: Optional[str] = typer.Option(
677
- None,
678
- help="Name of the Wasmer app.",
679
- ),
680
- wasmer_deploy_config: Optional[Path] = typer.Option(
681
- None,
682
- help="Save the output of the Wasmer build to a json file",
683
- ),
684
707
  ) -> None:
685
- # We assume wasmer as an active flag if we pass wasmer deploy or wasmer deploy config
686
- wasmer = wasmer or wasmer_deploy or (wasmer_deploy_config is not None)
687
-
688
708
  if not path.exists():
689
709
  raise Exception(f"The path {path} does not exist")
690
710
 
@@ -700,29 +720,21 @@ def serve(
700
720
  build_backend,
701
721
  path,
702
722
  registry=wasmer_registry,
703
- token=wasmer_token,
704
723
  bin=wasmer_bin,
705
724
  )
706
725
  else:
707
726
  runner = LocalRunner(build_backend, path)
708
727
 
709
728
  commands_to_run = resolve_run_commands(
710
- run_commands=run_commands,
711
- start=bool(start),
729
+ command_names=command_names,
730
+ start=start,
712
731
  after_deploy=after_deploy,
713
732
  )
714
733
 
715
- if wasmer_deploy_config:
716
- if not isinstance(runner, WasmerRunner):
717
- raise RuntimeError("--wasmer-deploy-config requires the Wasmer runner")
718
- runner.deploy_config(wasmer_deploy_config)
719
- elif wasmer_deploy:
720
- if not isinstance(runner, WasmerRunner):
721
- raise RuntimeError("--wasmer-deploy requires the Wasmer runner")
722
- runner.deploy(app_owner=wasmer_app_owner, app_name=wasmer_app_name)
723
- elif commands_to_run:
724
- run_serve_commands(path, runner, commands_to_run)
725
-
734
+ if commands_to_run:
735
+ run_serve_commands(path, runner, commands_to_run, volume_specs=volume_specs)
736
+ else:
737
+ console.print("[bold]No commands specified. Use `--command` to run a command.[/bold]")
726
738
 
727
739
  @app.command(name="plan")
728
740
  def plan(
@@ -928,7 +940,7 @@ def build(
928
940
  ),
929
941
  wasmer: bool = typer.Option(
930
942
  False,
931
- help="Use Wasmer to build and serve the project.",
943
+ help="Use Wasmer to build and package the project.",
932
944
  ),
933
945
  skip_prepare: bool = typer.Option(
934
946
  False,
@@ -1077,6 +1089,7 @@ def build(
1077
1089
  build_volumes(path, serve)
1078
1090
  runner.build(serve)
1079
1091
  if serve.prepare and not skip_prepare:
1092
+ console.print("\n[bold]Running prepare step[/bold]")
1080
1093
  runner.prepare(env, serve.prepare)
1081
1094
 
1082
1095
 
@@ -1095,11 +1108,11 @@ def get_shipit_path(path: Path, shipit_path: Optional[Path] = None) -> Path:
1095
1108
 
1096
1109
 
1097
1110
  def resolve_run_commands(
1098
- run_commands: Optional[List[str]],
1111
+ command_names: Optional[List[str]],
1099
1112
  start: bool,
1100
1113
  after_deploy: bool,
1101
1114
  ) -> List[str]:
1102
- commands = list(run_commands or [])
1115
+ commands = list(command_names or [])
1103
1116
  if after_deploy and "after_deploy" not in commands:
1104
1117
  commands.append("after_deploy")
1105
1118
  if start and "start" not in commands:
@@ -1107,14 +1120,22 @@ def resolve_run_commands(
1107
1120
  return commands
1108
1121
 
1109
1122
 
1110
- def run_serve_commands(path: Path, runner: Runner, commands: List[str]) -> None:
1111
- volume_mappings = load_volume_mappings(path)
1123
+ def run_serve_commands(
1124
+ path: Path,
1125
+ runner: Runner,
1126
+ commands: List[str],
1127
+ volume_specs: Optional[List[str]] = None,
1128
+ ) -> None:
1129
+ volume_mappings = merge_volume_mappings(
1130
+ load_volume_mappings(path),
1131
+ parse_cli_volume_mappings(volume_specs),
1132
+ )
1112
1133
  for command in commands:
1113
1134
  if command in OPTIONAL_RUN_COMMANDS and not runner.has_serve_command(command):
1114
1135
  continue
1136
+ console.print(f"\nRunning command [bold]{command}[/bold]")
1115
1137
  runner.run_serve_command(command, volume_mappings=volume_mappings)
1116
1138
 
1117
-
1118
1139
  def main() -> None:
1119
1140
  args = sys.argv[1:]
1120
1141
  # If no subcommand or first token looks like option/path → default to "build"
@@ -141,6 +141,10 @@ class PhpProvider:
141
141
  )
142
142
  if not config.framework:
143
143
  config.framework = cls.detect_framework(path, composer_config)
144
+ if config.framework == PhpFramework.Drupal:
145
+ # Drupal relies on Apache-style rewrite behavior that the built-in
146
+ # php server handles more predictably than phpix by default.
147
+ config.phpix = False
144
148
  return config
145
149
 
146
150
  @classmethod
@@ -21,7 +21,7 @@ class LocalRunner:
21
21
  self.build_backend = build_backend
22
22
  self.src_dir = src_dir
23
23
  self.runner_path = self.src_dir / ".shipit" / "runner" / "local"
24
- self.serve_bin_path = self.runner_path / "serve" / "bin"
24
+ self.serve_bin_path = self.runner_path / "bin"
25
25
  self.prepare_bash_script = self.runner_path / "prepare" / "prepare.sh"
26
26
 
27
27
  def prepare_config(self, provider_config: object) -> object:
@@ -113,6 +113,5 @@ class LocalRunner:
113
113
  command: str,
114
114
  volume_mappings: Optional[Dict[str, str]] = None,
115
115
  ) -> None:
116
- console.print(f"\n[bold]Running {command} command[/bold]")
117
116
  command_path = self.serve_bin_path / command
118
117
  sh.Command(str(command_path))(_out=write_stdout, _err=write_stderr)
@@ -36,7 +36,7 @@ def serialize_provider_config(provider_config: Any) -> Dict[str, Any]:
36
36
  if provider_config is None:
37
37
  return {}
38
38
  if hasattr(provider_config, "model_dump"):
39
- return provider_config.model_dump(mode="json", exclude_defaults=True)
39
+ return provider_config.model_dump(mode="json", exclude_none=True)
40
40
  if isinstance(provider_config, dict):
41
41
  return provider_config
42
42
  return {}
@@ -149,29 +149,29 @@ class WasmerRunner:
149
149
  },
150
150
  "phpix": {
151
151
  "dependencies": {
152
- "latest": "phpix/phpix-83-32bit@=0.2.0-alpha.3",
153
- "8.3": "phpix/phpix-83-32bit@=0.2.0-alpha.3",
154
- "8.3.29": "phpix/phpix-83-32bit@=0.2.0-alpha.3",
155
- "8.2": "phpix/phpix-82-32bit@=0.2.0-alpha.3",
156
- "8.1": "phpix/phpix-81-32bit@=0.2.0-alpha.3",
157
- "7.4": "wasmer/phpix-32@=0.1.13803",
152
+ "latest": "phpix/phpix-83-32bit@=0.2.0-alpha.4",
153
+ "8.3": "phpix/phpix-83-32bit@=0.2.0-alpha.4",
154
+ "8.3.29": "phpix/phpix-83-32bit@=0.2.0-alpha.4",
155
+ "8.2": "phpix/phpix-82-32bit@=0.2.0-alpha.4",
156
+ "8.1": "phpix/phpix-81-32bit@=0.2.0-alpha.4",
157
+ "7.4": "php/php-32@=7.4.3301", # Note, we don't have PHPix + PHP 7.4 yet
158
158
  },
159
159
  "architecture_dependencies": {
160
160
  "64-bit": {
161
- "latest": "phpix/phpix-83-64bit@=0.2.0-alpha.3",
162
- "8.3": "phpix/phpix-83-64bit@=0.2.0-alpha.3",
163
- "8.3.29": "phpix/phpix-83-64bit@=0.2.0-alpha.3",
164
- "8.2": "phpix/phpix-82-64bit@=0.2.0-alpha.3",
165
- "8.1": "phpix/phpix-81-64bit@=0.2.0-alpha.3",
166
- "7.4": "wasmer/phpix-64@=0.1.13803",
161
+ "latest": "phpix/phpix-83-64bit@=0.2.0-alpha.4",
162
+ "8.3": "phpix/phpix-83-64bit@=0.2.0-alpha.4",
163
+ "8.3.29": "phpix/phpix-83-64bit@=0.2.0-alpha.4",
164
+ "8.2": "phpix/phpix-82-64bit@=0.2.0-alpha.4",
165
+ "8.1": "phpix/phpix-81-64bit@=0.2.0-alpha.4",
166
+ "7.4": "php/php-64@=7.4.3301",
167
167
  },
168
168
  "32-bit": {
169
- "latest": "phpix/phpix-83-32bit@=0.2.0-alpha.3",
170
- "8.3": "phpix/phpix-83-32bit@=0.2.0-alpha.3",
171
- "8.3.29": "phpix/phpix-83-32bit@=0.2.0-alpha.3",
172
- "8.2": "phpix/phpix-82-32bit@=0.2.0-alpha.3",
173
- "8.1": "phpix/phpix-81-32bit@=0.2.0-alpha.3",
174
- "7.4": "wasmer/phpix-32@=0.1.13803",
169
+ "latest": "phpix/phpix-83-32bit@=0.2.0-alpha.4",
170
+ "8.3": "phpix/phpix-83-32bit@=0.2.0-alpha.4",
171
+ "8.3.29": "phpix/phpix-83-32bit@=0.2.0-alpha.4",
172
+ "8.2": "phpix/phpix-82-32bit@=0.2.0-alpha.4",
173
+ "8.1": "phpix/phpix-81-32bit@=0.2.0-alpha.4",
174
+ "7.4": "php/php-32@=7.4.3301",
175
175
  },
176
176
  },
177
177
  "scripts": {"php", "phpix"},
@@ -223,6 +223,7 @@ class WasmerRunner:
223
223
 
224
224
  def prepare_config(self, provider_config: Any) -> Any:
225
225
  from shipit.providers.python import PythonConfig
226
+ from shipit.providers.php import PhpConfig
226
227
 
227
228
  if isinstance(provider_config, PythonConfig):
228
229
  provider_config.python_extra_index_url = (
@@ -230,6 +231,8 @@ class WasmerRunner:
230
231
  )
231
232
  provider_config.cross_platform = "wasix_wasm32"
232
233
  provider_config.precompile_python = True
234
+ elif isinstance(provider_config, PhpConfig):
235
+ provider_config.phpix = True
233
236
  self.provider_config = provider_config
234
237
  return provider_config
235
238
 
@@ -315,13 +318,11 @@ class WasmerRunner:
315
318
  def prepare(self, env: Dict[str, str], prepare: List[PrepareStep]) -> None:
316
319
  prepare_dir = self.wasmer_dir_path / "prepare"
317
320
  self.run_serve_command(
318
- "bash",
319
- volume_mappings=load_volume_mappings(self.src_dir),
320
- extra_args=[
321
- f"--mapdir=/prepare:{prepare_dir}",
322
- "--",
323
- "/prepare/prepare.sh",
324
- ],
321
+ "bash /prepare/prepare.sh",
322
+ volume_mappings={
323
+ **load_volume_mappings(self.src_dir),
324
+ "/prepare": prepare_dir,
325
+ },
325
326
  )
326
327
 
327
328
  def find_file_in_mounts(self, serve: Serve, program: str) -> Optional[Path]:
@@ -606,10 +607,14 @@ class WasmerRunner:
606
607
  self,
607
608
  command: str,
608
609
  volume_mappings: Optional[Dict[str, str]] = None,
609
- extra_args: Optional[List[str]] = None,
610
610
  ) -> None:
611
- console.print(f"\n[bold]Serving site[/bold]: running {command} command")
612
- extra_args = extra_args or []
611
+ parsed_command = shlex.split(command)
612
+ if not parsed_command:
613
+ raise ValueError("Serve command cannot be empty")
614
+
615
+ command_name = parsed_command[0]
616
+ command_args = parsed_command[1:]
617
+ extra_args = []
613
618
 
614
619
  if self.wasmer_registry:
615
620
  extra_args = [f"--registry={self.wasmer_registry}"] + extra_args
@@ -620,12 +625,13 @@ class WasmerRunner:
620
625
  str(self.wasmer_dir_path.absolute()),
621
626
  "--net",
622
627
  "--forward-host-env",
623
- f"--command={command}",
628
+ f"--command={command_name}",
624
629
  *volume_mapdir_args(
625
630
  self.build_backend,
626
631
  volume_mappings or {},
627
632
  ),
628
633
  *extra_args,
634
+ *(["--", *command_args] if command_args else []),
629
635
  ],
630
636
  env=os.environ,
631
637
  )
@@ -1,7 +1,7 @@
1
1
  import sys
2
2
  from rich.console import Console
3
3
 
4
- console = Console()
4
+ console = Console(stderr=True)
5
5
 
6
6
 
7
7
  def write_stdout(line: str) -> None:
@@ -0,0 +1,5 @@
1
+ __all__ = ["version", "version_info"]
2
+
3
+
4
+ version = "0.19.2"
5
+ version_info = (0, 19, 2, "final", 0)