shipit-cli 0.7.1__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/PKG-INFO +3 -2
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/pyproject.toml +11 -3
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/assets/wordpress/install.sh +4 -9
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/cli.py +43 -33
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/generator.py +14 -2
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/hugo.py +6 -2
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/laravel.py +1 -1
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/mkdocs.py +2 -0
- shipit_cli-0.9.0/src/shipit/providers/node_static.py +304 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/php.py +2 -2
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/python.py +16 -15
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/registry.py +1 -1
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/staticfile.py +14 -2
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/wordpress.py +1 -1
- shipit_cli-0.9.0/src/shipit/version.py +5 -0
- shipit_cli-0.9.0/tests/test_e2e.py +359 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/tests/test_generate_shipit_examples.py +8 -1
- shipit_cli-0.7.1/src/shipit/providers/node_static.py +0 -88
- shipit_cli-0.7.1/src/shipit/version.py +0 -5
- shipit_cli-0.7.1/tests/test_examples_build.py +0 -45
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/.gitignore +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/README.md +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/__init__.py +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/assets/php/php.ini +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/assets/wordpress/wp-config.php +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/procfile.py +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/base.py +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/src/shipit/providers/gatsby.py +0 -0
- {shipit_cli-0.7.1 → shipit_cli-0.9.0}/tests/test_version.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shipit-cli
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.9.0
|
|
4
|
+
Summary: Shipit CLI is the best way to build, serve and deploy your projects anywhere.
|
|
5
5
|
Project-URL: homepage, https://wasmer.io
|
|
6
6
|
Project-URL: repository, https://github.com/wasmerio/shipit
|
|
7
7
|
Project-URL: Changelog, https://github.com/wasmerio/shipit/changelog
|
|
@@ -10,6 +10,7 @@ Requires-Dist: dotenv>=0.9.9
|
|
|
10
10
|
Requires-Dist: pyyaml>=6.0.2
|
|
11
11
|
Requires-Dist: requests>=2.32.5
|
|
12
12
|
Requires-Dist: rich>=14.1.0
|
|
13
|
+
Requires-Dist: semantic-version>=2.10.0
|
|
13
14
|
Requires-Dist: sh>=2.2.2
|
|
14
15
|
Requires-Dist: starlark-pyo3>=2025.1
|
|
15
16
|
Requires-Dist: tomlkit>=0.13.3
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "shipit-cli"
|
|
3
|
-
version = "0.
|
|
4
|
-
description = "
|
|
3
|
+
version = "0.9.0"
|
|
4
|
+
description = "Shipit CLI is the best way to build, serve and deploy your projects anywhere."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
7
7
|
dependencies = [
|
|
@@ -9,6 +9,7 @@ dependencies = [
|
|
|
9
9
|
"pyyaml>=6.0.2",
|
|
10
10
|
"requests>=2.32.5",
|
|
11
11
|
"rich>=14.1.0",
|
|
12
|
+
"semantic-version>=2.10.0",
|
|
12
13
|
"sh>=2.2.2",
|
|
13
14
|
"starlark-pyo3>=2025.1",
|
|
14
15
|
"tomlkit>=0.13.3",
|
|
@@ -35,5 +36,12 @@ only-include = ["src/shipit", "tests"]
|
|
|
35
36
|
|
|
36
37
|
[tool.uv]
|
|
37
38
|
dev-dependencies = [
|
|
38
|
-
"
|
|
39
|
+
"aiohttp>=3.12.15",
|
|
40
|
+
"pytest>=8.4.1",
|
|
41
|
+
"pytest-asyncio>=1.2.0",
|
|
42
|
+
"pytest-rerunfailures>=16.0.1",
|
|
43
|
+
"pytest-xdist>=3.8.0",
|
|
39
44
|
]
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
asyncio_mode = "auto"
|
|
@@ -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"
|
|
@@ -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 = ""
|
|
@@ -293,7 +305,7 @@ class DockerBuilder:
|
|
|
293
305
|
image_name,
|
|
294
306
|
command,
|
|
295
307
|
*(extra_args or []),
|
|
296
|
-
_env=os.environ, # Pass the current environment variables to the Docker client
|
|
308
|
+
_env={"DOCKER_BUILDKIT": "1", **os.environ}, # Pass the current environment variables to the Docker client
|
|
297
309
|
_out=write_stdout,
|
|
298
310
|
_err=write_stderr,
|
|
299
311
|
)
|
|
@@ -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]
|
|
@@ -353,14 +370,17 @@ RUN chmod {oct(mode)[2:]} {path.absolute()}
|
|
|
353
370
|
base_path = self.docker_path
|
|
354
371
|
shutil.rmtree(base_path, ignore_errors=True)
|
|
355
372
|
base_path.mkdir(parents=True, exist_ok=True)
|
|
356
|
-
self.docker_file_contents = "
|
|
373
|
+
self.docker_file_contents = "# syntax=docker/dockerfile:1.7-labs\n"
|
|
374
|
+
self.docker_file_contents += "FROM debian:trixie-slim AS build\n"
|
|
357
375
|
|
|
358
376
|
self.docker_file_contents += """
|
|
359
377
|
RUN apt-get update \\
|
|
360
378
|
&& apt-get -y --no-install-recommends install \\
|
|
361
|
-
build-essential gcc make \\
|
|
362
|
-
dpkg-dev pkg-config \\
|
|
379
|
+
build-essential gcc make autoconf libtool bison \\
|
|
380
|
+
dpkg-dev pkg-config re2c locate \\
|
|
363
381
|
libmariadb-dev libmariadb-dev-compat libpq-dev \\
|
|
382
|
+
libvips-dev default-libmysqlclient-dev libmagickwand-dev \\
|
|
383
|
+
libicu-dev libxml2-dev libxslt-dev \\
|
|
364
384
|
sudo curl ca-certificates \\
|
|
365
385
|
&& rm -rf /var/lib/apt/lists/*
|
|
366
386
|
|
|
@@ -407,7 +427,7 @@ RUN curl https://mise.run | sh
|
|
|
407
427
|
# Read the file content and write it to the target file
|
|
408
428
|
content_base64 = base64.b64encode(
|
|
409
429
|
(ASSETS_PATH / step.source).read_bytes()
|
|
410
|
-
)
|
|
430
|
+
).decode("utf-8")
|
|
411
431
|
self.docker_file_contents += (
|
|
412
432
|
f"RUN echo '{content_base64}' | base64 -d > {step.target}\n"
|
|
413
433
|
)
|
|
@@ -418,7 +438,11 @@ RUN curl https://mise.run | sh
|
|
|
418
438
|
else:
|
|
419
439
|
raise Exception(f"Asset {step.source} does not exist")
|
|
420
440
|
else:
|
|
421
|
-
|
|
441
|
+
if step.ignore:
|
|
442
|
+
exclude = " \\\n" +" \\\n".join([f" --exclude={ignore}" for ignore in step.ignore]) + " \\\n "
|
|
443
|
+
else:
|
|
444
|
+
exclude = ""
|
|
445
|
+
self.docker_file_contents += f"COPY{exclude} {step.source} {step.target}\n"
|
|
422
446
|
elif isinstance(step, EnvStep):
|
|
423
447
|
env_vars = " ".join(
|
|
424
448
|
[f"{key}={value}" for key, value in step.variables.items()]
|
|
@@ -446,12 +470,6 @@ Shipit
|
|
|
446
470
|
def get_path(self) -> Path:
|
|
447
471
|
return Path("/")
|
|
448
472
|
|
|
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
473
|
def prepare(self, env: Dict[str, str], prepare: List[PrepareStep]) -> None:
|
|
456
474
|
raise NotImplementedError
|
|
457
475
|
|
|
@@ -461,13 +479,12 @@ Shipit
|
|
|
461
479
|
for dep in serve.deps:
|
|
462
480
|
self.add_dependency(dep)
|
|
463
481
|
|
|
464
|
-
build_path = self.get_build_path()
|
|
465
482
|
for command in serve.commands:
|
|
466
483
|
console.print(f"* {command}")
|
|
467
484
|
command_path = serve_command_path / command
|
|
468
485
|
self.create_file(
|
|
469
486
|
command_path,
|
|
470
|
-
f"#!/bin/bash\ncd {
|
|
487
|
+
f"#!/bin/bash\ncd {serve.cwd}\n{serve.commands[command]}",
|
|
471
488
|
mode=0o755,
|
|
472
489
|
)
|
|
473
490
|
|
|
@@ -480,6 +497,7 @@ class LocalBuilder:
|
|
|
480
497
|
def __init__(self, src_dir: Path) -> None:
|
|
481
498
|
self.src_dir = src_dir
|
|
482
499
|
self.local_path = self.src_dir / ".shipit" / "local"
|
|
500
|
+
self.serve_bin_path = self.local_path / "serve" / "bin"
|
|
483
501
|
self.prepare_bash_script = self.local_path / "prepare" / "prepare.sh"
|
|
484
502
|
self.build_path = self.local_path / "build"
|
|
485
503
|
self.workdir = self.build_path
|
|
@@ -503,6 +521,8 @@ class LocalBuilder:
|
|
|
503
521
|
elif isinstance(step, WorkdirStep):
|
|
504
522
|
console.print(f"[bold]Working in {step.path}[/bold]")
|
|
505
523
|
self.workdir = step.path
|
|
524
|
+
# We make sure the dir exists
|
|
525
|
+
step.path.mkdir(parents=True, exist_ok=True)
|
|
506
526
|
elif isinstance(step, RunStep):
|
|
507
527
|
extra = ""
|
|
508
528
|
if step.inputs:
|
|
@@ -525,9 +545,10 @@ class LocalBuilder:
|
|
|
525
545
|
exe = shutil.which(program, path=PATH)
|
|
526
546
|
if not exe:
|
|
527
547
|
raise Exception(f"Program is not installed: {program}")
|
|
528
|
-
cmd = sh.Command(
|
|
548
|
+
cmd = sh.Command("bash") # "grep"
|
|
529
549
|
result = cmd(
|
|
530
|
-
|
|
550
|
+
"-c",
|
|
551
|
+
command_line,
|
|
531
552
|
_env={**env, "PATH": PATH},
|
|
532
553
|
_cwd=build_path,
|
|
533
554
|
_out=write_stdout,
|
|
@@ -628,12 +649,6 @@ class LocalBuilder:
|
|
|
628
649
|
def get_path(self) -> Path:
|
|
629
650
|
return self.local_path
|
|
630
651
|
|
|
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
652
|
def build_prepare(self, serve: Serve) -> None:
|
|
638
653
|
self.prepare_bash_script.parent.mkdir(parents=True, exist_ok=True)
|
|
639
654
|
commands: List[str] = []
|
|
@@ -676,14 +691,13 @@ class LocalBuilder:
|
|
|
676
691
|
def build_serve(self, serve: Serve) -> None:
|
|
677
692
|
# Remember serve configuration for run-time
|
|
678
693
|
console.print("\n[bold]Building serve[/bold]")
|
|
679
|
-
|
|
680
|
-
serve_command_path.mkdir(parents=True, exist_ok=False)
|
|
694
|
+
self.serve_bin_path.mkdir(parents=True, exist_ok=False)
|
|
681
695
|
path = self.get_path() / ".path"
|
|
682
696
|
path_text = path.read_text()
|
|
683
697
|
console.print(f"[bold]Serve Commands:[/bold]")
|
|
684
698
|
for command in serve.commands:
|
|
685
699
|
console.print(f"* {command}")
|
|
686
|
-
command_path =
|
|
700
|
+
command_path = self.serve_bin_path / command
|
|
687
701
|
env_vars = ""
|
|
688
702
|
if serve.env:
|
|
689
703
|
env_vars = " ".join([f"{k}={v}" for k, v in serve.env.items()])
|
|
@@ -707,8 +721,7 @@ class LocalBuilder:
|
|
|
707
721
|
|
|
708
722
|
def run_serve_command(self, command: str) -> None:
|
|
709
723
|
console.print(f"\n[bold]Running {command} command[/bold]")
|
|
710
|
-
|
|
711
|
-
command_path = base_path / command
|
|
724
|
+
command_path = self.serve_bin_path / command
|
|
712
725
|
sh.Command(str(command_path))(_out=write_stdout, _err=write_stderr)
|
|
713
726
|
|
|
714
727
|
|
|
@@ -808,9 +821,6 @@ class WasmerBuilder:
|
|
|
808
821
|
) -> None:
|
|
809
822
|
return self.inner_builder.build(env, mounts, build)
|
|
810
823
|
|
|
811
|
-
def get_build_path(self) -> Path:
|
|
812
|
-
return Path("/app")
|
|
813
|
-
|
|
814
824
|
def build_prepare(self, serve: Serve) -> None:
|
|
815
825
|
print("Building prepare")
|
|
816
826
|
prepare_dir = self.wasmer_dir_path / "prepare"
|
|
@@ -1704,7 +1714,7 @@ def main() -> None:
|
|
|
1704
1714
|
app()
|
|
1705
1715
|
except Exception as e:
|
|
1706
1716
|
console.print(f"[bold red]{type(e).__name__}[/bold red]: {e}")
|
|
1707
|
-
raise e
|
|
1717
|
+
# raise e
|
|
1708
1718
|
|
|
1709
1719
|
|
|
1710
1720
|
if __name__ == "__main__":
|
|
@@ -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}",')
|
|
@@ -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
|
|
|
@@ -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:
|