@ryanatkn/gro 0.179.0 → 0.181.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/README.md +1 -1
- package/dist/build.task.d.ts +2 -0
- package/dist/build.task.d.ts.map +1 -1
- package/dist/build.task.js +15 -11
- package/dist/build_cache.d.ts +4 -4
- package/dist/build_cache.d.ts.map +1 -1
- package/dist/build_cache.js +54 -44
- package/dist/changelog.d.ts +2 -2
- package/dist/changelog.d.ts.map +1 -1
- package/dist/changeset.task.js +11 -11
- package/dist/check.task.js +2 -2
- package/dist/child_process_logging.js +1 -1
- package/dist/clean.task.js +2 -2
- package/dist/clean_fs.d.ts +1 -1
- package/dist/clean_fs.d.ts.map +1 -1
- package/dist/clean_fs.js +3 -4
- package/dist/cli.d.ts +7 -7
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +11 -12
- package/dist/commit.task.js +2 -2
- package/dist/deploy.task.d.ts +7 -0
- package/dist/deploy.task.d.ts.map +1 -1
- package/dist/deploy.task.js +30 -17
- package/dist/disknode.d.ts +1 -1
- package/dist/disknode.d.ts.map +1 -1
- package/dist/esbuild_helpers.d.ts +1 -1
- package/dist/esbuild_helpers.d.ts.map +1 -1
- package/dist/esbuild_plugin_external_worker.d.ts +1 -1
- package/dist/esbuild_plugin_external_worker.d.ts.map +1 -1
- package/dist/esbuild_plugin_external_worker.js +1 -1
- package/dist/esbuild_plugin_svelte.js +4 -4
- package/dist/esbuild_plugin_sveltekit_local_imports.js +2 -2
- package/dist/esbuild_plugin_sveltekit_shim_alias.js +1 -1
- package/dist/filer.d.ts +4 -4
- package/dist/filer.d.ts.map +1 -1
- package/dist/filer.js +105 -54
- package/dist/format.task.js +1 -1
- package/dist/format_directory.d.ts +2 -2
- package/dist/format_directory.d.ts.map +1 -1
- package/dist/format_file.js +1 -1
- package/dist/gen.d.ts +5 -5
- package/dist/gen.d.ts.map +1 -1
- package/dist/gen.js +28 -22
- package/dist/gen.task.js +3 -3
- package/dist/gen_helpers.d.ts +3 -3
- package/dist/gen_helpers.d.ts.map +1 -1
- package/dist/github.d.ts +2 -2
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +1 -1
- package/dist/gro.config.default.js +1 -1
- package/dist/gro_config.d.ts +1 -1
- package/dist/gro_config.d.ts.map +1 -1
- package/dist/gro_config.js +4 -4
- package/dist/gro_helpers.d.ts +1 -1
- package/dist/gro_helpers.d.ts.map +1 -1
- package/dist/gro_helpers.js +1 -1
- package/dist/gro_plugin_gen.js +4 -4
- package/dist/gro_plugin_server.d.ts +2 -2
- package/dist/gro_plugin_server.d.ts.map +1 -1
- package/dist/gro_plugin_server.js +7 -7
- package/dist/gro_plugin_sveltekit_app.d.ts.map +1 -1
- package/dist/gro_plugin_sveltekit_app.js +40 -36
- package/dist/gro_plugin_sveltekit_library.js +3 -2
- package/dist/input_path.d.ts +5 -5
- package/dist/input_path.d.ts.map +1 -1
- package/dist/input_path.js +17 -15
- package/dist/invoke.js +2 -2
- package/dist/invoke_task.d.ts +2 -2
- package/dist/invoke_task.d.ts.map +1 -1
- package/dist/invoke_task.js +5 -5
- package/dist/lint.task.js +2 -2
- package/dist/loader.js +2 -2
- package/dist/modules.d.ts +3 -3
- package/dist/modules.d.ts.map +1 -1
- package/dist/modules.js +4 -4
- package/dist/package_json.d.ts +6 -6
- package/dist/package_json.d.ts.map +1 -1
- package/dist/package_json.js +14 -16
- package/dist/parse_exports.d.ts +4 -4
- package/dist/parse_exports.d.ts.map +1 -1
- package/dist/parse_exports_context.d.ts +1 -1
- package/dist/parse_exports_context.d.ts.map +1 -1
- package/dist/parse_imports.d.ts +2 -2
- package/dist/parse_imports.d.ts.map +1 -1
- package/dist/parse_imports.js +1 -1
- package/dist/paths.d.ts +1 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +1 -1
- package/dist/publish.task.js +8 -8
- package/dist/reinstall.task.js +1 -1
- package/dist/release.task.js +1 -1
- package/dist/resolve.task.js +2 -2
- package/dist/resolve_specifier.d.ts +2 -2
- package/dist/resolve_specifier.d.ts.map +1 -1
- package/dist/resolve_specifier.js +5 -4
- package/dist/run.task.js +2 -2
- package/dist/run_gen.d.ts +2 -2
- package/dist/run_gen.d.ts.map +1 -1
- package/dist/run_gen.js +10 -9
- package/dist/run_task.d.ts +2 -2
- package/dist/run_task.d.ts.map +1 -1
- package/dist/run_task.js +4 -4
- package/dist/source_json.d.ts +5 -5
- package/dist/source_json.d.ts.map +1 -1
- package/dist/source_json.js +18 -17
- package/dist/svelte_config.js +1 -1
- package/dist/sveltekit_helpers.d.ts +3 -3
- package/dist/sveltekit_helpers.d.ts.map +1 -1
- package/dist/sveltekit_helpers.js +4 -4
- package/dist/sveltekit_shim_app_forms.js +1 -1
- package/dist/sveltekit_shim_app_navigation.js +1 -1
- package/dist/sveltekit_shim_app_paths.js +1 -1
- package/dist/sveltekit_shim_env.js +1 -1
- package/dist/sync.task.js +1 -1
- package/dist/task.d.ts +5 -5
- package/dist/task.d.ts.map +1 -1
- package/dist/task.js +5 -5
- package/dist/task_logging.d.ts +1 -1
- package/dist/task_logging.d.ts.map +1 -1
- package/dist/task_logging.js +2 -2
- package/dist/test.task.d.ts.map +1 -1
- package/dist/test.task.js +5 -4
- package/dist/typecheck.task.js +4 -4
- package/dist/upgrade.task.js +6 -6
- package/dist/watch_dir.d.ts +1 -1
- package/dist/watch_dir.d.ts.map +1 -1
- package/dist/watch_dir.js +2 -2
- package/package.json +8 -8
- package/src/lib/build.task.ts +16 -11
- package/src/lib/build_cache.ts +81 -65
- package/src/lib/changelog.ts +2 -2
- package/src/lib/changeset.task.ts +12 -12
- package/src/lib/check.task.ts +2 -2
- package/src/lib/child_process_logging.ts +1 -1
- package/src/lib/clean.task.ts +2 -2
- package/src/lib/clean_fs.ts +4 -4
- package/src/lib/cli.ts +18 -17
- package/src/lib/commit.task.ts +2 -2
- package/src/lib/deploy.task.ts +33 -16
- package/src/lib/disknode.ts +1 -1
- package/src/lib/esbuild_helpers.ts +1 -1
- package/src/lib/esbuild_plugin_external_worker.ts +3 -3
- package/src/lib/esbuild_plugin_svelte.ts +4 -4
- package/src/lib/esbuild_plugin_sveltekit_local_imports.ts +2 -2
- package/src/lib/esbuild_plugin_sveltekit_shim_alias.ts +1 -1
- package/src/lib/filer.ts +117 -58
- package/src/lib/format.task.ts +1 -1
- package/src/lib/format_directory.ts +2 -2
- package/src/lib/format_file.ts +1 -1
- package/src/lib/gen.task.ts +3 -3
- package/src/lib/gen.ts +56 -50
- package/src/lib/gen_helpers.ts +3 -3
- package/src/lib/github.ts +2 -2
- package/src/lib/gro.config.default.ts +1 -1
- package/src/lib/gro_config.ts +5 -5
- package/src/lib/gro_helpers.ts +1 -1
- package/src/lib/gro_plugin_gen.ts +4 -4
- package/src/lib/gro_plugin_server.ts +9 -9
- package/src/lib/gro_plugin_sveltekit_app.ts +44 -40
- package/src/lib/gro_plugin_sveltekit_library.ts +3 -3
- package/src/lib/input_path.ts +23 -24
- package/src/lib/invoke.ts +2 -2
- package/src/lib/invoke_task.ts +5 -5
- package/src/lib/lint.task.ts +2 -2
- package/src/lib/loader.ts +2 -2
- package/src/lib/modules.ts +7 -7
- package/src/lib/package_json.ts +19 -23
- package/src/lib/parse_exports.ts +4 -4
- package/src/lib/parse_exports_context.ts +2 -2
- package/src/lib/parse_imports.ts +3 -3
- package/src/lib/paths.ts +2 -2
- package/src/lib/publish.task.ts +8 -8
- package/src/lib/reinstall.task.ts +1 -1
- package/src/lib/release.task.ts +1 -1
- package/src/lib/resolve.task.ts +2 -2
- package/src/lib/resolve_specifier.ts +9 -5
- package/src/lib/run.task.ts +2 -2
- package/src/lib/run_gen.ts +18 -13
- package/src/lib/run_task.ts +6 -6
- package/src/lib/source_json.ts +26 -22
- package/src/lib/svelte_config.ts +1 -1
- package/src/lib/sveltekit_helpers.ts +7 -7
- package/src/lib/sveltekit_shim_app_forms.ts +1 -1
- package/src/lib/sveltekit_shim_app_navigation.ts +1 -1
- package/src/lib/sveltekit_shim_app_paths.ts +1 -1
- package/src/lib/sync.task.ts +1 -1
- package/src/lib/task.ts +16 -14
- package/src/lib/task_logging.ts +3 -3
- package/src/lib/test.task.ts +4 -3
- package/src/lib/typecheck.task.ts +4 -4
- package/src/lib/upgrade.task.ts +6 -6
- package/src/lib/watch_dir.ts +3 -3
- package/dist/search_fs.d.ts +0 -26
- package/dist/search_fs.d.ts.map +0 -1
- package/dist/search_fs.js +0 -52
- package/src/lib/search_fs.ts +0 -100
package/src/lib/build.task.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
2
|
import {styleText as st} from 'node:util';
|
|
3
|
-
import {git_check_clean_workspace, git_current_commit_hash} from '@
|
|
4
|
-
import {
|
|
3
|
+
import {git_check_clean_workspace, git_current_commit_hash} from '@fuzdev/fuz_util/git.js';
|
|
4
|
+
import {rm} from 'node:fs/promises';
|
|
5
5
|
import {join} from 'node:path';
|
|
6
|
+
import {fs_exists} from '@fuzdev/fuz_util/fs.js';
|
|
6
7
|
|
|
7
8
|
import {TaskError, type Task} from './task.ts';
|
|
8
9
|
import {Plugins} from './plugin.ts';
|
|
@@ -19,6 +20,8 @@ import {paths} from './paths.ts';
|
|
|
19
20
|
export const Args = z.strictObject({
|
|
20
21
|
sync: z.boolean().meta({description: 'dual of no-sync'}).default(true),
|
|
21
22
|
'no-sync': z.boolean().meta({description: 'opt out of gro sync'}).default(false),
|
|
23
|
+
gen: z.boolean().meta({description: 'dual of no-gen'}).default(true),
|
|
24
|
+
'no-gen': z.boolean().meta({description: 'opt out of gro gen'}).default(false),
|
|
22
25
|
install: z.boolean().meta({description: 'dual of no-install'}).default(true),
|
|
23
26
|
'no-install': z // convenience, same as `gro build -- gro sync --no-install` but the latter takes precedence
|
|
24
27
|
.boolean()
|
|
@@ -49,11 +52,15 @@ export const task: Task<Args> = {
|
|
|
49
52
|
Args,
|
|
50
53
|
run: async (ctx): Promise<void> => {
|
|
51
54
|
const {args, invoke_task, log, config} = ctx;
|
|
52
|
-
const {sync, install, force_build} = args;
|
|
55
|
+
const {sync, gen, install, force_build} = args;
|
|
53
56
|
|
|
54
57
|
if (sync || install) {
|
|
55
58
|
if (!sync) log.warn('sync is false but install is true, so ignoring the sync option');
|
|
56
|
-
await invoke_task('sync', {install});
|
|
59
|
+
await invoke_task('sync', {install, gen: false});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (gen) {
|
|
63
|
+
await invoke_task('gen');
|
|
57
64
|
}
|
|
58
65
|
|
|
59
66
|
// Batch git calls upfront for performance (spawning processes is expensive)
|
|
@@ -81,15 +88,13 @@ export const task: Task<Args> = {
|
|
|
81
88
|
// Rationale: Uncommitted changes could be reverted, leaving cached outputs from reverted code.
|
|
82
89
|
// This conservative approach prioritizes safety over convenience during development.
|
|
83
90
|
const cache_path = join(paths.build, 'build.json');
|
|
84
|
-
if (
|
|
85
|
-
|
|
91
|
+
if (await fs_exists(cache_path)) {
|
|
92
|
+
await rm(cache_path, {force: true});
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
// Delete all build output directories
|
|
89
|
-
build_dirs = discover_build_output_dirs();
|
|
90
|
-
|
|
91
|
-
rmSync(dir, {recursive: true, force: true});
|
|
92
|
-
}
|
|
96
|
+
build_dirs = await discover_build_output_dirs();
|
|
97
|
+
await Promise.all(build_dirs.map((dir) => rm(dir, {recursive: true, force: true})));
|
|
93
98
|
|
|
94
99
|
log.info(st('yellow', 'workspace has uncommitted changes - skipping build cache'));
|
|
95
100
|
// Skip clean_fs - already manually cleaned cache and all build outputs above
|
|
@@ -138,7 +143,7 @@ export const task: Task<Args> = {
|
|
|
138
143
|
} else {
|
|
139
144
|
// Commit is stable - safe to save cache
|
|
140
145
|
const metadata = await create_build_cache_metadata(config, log, initial_commit, build_dirs);
|
|
141
|
-
save_build_cache_metadata(metadata, log);
|
|
146
|
+
await save_build_cache_metadata(metadata, log);
|
|
142
147
|
log.debug('Build cache metadata saved');
|
|
143
148
|
}
|
|
144
149
|
}
|
package/src/lib/build_cache.ts
CHANGED
|
@@ -1,16 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
existsSync,
|
|
3
|
-
mkdirSync,
|
|
4
|
-
readdirSync,
|
|
5
|
-
readFileSync,
|
|
6
|
-
rmSync,
|
|
7
|
-
statSync,
|
|
8
|
-
writeFileSync,
|
|
9
|
-
} from 'node:fs';
|
|
1
|
+
import {mkdir, readdir, readFile, rm, stat, writeFile} from 'node:fs/promises';
|
|
10
2
|
import {join} from 'node:path';
|
|
11
|
-
import type {Logger} from '@
|
|
3
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
12
4
|
import {styleText as st} from 'node:util';
|
|
13
|
-
import {git_current_commit_hash} from '@
|
|
5
|
+
import {git_current_commit_hash} from '@fuzdev/fuz_util/git.js';
|
|
6
|
+
import {fs_exists} from '@fuzdev/fuz_util/fs.js';
|
|
7
|
+
import {map_concurrent} from '@fuzdev/fuz_util/async.js';
|
|
14
8
|
import {z} from 'zod';
|
|
15
9
|
|
|
16
10
|
import {to_hash} from './hash.ts';
|
|
@@ -89,15 +83,15 @@ export const compute_build_cache_key = async (
|
|
|
89
83
|
* Loads build cache metadata from .gro/ directory.
|
|
90
84
|
* Invalid or corrupted cache files are automatically deleted.
|
|
91
85
|
*/
|
|
92
|
-
export const load_build_cache_metadata = (): BuildCacheMetadata | null => {
|
|
86
|
+
export const load_build_cache_metadata = async (): Promise<BuildCacheMetadata | null> => {
|
|
93
87
|
const metadata_path = join(paths.build, BUILD_CACHE_METADATA_FILENAME);
|
|
94
88
|
|
|
95
|
-
if (!
|
|
89
|
+
if (!(await fs_exists(metadata_path))) {
|
|
96
90
|
return null;
|
|
97
91
|
}
|
|
98
92
|
|
|
99
93
|
try {
|
|
100
|
-
const contents =
|
|
94
|
+
const contents = await readFile(metadata_path, 'utf-8');
|
|
101
95
|
const parsed = JSON.parse(contents);
|
|
102
96
|
|
|
103
97
|
// Validate structure with Zod
|
|
@@ -107,7 +101,7 @@ export const load_build_cache_metadata = (): BuildCacheMetadata | null => {
|
|
|
107
101
|
if (metadata.version !== BUILD_CACHE_VERSION) {
|
|
108
102
|
// Clean up stale cache with old schema version
|
|
109
103
|
try {
|
|
110
|
-
|
|
104
|
+
await rm(metadata_path, {force: true});
|
|
111
105
|
} catch {
|
|
112
106
|
// Ignore cleanup errors
|
|
113
107
|
}
|
|
@@ -119,7 +113,7 @@ export const load_build_cache_metadata = (): BuildCacheMetadata | null => {
|
|
|
119
113
|
// Clean up corrupted/invalid cache file
|
|
120
114
|
// (catches JSON.parse, Zod validation, and version errors)
|
|
121
115
|
try {
|
|
122
|
-
|
|
116
|
+
await rm(metadata_path, {force: true});
|
|
123
117
|
} catch {
|
|
124
118
|
// Ignore cleanup errors
|
|
125
119
|
}
|
|
@@ -131,13 +125,16 @@ export const load_build_cache_metadata = (): BuildCacheMetadata | null => {
|
|
|
131
125
|
* Saves build cache metadata to .gro/ directory.
|
|
132
126
|
* Errors are logged but don't fail the build (cache is optional).
|
|
133
127
|
*/
|
|
134
|
-
export const save_build_cache_metadata = (
|
|
128
|
+
export const save_build_cache_metadata = async (
|
|
129
|
+
metadata: BuildCacheMetadata,
|
|
130
|
+
log?: Logger,
|
|
131
|
+
): Promise<void> => {
|
|
135
132
|
try {
|
|
136
133
|
// Ensure .gro directory exists
|
|
137
|
-
|
|
134
|
+
await mkdir(paths.build, {recursive: true});
|
|
138
135
|
|
|
139
136
|
const metadata_path = join(paths.build, BUILD_CACHE_METADATA_FILENAME);
|
|
140
|
-
|
|
137
|
+
await writeFile(metadata_path, JSON.stringify(metadata, null, '\t'), 'utf-8');
|
|
141
138
|
} catch (error) {
|
|
142
139
|
// Cache writes are optional - log warning but don't fail the build
|
|
143
140
|
log?.warn(
|
|
@@ -154,33 +151,38 @@ export const save_build_cache_metadata = (metadata: BuildCacheMetadata, log?: Lo
|
|
|
154
151
|
*/
|
|
155
152
|
export const validate_build_cache = async (metadata: BuildCacheMetadata): Promise<boolean> => {
|
|
156
153
|
// Verify all tracked output files exist and have matching size
|
|
154
|
+
// Sequential checks with early return for performance
|
|
157
155
|
for (const output of metadata.outputs) {
|
|
158
|
-
|
|
156
|
+
// eslint-disable-next-line no-await-in-loop
|
|
157
|
+
if (!(await fs_exists(output.path))) {
|
|
159
158
|
return false;
|
|
160
159
|
}
|
|
161
160
|
|
|
162
161
|
// Fast negative check: size mismatch = definitely invalid
|
|
163
162
|
// This avoids expensive file reads and hashing for files that have clearly changed
|
|
164
|
-
|
|
163
|
+
// eslint-disable-next-line no-await-in-loop
|
|
164
|
+
const stats = await stat(output.path);
|
|
165
165
|
if (stats.size !== output.size) {
|
|
166
166
|
return false;
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// Size matches for all files - now verify content with cryptographic hashing
|
|
171
|
-
// Hash
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
171
|
+
// Hash files with controlled concurrency (could be 10k+ files)
|
|
172
|
+
const results = await map_concurrent(
|
|
173
|
+
metadata.outputs,
|
|
174
|
+
async (output) => {
|
|
175
|
+
try {
|
|
176
|
+
const contents = await readFile(output.path);
|
|
177
|
+
const actual_hash = await to_hash(contents);
|
|
178
|
+
return actual_hash === output.hash;
|
|
179
|
+
} catch {
|
|
180
|
+
// File deleted/inaccessible between checks = cache invalid
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
20,
|
|
185
|
+
);
|
|
184
186
|
return results.every((valid) => valid);
|
|
185
187
|
};
|
|
186
188
|
|
|
@@ -198,7 +200,7 @@ export const is_build_cache_valid = async (
|
|
|
198
200
|
git_commit?: string | null,
|
|
199
201
|
): Promise<boolean> => {
|
|
200
202
|
// Load existing metadata
|
|
201
|
-
const metadata = load_build_cache_metadata();
|
|
203
|
+
const metadata = await load_build_cache_metadata();
|
|
202
204
|
if (!metadata) {
|
|
203
205
|
log.debug('No build cache metadata found');
|
|
204
206
|
return false;
|
|
@@ -250,8 +252,12 @@ export const collect_build_outputs = async (
|
|
|
250
252
|
const files_to_hash: Array<FileEntry> = [];
|
|
251
253
|
|
|
252
254
|
// Recursively collect files
|
|
253
|
-
const collect_files = (
|
|
254
|
-
|
|
255
|
+
const collect_files = async (
|
|
256
|
+
dir: string,
|
|
257
|
+
relative_base: string,
|
|
258
|
+
dir_prefix: string,
|
|
259
|
+
): Promise<void> => {
|
|
260
|
+
const entries = await readdir(dir, {withFileTypes: true});
|
|
255
261
|
|
|
256
262
|
for (const entry of entries) {
|
|
257
263
|
// Skip metadata file itself
|
|
@@ -264,7 +270,8 @@ export const collect_build_outputs = async (
|
|
|
264
270
|
const cache_key = join(dir_prefix, relative_path);
|
|
265
271
|
|
|
266
272
|
if (entry.isDirectory()) {
|
|
267
|
-
|
|
273
|
+
// eslint-disable-next-line no-await-in-loop
|
|
274
|
+
await collect_files(full_path, relative_path, dir_prefix);
|
|
268
275
|
} else if (entry.isFile()) {
|
|
269
276
|
files_to_hash.push({full_path, cache_key});
|
|
270
277
|
}
|
|
@@ -272,19 +279,22 @@ export const collect_build_outputs = async (
|
|
|
272
279
|
}
|
|
273
280
|
};
|
|
274
281
|
|
|
275
|
-
// Collect files from all build directories
|
|
282
|
+
// Collect files from all build directories sequentially
|
|
276
283
|
for (const build_dir of build_dirs) {
|
|
277
|
-
|
|
284
|
+
// eslint-disable-next-line no-await-in-loop
|
|
285
|
+
if (!(await fs_exists(build_dir))) {
|
|
278
286
|
continue; // Skip non-existent directories
|
|
279
287
|
}
|
|
280
|
-
|
|
288
|
+
// eslint-disable-next-line no-await-in-loop
|
|
289
|
+
await collect_files(build_dir, '', build_dir);
|
|
281
290
|
}
|
|
282
291
|
|
|
283
|
-
// Hash
|
|
284
|
-
|
|
292
|
+
// Hash files with controlled concurrency and collect stats (could be 10k+ files)
|
|
293
|
+
return map_concurrent(
|
|
294
|
+
files_to_hash,
|
|
285
295
|
async ({full_path, cache_key}): Promise<BuildOutputEntry> => {
|
|
286
|
-
const stats =
|
|
287
|
-
const contents =
|
|
296
|
+
const stats = await stat(full_path);
|
|
297
|
+
const contents = await readFile(full_path);
|
|
288
298
|
const hash = await to_hash(contents);
|
|
289
299
|
|
|
290
300
|
return {
|
|
@@ -296,40 +306,46 @@ export const collect_build_outputs = async (
|
|
|
296
306
|
mode: stats.mode,
|
|
297
307
|
};
|
|
298
308
|
},
|
|
309
|
+
20,
|
|
299
310
|
);
|
|
300
|
-
|
|
301
|
-
return await Promise.all(hash_promises);
|
|
302
311
|
};
|
|
303
312
|
|
|
304
313
|
/**
|
|
305
314
|
* Discovers all build output directories in the current working directory.
|
|
306
315
|
* Returns an array of directory names that exist: build/, dist/, dist_*
|
|
307
316
|
*/
|
|
308
|
-
export const discover_build_output_dirs = (): Array<string
|
|
317
|
+
export const discover_build_output_dirs = async (): Promise<Array<string>> => {
|
|
309
318
|
const build_dirs: Array<string> = [];
|
|
310
319
|
|
|
311
|
-
// Check for SvelteKit app output (build/)
|
|
312
|
-
|
|
320
|
+
// Check for SvelteKit app output (build/) and library output (dist/) in parallel
|
|
321
|
+
const [build_exists, dist_exists] = await Promise.all([
|
|
322
|
+
fs_exists(SVELTEKIT_BUILD_DIRNAME),
|
|
323
|
+
fs_exists(SVELTEKIT_DIST_DIRNAME),
|
|
324
|
+
]);
|
|
325
|
+
|
|
326
|
+
if (build_exists) {
|
|
313
327
|
build_dirs.push(SVELTEKIT_BUILD_DIRNAME);
|
|
314
328
|
}
|
|
315
|
-
|
|
316
|
-
// Check for SvelteKit library output (dist/)
|
|
317
|
-
if (existsSync(SVELTEKIT_DIST_DIRNAME)) {
|
|
329
|
+
if (dist_exists) {
|
|
318
330
|
build_dirs.push(SVELTEKIT_DIST_DIRNAME);
|
|
319
331
|
}
|
|
320
332
|
|
|
321
333
|
// Check for server and other plugin outputs (dist_*)
|
|
322
|
-
const root_entries =
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
334
|
+
const root_entries = await readdir('.');
|
|
335
|
+
const dist_dir_checks = await Promise.all(
|
|
336
|
+
root_entries
|
|
337
|
+
.filter((p) => p.startsWith(GRO_DIST_PREFIX))
|
|
338
|
+
.map(async (p) => {
|
|
339
|
+
try {
|
|
340
|
+
const s = await stat(p);
|
|
341
|
+
return s.isDirectory() ? p : null;
|
|
342
|
+
} catch {
|
|
343
|
+
// File was deleted/moved during iteration - skip it
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
}),
|
|
347
|
+
);
|
|
348
|
+
build_dirs.push(...dist_dir_checks.filter((p): p is string => p !== null));
|
|
333
349
|
|
|
334
350
|
return build_dirs;
|
|
335
351
|
};
|
|
@@ -350,7 +366,7 @@ export const create_build_cache_metadata = async (
|
|
|
350
366
|
build_dirs?: Array<string>,
|
|
351
367
|
): Promise<BuildCacheMetadata> => {
|
|
352
368
|
const cache_key = await compute_build_cache_key(config, log, git_commit);
|
|
353
|
-
const dirs = build_dirs ?? discover_build_output_dirs();
|
|
369
|
+
const dirs = build_dirs ?? (await discover_build_output_dirs());
|
|
354
370
|
const outputs = await collect_build_outputs(dirs);
|
|
355
371
|
|
|
356
372
|
return {
|
package/src/lib/changelog.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {readFile, writeFile} from 'node:fs/promises';
|
|
2
2
|
import {z} from 'zod';
|
|
3
|
-
import type {Logger} from '@
|
|
4
|
-
import type {FetchValueCache} from '@
|
|
3
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
4
|
+
import type {FetchValueCache} from '@fuzdev/fuz_util/fetch.js';
|
|
5
5
|
|
|
6
6
|
import {github_fetch_commit_prs} from './github.ts';
|
|
7
7
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
|
-
import {spawn} from '@
|
|
2
|
+
import {spawn} from '@fuzdev/fuz_util/process.js';
|
|
3
3
|
import {styleText as st} from 'node:util';
|
|
4
4
|
import type {WrittenConfig} from '@changesets/types';
|
|
5
|
-
import {readFile, writeFile} from 'node:fs/promises';
|
|
5
|
+
import {readdir, readFile, writeFile} from 'node:fs/promises';
|
|
6
6
|
import {join} from 'node:path';
|
|
7
|
-
import {
|
|
7
|
+
import {fs_exists} from '@fuzdev/fuz_util/fs.js';
|
|
8
8
|
import {
|
|
9
9
|
GitOrigin,
|
|
10
10
|
git_check_fully_staged_workspace,
|
|
11
11
|
git_push_to_create,
|
|
12
|
-
} from '@
|
|
12
|
+
} from '@fuzdev/fuz_util/git.js';
|
|
13
13
|
|
|
14
14
|
import {TaskError, type Task} from './task.ts';
|
|
15
15
|
import {find_cli, spawn_cli} from './cli.ts';
|
|
@@ -92,14 +92,14 @@ export const task: Task<Args> = {
|
|
|
92
92
|
|
|
93
93
|
const bump: ChangesetBump = minor ? 'minor' : major ? 'major' : 'patch';
|
|
94
94
|
|
|
95
|
-
const found_changeset_cli = find_cli(changeset_cli);
|
|
95
|
+
const found_changeset_cli = await find_cli(changeset_cli);
|
|
96
96
|
if (!found_changeset_cli) {
|
|
97
97
|
throw new TaskError(
|
|
98
98
|
'changeset command not found: install @changesets/cli locally or globally',
|
|
99
99
|
);
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
const package_json = load_package_json();
|
|
102
|
+
const package_json = await load_package_json();
|
|
103
103
|
|
|
104
104
|
const has_sveltekit_library_result = await has_sveltekit_library(package_json, svelte_config);
|
|
105
105
|
if (!has_sveltekit_library_result.ok) {
|
|
@@ -110,7 +110,7 @@ export const task: Task<Args> = {
|
|
|
110
110
|
|
|
111
111
|
const path = join(dir, 'config.json');
|
|
112
112
|
|
|
113
|
-
const inited =
|
|
113
|
+
const inited = await fs_exists(path);
|
|
114
114
|
|
|
115
115
|
if (!inited) {
|
|
116
116
|
await spawn_cli(found_changeset_cli, ['init'], log);
|
|
@@ -143,7 +143,7 @@ export const task: Task<Args> = {
|
|
|
143
143
|
|
|
144
144
|
if (message) {
|
|
145
145
|
// TODO see the helper below, simplify this to CLI flags when support is added to Changesets
|
|
146
|
-
const changeset_adder = create_changeset_adder(package_json.name, dir, message, bump);
|
|
146
|
+
const changeset_adder = await create_changeset_adder(package_json.name, dir, message, bump);
|
|
147
147
|
await spawn_cli(found_changeset_cli, ['add', '--empty'], log);
|
|
148
148
|
await changeset_adder();
|
|
149
149
|
if (!(await git_check_fully_staged_workspace())) {
|
|
@@ -161,15 +161,15 @@ export const task: Task<Args> = {
|
|
|
161
161
|
* TODO ideally this wouldn't exist and we'd use CLI flags, but they doesn't exist yet
|
|
162
162
|
* @see https://github.com/changesets/changesets/pull/1121
|
|
163
163
|
*/
|
|
164
|
-
const create_changeset_adder = (
|
|
164
|
+
const create_changeset_adder = async (
|
|
165
165
|
repo_name: string,
|
|
166
166
|
dir: string,
|
|
167
167
|
message: string,
|
|
168
168
|
bump: ChangesetBump,
|
|
169
|
-
) => {
|
|
170
|
-
const filenames_before =
|
|
169
|
+
): Promise<() => Promise<void>> => {
|
|
170
|
+
const filenames_before = await readdir(dir);
|
|
171
171
|
return async () => {
|
|
172
|
-
const filenames_after =
|
|
172
|
+
const filenames_after = await readdir(dir);
|
|
173
173
|
const filenames_added = filenames_after.filter((p) => !filenames_before.includes(p));
|
|
174
174
|
if (!filenames_added.length) {
|
|
175
175
|
throw Error('expected to find a new changeset file');
|
package/src/lib/check.task.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {z} from 'zod';
|
|
2
|
-
import {spawn} from '@
|
|
2
|
+
import {spawn} from '@fuzdev/fuz_util/process.js';
|
|
3
3
|
import {styleText as st} from 'node:util';
|
|
4
|
-
import {git_check_clean_workspace} from '@
|
|
4
|
+
import {git_check_clean_workspace} from '@fuzdev/fuz_util/git.js';
|
|
5
5
|
|
|
6
6
|
import {TaskError, type Task} from './task.ts';
|
|
7
7
|
import {sync_package_json} from './package_json.ts';
|
package/src/lib/clean.task.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {spawn} from '@
|
|
1
|
+
import {spawn} from '@fuzdev/fuz_util/process.js';
|
|
2
2
|
import {z} from 'zod';
|
|
3
|
-
import {GitOrigin} from '@
|
|
3
|
+
import {GitOrigin} from '@fuzdev/fuz_util/git.js';
|
|
4
4
|
|
|
5
5
|
import type {Task} from './task.ts';
|
|
6
6
|
import {clean_fs} from './clean_fs.ts';
|
package/src/lib/clean_fs.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {rm} from 'node:fs/promises';
|
|
2
|
-
import
|
|
1
|
+
import {readdir, rm} from 'node:fs/promises';
|
|
2
|
+
import type {RmOptions} from 'node:fs';
|
|
3
3
|
|
|
4
4
|
import {paths} from './paths.ts';
|
|
5
5
|
import {
|
|
@@ -35,8 +35,8 @@ export const clean_fs = async (
|
|
|
35
35
|
promises.push(rm(paths.build_dev, rm_options));
|
|
36
36
|
}
|
|
37
37
|
if (build || build_dist) {
|
|
38
|
-
const
|
|
39
|
-
for (const path of
|
|
38
|
+
const dir_paths = (await readdir('.')).filter((p) => p.startsWith(GRO_DIST_PREFIX));
|
|
39
|
+
for (const path of dir_paths) {
|
|
40
40
|
promises.push(rm(path, rm_options));
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/lib/cli.ts
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type {SpawnOptions} from 'node:child_process';
|
|
2
2
|
import {
|
|
3
3
|
spawn,
|
|
4
|
+
spawn_out,
|
|
4
5
|
spawn_process,
|
|
5
6
|
type SpawnResult,
|
|
6
7
|
type SpawnedProcess,
|
|
7
|
-
} from '@
|
|
8
|
+
} from '@fuzdev/fuz_util/process.js';
|
|
8
9
|
import {join} from 'node:path';
|
|
9
|
-
import {
|
|
10
|
+
import {fs_exists} from '@fuzdev/fuz_util/fs.js';
|
|
10
11
|
import {fileURLToPath, type URL} from 'node:url';
|
|
11
|
-
import type {Logger} from '@
|
|
12
|
-
import type {PathId} from '@
|
|
12
|
+
import type {Logger} from '@fuzdev/fuz_util/log.js';
|
|
13
|
+
import type {PathId} from '@fuzdev/fuz_util/path.js';
|
|
13
14
|
|
|
14
15
|
import {NODE_MODULES_DIRNAME} from './constants.ts';
|
|
15
16
|
import {print_command_args} from './args.ts';
|
|
@@ -24,18 +25,18 @@ export type Cli =
|
|
|
24
25
|
* Searches the filesystem for the CLI `name`, first local to the cwd and then globally.
|
|
25
26
|
* @returns `null` if not found locally or globally
|
|
26
27
|
*/
|
|
27
|
-
export const find_cli = (
|
|
28
|
+
export const find_cli = async (
|
|
28
29
|
name: string,
|
|
29
30
|
cwd: string | URL = process.cwd(),
|
|
30
31
|
options?: SpawnOptions,
|
|
31
|
-
): Cli | null => {
|
|
32
|
+
): Promise<Cli | null> => {
|
|
32
33
|
const final_cwd = typeof cwd === 'string' ? cwd : fileURLToPath(cwd);
|
|
33
34
|
const local_id = join(final_cwd, NODE_MODULES_DIRNAME, `.bin/${name}`);
|
|
34
|
-
if (
|
|
35
|
+
if (await fs_exists(local_id)) {
|
|
35
36
|
return {name, id: local_id, kind: 'local'};
|
|
36
37
|
}
|
|
37
|
-
const {stdout} =
|
|
38
|
-
const global_id = stdout
|
|
38
|
+
const {stdout} = await spawn_out('which', [name], options);
|
|
39
|
+
const global_id = stdout?.trim();
|
|
39
40
|
if (!global_id) return null;
|
|
40
41
|
return {name, id: global_id, kind: 'global'};
|
|
41
42
|
};
|
|
@@ -51,7 +52,7 @@ export const spawn_cli = async (
|
|
|
51
52
|
log?: Logger,
|
|
52
53
|
options?: SpawnOptions,
|
|
53
54
|
): Promise<SpawnResult | undefined> => {
|
|
54
|
-
const cli = resolve_cli(name_or_cli, args, options?.cwd, log, options);
|
|
55
|
+
const cli = await resolve_cli(name_or_cli, args, options?.cwd, log, options);
|
|
55
56
|
if (!cli) return;
|
|
56
57
|
return spawn(cli.id, args, options);
|
|
57
58
|
};
|
|
@@ -61,27 +62,27 @@ export const spawn_cli = async (
|
|
|
61
62
|
* If a string is provided for `name_or_cli`, it checks first local to the cwd and then globally.
|
|
62
63
|
* @returns `undefined` if no CLI is found, or the spawn result
|
|
63
64
|
*/
|
|
64
|
-
export const spawn_cli_process = (
|
|
65
|
+
export const spawn_cli_process = async (
|
|
65
66
|
name_or_cli: string | Cli,
|
|
66
67
|
args: Array<string> = [],
|
|
67
68
|
log?: Logger,
|
|
68
69
|
options?: SpawnOptions,
|
|
69
|
-
): SpawnedProcess | undefined => {
|
|
70
|
-
const cli = resolve_cli(name_or_cli, args, options?.cwd, log, options);
|
|
70
|
+
): Promise<SpawnedProcess | undefined> => {
|
|
71
|
+
const cli = await resolve_cli(name_or_cli, args, options?.cwd, log, options);
|
|
71
72
|
if (!cli) return;
|
|
72
73
|
return spawn_process(cli.id, args, options);
|
|
73
74
|
};
|
|
74
75
|
|
|
75
|
-
export const resolve_cli = (
|
|
76
|
+
export const resolve_cli = async (
|
|
76
77
|
name_or_cli: string | Cli,
|
|
77
78
|
args: Array<string> = [],
|
|
78
79
|
cwd: string | URL | undefined,
|
|
79
80
|
log?: Logger,
|
|
80
81
|
options?: SpawnOptions,
|
|
81
|
-
): Cli | undefined => {
|
|
82
|
+
): Promise<Cli | undefined> => {
|
|
82
83
|
let final_cli;
|
|
83
84
|
if (typeof name_or_cli === 'string') {
|
|
84
|
-
const found = find_cli(name_or_cli, cwd, options);
|
|
85
|
+
const found = await find_cli(name_or_cli, cwd, options);
|
|
85
86
|
if (!found) return;
|
|
86
87
|
final_cli = found;
|
|
87
88
|
} else {
|
package/src/lib/commit.task.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {spawn} from '@
|
|
1
|
+
import {spawn} from '@fuzdev/fuz_util/process.js';
|
|
2
2
|
import {z} from 'zod';
|
|
3
|
-
import {GitOrigin, git_current_branch_name, git_push} from '@
|
|
3
|
+
import {GitOrigin, git_current_branch_name, git_push} from '@fuzdev/fuz_util/git.js';
|
|
4
4
|
|
|
5
5
|
import type {Task} from './task.ts';
|
|
6
6
|
|