shipit-cli 0.14.0__py3-none-any.whl → 0.15.1__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.
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  from pathlib import Path
4
2
  from typing import Dict, Optional
5
3
 
@@ -12,65 +10,76 @@ from .base import (
12
10
  ServiceSpec,
13
11
  VolumeSpec,
14
12
  CustomCommands,
13
+ Config,
15
14
  )
15
+ from .php import PhpConfig, PhpProvider
16
+ from .node_static import NodeStaticConfig, NodeStaticProvider
17
+ from pydantic_settings import SettingsConfigDict
18
+
19
+
20
+ class LaravelConfig(PhpConfig, NodeStaticConfig):
21
+ model_config = SettingsConfigDict(extra="ignore", env_prefix="SHIPIT_")
16
22
 
17
23
 
18
- class LaravelProvider:
19
- def __init__(self, path: Path, custom_commands: CustomCommands):
24
+ class LaravelProvider(PhpProvider):
25
+ def __init__(self, path: Path, config: LaravelConfig):
20
26
  self.path = path
21
- self.custom_commands = custom_commands
27
+ self.node_provider = NodeStaticProvider(path, config, only_build=True)
28
+ self.config = config
29
+
30
+ @classmethod
31
+ def load_config(cls, path: Path, base_config: Config) -> LaravelConfig:
32
+ config = super().load_config(path, base_config)
33
+ node_config = NodeStaticProvider.load_config(path, base_config)
34
+ node_config.static_dir = None
35
+ node_config.static_generator = None
36
+ return LaravelConfig(
37
+ **(
38
+ config.model_dump()
39
+ | node_config.model_dump()
40
+ | base_config.model_dump()
41
+ )
42
+ )
22
43
 
23
44
  @classmethod
24
45
  def name(cls) -> str:
25
46
  return "laravel"
26
47
 
27
48
  @classmethod
28
- def detect(cls, path: Path, custom_commands: CustomCommands) -> Optional[DetectResult]:
49
+ def detect(cls, path: Path, config: Config) -> Optional[DetectResult]:
29
50
  if _exists(path, "artisan") and _exists(path, "composer.json"):
30
51
  return DetectResult(cls.name(), 95)
31
52
  return None
32
53
 
33
- def initialize(self) -> None:
34
- pass
35
-
36
54
  def serve_name(self) -> Optional[str]:
37
55
  return None
38
56
 
39
- def platform(self) -> Optional[str]:
40
- return "laravel"
41
-
42
57
  def dependencies(self) -> list[DependencySpec]:
43
58
  return [
44
59
  DependencySpec(
45
60
  "php",
46
- env_var="SHIPIT_PHP_VERSION",
47
- default_version="8.3",
61
+ var_name="config.php_version",
48
62
  use_in_build=True,
49
63
  use_in_serve=True,
50
64
  ),
51
65
  DependencySpec("composer", use_in_build=True),
52
- DependencySpec("pie", use_in_build=True),
53
- DependencySpec("pnpm", use_in_build=True),
66
+ # DependencySpec("pie", use_in_build=True),
67
+ *self.node_provider.dependencies(),
54
68
  DependencySpec("bash", use_in_serve=True),
55
69
  ]
56
70
 
57
- def declarations(self) -> Optional[str]:
58
- return "HOME = getenv(\"HOME\")"
59
-
60
71
  def build_steps(self) -> list[str]:
61
72
  return [
62
- "env(HOME=HOME, COMPOSER_FUND=\"0\")",
63
- "workdir(app[\"build\"])",
64
- "run(\"pie install php/pdo_pgsql\")",
65
- "run(\"composer install --optimize-autoloader --no-scripts --no-interaction\", inputs=[\"composer.json\", \"composer.lock\", \"artisan\"], outputs=[\".\"], group=\"install\")",
66
- "run(\"pnpm install\", inputs=[\"package.json\", \"package-lock.json\"], outputs=[\".\"], group=\"install\")",
67
- "copy(\".\", \".\", ignore=[\".git\"])",
68
- "run(\"pnpm run build\", outputs=[\".\"], group=\"build\")",
73
+ 'env(COMPOSER_HOME="/tmp", COMPOSER_FUND="0")',
74
+ 'workdir(app.path)',
75
+ # "run(\"pie install php/pdo_pgsql\")",
76
+ 'run("composer install --optimize-autoloader --no-scripts --no-interaction", inputs=["composer.json", "composer.lock", "artisan"], outputs=["."], group="install")',
77
+ *self.node_provider.build_steps(),
69
78
  ]
70
79
 
71
80
  def prepare_steps(self) -> Optional[list[str]]:
72
81
  return [
73
- 'workdir(app["serve"])',
82
+ 'workdir(app.serve_path)',
74
83
  'run("mkdir -p storage/framework/{sessions,views,cache,testing} storage/logs bootstrap/cache")',
75
84
  'run("php artisan config:cache")',
76
85
  'run("php artisan event:cache")',
@@ -85,13 +94,13 @@ class LaravelProvider:
85
94
  }
86
95
 
87
96
  def mounts(self) -> list[MountSpec]:
88
- return [MountSpec("app")]
97
+ return [MountSpec("app"), *self.node_provider.mounts()]
89
98
 
90
99
  def volumes(self) -> list[VolumeSpec]:
91
100
  return []
92
101
 
93
102
  def env(self) -> Optional[Dict[str, str]]:
94
103
  return None
95
-
104
+
96
105
  def services(self) -> list[ServiceSpec]:
97
106
  return []
@@ -1,5 +1,3 @@
1
- from __future__ import annotations
2
-
3
1
  from pathlib import Path
4
2
  from typing import Dict, Optional
5
3
 
@@ -12,37 +10,54 @@ from .base import (
12
10
  ServiceSpec,
13
11
  VolumeSpec,
14
12
  CustomCommands,
13
+ Config,
15
14
  )
16
- from .staticfile import StaticFileProvider
17
- from .python import PythonProvider
15
+ from .staticfile import StaticFileProvider, StaticFileConfig
16
+ from .python import PythonProvider, PythonConfig
17
+ from pydantic_settings import SettingsConfigDict
18
+
19
+
20
+ class MkdocsConfig(PythonConfig, StaticFileConfig):
21
+ model_config = SettingsConfigDict(extra="ignore", env_prefix="SHIPIT_")
22
+
23
+ mkdocs_version: Optional[str] = None
18
24
 
19
25
 
20
26
  class MkdocsProvider(StaticFileProvider):
21
- def __init__(self, path: Path, custom_commands: CustomCommands):
27
+ def __init__(self, path: Path, config: MkdocsConfig):
22
28
  self.path = path
23
- self.python_provider = PythonProvider(path, custom_commands, only_build=True, extra_dependencies={"mkdocs"})
29
+ self.python_provider = PythonProvider(path, config, only_build=True)
30
+
31
+ @classmethod
32
+ def load_config(cls, path: Path, base_config: Config) -> MkdocsConfig:
33
+ python_config = PythonProvider.load_config(
34
+ path, base_config, must_have_deps={"mkdocs"}
35
+ )
36
+ staticfile_config = StaticFileProvider.load_config(path, base_config)
37
+
38
+ return MkdocsConfig(
39
+ **(
40
+ python_config.model_dump()
41
+ | staticfile_config.model_dump()
42
+ | base_config.model_dump()
43
+ )
44
+ )
24
45
 
25
46
  @classmethod
26
47
  def name(cls) -> str:
27
48
  return "mkdocs"
28
49
 
29
50
  @classmethod
30
- def detect(cls, path: Path, custom_commands: CustomCommands) -> Optional[DetectResult]:
51
+ def detect(cls, path: Path, config: Config) -> Optional[DetectResult]:
31
52
  if _exists(path, "mkdocs.yml", "mkdocs.yaml"):
32
53
  return DetectResult(cls.name(), 85)
33
- if custom_commands.build and custom_commands.build.startswith("mkdocs "):
54
+ if config.commands.build and config.commands.build.startswith("mkdocs "):
34
55
  return DetectResult(cls.name(), 85)
35
56
  return None
36
57
 
37
- def initialize(self) -> None:
38
- pass
39
-
40
58
  def serve_name(self) -> Optional[str]:
41
59
  return None
42
60
 
43
- def platform(self) -> Optional[str]:
44
- return None
45
-
46
61
  def dependencies(self) -> list[DependencySpec]:
47
62
  return [
48
63
  *self.python_provider.dependencies(),
@@ -50,25 +65,25 @@ class MkdocsProvider(StaticFileProvider):
50
65
  ]
51
66
 
52
67
  def declarations(self) -> Optional[str]:
53
- return "mkdocs_version = getenv(\"SHIPIT_MKDOCS_VERSION\") or \"1.6.1\"\n" + (self.python_provider.declarations() or "")
68
+ return self.python_provider.declarations() or ""
54
69
 
55
70
  def build_steps(self) -> list[str]:
56
71
  return [
57
72
  *self.python_provider.build_steps(),
58
- "run(\"uv run mkdocs build --site-dir={}\".format(app[\"build\"]), outputs=[\".\"], group=\"build\")",
73
+ 'run("uv run mkdocs build --site-dir={}".format(static_app.path), outputs=["."], group="build")',
59
74
  ]
60
75
 
61
76
  def prepare_steps(self) -> Optional[list[str]]:
62
77
  return self.python_provider.prepare_steps()
63
78
 
64
79
  def mounts(self) -> list[MountSpec]:
65
- return [MountSpec("app"), *self.python_provider.mounts()]
80
+ return [*self.python_provider.mounts(), *super().mounts()]
66
81
 
67
82
  def volumes(self) -> list[VolumeSpec]:
68
83
  return []
69
84
 
70
85
  def env(self) -> Optional[Dict[str, str]]:
71
86
  return self.python_provider.env()
72
-
87
+
73
88
  def services(self) -> list[ServiceSpec]:
74
89
  return []
@@ -1,11 +1,10 @@
1
- from __future__ import annotations
2
-
3
1
  import json
4
2
  import yaml
5
3
  from pathlib import Path
6
- from typing import Dict, Optional, Any, Set
4
+ from typing import Dict, Optional, Any, Set, List
7
5
  from enum import Enum
8
6
  from semantic_version import Version, NpmSpec
7
+ from pydantic import Field
9
8
 
10
9
 
11
10
  from .base import (
@@ -15,9 +14,10 @@ from .base import (
15
14
  MountSpec,
16
15
  ServiceSpec,
17
16
  VolumeSpec,
18
- CustomCommands,
17
+ Config,
19
18
  )
20
- from .staticfile import StaticFileProvider
19
+ from .staticfile import StaticFileProvider, StaticFileConfig
20
+ from pydantic_settings import SettingsConfigDict
21
21
 
22
22
 
23
23
  class PackageManager(Enum):
@@ -46,7 +46,7 @@ class PackageManager(Enum):
46
46
 
47
47
  return DependencySpec(
48
48
  dep_name,
49
- env_var=f"SHIPIT_{dep_name.upper()}_VERSION",
49
+ var_name=f"config.{dep_name.lower()}_version",
50
50
  default_version=default_version,
51
51
  )
52
52
 
@@ -114,60 +114,146 @@ class StaticGenerator(Enum):
114
114
  REMIX_OLD = "remix-old"
115
115
  REMIX_V2 = "remix-v2"
116
116
 
117
+ def get_output_dir(self) -> str:
118
+ if self == StaticGenerator.NEXT:
119
+ return "out"
120
+ elif self == StaticGenerator.NUXT_V3:
121
+ return ".output/public"
122
+ elif self in [
123
+ StaticGenerator.ASTRO,
124
+ StaticGenerator.VITE,
125
+ StaticGenerator.NUXT_OLD,
126
+ StaticGenerator.REMIX_V2,
127
+ ]:
128
+ return "dist"
129
+ elif self == StaticGenerator.GATSBY:
130
+ return "public"
131
+ elif self == StaticGenerator.REMIX_OLD:
132
+ return "build/client"
133
+ elif self in [
134
+ StaticGenerator.DOCUSAURUS,
135
+ StaticGenerator.DOCUSAURUS_OLD,
136
+ StaticGenerator.SVELTE,
137
+ ]:
138
+ return "build"
139
+ else:
140
+ return "dist"
141
+
142
+ @classmethod
143
+ def detect_generators_from_command(cls, build_command) -> List["StaticGenerator"]:
144
+ commands = {
145
+ "gatsby": [StaticGenerator.GATSBY],
146
+ "astro": [StaticGenerator.ASTRO],
147
+ "remix-ssg": [StaticGenerator.REMIX_OLD],
148
+ "vite": [StaticGenerator.VITE, StaticGenerator.REMIX_V2],
149
+ "docusaurus": [StaticGenerator.DOCUSAURUS, StaticGenerator.DOCUSAURUS_OLD],
150
+ "next": [StaticGenerator.NEXT],
151
+ "nuxi": [StaticGenerator.NUXT_V3],
152
+ "nuxt": [StaticGenerator.NUXT_OLD],
153
+ "svelte-kit": [StaticGenerator.SVELTE],
154
+ }
155
+ build_command = build_command.split(" ")[0]
156
+ if build_command in commands:
157
+ return commands[build_command]
158
+ else:
159
+ return []
160
+
161
+ def build_command(self) -> str:
162
+ return {
163
+ StaticGenerator.GATSBY: "gatsby build",
164
+ StaticGenerator.ASTRO: "astro build",
165
+ StaticGenerator.REMIX_OLD: "remix-ssg build",
166
+ StaticGenerator.REMIX_V2: "vite build",
167
+ StaticGenerator.DOCUSAURUS: "docusaurus build",
168
+ StaticGenerator.DOCUSAURUS_OLD: "docusaurus build",
169
+ StaticGenerator.SVELTE: "svelte-kit build",
170
+ StaticGenerator.VITE: "vite build",
171
+ StaticGenerator.NEXT: "next export",
172
+ StaticGenerator.NUXT_V3: "nuxi generate",
173
+ StaticGenerator.NUXT_OLD: "nuxt generate",
174
+ StaticGenerator.REMIX: "remix-ssg build",
175
+ }[self]
117
176
 
118
- class NodeStaticProvider(StaticFileProvider):
119
- package_manager: PackageManager
120
- package_json: Optional[Dict[str, Any]]
121
- extra_dependencies: Set[str]
177
+
178
+ class NodeStaticConfig(StaticFileConfig):
179
+ model_config = SettingsConfigDict(extra="ignore", env_prefix="SHIPIT_")
180
+
181
+ package_manager: Optional[PackageManager] = None
182
+ extra_dependencies: Set[str] = Field(default_factory=set)
122
183
  static_generator: Optional[StaticGenerator] = None
123
184
  build_command: Optional[str] = None
185
+ node_version: Optional[str] = "22"
186
+ npm_version: Optional[str] = None
187
+ pnpm_version: Optional[str] = None
188
+ yarn_version: Optional[str] = None
189
+ bun_version: Optional[str] = None
124
190
 
125
- def __init__(self, path: Path, custom_commands: CustomCommands):
126
- super().__init__(path, custom_commands)
127
- if (path / "package-lock.json").exists():
128
- self.package_manager = PackageManager.NPM
129
- elif (path / "pnpm-lock.yaml").exists():
130
- self.package_manager = PackageManager.PNPM
131
- elif (path / "yarn.lock").exists():
132
- self.package_manager = PackageManager.YARN
133
- elif (path / "bun.lockb").exists():
134
- self.package_manager = PackageManager.BUN
135
- else:
136
- self.package_manager = PackageManager.PNPM
137
-
138
- self.package_json = self.parse_package_json(path)
139
-
140
- if self.has_dependency(self.package_json, "gatsby"):
141
- self.static_generator = StaticGenerator.GATSBY
142
- elif self.has_dependency(self.package_json, "astro"):
143
- self.static_generator = StaticGenerator.ASTRO
144
- elif self.has_dependency(self.package_json, "docusaurus"):
145
- self.static_generator = StaticGenerator.DOCUSAURUS_OLD
146
- elif self.has_dependency(self.package_json, "@docusaurus/core"):
147
- self.static_generator = StaticGenerator.DOCUSAURUS
148
- elif self.has_dependency(self.package_json, "svelte"):
149
- self.static_generator = StaticGenerator.SVELTE
150
- elif self.has_dependency(
151
- self.package_json, "@remix-run/dev", "1"
152
- ) or self.has_dependency(self.package_json, "@remix-run/dev", "0"):
153
- self.static_generator = StaticGenerator.REMIX_OLD
154
- elif self.has_dependency(self.package_json, "@remix-run/dev"):
155
- self.static_generator = StaticGenerator.REMIX_V2
156
- elif self.has_dependency(self.package_json, "vite"):
157
- self.static_generator = StaticGenerator.VITE
158
- elif self.has_dependency(self.package_json, "next"):
159
- self.static_generator = StaticGenerator.NEXT
160
- elif self.has_dependency(self.package_json, "nuxt", "2") or self.has_dependency(
161
- self.package_json, "nuxt", "1"
162
- ):
163
- self.static_generator = StaticGenerator.NUXT_OLD
164
- elif self.has_dependency(self.package_json, "nuxt"):
165
- self.static_generator = StaticGenerator.NUXT_V3
166
-
167
- self.build_command = self.get_build_command(self.package_json, self.package_manager, self.static_generator)
168
-
169
- # if self.has_dependency(self.package_json, "sharp"):
170
- # self.extra_dependencies.add("libvips")
191
+
192
+ class NodeStaticProvider(StaticFileProvider):
193
+ only_build: bool = False
194
+
195
+ def __init__(
196
+ self, path: Path, config: NodeStaticConfig, only_build: bool = False
197
+ ):
198
+ super().__init__(path, config)
199
+ self.only_build = only_build
200
+
201
+ @classmethod
202
+ def load_config(
203
+ cls, path: Path, base_config: Config
204
+ ) -> NodeStaticConfig:
205
+ config = NodeStaticConfig(**base_config.model_dump())
206
+ if not config.package_manager:
207
+ if (path / "package-lock.json").exists():
208
+ config.package_manager = PackageManager.NPM
209
+ elif (path / "pnpm-lock.yaml").exists():
210
+ config.package_manager = PackageManager.PNPM
211
+ elif (path / "yarn.lock").exists():
212
+ config.package_manager = PackageManager.YARN
213
+ elif (path / "bun.lockb").exists():
214
+ config.package_manager = PackageManager.BUN
215
+ else:
216
+ config.package_manager = PackageManager.PNPM
217
+
218
+ package_json = cls.parse_package_json(path)
219
+
220
+ if not config.static_generator:
221
+ if cls.has_dependency(package_json, "gatsby"):
222
+ config.static_generator = StaticGenerator.GATSBY
223
+ elif cls.has_dependency(package_json, "astro"):
224
+ config.static_generator = StaticGenerator.ASTRO
225
+ elif cls.has_dependency(package_json, "docusaurus"):
226
+ config.static_generator = StaticGenerator.DOCUSAURUS_OLD
227
+ elif cls.has_dependency(package_json, "@docusaurus/core"):
228
+ config.static_generator = StaticGenerator.DOCUSAURUS
229
+ elif cls.has_dependency(package_json, "svelte"):
230
+ config.static_generator = StaticGenerator.SVELTE
231
+ elif cls.has_dependency(
232
+ package_json, "@remix-run/dev", "1"
233
+ ) or cls.has_dependency(package_json, "@remix-run/dev", "0"):
234
+ config.static_generator = StaticGenerator.REMIX_OLD
235
+ elif cls.has_dependency(package_json, "@remix-run/dev"):
236
+ config.static_generator = StaticGenerator.REMIX_V2
237
+ elif cls.has_dependency(package_json, "vite"):
238
+ config.static_generator = StaticGenerator.VITE
239
+ elif cls.has_dependency(package_json, "next"):
240
+ config.static_generator = StaticGenerator.NEXT
241
+ elif cls.has_dependency(package_json, "nuxt", "2") or cls.has_dependency(
242
+ package_json, "nuxt", "1"
243
+ ):
244
+ config.static_generator = StaticGenerator.NUXT_OLD
245
+ elif cls.has_dependency(package_json, "nuxt"):
246
+ config.static_generator = StaticGenerator.NUXT_V3
247
+
248
+ if not config.build_command:
249
+ config.build_command = cls.get_build_command(
250
+ package_json, config.package_manager, config.static_generator
251
+ )
252
+
253
+ if not config.static_dir:
254
+ config.static_dir = config.static_generator.get_output_dir()
255
+
256
+ return config
171
257
 
172
258
  @classmethod
173
259
  def parse_package_json(cls, path: Path) -> Optional[Dict[str, Any]]:
@@ -211,8 +297,27 @@ class NodeStaticProvider(StaticFileProvider):
211
297
 
212
298
  @classmethod
213
299
  def detect(
214
- cls, path: Path, custom_commands: CustomCommands
300
+ cls, path: Path, config: Config
215
301
  ) -> Optional[DetectResult]:
302
+ if config.commands.install:
303
+ # Detect this provider from the install command
304
+ if config.commands.install in ["npm install", "npm ci", "npm i", "pnpm install", "pnpm ci", "pnpm i", "yarn install", "yarn ci", "yarn i", "bun install", "bun ci", "bun i"]:
305
+ return DetectResult(cls.name(), 40)
306
+
307
+ if config.commands.build:
308
+ if config.commands.build.startswith("npm run "):
309
+ return DetectResult(cls.name(), 40)
310
+ elif config.commands.build.startswith("pnpm run "):
311
+ return DetectResult(cls.name(), 40)
312
+ elif config.commands.build.startswith("yarn run "):
313
+ return DetectResult(cls.name(), 40)
314
+ elif config.commands.build.startswith("bun run "):
315
+ return DetectResult(cls.name(), 40)
316
+
317
+ static_generators = StaticGenerator.detect_generators_from_command(config.commands.build)
318
+ if static_generators:
319
+ return DetectResult(cls.name(), 40)
320
+
216
321
  package_json = cls.parse_package_json(path)
217
322
  if not package_json:
218
323
  return None
@@ -231,119 +336,80 @@ class NodeStaticProvider(StaticFileProvider):
231
336
  return DetectResult(cls.name(), 40)
232
337
  return None
233
338
 
234
- def initialize(self) -> None:
235
- pass
236
-
237
339
  def serve_name(self) -> Optional[str]:
238
340
  return None
239
341
 
240
- def platform(self) -> Optional[str]:
241
- return self.static_generator.value if self.static_generator else None
242
-
243
342
  def dependencies(self) -> list[DependencySpec]:
244
- package_manager_dep = self.package_manager.as_dependency(self.path)
343
+ package_manager_dep = self.config.package_manager.as_dependency(self.path)
245
344
  package_manager_dep.use_in_build = True
246
345
  return [
247
346
  DependencySpec(
248
347
  "node",
249
- env_var="SHIPIT_NODE_VERSION",
250
- default_version="22",
348
+ var_name="config.node_version",
251
349
  use_in_build=True,
252
350
  ),
253
351
  package_manager_dep,
254
- DependencySpec("static-web-server", use_in_serve=True),
352
+ *super().dependencies(),
255
353
  ]
256
354
 
257
- def declarations(self) -> Optional[str]:
258
- output_dir = self.get_output_dir()
259
- return (
260
- f'shipit_static_dir = getenv("SHIPIT_STATIC_DIR") or "{output_dir}"\n'
261
- )
262
-
263
- def get_output_dir(self) -> str:
264
- if self.static_generator == StaticGenerator.NEXT:
265
- return "out"
266
- elif self.static_generator in [
267
- StaticGenerator.ASTRO,
268
- StaticGenerator.VITE,
269
- StaticGenerator.NUXT_OLD,
270
- StaticGenerator.NUXT_V3,
271
- StaticGenerator.REMIX_V2,
272
- ]:
273
- return "dist"
274
- elif self.static_generator == StaticGenerator.GATSBY:
275
- return "public"
276
- elif self.static_generator == StaticGenerator.REMIX_OLD:
277
- return "build/client"
278
- elif self.static_generator in [
279
- StaticGenerator.DOCUSAURUS,
280
- StaticGenerator.DOCUSAURUS_OLD,
281
- StaticGenerator.SVELTE,
282
- ]:
283
- return "build"
284
- else:
285
- return "dist"
286
-
287
355
  @classmethod
288
- def get_build_command(cls, package_json: Optional[Dict[str, Any]], package_manager: PackageManager, static_generator: StaticGenerator) -> Optional[str]:
356
+ def get_build_command(
357
+ cls,
358
+ package_json: Optional[Dict[str, Any]],
359
+ package_manager: PackageManager,
360
+ static_generator: StaticGenerator,
361
+ ) -> Optional[str]:
289
362
  if package_json:
290
- build_command = package_json.get("scripts", {}).get("build")
363
+ scripts = package_json.get("scripts", {})
364
+ generate_command = scripts.get("generate")
365
+ if generate_command:
366
+ return package_manager.run_command("generate")
367
+ build_command = scripts.get("build")
291
368
  if build_command:
292
369
  return package_manager.run_command("build")
293
- if static_generator == StaticGenerator.GATSBY:
294
- return package_manager.run_execute_command("gatsby build")
295
- elif static_generator == StaticGenerator.ASTRO:
296
- return package_manager.run_execute_command("astro build")
297
- elif static_generator == StaticGenerator.REMIX_OLD:
298
- return package_manager.run_execute_command("remix-ssg build")
299
- elif static_generator == StaticGenerator.REMIX_V2:
300
- return package_manager.run_execute_command("vite build")
301
- elif static_generator == StaticGenerator.DOCUSAURUS:
302
- return package_manager.run_execute_command("docusaurus build")
303
- elif static_generator == StaticGenerator.DOCUSAURUS_OLD:
304
- return package_manager.run_execute_command("docusaurus build")
305
- elif static_generator == StaticGenerator.SVELTE:
306
- return package_manager.run_execute_command("svelte-kit build")
307
- elif static_generator == StaticGenerator.VITE:
308
- return package_manager.run_execute_command("vite build")
309
- elif static_generator == StaticGenerator.NEXT:
310
- return package_manager.run_execute_command("next export")
311
- elif static_generator == StaticGenerator.NUXT_V3:
312
- return package_manager.run_execute_command("nuxi generate")
313
- elif static_generator == StaticGenerator.NUXT_OLD:
314
- return package_manager.run_execute_command("nuxt generate")
315
- return None
370
+ command = static_generator.build_command()
371
+ return package_manager.run_execute_command(command)
316
372
 
317
373
  def build_steps(self) -> list[str]:
318
- lockfile = self.package_manager.lockfile()
374
+ lockfile = self.config.package_manager.lockfile()
319
375
  has_lockfile = (self.path / lockfile).exists()
320
- install_command = self.package_manager.install_command(
376
+ install_command = self.config.package_manager.install_command(
321
377
  has_lockfile=has_lockfile
322
378
  )
323
- input_files = ["package.json"]
324
- # if has_lockfile:
325
- # input_files.append(lockfile)
326
- inputs_install_files = ", ".join([f'"{file}"' for file in input_files])
327
-
328
379
  ignored_files = ["node_modules", ".git"]
329
380
  if has_lockfile:
330
381
  ignored_files.append(lockfile)
331
382
  all_ignored_files = ", ".join([f'"{file}"' for file in ignored_files])
332
-
333
- return [
334
- 'workdir(temp["build"])',
335
- f'copy("{lockfile}")' if has_lockfile else None,
336
- # 'run("npx corepack enable", inputs=["package.json"], group="install")',
337
- f'run("{install_command}", inputs=[{inputs_install_files}], group="install")',
338
- f'copy(".", ignore=[{all_ignored_files}])',
339
- f'run("{self.build_command}", outputs=[shipit_static_dir], group="build")',
340
- f'run("cp -R {{}}/* {{}}/".format(shipit_static_dir, app["build"]))',
341
- ]
383
+
384
+ return filter(
385
+ None,
386
+ [
387
+ 'workdir(temp.path)' if not self.only_build else None,
388
+ f'copy("{lockfile}")' if has_lockfile else None,
389
+ 'env(CI="true", NODE_ENV="production", NPM_CONFIG_FUND="false")'
390
+ if self.config.package_manager == PackageManager.NPM
391
+ else None,
392
+ # 'run("npx corepack enable", inputs=["package.json"], group="install")',
393
+ f'run("{install_command}", inputs=["package.json"], group="install")',
394
+ f'copy(".", ignore=[{all_ignored_files}])',
395
+ f'run("{self.config.build_command}", outputs=[config.static_dir], group="build")'
396
+ if not self.only_build
397
+ else None,
398
+ f'run("{self.config.build_command}", group="build")'
399
+ if self.only_build
400
+ else None,
401
+ 'run("cp -R {}/* {}/".format(config.static_dir, static_app.path))'
402
+ if not self.only_build
403
+ else None,
404
+ ],
405
+ )
342
406
 
343
407
  def prepare_steps(self) -> Optional[list[str]]:
344
408
  return None
345
409
 
346
410
  def mounts(self) -> list[MountSpec]:
411
+ if self.only_build:
412
+ return []
347
413
  return [MountSpec("temp", attach_to_serve=False), *super().mounts()]
348
414
 
349
415
  def volumes(self) -> list[VolumeSpec]: