@fuzdev/gro 0.192.0
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.
- package/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/args.d.ts +37 -0
- package/dist/args.d.ts.map +1 -0
- package/dist/args.js +102 -0
- package/dist/build.task.d.ts +20 -0
- package/dist/build.task.d.ts.map +1 -0
- package/dist/build.task.js +119 -0
- package/dist/build_cache.d.ts +100 -0
- package/dist/build_cache.d.ts.map +1 -0
- package/dist/build_cache.js +299 -0
- package/dist/changelog.d.ts +11 -0
- package/dist/changelog.d.ts.map +1 -0
- package/dist/changelog.js +47 -0
- package/dist/changeset.task.d.ts +35 -0
- package/dist/changeset.task.d.ts.map +1 -0
- package/dist/changeset.task.js +151 -0
- package/dist/changeset_helpers.d.ts +17 -0
- package/dist/changeset_helpers.d.ts.map +1 -0
- package/dist/changeset_helpers.js +7 -0
- package/dist/check.task.d.ts +28 -0
- package/dist/check.task.d.ts.map +1 -0
- package/dist/check.task.js +104 -0
- package/dist/child_process_logging.d.ts +10 -0
- package/dist/child_process_logging.d.ts.map +1 -0
- package/dist/child_process_logging.js +26 -0
- package/dist/clean.task.d.ts +15 -0
- package/dist/clean.task.d.ts.map +1 -0
- package/dist/clean.task.js +40 -0
- package/dist/clean_fs.d.ts +9 -0
- package/dist/clean_fs.d.ts.map +1 -0
- package/dist/clean_fs.js +28 -0
- package/dist/cli.d.ts +34 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +61 -0
- package/dist/commit.task.d.ts +11 -0
- package/dist/commit.task.d.ts.map +1 -0
- package/dist/commit.task.js +24 -0
- package/dist/constants.d.ts +46 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +52 -0
- package/dist/deploy.task.d.ts +29 -0
- package/dist/deploy.task.d.ts.map +1 -0
- package/dist/deploy.task.js +217 -0
- package/dist/dev.task.d.ts +16 -0
- package/dist/dev.task.d.ts.map +1 -0
- package/dist/dev.task.js +44 -0
- package/dist/disknode.d.ts +23 -0
- package/dist/disknode.d.ts.map +1 -0
- package/dist/disknode.js +1 -0
- package/dist/env.d.ts +11 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +49 -0
- package/dist/esbuild_helpers.d.ts +16 -0
- package/dist/esbuild_helpers.d.ts.map +1 -0
- package/dist/esbuild_helpers.js +36 -0
- package/dist/esbuild_plugin_external_worker.d.ts +23 -0
- package/dist/esbuild_plugin_external_worker.d.ts.map +1 -0
- package/dist/esbuild_plugin_external_worker.js +55 -0
- package/dist/esbuild_plugin_svelte.d.ts +15 -0
- package/dist/esbuild_plugin_svelte.d.ts.map +1 -0
- package/dist/esbuild_plugin_svelte.js +83 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts +8 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_local_imports.js +30 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts +7 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_shim_alias.js +18 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts +9 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_shim_app.js +22 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts +11 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.d.ts.map +1 -0
- package/dist/esbuild_plugin_sveltekit_shim_env.js +18 -0
- package/dist/filer.d.ts +33 -0
- package/dist/filer.d.ts.map +1 -0
- package/dist/filer.js +385 -0
- package/dist/format.task.d.ts +11 -0
- package/dist/format.task.d.ts.map +1 -0
- package/dist/format.task.js +27 -0
- package/dist/format_directory.d.ts +13 -0
- package/dist/format_directory.d.ts.map +1 -0
- package/dist/format_directory.js +40 -0
- package/dist/format_file.d.ts +9 -0
- package/dist/format_file.d.ts.map +1 -0
- package/dist/format_file.js +42 -0
- package/dist/gen.d.ts +142 -0
- package/dist/gen.d.ts.map +1 -0
- package/dist/gen.js +199 -0
- package/dist/gen.task.d.ts +12 -0
- package/dist/gen.task.d.ts.map +1 -0
- package/dist/gen.task.js +149 -0
- package/dist/gen_helpers.d.ts +11 -0
- package/dist/gen_helpers.d.ts.map +1 -0
- package/dist/gen_helpers.js +76 -0
- package/dist/github.d.ts +19 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +33 -0
- package/dist/gro.config.default.d.ts +13 -0
- package/dist/gro.config.default.d.ts.map +1 -0
- package/dist/gro.config.default.js +33 -0
- package/dist/gro.d.ts +3 -0
- package/dist/gro.d.ts.map +1 -0
- package/dist/gro.js +21 -0
- package/dist/gro_config.d.ts +115 -0
- package/dist/gro_config.d.ts.map +1 -0
- package/dist/gro_config.js +114 -0
- package/dist/gro_helpers.d.ts +49 -0
- package/dist/gro_helpers.d.ts.map +1 -0
- package/dist/gro_helpers.js +97 -0
- package/dist/gro_plugin_gen.d.ts +12 -0
- package/dist/gro_plugin_gen.d.ts.map +1 -0
- package/dist/gro_plugin_gen.js +101 -0
- package/dist/gro_plugin_server.d.ts +80 -0
- package/dist/gro_plugin_server.d.ts.map +1 -0
- package/dist/gro_plugin_server.js +167 -0
- package/dist/gro_plugin_sveltekit_app.d.ts +9 -0
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -0
- package/dist/gro_plugin_sveltekit_app.js +42 -0
- package/dist/gro_plugin_sveltekit_library.d.ts +16 -0
- package/dist/gro_plugin_sveltekit_library.d.ts.map +1 -0
- package/dist/gro_plugin_sveltekit_library.js +34 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/input_path.d.ts +64 -0
- package/dist/input_path.d.ts.map +1 -0
- package/dist/input_path.js +199 -0
- package/dist/invoke.d.ts +2 -0
- package/dist/invoke.d.ts.map +1 -0
- package/dist/invoke.js +28 -0
- package/dist/invoke_task.d.ts +30 -0
- package/dist/invoke_task.d.ts.map +1 -0
- package/dist/invoke_task.js +104 -0
- package/dist/lint.task.d.ts +11 -0
- package/dist/lint.task.d.ts.map +1 -0
- package/dist/lint.task.js +32 -0
- package/dist/loader.d.ts +6 -0
- package/dist/loader.d.ts.map +1 -0
- package/dist/loader.js +192 -0
- package/dist/module.d.ts +4 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +6 -0
- package/dist/modules.d.ts +36 -0
- package/dist/modules.d.ts.map +1 -0
- package/dist/modules.js +71 -0
- package/dist/package_json.d.ts +32 -0
- package/dist/package_json.d.ts.map +1 -0
- package/dist/package_json.js +178 -0
- package/dist/parse_exports.d.ts +20 -0
- package/dist/parse_exports.d.ts.map +1 -0
- package/dist/parse_exports.js +65 -0
- package/dist/parse_exports_context.d.ts +21 -0
- package/dist/parse_exports_context.d.ts.map +1 -0
- package/dist/parse_exports_context.js +332 -0
- package/dist/parse_imports.d.ts +5 -0
- package/dist/parse_imports.d.ts.map +1 -0
- package/dist/parse_imports.js +140 -0
- package/dist/paths.d.ts +41 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +69 -0
- package/dist/plugin.d.ts +36 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +78 -0
- package/dist/publish.task.d.ts +26 -0
- package/dist/publish.task.d.ts.map +1 -0
- package/dist/publish.task.js +176 -0
- package/dist/register.d.ts +2 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +2 -0
- package/dist/reinstall.task.d.ts +8 -0
- package/dist/reinstall.task.d.ts.map +1 -0
- package/dist/reinstall.task.js +35 -0
- package/dist/release.task.d.ts +8 -0
- package/dist/release.task.d.ts.map +1 -0
- package/dist/release.task.js +20 -0
- package/dist/resolve.task.d.ts +11 -0
- package/dist/resolve.task.d.ts.map +1 -0
- package/dist/resolve.task.js +38 -0
- package/dist/resolve_specifier.d.ts +22 -0
- package/dist/resolve_specifier.d.ts.map +1 -0
- package/dist/resolve_specifier.js +57 -0
- package/dist/run.task.d.ts +16 -0
- package/dist/run.task.d.ts.map +1 -0
- package/dist/run.task.js +52 -0
- package/dist/run_gen.d.ts +10 -0
- package/dist/run_gen.d.ts.map +1 -0
- package/dist/run_gen.js +73 -0
- package/dist/run_task.d.ts +17 -0
- package/dist/run_task.d.ts.map +1 -0
- package/dist/run_task.js +45 -0
- package/dist/source_json.d.ts +7 -0
- package/dist/source_json.d.ts.map +1 -0
- package/dist/source_json.js +145 -0
- package/dist/svelte_config.d.ts +57 -0
- package/dist/svelte_config.d.ts.map +1 -0
- package/dist/svelte_config.js +81 -0
- package/dist/sveltekit_helpers.d.ts +75 -0
- package/dist/sveltekit_helpers.d.ts.map +1 -0
- package/dist/sveltekit_helpers.js +94 -0
- package/dist/sveltekit_shim_app.d.ts +11 -0
- package/dist/sveltekit_shim_app.d.ts.map +1 -0
- package/dist/sveltekit_shim_app.js +31 -0
- package/dist/sveltekit_shim_app_environment.d.ts +13 -0
- package/dist/sveltekit_shim_app_environment.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_environment.js +14 -0
- package/dist/sveltekit_shim_app_forms.d.ts +5 -0
- package/dist/sveltekit_shim_app_forms.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_forms.js +6 -0
- package/dist/sveltekit_shim_app_navigation.d.ts +10 -0
- package/dist/sveltekit_shim_app_navigation.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_navigation.js +11 -0
- package/dist/sveltekit_shim_app_paths.d.ts +17 -0
- package/dist/sveltekit_shim_app_paths.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_paths.js +10 -0
- package/dist/sveltekit_shim_app_state.d.ts +5 -0
- package/dist/sveltekit_shim_app_state.d.ts.map +1 -0
- package/dist/sveltekit_shim_app_state.js +26 -0
- package/dist/sveltekit_shim_env.d.ts +5 -0
- package/dist/sveltekit_shim_env.d.ts.map +1 -0
- package/dist/sveltekit_shim_env.js +23 -0
- package/dist/sync.task.d.ts +16 -0
- package/dist/sync.task.d.ts.map +1 -0
- package/dist/sync.task.js +39 -0
- package/dist/task.d.ts +98 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +109 -0
- package/dist/task_logging.d.ts +6 -0
- package/dist/task_logging.d.ts.map +1 -0
- package/dist/task_logging.js +201 -0
- package/dist/test.task.d.ts +13 -0
- package/dist/test.task.d.ts.map +1 -0
- package/dist/test.task.js +53 -0
- package/dist/typecheck.task.d.ts +13 -0
- package/dist/typecheck.task.d.ts.map +1 -0
- package/dist/typecheck.task.js +68 -0
- package/dist/upgrade.task.d.ts +20 -0
- package/dist/upgrade.task.d.ts.map +1 -0
- package/dist/upgrade.task.js +111 -0
- package/dist/watch_dir.d.ts +36 -0
- package/dist/watch_dir.d.ts.map +1 -0
- package/dist/watch_dir.js +69 -0
- package/package.json +149 -0
- package/src/lib/args.ts +115 -0
- package/src/lib/build.task.ts +151 -0
- package/src/lib/build_cache.ts +378 -0
- package/src/lib/changelog.ts +69 -0
- package/src/lib/changeset.task.ts +228 -0
- package/src/lib/changeset_helpers.ts +14 -0
- package/src/lib/check.task.ts +132 -0
- package/src/lib/child_process_logging.ts +38 -0
- package/src/lib/clean.task.ts +48 -0
- package/src/lib/clean_fs.ts +54 -0
- package/src/lib/cli.ts +98 -0
- package/src/lib/commit.task.ts +34 -0
- package/src/lib/constants.ts +56 -0
- package/src/lib/deploy.task.ts +287 -0
- package/src/lib/dev.task.ts +52 -0
- package/src/lib/disknode.ts +26 -0
- package/src/lib/env.ts +78 -0
- package/src/lib/esbuild_helpers.ts +49 -0
- package/src/lib/esbuild_plugin_external_worker.ts +94 -0
- package/src/lib/esbuild_plugin_svelte.ts +134 -0
- package/src/lib/esbuild_plugin_sveltekit_local_imports.ts +38 -0
- package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +27 -0
- package/src/lib/esbuild_plugin_sveltekit_shim_app.ts +42 -0
- package/src/lib/esbuild_plugin_sveltekit_shim_env.ts +47 -0
- package/src/lib/filer.ts +458 -0
- package/src/lib/format.task.ts +44 -0
- package/src/lib/format_directory.ts +65 -0
- package/src/lib/format_file.ts +49 -0
- package/src/lib/gen.task.ts +206 -0
- package/src/lib/gen.ts +406 -0
- package/src/lib/gen_helpers.ts +131 -0
- package/src/lib/github.ts +46 -0
- package/src/lib/gro.config.default.ts +42 -0
- package/src/lib/gro.ts +29 -0
- package/src/lib/gro_config.ts +254 -0
- package/src/lib/gro_helpers.ts +108 -0
- package/src/lib/gro_plugin_gen.ts +149 -0
- package/src/lib/gro_plugin_server.ts +288 -0
- package/src/lib/gro_plugin_sveltekit_app.ts +58 -0
- package/src/lib/gro_plugin_sveltekit_library.ts +63 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/input_path.ts +254 -0
- package/src/lib/invoke.ts +34 -0
- package/src/lib/invoke_task.ts +139 -0
- package/src/lib/lint.task.ts +39 -0
- package/src/lib/loader.ts +229 -0
- package/src/lib/module.ts +13 -0
- package/src/lib/modules.ts +117 -0
- package/src/lib/package_json.ts +255 -0
- package/src/lib/parse_exports.ts +100 -0
- package/src/lib/parse_exports_context.ts +395 -0
- package/src/lib/parse_imports.ts +180 -0
- package/src/lib/paths.ts +111 -0
- package/src/lib/plugin.ts +106 -0
- package/src/lib/publish.task.ts +228 -0
- package/src/lib/register.ts +3 -0
- package/src/lib/reinstall.task.ts +45 -0
- package/src/lib/release.task.ts +26 -0
- package/src/lib/resolve.task.ts +43 -0
- package/src/lib/resolve_specifier.ts +81 -0
- package/src/lib/run.task.ts +65 -0
- package/src/lib/run_gen.ts +110 -0
- package/src/lib/run_task.ts +82 -0
- package/src/lib/source_json.ts +183 -0
- package/src/lib/svelte_config.ts +140 -0
- package/src/lib/sveltekit_helpers.ts +193 -0
- package/src/lib/sveltekit_shim_app.ts +41 -0
- package/src/lib/sveltekit_shim_app_environment.ts +16 -0
- package/src/lib/sveltekit_shim_app_forms.ts +13 -0
- package/src/lib/sveltekit_shim_app_navigation.ts +23 -0
- package/src/lib/sveltekit_shim_app_paths.ts +26 -0
- package/src/lib/sveltekit_shim_app_state.ts +35 -0
- package/src/lib/sveltekit_shim_env.ts +45 -0
- package/src/lib/sync.task.ts +47 -0
- package/src/lib/task.ts +245 -0
- package/src/lib/task_logging.ts +255 -0
- package/src/lib/test.task.ts +63 -0
- package/src/lib/typecheck.task.ts +81 -0
- package/src/lib/upgrade.task.ts +148 -0
- package/src/lib/watch_dir.ts +115 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Ryan Atkinson <mail@ryanatkn.com> <https://ryanatkn.com/>
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# gro <img src="static/logo.svg" alt="a pixelated green oak acorn with a glint of sun" width="32" height="32">
|
|
2
|
+
|
|
3
|
+
[<img src="static/logo.svg" alt="a pixelated green oak acorn with a glint of sun" align="right" width="192" height="192">](https://gro.fuzdev.com/)
|
|
4
|
+
|
|
5
|
+
> task runner and toolkit extending SvelteKit 🌰 generate, run, optimize
|
|
6
|
+
|
|
7
|
+
[`npm i -D @fuzdev/gro`](https://www.npmjs.com/package/@fuzdev/gro)
|
|
8
|
+
|
|
9
|
+
> ⚠️ I still use Gro heavily but I'm transitioning to Rust-based tooling
|
|
10
|
+
> with [Fuz](https://github.com/fuzdev) using [Deno](https://github.com/denoland) as a sidecar.
|
|
11
|
+
> I consider Gro deprecated but there should be a migration path.
|
|
12
|
+
> Please open issues if you need help.
|
|
13
|
+
|
|
14
|
+
> ⚠️[Windows won't be supported](https://github.com/fuzdev/gro/issues/319), I chose Bash instead.
|
|
15
|
+
|
|
16
|
+
Docs at [gro.fuzdev.com/docs](https://gro.fuzdev.com/docs) and [src/docs](./src/docs).
|
|
17
|
+
|
|
18
|
+
Need help or want to share thoughts? See the
|
|
19
|
+
[issues](https://github.com/fuzdev/gro/issues) and
|
|
20
|
+
[discussions](https://github.com/fuzdev/gro/discussions).
|
|
21
|
+
|
|
22
|
+
## about
|
|
23
|
+
|
|
24
|
+
Gro is a task runner and toolkit
|
|
25
|
+
extending [SvelteKit](https://github.com/sveltejs/kit),
|
|
26
|
+
[Vite](https://github.com/vitejs/vite),
|
|
27
|
+
and [esbuild](https://github.com/evanw/esbuild)
|
|
28
|
+
for making web frontends, servers, and libraries with TypeScript.
|
|
29
|
+
It's a dev tool, not for production use.
|
|
30
|
+
It includes:
|
|
31
|
+
|
|
32
|
+
- [task runner](/src/docs/task.md) that uses the filesystem convention `*.task.ts`
|
|
33
|
+
- lots of [common builtin tasks](/src/docs/tasks.md) that users can easily override and compose
|
|
34
|
+
- tools and patterns for
|
|
35
|
+
[developing](/src/docs/dev.md),
|
|
36
|
+
[building](/src/docs/build.md),
|
|
37
|
+
[testing](/src/docs/test.md),
|
|
38
|
+
[deploying](/src/docs/deploy.md),
|
|
39
|
+
and [publishing](/src/docs/publish.md)
|
|
40
|
+
[SvelteKit](https://github.com/sveltejs/kit) apps, library packages, and Node servers
|
|
41
|
+
- integrated [TypeScript](https://github.com/microsoft/typescript),
|
|
42
|
+
[Svelte](https://github.com/sveltejs/svelte),
|
|
43
|
+
and [SvelteKit](https://github.com/sveltejs/kit)
|
|
44
|
+
- defers to SvelteKit and Vite for the frontend and
|
|
45
|
+
[`@sveltejs/package`](https://kit.svelte.dev/docs/packaging) for the library
|
|
46
|
+
- exposes all of its internals in `$lib`
|
|
47
|
+
- uses [Changesets](https://github.com/changesets/changesets) for versioning and changelogs
|
|
48
|
+
- provides a [Node loader](/src/lib/loader.ts) with a [register hook](/src/lib/register.ts)
|
|
49
|
+
- uses Node's type stripping and supports importing JSON, SvelteKit shims,
|
|
50
|
+
and SSR'd Svelte files in tests/tasks/scripts
|
|
51
|
+
- supports [SvelteKit module imports](https://kit.svelte.dev/docs/modules) for
|
|
52
|
+
`$lib`, `$env`, and `$app` in tasks, tests, Node servers,
|
|
53
|
+
and other code outside of the SvelteKit frontend,
|
|
54
|
+
so you can use SvelteKit patterns everywhere
|
|
55
|
+
(these are best-effort shims, not perfect)
|
|
56
|
+
- supports running TypeScript files directly without a task via `gro run a.ts`
|
|
57
|
+
or `node --import @fuzdev/gro/register.js a.ts`
|
|
58
|
+
- [configurable plugins](/src/docs/plugin.md) to support SvelteKit,
|
|
59
|
+
[auto-restarting Node servers](/src/lib/gro_plugin_server.ts),
|
|
60
|
+
and other external build processes
|
|
61
|
+
- see the [Gro config docs](/src/docs/config.md) and
|
|
62
|
+
[the default config](https://github.com/fuzdev/gro/blob/main/src/lib/gro.config.default.ts)
|
|
63
|
+
- see [`fuz_template`](https://github.com/fuz-dev/fuz_template)
|
|
64
|
+
for a simple starter project example, and
|
|
65
|
+
[`@feltjs/felt`](https://github.com/feltjs/felt) for a more complex example with custom tasks
|
|
66
|
+
- [testing](/src/docs/test.md) with [`vitest`](https://github.com/vitest-dev/vitest)
|
|
67
|
+
- codegen by convention with [`gen`](/src/docs/gen.md)
|
|
68
|
+
- linting with [ESLint](https://github.com/eslint/eslint)
|
|
69
|
+
(I also maintain [`@feltjs/eslint-config`](https://github.com/feltjs/eslint-config))
|
|
70
|
+
- formatting with [Prettier](https://github.com/prettier/prettier)
|
|
71
|
+
|
|
72
|
+
## docs
|
|
73
|
+
|
|
74
|
+
- early API docs at [/docs/api](https://gro.fuzdev.com/docs/api)
|
|
75
|
+
- developing web frontends, servers, and libraries
|
|
76
|
+
- [config](/src/docs/config.md)
|
|
77
|
+
- [dev](/src/docs/dev.md)
|
|
78
|
+
- [build](/src/docs/build.md) for production
|
|
79
|
+
- [deploy](/src/docs/deploy.md) to a branch, like for GitHub pages
|
|
80
|
+
- [publish](/src/docs/publish.md) to npm
|
|
81
|
+
- [`Task`](/src/docs/task.md) runner
|
|
82
|
+
- builtin [tasks](/src/docs/tasks.md) list
|
|
83
|
+
- [testing](/src/docs/test.md) with [`vitest`](https://github.com/vitest-dev/vitest)
|
|
84
|
+
- [`gen`](/src/docs/gen.md) code generation
|
|
85
|
+
- [`public` package](/src/docs/package_json.md#public-packages) features (nonstandard)
|
|
86
|
+
- full [docs index](/src/docs#readme)
|
|
87
|
+
|
|
88
|
+
## install
|
|
89
|
+
|
|
90
|
+
> depends on node >=20.12
|
|
91
|
+
|
|
92
|
+
Typical usage installs [@fuzdev/gro](https://www.npmjs.com/package/@fuzdev/gro)
|
|
93
|
+
as a dev dependency:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
npm i -D @fuzdev/gro
|
|
97
|
+
npx @fuzdev/gro # note the package is namespaced, don't install `gro`
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
It's handy to install globally too:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
npm i -g @fuzdev/gro
|
|
104
|
+
gro
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## usage
|
|
108
|
+
|
|
109
|
+
Gro has a task runner that discovers and runs TypeScript modules with the `.task.` subextension.
|
|
110
|
+
Running `gro` with no args prints the tasks
|
|
111
|
+
it finds in the current directory along with its builtin tasks:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
gro # prints available tasks - defers to any local gro installation
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
Run a task: gro [name]
|
|
119
|
+
View help: gro [name] --help
|
|
120
|
+
|
|
121
|
+
19 tasks in gro:
|
|
122
|
+
|
|
123
|
+
build build the project
|
|
124
|
+
changeset call changeset with gro patterns
|
|
125
|
+
check check that everything is ready to commit
|
|
126
|
+
clean remove temporary dev and build files, and optionally prune git branches
|
|
127
|
+
commit commit and push to a new branch
|
|
128
|
+
deploy deploy to a branch
|
|
129
|
+
dev start SvelteKit and other dev plugins
|
|
130
|
+
format format source files
|
|
131
|
+
gen run code generation scripts
|
|
132
|
+
lint run eslint
|
|
133
|
+
publish bump version, publish to the configured registry, and git push
|
|
134
|
+
reinstall refreshes package-lock.json with the latest and cleanest deps
|
|
135
|
+
release publish and deploy
|
|
136
|
+
resolve diagnostic that logs resolved filesystem info for the given input paths
|
|
137
|
+
run execute a file with the loader, like `node` but works for TypeScript
|
|
138
|
+
sync run `gro gen`, update `package.json`, and optionally install packages to sync up
|
|
139
|
+
test run tests with vitest
|
|
140
|
+
typecheck run svelte-check or tsc on the project without emitting any files
|
|
141
|
+
upgrade upgrade deps
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
To run tasks, Gro matches your CLI input against its filesystem conventions.
|
|
145
|
+
It tries to do the right thing, where right is helpful but not surprising,
|
|
146
|
+
with some magic but not too much:
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
gro # displays all available tasks matching `src/lib/**/*.task.ts` and Gro's builtins
|
|
150
|
+
gro a # tries to run `src/lib/a.task.ts`, then `./a.task.ts`, then Gro's builtin if one exists
|
|
151
|
+
gro a --help # displays docs for the "a" task and its args, works for every task
|
|
152
|
+
gro some/dir # lists all tasks inside `src/lib/some/dir`
|
|
153
|
+
gro some/file # runs `src/lib/some/file.task.ts`
|
|
154
|
+
gro some/file.task.ts # same as above
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
Gro can also run non-task TypeScript files directly
|
|
158
|
+
with [the `gro run` task](/src/lib/run.task.ts) or [register hook](/src/lib/register.ts):
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
gro run foo.ts
|
|
162
|
+
node --import @fuzdev/gro/register.js foo.ts
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Or programmatically:
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
// myfile.js
|
|
169
|
+
import {register} from 'node:module';
|
|
170
|
+
register('@fuzdev/gro/loader.js', import.meta.url);
|
|
171
|
+
await import('./foo.ts');
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Gro has a number of builtin tasks that you can run with the CLI.
|
|
175
|
+
To learn more [see the task docs](/src/docs/task.md)
|
|
176
|
+
and [the generated task index](/src/docs/tasks.md).
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
gro dev # start developing in watch mode
|
|
180
|
+
gro dev -- vite --port 3003 # forward args by separating sections with --
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
gro build # build everything for production
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
[Testing](/src/docs/test.md) with [`vitest`](https://github.com/vitest-dev/vitest),
|
|
188
|
+
including shims for [SvelteKit modules](https://kit.svelte.dev/docs/modules):
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
gro test # run all tests for `*.test.ts` files with `vitest`
|
|
192
|
+
gro test filepattern1 some.test another.test
|
|
193
|
+
gro test optional_pattern -t "optional search string for test name"
|
|
194
|
+
gro test -- vitest --forwarded_args 'to vitest'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Check all the things:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
gro check # does all of the following:
|
|
201
|
+
gro typecheck # svelte-check with tsc fallback
|
|
202
|
+
gro test # run tests
|
|
203
|
+
gro gen --check # ensure generated files are current
|
|
204
|
+
gro format --check # ensure everything is formatted
|
|
205
|
+
gro lint # eslint
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
For a usage example see [the `check.yml` CI config](.github/workflows/check.yml).
|
|
209
|
+
|
|
210
|
+
Formatting with [`prettier`](https://github.com/prettier/prettier):
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
gro format # format all of the source files using Prettier
|
|
214
|
+
gro format --check # check that all source files are formatted
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Codegen with [`gen`](/src/docs/gen.md):
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
gro gen # run codegen for all `*.gen.*` files
|
|
221
|
+
gro gen --check # error if any generated files are new or different
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
To deploy: (also see [`src/docs/deploy.md`](/src/docs/deploy.md))
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
gro deploy # build and push to the `deploy` branch
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
To publish: (also see [`src/docs/publish.md`](/src/docs/publish.md))
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
gro publish # flush changeset to changelog, bump version, publish to npm, and git push
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
More:
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
gro clean # delete all build artifacts from the filesystem
|
|
240
|
+
gro clean --sveltekit --nodemodules --git # also deletes dirs and prunes git branches
|
|
241
|
+
gro upgrade excluded-dep-1 excluded-dep-2 # npm updates to the latest everything
|
|
242
|
+
gro --version # print the Gro version
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
For more see [the tasks index](/src/docs/tasks.md),
|
|
246
|
+
[the task feature docs](/src/docs/task.md), and [the docs index](/src/docs/README.md).
|
|
247
|
+
|
|
248
|
+
## develop
|
|
249
|
+
|
|
250
|
+
```bash
|
|
251
|
+
npm i
|
|
252
|
+
npm run bootstrap # build and link `gro` without itself - needed only once
|
|
253
|
+
gro build # same as `npm run bootstrap` when the `gro` CLI is available
|
|
254
|
+
gro test # make sure everything looks good - same as `npm test`
|
|
255
|
+
gro test some.test another.test
|
|
256
|
+
|
|
257
|
+
# use your development version of `gro` locally in another project:
|
|
258
|
+
gro build # updates the `gro` CLI, same as `npm run bootstrap`
|
|
259
|
+
cd ../otherproject
|
|
260
|
+
npm link ../gro # from `otherproject/`
|
|
261
|
+
gro build # from `../gro` on changes
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
## credits 🐢<sub>🐢</sub><sub><sub>🐢</sub></sub>
|
|
265
|
+
|
|
266
|
+
Gro builds on
|
|
267
|
+
[TypeScript](https://github.com/microsoft/TypeScript) ∙
|
|
268
|
+
[Svelte](https://github.com/sveltejs/svelte) ∙
|
|
269
|
+
[SvelteKit](https://github.com/sveltejs/kit) ∙
|
|
270
|
+
[Vite](https://github.com/vitejs/vite) ∙
|
|
271
|
+
[esbuild](https://github.com/evanw/esbuild) ∙
|
|
272
|
+
[Vitest](https://github.com/vitest-dev/vitest) ∙
|
|
273
|
+
[chokidar](https://github.com/paulmillr/chokidar) ∙
|
|
274
|
+
[zod](https://github.com/colinhacks/zod) ∙
|
|
275
|
+
[@fuzdev/fuz_util](https://github.com/fuzdev/fuz_util) ∙
|
|
276
|
+
[ESLint](https://github.com/eslint/eslint) ∙
|
|
277
|
+
[Prettier](https://github.com/prettier/prettier) ∙
|
|
278
|
+
[svelte-check](https://github.com/sveltejs/language-tools/tree/master/packages/svelte-check) &
|
|
279
|
+
[more](package.json)
|
|
280
|
+
|
|
281
|
+
## license [🐦](https://wikipedia.org/wiki/Free_and_open-source_software)
|
|
282
|
+
|
|
283
|
+
[MIT](LICENSE)
|
package/dist/args.d.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Args } from '@fuzdev/fuz_util/args.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parses `task_name` and `args` from `process.argv`,
|
|
4
|
+
* ignoring anything after any `--`.
|
|
5
|
+
*/
|
|
6
|
+
export declare const to_task_args: (argv?: string[]) => {
|
|
7
|
+
task_name: string;
|
|
8
|
+
args: Args;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Gets the array of raw string args starting with the first `--`, if any.
|
|
12
|
+
*/
|
|
13
|
+
export declare const to_raw_rest_args: (argv?: string[]) => Array<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Parses `process.argv` for the specified `command`, so given
|
|
16
|
+
* `gro taskname arg1 --arg2 -- eslint eslintarg1 --eslintarg2 -- tsc --tscarg1 --tscarg2`
|
|
17
|
+
* the `command` `'eslint'` returns `eslintarg1 --eslintarg2`
|
|
18
|
+
* and `'tsc'` returns `--tscarg1` and `--tscarg2`.
|
|
19
|
+
*/
|
|
20
|
+
export declare const to_forwarded_args: (command: string, raw_rest_args?: Array<string>, cache?: Record<string, Args | undefined>) => Args;
|
|
21
|
+
export declare const to_forwarded_args_by_command: (raw_rest_args?: string[]) => Record<string, Args | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Gets all args after the first `--` without assuming a command name.
|
|
24
|
+
* This is useful for tasks that want to forward args directly to a tool
|
|
25
|
+
* without requiring users to specify the tool name explicitly.
|
|
26
|
+
* Optionally strips a specific command name if present for backward compatibility.
|
|
27
|
+
* @example
|
|
28
|
+
* ```ts
|
|
29
|
+
* // `gro test -- --watch` → {watch: true}
|
|
30
|
+
* // `gro test -- foo.test.ts` → {_: ['foo.test.ts']}
|
|
31
|
+
* // `gro test -- vitest --watch` with command_to_strip='vitest' → {watch: true}
|
|
32
|
+
* to_implicit_forwarded_args('vitest')
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare const to_implicit_forwarded_args: (command_to_strip?: string, raw_rest_args?: string[]) => Args;
|
|
36
|
+
export declare const print_command_args: (serialized_args: Array<string>) => string;
|
|
37
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/args.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,IAAI,EAAC,MAAM,0BAA0B,CAAC;AAE/D;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,eAAmB,KAAG;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAMhF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,eAAmB,KAAG,KAAK,CAAC,MAAM,CAGlE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC7B,SAAS,MAAM,EACf,gBAAgB,KAAK,CAAC,MAAM,CAAC,EAC7B,wCAAmD,KACjD,IAA4B,CAAC;AAEhC,eAAO,MAAM,4BAA4B,GACxC,wBAAkC,KAChC,MAAM,CAAC,MAAM,EAAE,IAAI,GAAG,SAAS,CAuCjC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,0BAA0B,GACtC,mBAAmB,MAAM,EACzB,wBAAkC,KAChC,IAaF,CAAC;AAEF,eAAO,MAAM,kBAAkB,GAAI,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAAG,MAK1C,CAAC"}
|
package/dist/args.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { styleText as st } from 'node:util';
|
|
2
|
+
import { argv_parse } from '@fuzdev/fuz_util/args.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parses `task_name` and `args` from `process.argv`,
|
|
5
|
+
* ignoring anything after any `--`.
|
|
6
|
+
*/
|
|
7
|
+
export const to_task_args = (argv = process.argv) => {
|
|
8
|
+
const forwarded_index = argv.indexOf('--');
|
|
9
|
+
const args = argv_parse(forwarded_index === -1 ? argv.slice(2) : argv.slice(2, forwarded_index));
|
|
10
|
+
const task_name = args._.shift() ?? '';
|
|
11
|
+
if (!args._.length)
|
|
12
|
+
delete args._; // enable schema defaults
|
|
13
|
+
return { task_name, args };
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Gets the array of raw string args starting with the first `--`, if any.
|
|
17
|
+
*/
|
|
18
|
+
export const to_raw_rest_args = (argv = process.argv) => {
|
|
19
|
+
const forwarded_index = argv.indexOf('--');
|
|
20
|
+
return forwarded_index === -1 ? [] : argv.slice(forwarded_index);
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Parses `process.argv` for the specified `command`, so given
|
|
24
|
+
* `gro taskname arg1 --arg2 -- eslint eslintarg1 --eslintarg2 -- tsc --tscarg1 --tscarg2`
|
|
25
|
+
* the `command` `'eslint'` returns `eslintarg1 --eslintarg2`
|
|
26
|
+
* and `'tsc'` returns `--tscarg1` and `--tscarg2`.
|
|
27
|
+
*/
|
|
28
|
+
export const to_forwarded_args = (command, raw_rest_args, cache = to_forwarded_args_by_command(raw_rest_args)) => cache[command] ?? {};
|
|
29
|
+
export const to_forwarded_args_by_command = (raw_rest_args = to_raw_rest_args()) => {
|
|
30
|
+
// Parse each segment of `argv` separated by `--`.
|
|
31
|
+
const argvs = [];
|
|
32
|
+
let arr;
|
|
33
|
+
for (const arg of raw_rest_args) {
|
|
34
|
+
if (arg === '--') {
|
|
35
|
+
if (arr?.length)
|
|
36
|
+
argvs.push(arr);
|
|
37
|
+
arr = [];
|
|
38
|
+
}
|
|
39
|
+
else if (!arr) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
else if (arg) {
|
|
43
|
+
arr.push(arg);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (arr?.length)
|
|
47
|
+
argvs.push(arr);
|
|
48
|
+
// Add each segment of parsed `argv` keyed by the first rest arg,
|
|
49
|
+
// which is assumed to be the CLI command that gets forwarded the args.
|
|
50
|
+
const forwarded_args_by_command = {};
|
|
51
|
+
for (const argv of argvs) {
|
|
52
|
+
const args = argv_parse(argv);
|
|
53
|
+
let command = args._.shift();
|
|
54
|
+
if (!command) {
|
|
55
|
+
// Skip sections without a command name - these are handled by `to_implicit_forwarded_args`.
|
|
56
|
+
// This allows `gro run script.ts -- --help` to pass `--help` to the script.
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
// Gro commands get combined with their task name.
|
|
60
|
+
if (command === 'gro') {
|
|
61
|
+
if (!args._.length) {
|
|
62
|
+
throw Error(`Malformed args following a \`--\`. Expected gro taskname: \`${argv.join(' ')}\``);
|
|
63
|
+
}
|
|
64
|
+
command += ' ' + args._.shift();
|
|
65
|
+
}
|
|
66
|
+
if (!args._.length)
|
|
67
|
+
delete args._;
|
|
68
|
+
forwarded_args_by_command[command] = args;
|
|
69
|
+
}
|
|
70
|
+
return forwarded_args_by_command;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Gets all args after the first `--` without assuming a command name.
|
|
74
|
+
* This is useful for tasks that want to forward args directly to a tool
|
|
75
|
+
* without requiring users to specify the tool name explicitly.
|
|
76
|
+
* Optionally strips a specific command name if present for backward compatibility.
|
|
77
|
+
* @example
|
|
78
|
+
* ```ts
|
|
79
|
+
* // `gro test -- --watch` → {watch: true}
|
|
80
|
+
* // `gro test -- foo.test.ts` → {_: ['foo.test.ts']}
|
|
81
|
+
* // `gro test -- vitest --watch` with command_to_strip='vitest' → {watch: true}
|
|
82
|
+
* to_implicit_forwarded_args('vitest')
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
export const to_implicit_forwarded_args = (command_to_strip, raw_rest_args = to_raw_rest_args()) => {
|
|
86
|
+
const start = raw_rest_args.indexOf('--');
|
|
87
|
+
if (start === -1)
|
|
88
|
+
return {};
|
|
89
|
+
let argv = raw_rest_args.slice(start + 1);
|
|
90
|
+
if (command_to_strip && argv[0] === command_to_strip) {
|
|
91
|
+
argv = argv.slice(1);
|
|
92
|
+
}
|
|
93
|
+
const args = argv_parse(argv);
|
|
94
|
+
if (!args._.length)
|
|
95
|
+
delete args._;
|
|
96
|
+
return args;
|
|
97
|
+
};
|
|
98
|
+
export const print_command_args = (serialized_args) => st('gray', '[') +
|
|
99
|
+
st('magenta', 'running command') +
|
|
100
|
+
st('gray', ']') +
|
|
101
|
+
' ' +
|
|
102
|
+
serialized_args.join(' ');
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type Task } from './task.ts';
|
|
3
|
+
/** @nodocs */
|
|
4
|
+
export declare const Args: z.ZodObject<{
|
|
5
|
+
sync: z.ZodDefault<z.ZodBoolean>;
|
|
6
|
+
'no-sync': z.ZodDefault<z.ZodBoolean>;
|
|
7
|
+
gen: z.ZodDefault<z.ZodBoolean>;
|
|
8
|
+
'no-gen': z.ZodDefault<z.ZodBoolean>;
|
|
9
|
+
install: z.ZodDefault<z.ZodBoolean>;
|
|
10
|
+
'no-install': z.ZodDefault<z.ZodBoolean>;
|
|
11
|
+
force_build: z.ZodDefault<z.ZodBoolean>;
|
|
12
|
+
}, z.core.$strict>;
|
|
13
|
+
export type Args = z.infer<typeof Args>;
|
|
14
|
+
/**
|
|
15
|
+
* Length of git commit hash when displayed in logs (standard git convention).
|
|
16
|
+
*/
|
|
17
|
+
export declare const GIT_SHORT_HASH_LENGTH = 7;
|
|
18
|
+
/** @nodocs */
|
|
19
|
+
export declare const task: Task<Args>;
|
|
20
|
+
//# sourceMappingURL=build.task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.task.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/build.task.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAOtB,OAAO,EAAY,KAAK,IAAI,EAAC,MAAM,WAAW,CAAC;AAW/C,cAAc;AACd,eAAO,MAAM,IAAI;;;;;;;;kBAcf,CAAC;AACH,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;AAExC;;GAEG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AASvC,cAAc;AACd,eAAO,MAAM,IAAI,EAAE,IAAI,CAAC,IAAI,CAqG3B,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { styleText as st } from 'node:util';
|
|
3
|
+
import { git_check_clean_workspace, git_current_commit_hash } from '@fuzdev/fuz_util/git.js';
|
|
4
|
+
import { rm } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { fs_exists } from '@fuzdev/fuz_util/fs.js';
|
|
7
|
+
import { TaskError } from "./task.js";
|
|
8
|
+
import { Plugins } from "./plugin.js";
|
|
9
|
+
import { clean_fs } from "./clean_fs.js";
|
|
10
|
+
import { is_build_cache_valid, create_build_cache_metadata, save_build_cache_metadata, discover_build_output_dirs, } from "./build_cache.js";
|
|
11
|
+
import { paths } from "./paths.js";
|
|
12
|
+
/** @nodocs */
|
|
13
|
+
export const Args = z.strictObject({
|
|
14
|
+
sync: z.boolean().meta({ description: 'dual of no-sync' }).default(true),
|
|
15
|
+
'no-sync': z.boolean().meta({ description: 'opt out of gro sync' }).default(false),
|
|
16
|
+
gen: z.boolean().meta({ description: 'dual of no-gen' }).default(true),
|
|
17
|
+
'no-gen': z.boolean().meta({ description: 'opt out of gro gen' }).default(false),
|
|
18
|
+
install: z.boolean().meta({ description: 'dual of no-install' }).default(true),
|
|
19
|
+
'no-install': z // convenience, same as `gro build -- gro sync --no-install` but the latter takes precedence
|
|
20
|
+
.boolean()
|
|
21
|
+
.meta({ description: 'opt out of installing packages before building' })
|
|
22
|
+
.default(false),
|
|
23
|
+
force_build: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.meta({ description: 'force a fresh build, ignoring the cache' })
|
|
26
|
+
.default(false),
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Length of git commit hash when displayed in logs (standard git convention).
|
|
30
|
+
*/
|
|
31
|
+
export const GIT_SHORT_HASH_LENGTH = 7;
|
|
32
|
+
/**
|
|
33
|
+
* Formats a git commit hash for display in logs.
|
|
34
|
+
* Returns '[none]' if hash is null (e.g., not in a git repo).
|
|
35
|
+
*/
|
|
36
|
+
const format_commit_hash = (hash) => hash?.slice(0, GIT_SHORT_HASH_LENGTH) ?? '[none]';
|
|
37
|
+
/** @nodocs */
|
|
38
|
+
export const task = {
|
|
39
|
+
summary: 'build the project',
|
|
40
|
+
Args,
|
|
41
|
+
run: async (ctx) => {
|
|
42
|
+
const { args, invoke_task, log, config } = ctx;
|
|
43
|
+
const { sync, gen, install, force_build } = args;
|
|
44
|
+
if (sync || install) {
|
|
45
|
+
if (!sync)
|
|
46
|
+
log.warn('sync is false but install is true, so ignoring the sync option');
|
|
47
|
+
await invoke_task('sync', { install, gen: false });
|
|
48
|
+
}
|
|
49
|
+
if (gen) {
|
|
50
|
+
await invoke_task('gen');
|
|
51
|
+
}
|
|
52
|
+
// Batch git calls upfront for performance (spawning processes is expensive)
|
|
53
|
+
const [workspace_status, initial_commit] = await Promise.all([
|
|
54
|
+
git_check_clean_workspace(),
|
|
55
|
+
git_current_commit_hash(),
|
|
56
|
+
]);
|
|
57
|
+
const workspace_dirty = !!workspace_status;
|
|
58
|
+
// Discover build output directories once to avoid redundant filesystem scans
|
|
59
|
+
let build_dirs;
|
|
60
|
+
// Check build cache unless force_build is set or workspace is dirty
|
|
61
|
+
if (!workspace_dirty && !force_build) {
|
|
62
|
+
const cache_valid = await is_build_cache_valid(config, log, initial_commit);
|
|
63
|
+
if (cache_valid) {
|
|
64
|
+
log.info(st('cyan', 'skipping build, cache is valid'), st('dim', '(use --force_build to rebuild)'));
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (workspace_dirty) {
|
|
69
|
+
// IMPORTANT: When workspace is dirty, we delete cache AND all outputs to prevent stale state.
|
|
70
|
+
// Rationale: Uncommitted changes could be reverted, leaving cached outputs from reverted code.
|
|
71
|
+
// This conservative approach prioritizes safety over convenience during development.
|
|
72
|
+
const cache_path = join(paths.build, 'build.json');
|
|
73
|
+
if (await fs_exists(cache_path)) {
|
|
74
|
+
await rm(cache_path, { force: true });
|
|
75
|
+
}
|
|
76
|
+
// Delete all build output directories
|
|
77
|
+
build_dirs = await discover_build_output_dirs();
|
|
78
|
+
await Promise.all(build_dirs.map((dir) => rm(dir, { recursive: true, force: true })));
|
|
79
|
+
log.info(st('yellow', 'workspace has uncommitted changes - skipping build cache'));
|
|
80
|
+
// Skip clean_fs - already manually cleaned cache and all build outputs above
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
log.info(st('yellow', 'forcing fresh build, ignoring cache'));
|
|
84
|
+
}
|
|
85
|
+
// Clean build outputs (skip if workspace was dirty - already cleaned manually above)
|
|
86
|
+
if (!workspace_dirty) {
|
|
87
|
+
await clean_fs({ build_dist: true });
|
|
88
|
+
}
|
|
89
|
+
const plugins = await Plugins.create({ ...ctx, dev: false, watch: false });
|
|
90
|
+
await plugins.setup();
|
|
91
|
+
await plugins.adapt();
|
|
92
|
+
await plugins.teardown();
|
|
93
|
+
// Verify workspace didn't become dirty during build
|
|
94
|
+
const final_workspace_status = await git_check_clean_workspace();
|
|
95
|
+
if (final_workspace_status !== workspace_status) {
|
|
96
|
+
// Workspace state changed during build - this indicates a problem
|
|
97
|
+
throw new TaskError('Build process modified tracked files or created untracked files.\n\n' +
|
|
98
|
+
'Git status after build:\n' +
|
|
99
|
+
final_workspace_status +
|
|
100
|
+
'\n\n' +
|
|
101
|
+
'Builds should only write to output directories (build/, dist/, etc.).\n' +
|
|
102
|
+
'This usually indicates a plugin or build step is incorrectly modifying source files.');
|
|
103
|
+
}
|
|
104
|
+
// Save build cache metadata after successful build (only if workspace is clean)
|
|
105
|
+
if (!workspace_dirty) {
|
|
106
|
+
// Race condition protection: verify git commit didn't change during build
|
|
107
|
+
const current_commit = await git_current_commit_hash();
|
|
108
|
+
if (current_commit !== initial_commit) {
|
|
109
|
+
log.warn(st('yellow', 'git commit changed during build'), st('dim', `(${format_commit_hash(initial_commit)} → ${format_commit_hash(current_commit)})`), '- cache not saved');
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
// Commit is stable - safe to save cache
|
|
113
|
+
const metadata = await create_build_cache_metadata(config, log, initial_commit, build_dirs);
|
|
114
|
+
await save_build_cache_metadata(metadata, log);
|
|
115
|
+
log.debug('Build cache metadata saved');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
};
|