shipit-cli 0.7.1__py3-none-any.whl → 0.8.0__py3-none-any.whl
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.
- shipit/assets/wordpress/install.sh +4 -9
- shipit/cli.py +30 -28
- shipit/generator.py +14 -2
- shipit/providers/hugo.py +6 -2
- shipit/providers/laravel.py +1 -1
- shipit/providers/mkdocs.py +2 -0
- shipit/providers/php.py +2 -2
- shipit/providers/python.py +16 -15
- shipit/providers/staticfile.py +12 -2
- shipit/providers/wordpress.py +1 -1
- shipit/version.py +2 -2
- {shipit_cli-0.7.1.dist-info → shipit_cli-0.8.0.dist-info}/METADATA +1 -1
- shipit_cli-0.8.0.dist-info/RECORD +23 -0
- shipit_cli-0.7.1.dist-info/RECORD +0 -23
- {shipit_cli-0.7.1.dist-info → shipit_cli-0.8.0.dist-info}/WHEEL +0 -0
- {shipit_cli-0.7.1.dist-info → shipit_cli-0.8.0.dist-info}/entry_points.txt +0 -0
|
@@ -12,7 +12,7 @@ echo "" > wp-content/upgrade/.keep
|
|
|
12
12
|
|
|
13
13
|
echo "Installing WordPress core..."
|
|
14
14
|
|
|
15
|
-
wp
|
|
15
|
+
wp core install \
|
|
16
16
|
--url="$WASMER_APP_URL" \
|
|
17
17
|
--title="$WP_SITE_TITLE" \
|
|
18
18
|
--admin_user="$WP_ADMIN_USERNAME" \
|
|
@@ -21,13 +21,8 @@ wp-cli core install \
|
|
|
21
21
|
--locale="$WP_LOCALE"
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
if [ -z "$
|
|
25
|
-
wp
|
|
26
|
-
fi
|
|
27
|
-
|
|
28
|
-
echo "Installing theme..."
|
|
29
|
-
wp-cli wasmer-aio-install install \
|
|
30
|
-
--locale="$WP_LOCALE" \
|
|
31
|
-
--theme=twentytwentyfive || true
|
|
24
|
+
if [ -z "$WP_UPDATE_DB" ]; then
|
|
25
|
+
wp core update-db
|
|
26
|
+
fi
|
|
32
27
|
|
|
33
28
|
echo "Installation complete"
|
shipit/cli.py
CHANGED
|
@@ -148,10 +148,12 @@ class Build:
|
|
|
148
148
|
|
|
149
149
|
def write_stdout(line: str) -> None:
|
|
150
150
|
sys.stdout.write(line) # print to console
|
|
151
|
+
sys.stdout.flush()
|
|
151
152
|
|
|
152
153
|
|
|
153
154
|
def write_stderr(line: str) -> None:
|
|
154
155
|
sys.stderr.write(line) # print to console
|
|
156
|
+
sys.stderr.flush()
|
|
155
157
|
|
|
156
158
|
|
|
157
159
|
class MapperItem(TypedDict):
|
|
@@ -179,6 +181,16 @@ class Builder(Protocol):
|
|
|
179
181
|
|
|
180
182
|
|
|
181
183
|
class DockerBuilder:
|
|
184
|
+
mise_mapper = {
|
|
185
|
+
"php": {
|
|
186
|
+
"source": "ubi:adwinying/php",
|
|
187
|
+
},
|
|
188
|
+
"composer": {
|
|
189
|
+
"source": "ubi:composer/composer",
|
|
190
|
+
"postinstall": """composer_dir=$(mise where ubi:composer/composer); ln -s "$composer_dir/composer.phar" /usr/local/bin/composer""",
|
|
191
|
+
},
|
|
192
|
+
}
|
|
193
|
+
|
|
182
194
|
def __init__(self, src_dir: Path, docker_client: Optional[str] = None) -> None:
|
|
183
195
|
self.src_dir = src_dir
|
|
184
196
|
self.docker_file_contents = ""
|
|
@@ -340,12 +352,17 @@ RUN chmod {oct(mode)[2:]} {path.absolute()}
|
|
|
340
352
|
)
|
|
341
353
|
self.docker_file_contents += f"RUN curl --proto '=https' --tlsv1.2 -sSfL https://get.static-web-server.net | sh\n"
|
|
342
354
|
return
|
|
355
|
+
|
|
356
|
+
mapped_dependency = self.mise_mapper.get(dependency.name, {})
|
|
357
|
+
package_name = mapped_dependency.get("source", dependency.name)
|
|
343
358
|
if dependency.version:
|
|
344
359
|
self.docker_file_contents += (
|
|
345
|
-
f"RUN mise use --global {
|
|
360
|
+
f"RUN mise use --global {package_name}@{dependency.version}\n"
|
|
346
361
|
)
|
|
347
362
|
else:
|
|
348
|
-
self.docker_file_contents += f"RUN mise use --global {
|
|
363
|
+
self.docker_file_contents += f"RUN mise use --global {package_name}\n"
|
|
364
|
+
if mapped_dependency.get("postinstall"):
|
|
365
|
+
self.docker_file_contents += f"RUN {mapped_dependency.get('postinstall')}\n"
|
|
349
366
|
|
|
350
367
|
def build(
|
|
351
368
|
self, env: Dict[str, str], mounts: List[Mount], steps: List[Step]
|
|
@@ -358,8 +375,8 @@ RUN chmod {oct(mode)[2:]} {path.absolute()}
|
|
|
358
375
|
self.docker_file_contents += """
|
|
359
376
|
RUN apt-get update \\
|
|
360
377
|
&& apt-get -y --no-install-recommends install \\
|
|
361
|
-
build-essential gcc make \\
|
|
362
|
-
dpkg-dev pkg-config \\
|
|
378
|
+
build-essential gcc make autoconf libtool bison \\
|
|
379
|
+
dpkg-dev pkg-config re2c locate \\
|
|
363
380
|
libmariadb-dev libmariadb-dev-compat libpq-dev \\
|
|
364
381
|
sudo curl ca-certificates \\
|
|
365
382
|
&& rm -rf /var/lib/apt/lists/*
|
|
@@ -407,7 +424,7 @@ RUN curl https://mise.run | sh
|
|
|
407
424
|
# Read the file content and write it to the target file
|
|
408
425
|
content_base64 = base64.b64encode(
|
|
409
426
|
(ASSETS_PATH / step.source).read_bytes()
|
|
410
|
-
)
|
|
427
|
+
).decode("utf-8")
|
|
411
428
|
self.docker_file_contents += (
|
|
412
429
|
f"RUN echo '{content_base64}' | base64 -d > {step.target}\n"
|
|
413
430
|
)
|
|
@@ -446,12 +463,6 @@ Shipit
|
|
|
446
463
|
def get_path(self) -> Path:
|
|
447
464
|
return Path("/")
|
|
448
465
|
|
|
449
|
-
def get_build_path(self) -> Path:
|
|
450
|
-
return self.get_path() / "app"
|
|
451
|
-
|
|
452
|
-
def get_serve_path(self) -> Path:
|
|
453
|
-
return self.get_path() / "serve"
|
|
454
|
-
|
|
455
466
|
def prepare(self, env: Dict[str, str], prepare: List[PrepareStep]) -> None:
|
|
456
467
|
raise NotImplementedError
|
|
457
468
|
|
|
@@ -461,13 +472,12 @@ Shipit
|
|
|
461
472
|
for dep in serve.deps:
|
|
462
473
|
self.add_dependency(dep)
|
|
463
474
|
|
|
464
|
-
build_path = self.get_build_path()
|
|
465
475
|
for command in serve.commands:
|
|
466
476
|
console.print(f"* {command}")
|
|
467
477
|
command_path = serve_command_path / command
|
|
468
478
|
self.create_file(
|
|
469
479
|
command_path,
|
|
470
|
-
f"#!/bin/bash\ncd {
|
|
480
|
+
f"#!/bin/bash\ncd {serve.cwd}\n{serve.commands[command]}",
|
|
471
481
|
mode=0o755,
|
|
472
482
|
)
|
|
473
483
|
|
|
@@ -480,6 +490,7 @@ class LocalBuilder:
|
|
|
480
490
|
def __init__(self, src_dir: Path) -> None:
|
|
481
491
|
self.src_dir = src_dir
|
|
482
492
|
self.local_path = self.src_dir / ".shipit" / "local"
|
|
493
|
+
self.serve_bin_path = self.local_path / "serve" / "bin"
|
|
483
494
|
self.prepare_bash_script = self.local_path / "prepare" / "prepare.sh"
|
|
484
495
|
self.build_path = self.local_path / "build"
|
|
485
496
|
self.workdir = self.build_path
|
|
@@ -503,6 +514,8 @@ class LocalBuilder:
|
|
|
503
514
|
elif isinstance(step, WorkdirStep):
|
|
504
515
|
console.print(f"[bold]Working in {step.path}[/bold]")
|
|
505
516
|
self.workdir = step.path
|
|
517
|
+
# We make sure the dir exists
|
|
518
|
+
step.path.mkdir(parents=True, exist_ok=True)
|
|
506
519
|
elif isinstance(step, RunStep):
|
|
507
520
|
extra = ""
|
|
508
521
|
if step.inputs:
|
|
@@ -628,12 +641,6 @@ class LocalBuilder:
|
|
|
628
641
|
def get_path(self) -> Path:
|
|
629
642
|
return self.local_path
|
|
630
643
|
|
|
631
|
-
def get_build_path(self) -> Path:
|
|
632
|
-
return self.get_path() / "build"
|
|
633
|
-
|
|
634
|
-
def get_serve_path(self) -> Path:
|
|
635
|
-
return self.get_path() / "serve"
|
|
636
|
-
|
|
637
644
|
def build_prepare(self, serve: Serve) -> None:
|
|
638
645
|
self.prepare_bash_script.parent.mkdir(parents=True, exist_ok=True)
|
|
639
646
|
commands: List[str] = []
|
|
@@ -676,14 +683,13 @@ class LocalBuilder:
|
|
|
676
683
|
def build_serve(self, serve: Serve) -> None:
|
|
677
684
|
# Remember serve configuration for run-time
|
|
678
685
|
console.print("\n[bold]Building serve[/bold]")
|
|
679
|
-
|
|
680
|
-
serve_command_path.mkdir(parents=True, exist_ok=False)
|
|
686
|
+
self.serve_bin_path.mkdir(parents=True, exist_ok=False)
|
|
681
687
|
path = self.get_path() / ".path"
|
|
682
688
|
path_text = path.read_text()
|
|
683
689
|
console.print(f"[bold]Serve Commands:[/bold]")
|
|
684
690
|
for command in serve.commands:
|
|
685
691
|
console.print(f"* {command}")
|
|
686
|
-
command_path =
|
|
692
|
+
command_path = self.serve_bin_path / command
|
|
687
693
|
env_vars = ""
|
|
688
694
|
if serve.env:
|
|
689
695
|
env_vars = " ".join([f"{k}={v}" for k, v in serve.env.items()])
|
|
@@ -707,8 +713,7 @@ class LocalBuilder:
|
|
|
707
713
|
|
|
708
714
|
def run_serve_command(self, command: str) -> None:
|
|
709
715
|
console.print(f"\n[bold]Running {command} command[/bold]")
|
|
710
|
-
|
|
711
|
-
command_path = base_path / command
|
|
716
|
+
command_path = self.serve_bin_path / command
|
|
712
717
|
sh.Command(str(command_path))(_out=write_stdout, _err=write_stderr)
|
|
713
718
|
|
|
714
719
|
|
|
@@ -808,9 +813,6 @@ class WasmerBuilder:
|
|
|
808
813
|
) -> None:
|
|
809
814
|
return self.inner_builder.build(env, mounts, build)
|
|
810
815
|
|
|
811
|
-
def get_build_path(self) -> Path:
|
|
812
|
-
return Path("/app")
|
|
813
|
-
|
|
814
816
|
def build_prepare(self, serve: Serve) -> None:
|
|
815
817
|
print("Building prepare")
|
|
816
818
|
prepare_dir = self.wasmer_dir_path / "prepare"
|
|
@@ -1704,7 +1706,7 @@ def main() -> None:
|
|
|
1704
1706
|
app()
|
|
1705
1707
|
except Exception as e:
|
|
1706
1708
|
console.print(f"[bold red]{type(e).__name__}[/bold red]: {e}")
|
|
1707
|
-
raise e
|
|
1709
|
+
# raise e
|
|
1708
1710
|
|
|
1709
1711
|
|
|
1710
1712
|
if __name__ == "__main__":
|
shipit/generator.py
CHANGED
|
@@ -109,7 +109,7 @@ def generate_shipit(path: Path, custom_commands: CustomCommands) -> str:
|
|
|
109
109
|
|
|
110
110
|
build_steps_block = ",\n".join([f" {s}" for s in build_steps])
|
|
111
111
|
deps_array = ", ".join(serve_dep_vars)
|
|
112
|
-
commands_lines = ",\n".join([f' "{k}": {v}' for k, v in plan.commands.items()])
|
|
112
|
+
commands_lines = ",\n".join([f' "{k}": {v}.replace("$PORT", PORT)' for k, v in plan.commands.items()])
|
|
113
113
|
env_lines = None
|
|
114
114
|
if plan.env is not None:
|
|
115
115
|
if len(plan.env) == 0:
|
|
@@ -119,31 +119,43 @@ def generate_shipit(path: Path, custom_commands: CustomCommands) -> str:
|
|
|
119
119
|
mounts_block = None
|
|
120
120
|
volumes_block = None
|
|
121
121
|
attach_serve_names: list[str] = []
|
|
122
|
+
|
|
122
123
|
if plan.mounts:
|
|
123
124
|
mounts = list(filter(lambda m: m.attach_to_serve, plan.mounts))
|
|
124
125
|
attach_serve_names = [m.name for m in mounts]
|
|
125
126
|
mounts_block = ",\n".join([f" {m.name}" for m in mounts])
|
|
127
|
+
|
|
126
128
|
if plan.volumes:
|
|
127
129
|
volumes_block = ",\n".join(
|
|
128
130
|
[f" {v.var_name or v.name}" for v in plan.volumes]
|
|
129
131
|
)
|
|
130
132
|
|
|
131
133
|
out: List[str] = []
|
|
134
|
+
|
|
132
135
|
if dep_block:
|
|
133
136
|
out.append(dep_block)
|
|
134
137
|
out.append("")
|
|
138
|
+
|
|
135
139
|
for m in plan.mounts:
|
|
136
140
|
out.append(f"{m.name} = mount(\"{m.name}\")")
|
|
141
|
+
out.append("")
|
|
142
|
+
|
|
137
143
|
if plan.volumes:
|
|
138
144
|
for v in plan.volumes:
|
|
139
145
|
out.append(f"{v.var_name or v.name} = volume(\"{v.name}\", {v.serve_path})")
|
|
146
|
+
out.append("")
|
|
147
|
+
|
|
140
148
|
if plan.services:
|
|
141
149
|
for s in plan.services:
|
|
142
150
|
out.append(f"{s.name} = service(\n name=\"{s.name}\",\n provider=\"{s.provider}\"\n)")
|
|
151
|
+
out.append("")
|
|
152
|
+
|
|
153
|
+
out.append("PORT = getenv(\"PORT\") or\"8080\"")
|
|
143
154
|
|
|
144
155
|
if plan.declarations:
|
|
145
156
|
out.append(plan.declarations)
|
|
146
|
-
|
|
157
|
+
|
|
158
|
+
out.append("")
|
|
147
159
|
out.append("serve(")
|
|
148
160
|
out.append(f' name="{plan.serve_name}",')
|
|
149
161
|
out.append(f' provider="{plan.provider}",')
|
shipit/providers/hugo.py
CHANGED
|
@@ -3,7 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Dict, Optional
|
|
5
5
|
|
|
6
|
-
from .base import DetectResult, DependencySpec, Provider, _exists, ServiceSpec, VolumeSpec, CustomCommands
|
|
6
|
+
from .base import DetectResult, DependencySpec, Provider, _exists, ServiceSpec, VolumeSpec, CustomCommands, MountSpec
|
|
7
7
|
from .staticfile import StaticFileProvider
|
|
8
8
|
|
|
9
9
|
class HugoProvider(StaticFileProvider):
|
|
@@ -43,10 +43,14 @@ class HugoProvider(StaticFileProvider):
|
|
|
43
43
|
|
|
44
44
|
def build_steps(self) -> list[str]:
|
|
45
45
|
return [
|
|
46
|
+
'workdir(temp["build"])',
|
|
46
47
|
'copy(".", ".", ignore=[".git"])',
|
|
47
48
|
'run("hugo build --destination={}".format(app["build"]), group="build")',
|
|
48
49
|
]
|
|
49
|
-
|
|
50
|
+
|
|
51
|
+
def mounts(self) -> list[MountSpec]:
|
|
52
|
+
return [MountSpec("temp", attach_to_serve=False), *super().mounts()]
|
|
53
|
+
|
|
50
54
|
def services(self) -> list[ServiceSpec]:
|
|
51
55
|
return []
|
|
52
56
|
|
shipit/providers/laravel.py
CHANGED
shipit/providers/mkdocs.py
CHANGED
|
@@ -30,6 +30,8 @@ class MkdocsProvider(StaticFileProvider):
|
|
|
30
30
|
def detect(cls, path: Path, custom_commands: CustomCommands) -> Optional[DetectResult]:
|
|
31
31
|
if _exists(path, "mkdocs.yml", "mkdocs.yaml"):
|
|
32
32
|
return DetectResult(cls.name(), 85)
|
|
33
|
+
if custom_commands.build and custom_commands.build.startswith("mkdocs "):
|
|
34
|
+
return DetectResult(cls.name(), 85)
|
|
33
35
|
return None
|
|
34
36
|
|
|
35
37
|
def initialize(self) -> None:
|
shipit/providers/php.py
CHANGED
|
@@ -92,9 +92,9 @@ class PhpProvider:
|
|
|
92
92
|
|
|
93
93
|
def base_commands(self) -> Dict[str, str]:
|
|
94
94
|
if _exists(self.path, "public/index.php"):
|
|
95
|
-
return {"start": '"php -S localhost:
|
|
95
|
+
return {"start": 'f"php -S localhost:{PORT} -t public"'}
|
|
96
96
|
elif _exists(self.path, "index.php"):
|
|
97
|
-
return {"start": '"php -S localhost:
|
|
97
|
+
return {"start": 'f"php -S localhost:{PORT} -t ."'}
|
|
98
98
|
|
|
99
99
|
def mounts(self) -> list[MountSpec]:
|
|
100
100
|
return [
|
shipit/providers/python.py
CHANGED
|
@@ -284,7 +284,7 @@ class PythonProvider:
|
|
|
284
284
|
if not self.only_build:
|
|
285
285
|
steps = ['workdir(app["build"])']
|
|
286
286
|
else:
|
|
287
|
-
steps = []
|
|
287
|
+
steps = ['workdir(temp["build"])']
|
|
288
288
|
|
|
289
289
|
extra_deps = ", ".join([f"{dep}" for dep in self.extra_dependencies])
|
|
290
290
|
has_requirements = _exists(self.path, "requirements.txt")
|
|
@@ -317,7 +317,7 @@ class PythonProvider:
|
|
|
317
317
|
]
|
|
318
318
|
if not self.only_build:
|
|
319
319
|
steps += [
|
|
320
|
-
'run(f"uv pip compile pyproject.toml --python-version={python_version} --universal --extra-index-url {python_extra_index_url} --index-url=https://pypi.org/simple --emit-index-url -o cross-requirements.txt", outputs=["cross-requirements.txt"]) if cross_platform else None',
|
|
320
|
+
'run(f"uv pip compile pyproject.toml --python-version={python_version} --universal --extra-index-url {python_extra_index_url} --index-url=https://pypi.org/simple --emit-index-url --no-deps -o cross-requirements.txt", outputs=["cross-requirements.txt"]) if cross_platform else None',
|
|
321
321
|
f'run(f"uvx pip install -r cross-requirements.txt {extra_deps} --target {{python_cross_packages_path}} --platform {{cross_platform}} --only-binary=:all: --python-version={{python_version}} --compile") if cross_platform else None',
|
|
322
322
|
'run("rm cross-requirements.txt") if cross_platform else None',
|
|
323
323
|
]
|
|
@@ -337,7 +337,7 @@ class PythonProvider:
|
|
|
337
337
|
]
|
|
338
338
|
if not self.only_build:
|
|
339
339
|
steps += [
|
|
340
|
-
'run(f"uv pip compile requirements.txt --python-version={python_version} --universal --extra-index-url {python_extra_index_url} --index-url=https://pypi.org/simple --emit-index-url -o cross-requirements.txt", inputs=["requirements.txt"], outputs=["cross-requirements.txt"]) if cross_platform else None',
|
|
340
|
+
'run(f"uv pip compile requirements.txt --python-version={python_version} --universal --extra-index-url {python_extra_index_url} --index-url=https://pypi.org/simple --emit-index-url --no-deps -o cross-requirements.txt", inputs=["requirements.txt"], outputs=["cross-requirements.txt"]) if cross_platform else None',
|
|
341
341
|
f'run(f"uvx pip install -r cross-requirements.txt {extra_deps} --target {{python_cross_packages_path}} --platform {{cross_platform}} --only-binary=:all: --python-version={{python_version}} --compile") if cross_platform else None',
|
|
342
342
|
'run("rm cross-requirements.txt") if cross_platform else None',
|
|
343
343
|
]
|
|
@@ -396,20 +396,20 @@ class PythonProvider:
|
|
|
396
396
|
if self.server == PythonServer.Daphne and self.asgi_application:
|
|
397
397
|
asgi_application = format_app_import(self.asgi_application)
|
|
398
398
|
start_cmd = (
|
|
399
|
-
f'"python -m daphne {asgi_application} --bind 0.0.0.0 --port
|
|
399
|
+
f'f"python -m daphne {asgi_application} --bind 0.0.0.0 --port {{PORT}}"'
|
|
400
400
|
)
|
|
401
401
|
elif self.server == PythonServer.Uvicorn:
|
|
402
402
|
if self.asgi_application:
|
|
403
403
|
asgi_application = format_app_import(self.asgi_application)
|
|
404
|
-
start_cmd = f'"python -m uvicorn {asgi_application} --host 0.0.0.0 --port
|
|
404
|
+
start_cmd = f'f"python -m uvicorn {asgi_application} --host 0.0.0.0 --port {{PORT}}"'
|
|
405
405
|
elif self.wsgi_application:
|
|
406
406
|
wsgi_application = format_app_import(self.wsgi_application)
|
|
407
|
-
start_cmd = f'"python -m uvicorn {wsgi_application} --interface=wsgi --host 0.0.0.0 --port
|
|
407
|
+
start_cmd = f'f"python -m uvicorn {wsgi_application} --interface=wsgi --host 0.0.0.0 --port {{PORT}}"'
|
|
408
408
|
# elif self.server == PythonServer.Gunicorn:
|
|
409
|
-
# start_cmd = f'"
|
|
409
|
+
# start_cmd = f'"fpython -m gunicorn {self.wsgi_application} --bind 0.0.0.0 --port {{PORT}}"'
|
|
410
410
|
if not start_cmd:
|
|
411
411
|
# We run the default runserver command if no server is specified
|
|
412
|
-
start_cmd = '"python manage.py runserver 0.0.0.0:
|
|
412
|
+
start_cmd = 'f"python manage.py runserver 0.0.0.0:{PORT}"'
|
|
413
413
|
migrate_cmd = '"python manage.py migrate"'
|
|
414
414
|
return {"start": start_cmd, "after_deploy": migrate_cmd}
|
|
415
415
|
|
|
@@ -423,21 +423,21 @@ class PythonProvider:
|
|
|
423
423
|
python_path = file_to_python_path(main_file)
|
|
424
424
|
path = f"{python_path}:app"
|
|
425
425
|
if self.server == PythonServer.Uvicorn:
|
|
426
|
-
start_cmd = f'"python -m uvicorn {path} --host 0.0.0.0 --port
|
|
426
|
+
start_cmd = f'f"python -m uvicorn {path} --host 0.0.0.0 --port {{PORT}}"'
|
|
427
427
|
elif self.server == PythonServer.Hypercorn:
|
|
428
|
-
start_cmd = f'"python -m hypercorn {path} --bind 0.0.0.0:
|
|
428
|
+
start_cmd = f'f"python -m hypercorn {path} --bind 0.0.0.0:{{PORT}}"'
|
|
429
429
|
else:
|
|
430
430
|
start_cmd = '"python -c \'print(\\"No start command detected, please provide a start command manually\\")\'"'
|
|
431
431
|
return {"start": start_cmd}
|
|
432
432
|
|
|
433
433
|
elif self.framework == PythonFramework.Streamlit:
|
|
434
|
-
start_cmd = f'"python -m streamlit run {main_file} --server.port
|
|
434
|
+
start_cmd = f'f"python -m streamlit run {main_file} --server.port {{PORT}} --server.address 0.0.0.0 --server.headless true"'
|
|
435
435
|
|
|
436
436
|
elif self.framework == PythonFramework.Flask:
|
|
437
437
|
python_path = file_to_python_path(main_file)
|
|
438
438
|
path = f"{python_path}:app"
|
|
439
|
-
# start_cmd = f'"python -m flask --app {path} run --debug --host 0.0.0.0 --port
|
|
440
|
-
start_cmd = f'"python -m uvicorn {path} --interface=wsgi --host 0.0.0.0 --port
|
|
439
|
+
# start_cmd = f'f"python -m flask --app {path} run --debug --host 0.0.0.0 --port {{PORT}}"'
|
|
440
|
+
start_cmd = f'f"python -m uvicorn {path} --interface=wsgi --host 0.0.0.0 --port {{PORT}}"'
|
|
441
441
|
|
|
442
442
|
elif self.framework == PythonFramework.MCP:
|
|
443
443
|
contents = (self.path / main_file).read_text()
|
|
@@ -449,7 +449,7 @@ class PythonProvider:
|
|
|
449
449
|
elif self.framework == PythonFramework.FastHTML:
|
|
450
450
|
python_path = file_to_python_path(main_file)
|
|
451
451
|
path = f"{python_path}:app"
|
|
452
|
-
start_cmd = f'"python -m uvicorn {path} --host 0.0.0.0 --port
|
|
452
|
+
start_cmd = f'f"python -m uvicorn {path} --host 0.0.0.0 --port {{PORT}}"'
|
|
453
453
|
|
|
454
454
|
else:
|
|
455
455
|
start_cmd = f'"python {main_file}"'
|
|
@@ -459,6 +459,7 @@ class PythonProvider:
|
|
|
459
459
|
def mounts(self) -> list[MountSpec]:
|
|
460
460
|
if self.only_build:
|
|
461
461
|
return [
|
|
462
|
+
MountSpec("temp", attach_to_serve=False),
|
|
462
463
|
MountSpec("local_venv", attach_to_serve=False),
|
|
463
464
|
]
|
|
464
465
|
return [
|
|
@@ -486,7 +487,7 @@ class PythonProvider:
|
|
|
486
487
|
env_vars["STREAMLIT_SERVER_HEADLESS"] = '"true"'
|
|
487
488
|
elif self.framework == PythonFramework.MCP:
|
|
488
489
|
env_vars["FASTMCP_HOST"] = '"0.0.0.0"'
|
|
489
|
-
env_vars["FASTMCP_PORT"] = '
|
|
490
|
+
env_vars["FASTMCP_PORT"] = 'PORT'
|
|
490
491
|
return env_vars
|
|
491
492
|
|
|
492
493
|
def services(self) -> list[ServiceSpec]:
|
shipit/providers/staticfile.py
CHANGED
|
@@ -2,6 +2,8 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Dict, Optional
|
|
5
|
+
import json
|
|
6
|
+
import yaml
|
|
5
7
|
|
|
6
8
|
from .base import (
|
|
7
9
|
DetectResult,
|
|
@@ -16,9 +18,17 @@ from .base import (
|
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
class StaticFileProvider:
|
|
21
|
+
config: Optional[dict] = None
|
|
22
|
+
|
|
19
23
|
def __init__(self, path: Path, custom_commands: CustomCommands):
|
|
20
24
|
self.path = path
|
|
21
25
|
self.custom_commands = custom_commands
|
|
26
|
+
if (self.path / "Staticfile").exists():
|
|
27
|
+
try:
|
|
28
|
+
self.config = yaml.safe_load((self.path / "Staticfile").read_text())
|
|
29
|
+
except yaml.YAMLError as e:
|
|
30
|
+
print(f"Error loading Staticfile: {e}")
|
|
31
|
+
pass
|
|
22
32
|
|
|
23
33
|
@classmethod
|
|
24
34
|
def name(cls) -> str:
|
|
@@ -58,7 +68,7 @@ class StaticFileProvider:
|
|
|
58
68
|
def build_steps(self) -> list[str]:
|
|
59
69
|
return [
|
|
60
70
|
'workdir(app["build"])',
|
|
61
|
-
'copy(
|
|
71
|
+
'copy({}, ".", ignore=[".git"])'.format(json.dumps(self.config and self.config.get("root") or "."))
|
|
62
72
|
]
|
|
63
73
|
|
|
64
74
|
def prepare_steps(self) -> Optional[list[str]]:
|
|
@@ -69,7 +79,7 @@ class StaticFileProvider:
|
|
|
69
79
|
|
|
70
80
|
def commands(self) -> Dict[str, str]:
|
|
71
81
|
return {
|
|
72
|
-
"start": '"static-web-server --root={} --log-level=info".format(app["serve"])'
|
|
82
|
+
"start": '"static-web-server --root={} --log-level=info --port={}".format(app["serve"], PORT)'
|
|
73
83
|
}
|
|
74
84
|
|
|
75
85
|
def mounts(self) -> list[MountSpec]:
|
shipit/providers/wordpress.py
CHANGED
|
@@ -70,7 +70,7 @@ class WordPressProvider(PhpProvider):
|
|
|
70
70
|
|
|
71
71
|
def commands(self) -> Dict[str, str]:
|
|
72
72
|
return {
|
|
73
|
-
"start": '"php -S localhost:
|
|
73
|
+
"start": 'f"php -S localhost:{PORT} -t ."',
|
|
74
74
|
"wp": '"php {}/wp-cli.phar --allow-root --path={}".format(assets[\"serve\"], app[\"serve\"])',
|
|
75
75
|
"after_deploy": '"bash {}/wordpress-install.sh".format(assets["serve"])',
|
|
76
76
|
}
|
shipit/version.py
CHANGED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
shipit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
shipit/cli.py,sha256=wfHNLe0Pe0uheeiFuWQi3DFlUA86oTN8-mojaKxru94,58696
|
|
3
|
+
shipit/generator.py,sha256=W4MynSFwId4PRWWrF0R3NsANye_Zv8TwXCUXai94pW0,6553
|
|
4
|
+
shipit/procfile.py,sha256=GlfdwzFUr0GWGKaaiXlLKNFInWaRNMy_wN14UEyU_5Q,2974
|
|
5
|
+
shipit/version.py,sha256=tLXsjc9rJ1_Aj9p3fPQjFAv5Eanmo1dQaEiaHbiBSwY,95
|
|
6
|
+
shipit/assets/php/php.ini,sha256=f4irndAjB4GuuouEImRkNV22Q-yw1KqR-43jAMDw730,2531
|
|
7
|
+
shipit/assets/wordpress/install.sh,sha256=fJkVeGAw_dj-ywmQipAWRjaz57sayD6F0OFvZKMIKug,669
|
|
8
|
+
shipit/assets/wordpress/wp-config.php,sha256=IdGQoeg8E89JiqwxO2i8WnGMzmhNWgRz80X6lbU5GXc,4134
|
|
9
|
+
shipit/providers/base.py,sha256=-lraLhnXtc2SfYNIUiyry7xD2NL4q0n6voNjr6qfRis,2994
|
|
10
|
+
shipit/providers/gatsby.py,sha256=kzfS-z040GaJ0a9u2_6S6K-ykGSX2yPG17VpjUWBOBA,2393
|
|
11
|
+
shipit/providers/hugo.py,sha256=l3IZ14LGYc3wQ7Uk0iQMDNN9Syd1G4HPzm0ePCGFyzE,1808
|
|
12
|
+
shipit/providers/laravel.py,sha256=2rCuOi2kC5OYQfAG7C0NMhG7KEgzfudwUT_CvVFz4hM,3031
|
|
13
|
+
shipit/providers/mkdocs.py,sha256=mDJpT3rzYAr5Vw-yt5fCpV0QgBZyksn9MrkPd4nzROU,2200
|
|
14
|
+
shipit/providers/node_static.py,sha256=QVUTTZbvUGtj2yT9WTbGmuM30rJzejnp76crIqSGA7o,2564
|
|
15
|
+
shipit/providers/php.py,sha256=BSOqS3UhABoe_ued8aXtyn0KdqWbOCq6VV2ehtoBlmk,3547
|
|
16
|
+
shipit/providers/python.py,sha256=kQpaaQi8ajHM_SFk2xI5lRIeOc6PXSKumb-Tv_5n6m0,20954
|
|
17
|
+
shipit/providers/registry.py,sha256=lHUViVuPJf1OIZD8I_NTX4LP7E3Uo5-MmLfarmAA_cM,729
|
|
18
|
+
shipit/providers/staticfile.py,sha256=BxZ7Z8dN0tAd-s8_m-NPgqJrVSvKwxCd-us-hCanL1E,2626
|
|
19
|
+
shipit/providers/wordpress.py,sha256=Wjc1fgFburewlf4hQ2ZmxTQko_SHQW-8jrDukzKx0Gs,3019
|
|
20
|
+
shipit_cli-0.8.0.dist-info/METADATA,sha256=p_XVn3jE5BNj2JQm_5-xBqszHGjdZYb2me6Ur0BOgTk,523
|
|
21
|
+
shipit_cli-0.8.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
22
|
+
shipit_cli-0.8.0.dist-info/entry_points.txt,sha256=7AE1NjSrHaSDfbfsRRO50KKnHFTbB0Imsccd1WynzAQ,72
|
|
23
|
+
shipit_cli-0.8.0.dist-info/RECORD,,
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
shipit/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
shipit/cli.py,sha256=1U65pviCsaH-fZO3hGYWoyO1WqXCfOxnGwPIomwc5Fg,58363
|
|
3
|
-
shipit/generator.py,sha256=GFsuqZG83gn7yxphE4GHwZjEB3sToJn24yNDE-zrTtM,6400
|
|
4
|
-
shipit/procfile.py,sha256=GlfdwzFUr0GWGKaaiXlLKNFInWaRNMy_wN14UEyU_5Q,2974
|
|
5
|
-
shipit/version.py,sha256=-1rPwQ4VEhKG8LAXODaAwzxwpFY9hDgohd2s_aRySc4,95
|
|
6
|
-
shipit/assets/php/php.ini,sha256=f4irndAjB4GuuouEImRkNV22Q-yw1KqR-43jAMDw730,2531
|
|
7
|
-
shipit/assets/wordpress/install.sh,sha256=GOIwJX3qPp7VuZXjkKVFFY6Mo9k7VFWfobS6aZYitPg,817
|
|
8
|
-
shipit/assets/wordpress/wp-config.php,sha256=IdGQoeg8E89JiqwxO2i8WnGMzmhNWgRz80X6lbU5GXc,4134
|
|
9
|
-
shipit/providers/base.py,sha256=-lraLhnXtc2SfYNIUiyry7xD2NL4q0n6voNjr6qfRis,2994
|
|
10
|
-
shipit/providers/gatsby.py,sha256=kzfS-z040GaJ0a9u2_6S6K-ykGSX2yPG17VpjUWBOBA,2393
|
|
11
|
-
shipit/providers/hugo.py,sha256=BvSYTDTVxHz6FW2mA4sqIsNayFRo5BK6Z4tWFRRimmY,1644
|
|
12
|
-
shipit/providers/laravel.py,sha256=yhOnaaXZ2US8EO5ZD5pBTerSOBi9IWBBIqeQrbW7YoM,3028
|
|
13
|
-
shipit/providers/mkdocs.py,sha256=pWTeIUEnSyB653s7Cw_OSllgiSGcDymRTEHgV5ChDLM,2070
|
|
14
|
-
shipit/providers/node_static.py,sha256=QVUTTZbvUGtj2yT9WTbGmuM30rJzejnp76crIqSGA7o,2564
|
|
15
|
-
shipit/providers/php.py,sha256=JIWl5CdVEdf9DAr9O9rR8NucucYCj_M5PbJRw_SnmYU,3541
|
|
16
|
-
shipit/providers/python.py,sha256=n0748miZ5RpQyQUCmkq3_G2Nnub8SaogZoJTNNFalZc,20801
|
|
17
|
-
shipit/providers/registry.py,sha256=lHUViVuPJf1OIZD8I_NTX4LP7E3Uo5-MmLfarmAA_cM,729
|
|
18
|
-
shipit/providers/staticfile.py,sha256=O1D0cXa_cFZH4OXRFLjBG3e-LbjMDo7ZBC2D3CvrPo4,2218
|
|
19
|
-
shipit/providers/wordpress.py,sha256=wMIcBpICqcEpbOgJCufrnM-r76AVI7_xC-NUlh9XMmE,3016
|
|
20
|
-
shipit_cli-0.7.1.dist-info/METADATA,sha256=uW1Lt7b6mOl7H5k3CPpaPPWNNr-0DHY6p5dxE4Z9B6g,523
|
|
21
|
-
shipit_cli-0.7.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
22
|
-
shipit_cli-0.7.1.dist-info/entry_points.txt,sha256=7AE1NjSrHaSDfbfsRRO50KKnHFTbB0Imsccd1WynzAQ,72
|
|
23
|
-
shipit_cli-0.7.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|