shipit-cli 0.19.6.dev0__tar.gz → 0.19.7__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.19.6.dev0 → shipit_cli-0.19.7}/PKG-INFO +1 -1
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/pyproject.toml +1 -1
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/assets/wordpress/install.sh +11 -15
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/node_static.py +338 -39
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/wordpress.py +5 -5
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/runners/wasmer.py +15 -15
- shipit_cli-0.19.7/src/shipit/version.py +5 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_e2e.py +49 -0
- shipit_cli-0.19.6.dev0/src/shipit/version.py +0 -5
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/.gitignore +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/README.md +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/__init__.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/assets/php/php.ini +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/assets/wordpress/.htaccess +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/assets/wordpress/start.php +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/assets/wordpress/wp-config.php +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/builders/__init__.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/builders/base.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/builders/docker.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/builders/local.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/cli.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/generator.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/procfile.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/base.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/go.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/hugo.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/jekyll.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/laravel.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/mkdocs.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/php.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/python.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/registry.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/providers/staticfile.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/runners/__init__.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/runners/base.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/runners/local.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/shipit_types.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/ui.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/utils.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/src/shipit/volumes.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_cli_after_deploy.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_generate_shipit_examples.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_php_provider.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_staticfile_provider.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_version.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_volumes.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/tests/test_wasmer_annotations.py +0 -0
- {shipit_cli-0.19.6.dev0 → shipit_cli-0.19.7}/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.
|
|
3
|
+
Version: 0.19.7
|
|
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
|
|
@@ -11,10 +11,6 @@ WP_LOCALE=${WP_LOCALE:-"en_US"}
|
|
|
11
11
|
WP_SITEURL=${WP_SITEURL:-"http://localhost"}
|
|
12
12
|
WP_SITE_TITLE=${WP_SITE_TITLE:-"WordPress"}
|
|
13
13
|
|
|
14
|
-
wp() {
|
|
15
|
-
php /opt/assets/wp-cli.phar --allow-root --path=/app "$@"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
14
|
if wp core is-installed; then
|
|
19
15
|
echo "🚀 Setting up WordPress from an existing installation"
|
|
20
16
|
if [ "${WP_UPDATE_DB:-true}" = "true" ]; then
|
|
@@ -30,17 +26,17 @@ else
|
|
|
30
26
|
echo "📁 Initializing wp-content..."
|
|
31
27
|
|
|
32
28
|
mkdir -p wp-content/plugins
|
|
33
|
-
|
|
29
|
+
mkdir -p wp-content/themes
|
|
34
30
|
mkdir -p wp-content/upgrade
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
32
|
+
if [ -n "${WPCONTENT_BASE_PATH:-}" ] && [ -d "${WPCONTENT_BASE_PATH}" ]; then
|
|
33
|
+
shopt -s dotglob nullglob
|
|
34
|
+
# Note: change this back to copy all, once using the WP Zip files
|
|
35
|
+
# cp -R "${WPCONTENT_BASE_PATH}"/* /app/wp-content
|
|
36
|
+
cp -R "${WPCONTENT_BASE_PATH}"/plugins/* /app/wp-content/plugins || true
|
|
37
|
+
cp -R "${WPCONTENT_BASE_PATH}"/themes/twentytwenty* /app/wp-content/themes || true
|
|
38
|
+
shopt -u dotglob nullglob
|
|
39
|
+
fi
|
|
44
40
|
|
|
45
41
|
echo "⚙️ Installing WordPress core"
|
|
46
42
|
|
|
@@ -52,8 +48,8 @@ else
|
|
|
52
48
|
--admin_email="$WP_ADMIN_EMAIL" \
|
|
53
49
|
--locale="$WP_LOCALE"
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
echo "🔄 Setting permalinks"
|
|
52
|
+
wp rewrite structure '/%year%/%monthnum%/%day%/%postname%/'
|
|
57
53
|
fi
|
|
58
54
|
|
|
59
55
|
# Install plugins from WP_PLUGINS environment variable
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
from shipit.providers.base import _exists
|
|
2
1
|
import json
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
from typing import Dict, Optional, Any, Set, List
|
|
2
|
+
import re
|
|
3
|
+
import shlex
|
|
6
4
|
from enum import Enum
|
|
7
|
-
from
|
|
8
|
-
from
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any, Dict, List, Optional, Set
|
|
9
7
|
|
|
8
|
+
import yaml
|
|
9
|
+
from pydantic import Field
|
|
10
|
+
from pydantic_settings import SettingsConfigDict
|
|
11
|
+
from semantic_version import NpmSpec, Version
|
|
10
12
|
|
|
11
13
|
from .base import (
|
|
14
|
+
Config,
|
|
12
15
|
DetectResult,
|
|
13
16
|
DependencySpec,
|
|
14
|
-
Provider,
|
|
15
17
|
MountSpec,
|
|
18
|
+
Provider,
|
|
16
19
|
ServiceSpec,
|
|
17
20
|
VolumeSpec,
|
|
18
|
-
|
|
21
|
+
_exists,
|
|
19
22
|
)
|
|
20
23
|
from .staticfile import StaticFileProvider, StaticFileConfig
|
|
21
|
-
from pydantic_settings import SettingsConfigDict
|
|
22
24
|
|
|
23
25
|
|
|
24
26
|
class PackageManager(Enum):
|
|
@@ -106,6 +108,13 @@ class StaticGenerator(Enum):
|
|
|
106
108
|
VITE = "vite"
|
|
107
109
|
NEXT = "next"
|
|
108
110
|
GATSBY = "gatsby"
|
|
111
|
+
ELEVENTY = "eleventy"
|
|
112
|
+
VITEPRESS = "vitepress"
|
|
113
|
+
VUEPRESS = "vuepress"
|
|
114
|
+
HEXO = "hexo"
|
|
115
|
+
METALSMITH = "metalsmith"
|
|
116
|
+
ASSEMBLE = "assemble"
|
|
117
|
+
HARP = "harp"
|
|
109
118
|
DOCUSAURUS_OLD = "docusaurus-old"
|
|
110
119
|
DOCUSAURUS = "docusaurus"
|
|
111
120
|
SVELTE = "svelte"
|
|
@@ -119,6 +128,8 @@ class StaticGenerator(Enum):
|
|
|
119
128
|
def get_output_dir(self) -> str:
|
|
120
129
|
if self == StaticGenerator.NEXT:
|
|
121
130
|
return "out"
|
|
131
|
+
elif self == StaticGenerator.ELEVENTY:
|
|
132
|
+
return "_site"
|
|
122
133
|
elif self == StaticGenerator.NUXT_V3:
|
|
123
134
|
return ".output/public"
|
|
124
135
|
elif self in [
|
|
@@ -129,6 +140,12 @@ class StaticGenerator(Enum):
|
|
|
129
140
|
return "dist"
|
|
130
141
|
elif self == StaticGenerator.GATSBY:
|
|
131
142
|
return "public"
|
|
143
|
+
elif self == StaticGenerator.HEXO:
|
|
144
|
+
return "public"
|
|
145
|
+
elif self == StaticGenerator.VITEPRESS:
|
|
146
|
+
return "docs/.vitepress/dist"
|
|
147
|
+
elif self == StaticGenerator.VUEPRESS:
|
|
148
|
+
return "docs/.vuepress/dist"
|
|
132
149
|
elif self in [
|
|
133
150
|
StaticGenerator.REMIX_OLD,
|
|
134
151
|
StaticGenerator.REMIX,
|
|
@@ -137,38 +154,68 @@ class StaticGenerator(Enum):
|
|
|
137
154
|
return "build/client"
|
|
138
155
|
elif self == StaticGenerator.REMIX_V2_CLASSIC:
|
|
139
156
|
return "public"
|
|
157
|
+
elif self == StaticGenerator.ASSEMBLE:
|
|
158
|
+
return "dist"
|
|
159
|
+
elif self == StaticGenerator.HARP:
|
|
160
|
+
return "www"
|
|
140
161
|
elif self in [
|
|
141
162
|
StaticGenerator.DOCUSAURUS,
|
|
142
163
|
StaticGenerator.DOCUSAURUS_OLD,
|
|
143
164
|
StaticGenerator.SVELTE,
|
|
165
|
+
StaticGenerator.METALSMITH,
|
|
144
166
|
]:
|
|
145
167
|
return "build"
|
|
146
168
|
else:
|
|
147
169
|
return "dist"
|
|
148
170
|
|
|
149
171
|
@classmethod
|
|
150
|
-
def detect_generators_from_command(
|
|
172
|
+
def detect_generators_from_command(
|
|
173
|
+
cls, build_command
|
|
174
|
+
) -> List["StaticGenerator"]:
|
|
151
175
|
commands = {
|
|
152
176
|
"gatsby": [StaticGenerator.GATSBY],
|
|
153
177
|
"astro": [StaticGenerator.ASTRO],
|
|
178
|
+
"@11ty/eleventy": [StaticGenerator.ELEVENTY],
|
|
179
|
+
"eleventy": [StaticGenerator.ELEVENTY],
|
|
154
180
|
"remix-ssg": [StaticGenerator.REMIX_OLD],
|
|
155
181
|
"remix": [StaticGenerator.REMIX_V2_CLASSIC, StaticGenerator.REMIX_V2],
|
|
156
182
|
"vite": [StaticGenerator.VITE],
|
|
157
|
-
"
|
|
183
|
+
"vitepress": [StaticGenerator.VITEPRESS],
|
|
184
|
+
"vuepress": [StaticGenerator.VUEPRESS],
|
|
185
|
+
"hexo": [StaticGenerator.HEXO],
|
|
186
|
+
"metalsmith": [StaticGenerator.METALSMITH],
|
|
187
|
+
"harp": [StaticGenerator.HARP],
|
|
188
|
+
"docusaurus": [
|
|
189
|
+
StaticGenerator.DOCUSAURUS,
|
|
190
|
+
StaticGenerator.DOCUSAURUS_OLD,
|
|
191
|
+
],
|
|
158
192
|
"next": [StaticGenerator.NEXT],
|
|
159
193
|
"nuxi": [StaticGenerator.NUXT_V3],
|
|
160
194
|
"nuxt": [StaticGenerator.NUXT_OLD],
|
|
161
195
|
"svelte-kit": [StaticGenerator.SVELTE],
|
|
162
196
|
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
197
|
+
try:
|
|
198
|
+
tokens = shlex.split(build_command)
|
|
199
|
+
except ValueError:
|
|
200
|
+
tokens = build_command.split()
|
|
201
|
+
|
|
202
|
+
for index, token in enumerate(tokens):
|
|
203
|
+
if token == "grunt" and "assemble" in tokens[index + 1 :]:
|
|
204
|
+
return [StaticGenerator.ASSEMBLE]
|
|
205
|
+
if token in commands:
|
|
206
|
+
return commands[token]
|
|
207
|
+
return []
|
|
208
|
+
|
|
169
209
|
def build_command(self) -> str:
|
|
170
210
|
return {
|
|
171
211
|
StaticGenerator.GATSBY: "gatsby build",
|
|
212
|
+
StaticGenerator.ELEVENTY: "@11ty/eleventy",
|
|
213
|
+
StaticGenerator.VITEPRESS: "vitepress build docs",
|
|
214
|
+
StaticGenerator.VUEPRESS: "vuepress build docs",
|
|
215
|
+
StaticGenerator.HEXO: "hexo generate",
|
|
216
|
+
StaticGenerator.METALSMITH: "metalsmith build",
|
|
217
|
+
StaticGenerator.ASSEMBLE: "grunt assemble",
|
|
218
|
+
StaticGenerator.HARP: "harp compile . www",
|
|
172
219
|
StaticGenerator.ASTRO: "astro build",
|
|
173
220
|
StaticGenerator.REMIX_OLD: "remix-ssg build",
|
|
174
221
|
StaticGenerator.REMIX_V2: "vite build",
|
|
@@ -200,6 +247,7 @@ class NodeStaticConfig(StaticFileConfig):
|
|
|
200
247
|
|
|
201
248
|
class NodeStaticProvider(StaticFileProvider):
|
|
202
249
|
only_build: bool = False
|
|
250
|
+
_ASSEMBLE_DEST_PATTERN = re.compile(r"\bdest\s*:\s*['\"]([^'\"]+)['\"]")
|
|
203
251
|
|
|
204
252
|
def __init__(
|
|
205
253
|
self, path: Path, config: NodeStaticConfig, only_build: bool = False
|
|
@@ -227,7 +275,25 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
227
275
|
package_json = cls.parse_package_json(path)
|
|
228
276
|
|
|
229
277
|
if not config.static_generator:
|
|
230
|
-
if cls.has_dependency(package_json, "
|
|
278
|
+
if cls.has_dependency(package_json, "@11ty/eleventy"):
|
|
279
|
+
config.static_generator = StaticGenerator.ELEVENTY
|
|
280
|
+
elif cls.has_dependency(package_json, "vitepress"):
|
|
281
|
+
config.static_generator = StaticGenerator.VITEPRESS
|
|
282
|
+
elif cls.has_dependency(package_json, "vuepress"):
|
|
283
|
+
config.static_generator = StaticGenerator.VUEPRESS
|
|
284
|
+
elif cls.has_dependency(package_json, "hexo") or cls.has_dependency(
|
|
285
|
+
package_json, "hexo-cli"
|
|
286
|
+
):
|
|
287
|
+
config.static_generator = StaticGenerator.HEXO
|
|
288
|
+
elif cls.has_dependency(package_json, "metalsmith"):
|
|
289
|
+
config.static_generator = StaticGenerator.METALSMITH
|
|
290
|
+
elif cls.has_dependency(package_json, "assemble") or cls.has_dependency(
|
|
291
|
+
package_json, "grunt-assemble"
|
|
292
|
+
):
|
|
293
|
+
config.static_generator = StaticGenerator.ASSEMBLE
|
|
294
|
+
elif cls.has_dependency(package_json, "harp"):
|
|
295
|
+
config.static_generator = StaticGenerator.HARP
|
|
296
|
+
elif cls.has_dependency(package_json, "gatsby"):
|
|
231
297
|
config.static_generator = StaticGenerator.GATSBY
|
|
232
298
|
elif cls.has_dependency(package_json, "astro"):
|
|
233
299
|
config.static_generator = StaticGenerator.ASTRO
|
|
@@ -242,7 +308,17 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
242
308
|
) or cls.has_dependency(package_json, "@remix-run/dev", "0"):
|
|
243
309
|
config.static_generator = StaticGenerator.REMIX_OLD
|
|
244
310
|
elif cls.has_dependency(package_json, "@remix-run/dev"):
|
|
245
|
-
has_vite =
|
|
311
|
+
has_vite = (
|
|
312
|
+
cls.has_dependency(package_json, "@remix-run/vite")
|
|
313
|
+
or cls.has_dependency(package_json, "vite")
|
|
314
|
+
or _exists(
|
|
315
|
+
path,
|
|
316
|
+
"vite.config.js",
|
|
317
|
+
"vite.config.ts",
|
|
318
|
+
"vite.config.mjs",
|
|
319
|
+
"vite.config.cjs",
|
|
320
|
+
)
|
|
321
|
+
)
|
|
246
322
|
if has_vite:
|
|
247
323
|
config.static_generator = StaticGenerator.REMIX_V2
|
|
248
324
|
else:
|
|
@@ -264,7 +340,12 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
264
340
|
)
|
|
265
341
|
|
|
266
342
|
if not config.static_dir:
|
|
267
|
-
|
|
343
|
+
if config.static_generator:
|
|
344
|
+
config.static_dir = cls.get_static_dir(
|
|
345
|
+
path, package_json, config.static_generator
|
|
346
|
+
)
|
|
347
|
+
else:
|
|
348
|
+
config.static_dir = "dist"
|
|
268
349
|
|
|
269
350
|
return config
|
|
270
351
|
|
|
@@ -282,6 +363,168 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
282
363
|
except Exception:
|
|
283
364
|
return None
|
|
284
365
|
|
|
366
|
+
@classmethod
|
|
367
|
+
def get_static_dir(
|
|
368
|
+
cls,
|
|
369
|
+
path: Path,
|
|
370
|
+
package_json: Optional[Dict[str, Any]],
|
|
371
|
+
static_generator: StaticGenerator,
|
|
372
|
+
) -> str:
|
|
373
|
+
if static_generator == StaticGenerator.VITEPRESS:
|
|
374
|
+
root = cls._script_build_root(package_json, "vitepress")
|
|
375
|
+
root = root or cls._default_docs_root(path, ".vitepress")
|
|
376
|
+
return cls._rooted_output_dir(root, ".vitepress/dist")
|
|
377
|
+
|
|
378
|
+
if static_generator == StaticGenerator.VUEPRESS:
|
|
379
|
+
root = cls._script_build_root(package_json, "vuepress")
|
|
380
|
+
root = root or cls._default_docs_root(path, ".vuepress")
|
|
381
|
+
return cls._rooted_output_dir(root, ".vuepress/dist")
|
|
382
|
+
|
|
383
|
+
if static_generator == StaticGenerator.METALSMITH:
|
|
384
|
+
return cls._metalsmith_output_dir(path) or static_generator.get_output_dir()
|
|
385
|
+
|
|
386
|
+
if static_generator == StaticGenerator.ASSEMBLE:
|
|
387
|
+
return cls._assemble_output_dir(path) or static_generator.get_output_dir()
|
|
388
|
+
|
|
389
|
+
if static_generator == StaticGenerator.HARP:
|
|
390
|
+
return (
|
|
391
|
+
cls._harp_output_dir(package_json)
|
|
392
|
+
or static_generator.get_output_dir()
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
return static_generator.get_output_dir()
|
|
396
|
+
|
|
397
|
+
@classmethod
|
|
398
|
+
def _script_commands(
|
|
399
|
+
cls, package_json: Optional[Dict[str, Any]]
|
|
400
|
+
) -> list[str]:
|
|
401
|
+
if not package_json:
|
|
402
|
+
return []
|
|
403
|
+
scripts = package_json.get("scripts", {})
|
|
404
|
+
if not isinstance(scripts, dict):
|
|
405
|
+
return []
|
|
406
|
+
|
|
407
|
+
preferred = ("generate", "build", "docs:build")
|
|
408
|
+
commands = [
|
|
409
|
+
scripts[name]
|
|
410
|
+
for name in preferred
|
|
411
|
+
if isinstance(scripts.get(name), str)
|
|
412
|
+
]
|
|
413
|
+
commands.extend(
|
|
414
|
+
command
|
|
415
|
+
for name, command in scripts.items()
|
|
416
|
+
if name not in preferred and isinstance(command, str)
|
|
417
|
+
)
|
|
418
|
+
return commands
|
|
419
|
+
|
|
420
|
+
@classmethod
|
|
421
|
+
def _args_after_command(cls, command: str, executable: str) -> list[str]:
|
|
422
|
+
try:
|
|
423
|
+
tokens = shlex.split(command)
|
|
424
|
+
except ValueError:
|
|
425
|
+
tokens = command.split()
|
|
426
|
+
|
|
427
|
+
for index, token in enumerate(tokens):
|
|
428
|
+
if token == executable:
|
|
429
|
+
return tokens[index + 1 :]
|
|
430
|
+
return []
|
|
431
|
+
|
|
432
|
+
@classmethod
|
|
433
|
+
def _script_build_root(
|
|
434
|
+
cls, package_json: Optional[Dict[str, Any]], executable: str
|
|
435
|
+
) -> Optional[str]:
|
|
436
|
+
for command in cls._script_commands(package_json):
|
|
437
|
+
args = cls._args_after_command(command, executable)
|
|
438
|
+
if not args or args[0] != "build":
|
|
439
|
+
continue
|
|
440
|
+
for arg in args[1:]:
|
|
441
|
+
if not arg.startswith("-"):
|
|
442
|
+
return cls._clean_output_dir(arg)
|
|
443
|
+
return None
|
|
444
|
+
|
|
445
|
+
@classmethod
|
|
446
|
+
def _default_docs_root(cls, path: Path, config_dir: str) -> str:
|
|
447
|
+
docs_path = path / "docs"
|
|
448
|
+
if (docs_path / config_dir).exists() or docs_path.exists():
|
|
449
|
+
return "docs"
|
|
450
|
+
return "."
|
|
451
|
+
|
|
452
|
+
@classmethod
|
|
453
|
+
def _rooted_output_dir(cls, root: str, output_dir: str) -> str:
|
|
454
|
+
root = cls._clean_output_dir(root)
|
|
455
|
+
if root == ".":
|
|
456
|
+
return output_dir
|
|
457
|
+
return f"{root}/{output_dir}"
|
|
458
|
+
|
|
459
|
+
@classmethod
|
|
460
|
+
def _clean_output_dir(cls, output_dir: str) -> str:
|
|
461
|
+
output_dir = output_dir.strip().rstrip("/")
|
|
462
|
+
if output_dir.startswith("./"):
|
|
463
|
+
output_dir = output_dir[2:]
|
|
464
|
+
return output_dir or "."
|
|
465
|
+
|
|
466
|
+
@classmethod
|
|
467
|
+
def _metalsmith_output_dir(cls, path: Path) -> Optional[str]:
|
|
468
|
+
for config_name in ("metalsmith.json", ".metalsmith.json"):
|
|
469
|
+
config_path = path / config_name
|
|
470
|
+
if not config_path.is_file():
|
|
471
|
+
continue
|
|
472
|
+
try:
|
|
473
|
+
config = json.loads(config_path.read_text())
|
|
474
|
+
except Exception:
|
|
475
|
+
continue
|
|
476
|
+
if not isinstance(config, dict):
|
|
477
|
+
continue
|
|
478
|
+
for key in ("destination", "dest"):
|
|
479
|
+
output_dir = config.get(key)
|
|
480
|
+
if isinstance(output_dir, str) and output_dir:
|
|
481
|
+
return cls._clean_output_dir(output_dir)
|
|
482
|
+
return None
|
|
483
|
+
|
|
484
|
+
@classmethod
|
|
485
|
+
def _assemble_output_dir(cls, path: Path) -> Optional[str]:
|
|
486
|
+
for config_name in ("Gruntfile.js", "Gruntfile.cjs"):
|
|
487
|
+
config_path = path / config_name
|
|
488
|
+
if not config_path.is_file():
|
|
489
|
+
continue
|
|
490
|
+
match = cls._ASSEMBLE_DEST_PATTERN.search(config_path.read_text())
|
|
491
|
+
if match:
|
|
492
|
+
return cls._clean_output_dir(match.group(1))
|
|
493
|
+
return None
|
|
494
|
+
|
|
495
|
+
@classmethod
|
|
496
|
+
def _harp_output_dir(
|
|
497
|
+
cls, package_json: Optional[Dict[str, Any]]
|
|
498
|
+
) -> Optional[str]:
|
|
499
|
+
for command in cls._script_commands(package_json):
|
|
500
|
+
args = cls._args_after_command(command, "harp")
|
|
501
|
+
if not args:
|
|
502
|
+
continue
|
|
503
|
+
if args[0] == "compile":
|
|
504
|
+
args = args[1:]
|
|
505
|
+
positional_args = []
|
|
506
|
+
for index, arg in enumerate(args):
|
|
507
|
+
if arg in ("--output", "-o") and index + 1 < len(args):
|
|
508
|
+
return cls._clean_output_dir(args[index + 1])
|
|
509
|
+
if not arg.startswith("-"):
|
|
510
|
+
positional_args.append(arg)
|
|
511
|
+
if len(positional_args) >= 2:
|
|
512
|
+
return cls._clean_output_dir(positional_args[1])
|
|
513
|
+
return None
|
|
514
|
+
|
|
515
|
+
@classmethod
|
|
516
|
+
def _is_package_manager_build_command(cls, command: str) -> bool:
|
|
517
|
+
package_manager_prefixes = (
|
|
518
|
+
"npm run ",
|
|
519
|
+
"pnpm run ",
|
|
520
|
+
"pnpm ",
|
|
521
|
+
"yarn run ",
|
|
522
|
+
"yarn ",
|
|
523
|
+
"bun run ",
|
|
524
|
+
"bun ",
|
|
525
|
+
)
|
|
526
|
+
return command.startswith(package_manager_prefixes)
|
|
527
|
+
|
|
285
528
|
@classmethod
|
|
286
529
|
def has_dependency(
|
|
287
530
|
cls,
|
|
@@ -314,26 +557,65 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
314
557
|
) -> Optional[DetectResult]:
|
|
315
558
|
if config.commands.install:
|
|
316
559
|
# Detect this provider from the install command
|
|
317
|
-
|
|
560
|
+
install_commands = [
|
|
561
|
+
"npm install",
|
|
562
|
+
"npm ci",
|
|
563
|
+
"npm i",
|
|
564
|
+
"pnpm install",
|
|
565
|
+
"pnpm ci",
|
|
566
|
+
"pnpm i",
|
|
567
|
+
"yarn install",
|
|
568
|
+
"yarn ci",
|
|
569
|
+
"yarn i",
|
|
570
|
+
"bun install",
|
|
571
|
+
"bun ci",
|
|
572
|
+
"bun i",
|
|
573
|
+
]
|
|
574
|
+
if config.commands.install in install_commands:
|
|
318
575
|
return DetectResult(cls.name(), 40)
|
|
319
576
|
|
|
577
|
+
has_package_manager_build_command = False
|
|
320
578
|
if config.commands.build:
|
|
321
|
-
if
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
elif config.commands.build.startswith("yarn run "):
|
|
326
|
-
return DetectResult(cls.name(), 40)
|
|
327
|
-
elif config.commands.build.startswith("bun run "):
|
|
328
|
-
return DetectResult(cls.name(), 40)
|
|
579
|
+
# Iterate over all generators and check if the build command matches
|
|
580
|
+
for static_generator in StaticGenerator:
|
|
581
|
+
if static_generator.build_command() in config.commands.build:
|
|
582
|
+
return DetectResult(cls.name(), 60)
|
|
329
583
|
|
|
330
|
-
static_generators = StaticGenerator.detect_generators_from_command(
|
|
584
|
+
static_generators = StaticGenerator.detect_generators_from_command(
|
|
585
|
+
config.commands.build
|
|
586
|
+
)
|
|
331
587
|
if static_generators:
|
|
332
|
-
return DetectResult(cls.name(),
|
|
588
|
+
return DetectResult(cls.name(), 60)
|
|
589
|
+
|
|
590
|
+
has_package_manager_build_command = (
|
|
591
|
+
cls._is_package_manager_build_command(config.commands.build)
|
|
592
|
+
)
|
|
333
593
|
|
|
334
594
|
package_json = cls.parse_package_json(path)
|
|
335
595
|
if not package_json:
|
|
596
|
+
if has_package_manager_build_command:
|
|
597
|
+
return DetectResult(cls.name(), 40)
|
|
336
598
|
return None
|
|
599
|
+
for build_command in cls._script_commands(package_json):
|
|
600
|
+
for static_generator in StaticGenerator:
|
|
601
|
+
if static_generator.build_command() in build_command:
|
|
602
|
+
return DetectResult(cls.name(), 60)
|
|
603
|
+
if StaticGenerator.detect_generators_from_command(build_command):
|
|
604
|
+
return DetectResult(cls.name(), 60)
|
|
605
|
+
|
|
606
|
+
pure_static_generators = [
|
|
607
|
+
"@11ty/eleventy",
|
|
608
|
+
"vitepress",
|
|
609
|
+
"vuepress",
|
|
610
|
+
"hexo",
|
|
611
|
+
"hexo-cli",
|
|
612
|
+
"metalsmith",
|
|
613
|
+
"assemble",
|
|
614
|
+
"grunt-assemble",
|
|
615
|
+
"harp",
|
|
616
|
+
"docusaurus",
|
|
617
|
+
"@docusaurus/core",
|
|
618
|
+
]
|
|
337
619
|
static_generators = [
|
|
338
620
|
"astro",
|
|
339
621
|
"vite",
|
|
@@ -341,12 +623,14 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
341
623
|
"nuxt",
|
|
342
624
|
"gatsby",
|
|
343
625
|
"svelte",
|
|
344
|
-
"docusaurus",
|
|
345
|
-
"@docusaurus/core",
|
|
346
626
|
"@remix-run/dev",
|
|
347
627
|
]
|
|
628
|
+
if any(cls.has_dependency(package_json, dep) for dep in pure_static_generators):
|
|
629
|
+
return DetectResult(cls.name(), 60)
|
|
348
630
|
if any(cls.has_dependency(package_json, dep) for dep in static_generators):
|
|
349
631
|
return DetectResult(cls.name(), 40)
|
|
632
|
+
if has_package_manager_build_command:
|
|
633
|
+
return DetectResult(cls.name(), 40)
|
|
350
634
|
return None
|
|
351
635
|
|
|
352
636
|
def dependencies(self) -> list[DependencySpec]:
|
|
@@ -367,16 +651,29 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
367
651
|
cls,
|
|
368
652
|
package_json: Optional[Dict[str, Any]],
|
|
369
653
|
package_manager: PackageManager,
|
|
370
|
-
static_generator: StaticGenerator,
|
|
654
|
+
static_generator: Optional[StaticGenerator],
|
|
371
655
|
) -> Optional[str]:
|
|
372
656
|
if package_json:
|
|
373
657
|
scripts = package_json.get("scripts", {})
|
|
658
|
+
if not isinstance(scripts, dict):
|
|
659
|
+
scripts = {}
|
|
660
|
+
docs_build_command = scripts.get("docs:build")
|
|
661
|
+
if (
|
|
662
|
+
static_generator
|
|
663
|
+
in [StaticGenerator.VITEPRESS, StaticGenerator.VUEPRESS]
|
|
664
|
+
and docs_build_command
|
|
665
|
+
):
|
|
666
|
+
return package_manager.run_command("docs:build")
|
|
374
667
|
generate_command = scripts.get("generate")
|
|
375
668
|
if generate_command:
|
|
376
669
|
return package_manager.run_command("generate")
|
|
377
670
|
build_command = scripts.get("build")
|
|
378
671
|
if build_command:
|
|
379
672
|
return package_manager.run_command("build")
|
|
673
|
+
if docs_build_command:
|
|
674
|
+
return package_manager.run_command("docs:build")
|
|
675
|
+
if not static_generator:
|
|
676
|
+
return None
|
|
380
677
|
command = static_generator.build_command()
|
|
381
678
|
return package_manager.run_execute_command(command)
|
|
382
679
|
|
|
@@ -393,20 +690,22 @@ class NodeStaticProvider(StaticFileProvider):
|
|
|
393
690
|
'env(CI="true", NODE_ENV="production", NPM_CONFIG_FUND="false")'
|
|
394
691
|
if self.config.package_manager == PackageManager.NPM
|
|
395
692
|
else None,
|
|
396
|
-
# 'run("npx corepack enable", inputs=["package.json"], group="install")',
|
|
397
693
|
f'run("{install_command}", inputs=["package.json"], group="install")',
|
|
398
694
|
],
|
|
399
695
|
)
|
|
400
|
-
|
|
696
|
+
|
|
401
697
|
def build_steps_build(self) -> list[str]:
|
|
402
698
|
return filter(
|
|
403
699
|
None,
|
|
404
700
|
[
|
|
405
|
-
|
|
406
|
-
|
|
701
|
+
(
|
|
702
|
+
f'run("{self.config.build_command}", '
|
|
703
|
+
'outputs=[config.static_dir], group="build")'
|
|
704
|
+
)
|
|
705
|
+
if self.config.build_command and not self.only_build
|
|
407
706
|
else None,
|
|
408
707
|
f'run("{self.config.build_command}", group="build")'
|
|
409
|
-
if self.only_build
|
|
708
|
+
if self.config.build_command and self.only_build
|
|
410
709
|
else None,
|
|
411
710
|
]
|
|
412
711
|
)
|
|
@@ -77,10 +77,10 @@ class WordPressProvider(PhpProvider):
|
|
|
77
77
|
'copy("wordpress/.htaccess", "{}/.htaccess".format(app.path), base="assets")'
|
|
78
78
|
)
|
|
79
79
|
return steps + super().build_steps_with_options(
|
|
80
|
-
extra_ignore=[],
|
|
80
|
+
extra_ignore=["wp-content"],
|
|
81
81
|
after_install=None,
|
|
82
82
|
after_build=None
|
|
83
|
-
)
|
|
83
|
+
) + ['copy("wp-content", "{}".format(wpcontent_base.path))']
|
|
84
84
|
|
|
85
85
|
def prepare_steps(self) -> Optional[list[str]]:
|
|
86
86
|
return super().prepare_steps()
|
|
@@ -94,13 +94,13 @@ class WordPressProvider(PhpProvider):
|
|
|
94
94
|
'-t {}".format(assets.serve_path, PORT, app.serve_path)'
|
|
95
95
|
)
|
|
96
96
|
return {
|
|
97
|
-
|
|
97
|
+
"wp": '"php {}/wp-cli.phar --allow-root --path={}".format(assets.serve_path, app.serve_path)',
|
|
98
98
|
"after_deploy": '"bash {}/setup-wp.sh".format(assets.serve_path)',
|
|
99
99
|
**commands,
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
def mounts(self) -> list[MountSpec]:
|
|
103
|
-
return super().mounts()
|
|
103
|
+
return super().mounts() + [MountSpec("wpcontent_base")]
|
|
104
104
|
|
|
105
105
|
def volumes(self) -> list[VolumeSpec]:
|
|
106
106
|
return [
|
|
@@ -114,7 +114,7 @@ class WordPressProvider(PhpProvider):
|
|
|
114
114
|
def env(self) -> Optional[Dict[str, str]]:
|
|
115
115
|
return {
|
|
116
116
|
"PAGER": '"cat"',
|
|
117
|
-
|
|
117
|
+
"WPCONTENT_BASE_PATH": '"{}".format(wpcontent_base.serve_path)',
|
|
118
118
|
**(super().env() or {}),
|
|
119
119
|
}
|
|
120
120
|
|
|
@@ -149,28 +149,28 @@ class WasmerRunner:
|
|
|
149
149
|
},
|
|
150
150
|
"phpix": {
|
|
151
151
|
"dependencies": {
|
|
152
|
-
"latest": "phpix/phpix-83-32bit@=0.2.0-
|
|
153
|
-
"8.3": "phpix/phpix-83-32bit@=0.2.0-
|
|
154
|
-
"8.3.29": "phpix/phpix-83-32bit@=0.2.0-
|
|
155
|
-
"8.2": "phpix/phpix-82-32bit@=0.2.0-
|
|
156
|
-
"8.1": "phpix/phpix-81-32bit@=0.2.0-
|
|
152
|
+
"latest": "phpix/phpix-83-32bit@=0.2.0-rc.1",
|
|
153
|
+
"8.3": "phpix/phpix-83-32bit@=0.2.0-rc.1",
|
|
154
|
+
"8.3.29": "phpix/phpix-83-32bit@=0.2.0-rc.1",
|
|
155
|
+
"8.2": "phpix/phpix-82-32bit@=0.2.0-rc.1",
|
|
156
|
+
"8.1": "phpix/phpix-81-32bit@=0.2.0-rc.1",
|
|
157
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-
|
|
162
|
-
"8.3": "phpix/phpix-83-64bit@=0.2.0-
|
|
163
|
-
"8.3.29": "phpix/phpix-83-64bit@=0.2.0-
|
|
164
|
-
"8.2": "phpix/phpix-82-64bit@=0.2.0-
|
|
165
|
-
"8.1": "phpix/phpix-81-64bit@=0.2.0-
|
|
161
|
+
"latest": "phpix/phpix-83-64bit@=0.2.0-rc.1",
|
|
162
|
+
"8.3": "phpix/phpix-83-64bit@=0.2.0-rc.1",
|
|
163
|
+
"8.3.29": "phpix/phpix-83-64bit@=0.2.0-rc.1",
|
|
164
|
+
"8.2": "phpix/phpix-82-64bit@=0.2.0-rc.1",
|
|
165
|
+
"8.1": "phpix/phpix-81-64bit@=0.2.0-rc.1",
|
|
166
166
|
"7.4": "php/php-64@=7.4.3301",
|
|
167
167
|
},
|
|
168
168
|
"32-bit": {
|
|
169
|
-
"latest": "phpix/phpix-83-32bit@=0.2.0-
|
|
170
|
-
"8.3": "phpix/phpix-83-32bit@=0.2.0-
|
|
171
|
-
"8.3.29": "phpix/phpix-83-32bit@=0.2.0-
|
|
172
|
-
"8.2": "phpix/phpix-82-32bit@=0.2.0-
|
|
173
|
-
"8.1": "phpix/phpix-81-32bit@=0.2.0-
|
|
169
|
+
"latest": "phpix/phpix-83-32bit@=0.2.0-rc.1",
|
|
170
|
+
"8.3": "phpix/phpix-83-32bit@=0.2.0-rc.1",
|
|
171
|
+
"8.3.29": "phpix/phpix-83-32bit@=0.2.0-rc.1",
|
|
172
|
+
"8.2": "phpix/phpix-82-32bit@=0.2.0-rc.1",
|
|
173
|
+
"8.1": "phpix/phpix-81-32bit@=0.2.0-rc.1",
|
|
174
174
|
"7.4": "php/php-32@=7.4.3301",
|
|
175
175
|
},
|
|
176
176
|
},
|
|
@@ -237,6 +237,55 @@ class E2ECase:
|
|
|
237
237
|
serve_pattern=r"server is listening on",
|
|
238
238
|
http=[HTTPRequest(path="/", body_match=r"Welcome to MkDocs with Plugins")],
|
|
239
239
|
),
|
|
240
|
+
# Eleventy / 11ty static site
|
|
241
|
+
E2ECase(
|
|
242
|
+
path="examples/eleventy",
|
|
243
|
+
serve_pattern=r"server is listening on",
|
|
244
|
+
http=[HTTPRequest(path="/", body_match=r"Eleventy Example")],
|
|
245
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
246
|
+
),
|
|
247
|
+
# VitePress static documentation site
|
|
248
|
+
E2ECase(
|
|
249
|
+
path="examples/vitepress",
|
|
250
|
+
serve_pattern=r"server is listening on",
|
|
251
|
+
http=[HTTPRequest(path="/", body_match=r"VitePress Example")],
|
|
252
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
253
|
+
),
|
|
254
|
+
# VuePress static documentation site
|
|
255
|
+
E2ECase(
|
|
256
|
+
path="examples/vuepress",
|
|
257
|
+
serve_pattern=r"server is listening on",
|
|
258
|
+
http=[HTTPRequest(path="/", body_match=r"VuePress Example")],
|
|
259
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
260
|
+
),
|
|
261
|
+
# Hexo static blog
|
|
262
|
+
E2ECase(
|
|
263
|
+
path="examples/hexo",
|
|
264
|
+
serve_pattern=r"server is listening on",
|
|
265
|
+
http=[HTTPRequest(path="/", body_match=r"Hexo Example")],
|
|
266
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
267
|
+
),
|
|
268
|
+
# Metalsmith static site
|
|
269
|
+
E2ECase(
|
|
270
|
+
path="examples/metalsmith",
|
|
271
|
+
serve_pattern=r"server is listening on",
|
|
272
|
+
http=[HTTPRequest(path="/", body_match=r"Metalsmith Example")],
|
|
273
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
274
|
+
),
|
|
275
|
+
# Assemble static site
|
|
276
|
+
E2ECase(
|
|
277
|
+
path="examples/assemble",
|
|
278
|
+
serve_pattern=r"server is listening on",
|
|
279
|
+
http=[HTTPRequest(path="/", body_match=r"Assemble Example")],
|
|
280
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
281
|
+
),
|
|
282
|
+
# Harp static site
|
|
283
|
+
E2ECase(
|
|
284
|
+
path="examples/harp",
|
|
285
|
+
serve_pattern=r"server is listening on",
|
|
286
|
+
http=[HTTPRequest(path="/", body_match=r"Harp Example")],
|
|
287
|
+
build_modes=(BuildMode.Local, BuildMode.Wasmer),
|
|
288
|
+
),
|
|
240
289
|
# Python FastAPI app on Uvicorn
|
|
241
290
|
E2ECase(
|
|
242
291
|
path="examples/python-fastapi",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|