@fuzdev/fuz_gitops 0.78.0 → 0.79.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 +91 -17
- package/dist/ModulesDetail.svelte +22 -27
- package/dist/ModulesDetail.svelte.d.ts.map +1 -1
- package/dist/ModulesNav.svelte +8 -5
- package/dist/ModulesNav.svelte.d.ts.map +1 -1
- package/dist/ModulesPage.svelte +3 -5
- package/dist/ModulesPage.svelte.d.ts.map +1 -1
- package/dist/PageFooter.svelte +2 -2
- package/dist/PageHeader.svelte +6 -6
- package/dist/PageHeader.svelte.d.ts +0 -3
- package/dist/PageHeader.svelte.d.ts.map +1 -1
- package/dist/PullRequestsDetail.svelte +29 -20
- package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
- package/dist/PullRequestsPage.svelte +4 -6
- package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
- package/dist/ReposTable.svelte +43 -55
- package/dist/ReposTable.svelte.d.ts.map +1 -1
- package/dist/ReposTree.svelte +9 -21
- package/dist/ReposTree.svelte.d.ts.map +1 -1
- package/dist/ReposTreeNav.svelte +9 -12
- package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
- package/dist/TablePage.svelte +3 -5
- package/dist/TablePage.svelte.d.ts.map +1 -1
- package/dist/TreeItemPage.svelte +3 -5
- package/dist/TreeItemPage.svelte.d.ts.map +1 -1
- package/dist/TreePage.svelte +3 -5
- package/dist/TreePage.svelte.d.ts.map +1 -1
- package/dist/changeset_generator.d.ts.map +1 -1
- package/dist/changeset_generator.js +2 -2
- package/dist/changeset_reader.d.ts.map +1 -1
- package/dist/changeset_reader.js +3 -3
- package/dist/ci_reconcile.d.ts +6 -10
- package/dist/ci_reconcile.d.ts.map +1 -1
- package/dist/ci_reconcile.js +6 -8
- package/dist/dependency_graph.d.ts +26 -49
- package/dist/dependency_graph.d.ts.map +1 -1
- package/dist/dependency_graph.js +40 -83
- package/dist/dependency_updater.d.ts +1 -1
- package/dist/dependency_updater.d.ts.map +1 -1
- package/dist/dependency_updater.js +14 -9
- package/dist/fetch_repo_data.d.ts +34 -8
- package/dist/fetch_repo_data.d.ts.map +1 -1
- package/dist/fetch_repo_data.js +44 -22
- package/dist/fs_fetch_value_cache.d.ts +1 -1
- package/dist/fs_fetch_value_cache.d.ts.map +1 -1
- package/dist/fs_fetch_value_cache.js +3 -3
- package/dist/git_operations.d.ts +6 -49
- package/dist/git_operations.d.ts.map +1 -1
- package/dist/git_operations.js +13 -126
- package/dist/github.d.ts +17 -2
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +17 -8
- package/dist/github_helpers.d.ts.map +1 -1
- package/dist/github_helpers.js +3 -11
- package/dist/gitops_analyze.task.d.ts +24 -2
- package/dist/gitops_analyze.task.d.ts.map +1 -1
- package/dist/gitops_analyze.task.js +47 -34
- package/dist/gitops_config.d.ts +34 -79
- package/dist/gitops_config.d.ts.map +1 -1
- package/dist/gitops_config.js +76 -53
- package/dist/gitops_constants.d.ts +6 -4
- package/dist/gitops_constants.d.ts.map +1 -1
- package/dist/gitops_constants.js +6 -4
- package/dist/gitops_plan.task.d.ts +29 -3
- package/dist/gitops_plan.task.d.ts.map +1 -1
- package/dist/gitops_plan.task.js +83 -61
- package/dist/gitops_publish.task.d.ts +62 -2
- package/dist/gitops_publish.task.d.ts.map +1 -1
- package/dist/gitops_publish.task.js +193 -105
- package/dist/gitops_run.task.d.ts +74 -0
- package/dist/gitops_run.task.d.ts.map +1 -1
- package/dist/gitops_run.task.js +176 -162
- package/dist/gitops_sync.task.d.ts +65 -3
- package/dist/gitops_sync.task.d.ts.map +1 -1
- package/dist/gitops_sync.task.js +163 -37
- package/dist/gitops_task_helpers.d.ts +86 -59
- package/dist/gitops_task_helpers.d.ts.map +1 -1
- package/dist/gitops_task_helpers.js +120 -79
- package/dist/gitops_validate.task.d.ts +1 -2
- package/dist/gitops_validate.task.d.ts.map +1 -1
- package/dist/gitops_validate.task.js +25 -32
- package/dist/graph_validation.d.ts +16 -27
- package/dist/graph_validation.d.ts.map +1 -1
- package/dist/graph_validation.js +24 -65
- package/dist/local_repo.d.ts +50 -62
- package/dist/local_repo.d.ts.map +1 -1
- package/dist/local_repo.js +83 -196
- package/dist/log_helpers.d.ts +8 -8
- package/dist/log_helpers.d.ts.map +1 -1
- package/dist/multi_repo_publisher.d.ts +10 -0
- package/dist/multi_repo_publisher.d.ts.map +1 -1
- package/dist/multi_repo_publisher.js +125 -61
- package/dist/npm_registry.d.ts +23 -19
- package/dist/npm_registry.d.ts.map +1 -1
- package/dist/npm_registry.js +21 -48
- package/dist/operations.d.ts +75 -180
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +15 -7
- package/dist/operations_defaults.d.ts +17 -2
- package/dist/operations_defaults.d.ts.map +1 -1
- package/dist/operations_defaults.js +111 -128
- package/dist/output_helpers.d.ts +36 -0
- package/dist/output_helpers.d.ts.map +1 -1
- package/dist/output_helpers.js +37 -3
- package/dist/preflight_checks.d.ts +20 -27
- package/dist/preflight_checks.d.ts.map +1 -1
- package/dist/preflight_checks.js +37 -126
- package/dist/publish_gate.d.ts.map +1 -1
- package/dist/publish_steps.d.ts +2 -4
- package/dist/publish_steps.d.ts.map +1 -1
- package/dist/publish_steps.js +4 -8
- package/dist/publishing_event.d.ts +2 -8
- package/dist/publishing_event.d.ts.map +1 -1
- package/dist/publishing_event.js +20 -17
- package/dist/publishing_event_handler.d.ts +10 -8
- package/dist/publishing_event_handler.d.ts.map +1 -1
- package/dist/publishing_event_handler.js +19 -17
- package/dist/publishing_plan.d.ts +16 -1
- package/dist/publishing_plan.d.ts.map +1 -1
- package/dist/publishing_plan.js +332 -254
- package/dist/publishing_plan_helpers.d.ts.map +1 -1
- package/dist/publishing_plan_helpers.js +3 -3
- package/dist/publishing_plan_logging.d.ts +1 -1
- package/dist/publishing_plan_logging.d.ts.map +1 -1
- package/dist/publishing_plan_logging.js +22 -15
- package/dist/repo.svelte.d.ts +7 -0
- package/dist/repo.svelte.d.ts.map +1 -1
- package/dist/repo.svelte.js +3 -0
- package/dist/repo_readiness.d.ts +210 -0
- package/dist/repo_readiness.d.ts.map +1 -0
- package/dist/repo_readiness.js +516 -0
- package/dist/repos_status.d.ts +3340 -0
- package/dist/repos_status.d.ts.map +1 -0
- package/dist/repos_status.js +555 -0
- package/dist/repos_status_load.d.ts +65 -0
- package/dist/repos_status_load.d.ts.map +1 -0
- package/dist/repos_status_load.js +131 -0
- package/dist/version_utils.js +1 -1
- package/package.json +15 -34
- package/src/lib/cargo_toml.ts +3 -3
- package/src/lib/changeset_generator.ts +19 -19
- package/src/lib/changeset_reader.ts +18 -18
- package/src/lib/ci_reconcile.ts +12 -16
- package/src/lib/dependency_graph.ts +61 -113
- package/src/lib/dependency_updater.ts +36 -30
- package/src/lib/fetch_repo_data.ts +71 -34
- package/src/lib/fs_fetch_value_cache.ts +15 -11
- package/src/lib/git_operations.ts +22 -194
- package/src/lib/github.ts +33 -21
- package/src/lib/github_helpers.ts +9 -16
- package/src/lib/gitops_analyze.task.ts +104 -66
- package/src/lib/gitops_config.ts +90 -139
- package/src/lib/gitops_constants.ts +6 -4
- package/src/lib/gitops_plan.task.ts +128 -76
- package/src/lib/gitops_publish.task.ts +280 -144
- package/src/lib/gitops_run.task.ts +265 -193
- package/src/lib/gitops_sync.task.ts +236 -52
- package/src/lib/gitops_task_helpers.ts +170 -114
- package/src/lib/gitops_validate.task.ts +44 -54
- package/src/lib/graph_validation.ts +28 -89
- package/src/lib/local_repo.ts +128 -335
- package/src/lib/log_helpers.ts +18 -28
- package/src/lib/multi_repo_publisher.ts +192 -110
- package/src/lib/npm_registry.ts +42 -67
- package/src/lib/operations.ts +99 -160
- package/src/lib/operations_defaults.ts +157 -201
- package/src/lib/output_helpers.ts +58 -6
- package/src/lib/preflight_checks.ts +52 -188
- package/src/lib/publish_gate.ts +7 -9
- package/src/lib/publish_steps.ts +27 -25
- package/src/lib/publishing_event.ts +26 -23
- package/src/lib/publishing_event_handler.ts +24 -22
- package/src/lib/publishing_plan.ts +474 -310
- package/src/lib/publishing_plan_helpers.ts +16 -12
- package/src/lib/publishing_plan_logging.ts +53 -44
- package/src/lib/repo.svelte.ts +16 -8
- package/src/lib/repo_readiness.ts +647 -0
- package/src/lib/repos_status.ts +671 -0
- package/src/lib/repos_status_load.ts +173 -0
- package/src/lib/version_utils.ts +3 -3
- package/dist/config_reconcile.d.ts +0 -46
- package/dist/config_reconcile.d.ts.map +0 -1
- package/dist/config_reconcile.js +0 -60
- package/dist/paths.d.ts +0 -7
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js +0 -6
- package/dist/repo_ops.d.ts +0 -59
- package/dist/repo_ops.d.ts.map +0 -1
- package/dist/repo_ops.js +0 -170
- package/dist/resolved_gitops_config.d.ts +0 -9
- package/dist/resolved_gitops_config.d.ts.map +0 -1
- package/dist/resolved_gitops_config.js +0 -12
- package/src/lib/config_reconcile.ts +0 -94
- package/src/lib/paths.ts +0 -6
- package/src/lib/repo_ops.ts +0 -216
- package/src/lib/resolved_gitops_config.ts +0 -27
package/dist/gitops_sync.task.js
CHANGED
|
@@ -2,16 +2,21 @@ import { TaskError } from '@fuzdev/gro';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { readFile, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { format_file } from '@fuzdev/gro/format_file.ts';
|
|
5
|
-
import { basename, resolve } from 'node:path';
|
|
5
|
+
import { basename, join, resolve } from 'node:path';
|
|
6
6
|
import { print_path } from '@fuzdev/gro/paths.ts';
|
|
7
7
|
import { load_from_env } from '@fuzdev/gro/env.ts';
|
|
8
8
|
import { package_json_load } from '@fuzdev/gro/package_json.ts';
|
|
9
|
-
import { existsSync } from 'node:fs';
|
|
9
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
10
|
+
import { styleText as st } from 'node:util';
|
|
10
11
|
import { compactReplacer } from 'svelte-docinfo';
|
|
11
12
|
import { fetch_repo_data } from './fetch_repo_data.js';
|
|
12
13
|
import { create_fs_fetch_value_cache } from './fs_fetch_value_cache.js';
|
|
13
|
-
import {
|
|
14
|
+
import { resolve_gitops_repos } from './gitops_task_helpers.js';
|
|
14
15
|
import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.js';
|
|
16
|
+
import { local_repos_load, local_repos_resolve } from './local_repo.js';
|
|
17
|
+
import { load_repos_status, to_repos_command } from './repos_status_load.js';
|
|
18
|
+
import { check_gen_readiness } from './repo_readiness.js';
|
|
19
|
+
import { default_repos_operations } from './operations_defaults.js';
|
|
15
20
|
// TODO add flag to ignore or invalidate cache -- no-cache? clean?
|
|
16
21
|
/** @nodocs */
|
|
17
22
|
export const Args = z.strictObject({
|
|
@@ -19,69 +24,72 @@ export const Args = z.strictObject({
|
|
|
19
24
|
.string()
|
|
20
25
|
.meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
|
|
21
26
|
.default(GITOPS_CONFIG_PATH_DEFAULT),
|
|
22
|
-
|
|
27
|
+
registry: z
|
|
23
28
|
.string()
|
|
24
|
-
.meta({
|
|
29
|
+
.meta({
|
|
30
|
+
description: 'path to the repos.toml registry, when `repos` would not find it walking up from the cwd'
|
|
31
|
+
})
|
|
25
32
|
.optional(),
|
|
26
33
|
outdir: z
|
|
27
34
|
.string()
|
|
28
35
|
.meta({ description: 'path to the directory for the generated files, defaults to $routes/' })
|
|
29
36
|
.optional(),
|
|
30
|
-
download: z.boolean().meta({ description: 'download all missing local repos' }).default(false),
|
|
31
37
|
check: z
|
|
32
38
|
.boolean()
|
|
33
|
-
.meta({
|
|
39
|
+
.meta({
|
|
40
|
+
description: 'report whether the repos are ready to generate from, as of the local refs, and exit non-zero if a real run would refuse; fetches nothing, needs no token, and writes nothing'
|
|
41
|
+
})
|
|
34
42
|
.default(false),
|
|
35
43
|
allow_dirty: z
|
|
36
44
|
.boolean()
|
|
37
45
|
.meta({
|
|
38
|
-
description: '
|
|
46
|
+
description: 'read repos off their registry branch, dirty, or mid-operation as they sit, warning instead of refusing'
|
|
39
47
|
})
|
|
40
|
-
.default(false)
|
|
48
|
+
.default(false)
|
|
41
49
|
});
|
|
42
50
|
/**
|
|
43
|
-
*
|
|
51
|
+
* Generates the dashboard's site data (`repos.json` and `repos.ts`) from each
|
|
52
|
+
* configured repo's working tree and its GitHub CI status and pull requests.
|
|
53
|
+
* It never moves a repo: see `prepare_gitops_sync` for what it reads and
|
|
54
|
+
* refuses. This is a task not a `.gen.` file because it makes network calls.
|
|
44
55
|
*
|
|
45
56
|
* @nodocs
|
|
46
57
|
*/
|
|
47
58
|
export const task = {
|
|
48
59
|
Args,
|
|
49
|
-
summary: '
|
|
50
|
-
run: async (
|
|
51
|
-
const {
|
|
52
|
-
// `
|
|
53
|
-
const {
|
|
60
|
+
summary: 'generates UI data from repo metadata, reading each repo as it sits',
|
|
61
|
+
run: async (ctx) => {
|
|
62
|
+
const { args, log, invoke_task } = ctx;
|
|
63
|
+
// `ctx.svelte_config` is a lazy getter, so it's only read when `outdir` isn't provided
|
|
64
|
+
const { config, registry, outdir = (await ctx.svelte_config).routes_path, check, allow_dirty } = args;
|
|
65
|
+
// The generated `repos.json` is the host project's site data, so a public host
|
|
66
|
+
// must never carry a private repo's metadata: `host` refuses the private repos
|
|
67
|
+
// the registry declares, before any fetch.
|
|
68
|
+
const package_json = await package_json_load();
|
|
69
|
+
const prepared = await prepare_gitops_sync({
|
|
54
70
|
config,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
71
|
+
registry,
|
|
72
|
+
host: { name: package_json.name, private: package_json.private === true },
|
|
73
|
+
check,
|
|
58
74
|
allow_dirty,
|
|
59
|
-
log
|
|
75
|
+
log
|
|
60
76
|
});
|
|
77
|
+
if (!prepared)
|
|
78
|
+
return;
|
|
79
|
+
const { local_repos, token } = prepared;
|
|
61
80
|
const outfile_json = resolve(outdir, 'repos.json');
|
|
62
81
|
const outfile_ts = resolve(outdir, 'repos.ts');
|
|
63
|
-
// This searches the parent directory for the env var, so we don't use SvelteKit's $env imports
|
|
64
|
-
const token = load_from_env('SECRET_GITHUB_API_TOKEN');
|
|
65
|
-
if (!token) {
|
|
66
|
-
throw new TaskError('the env var SECRET_GITHUB_API_TOKEN was not found');
|
|
67
|
-
}
|
|
68
|
-
// Exit early if only checking repo readiness
|
|
69
|
-
if (check) {
|
|
70
|
-
log.info('repos are ready');
|
|
71
|
-
return;
|
|
72
|
-
}
|
|
73
82
|
const cache = await create_fs_fetch_value_cache('repos');
|
|
74
83
|
log.info('fetching remote repo data');
|
|
75
|
-
const repos_json = await fetch_repo_data(local_repos, token, cache.data, log);
|
|
84
|
+
const repos_json = await fetch_repo_data({ local_repos, token, cache: cache.data, log });
|
|
76
85
|
// TODO should package_json be provided in the Gro task/gen contexts? check if it's always loaded
|
|
77
|
-
const package_json = await package_json_load();
|
|
78
86
|
const repo_specifier = package_json.name === '@fuzdev/fuz_gitops'
|
|
79
|
-
? '$lib/repo.svelte.
|
|
80
|
-
: '@fuzdev/fuz_gitops/repo.svelte.
|
|
87
|
+
? '$lib/repo.svelte.ts'
|
|
88
|
+
: '@fuzdev/fuz_gitops/repo.svelte.ts';
|
|
81
89
|
log.info(`generating ${outfile_json} and ${outfile_ts}`);
|
|
82
90
|
// Generate repos.json with the raw data
|
|
83
|
-
const json_contents =
|
|
84
|
-
|
|
91
|
+
const json_contents = format_file(JSON.stringify(repos_json, compactReplacer), {
|
|
92
|
+
lang: 'json'
|
|
85
93
|
});
|
|
86
94
|
const existing_json = existsSync(outfile_json) ? await readFile(outfile_json, 'utf8') : '';
|
|
87
95
|
const json_changed = existing_json !== json_contents;
|
|
@@ -107,7 +115,7 @@ export const task = {
|
|
|
107
115
|
export const repos_json: Array<RepoJson> = json as unknown as Array<RepoJson>;
|
|
108
116
|
`;
|
|
109
117
|
// TODO think about possibly using the `gen` functionality in this task, not sure what the API design could look like
|
|
110
|
-
const formatted_ts =
|
|
118
|
+
const formatted_ts = format_file(ts_contents, { filepath: outfile_ts });
|
|
111
119
|
const existing_ts = existsSync(outfile_ts) ? await readFile(outfile_ts, 'utf8') : '';
|
|
112
120
|
if (existing_ts === formatted_ts) {
|
|
113
121
|
log.info(`no changes to ${print_path(outfile_ts)}`);
|
|
@@ -126,5 +134,123 @@ export const task = {
|
|
|
126
134
|
else {
|
|
127
135
|
log.info('repos cache did not change');
|
|
128
136
|
}
|
|
129
|
-
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
const default_gitops_sync_deps = {
|
|
140
|
+
repos_ops: default_repos_operations,
|
|
141
|
+
load_repos: local_repos_load,
|
|
142
|
+
// this searches the parent directory for the env var, so we don't use SvelteKit's $env imports
|
|
143
|
+
load_token: () => load_from_env('SECRET_GITHUB_API_TOKEN') || undefined,
|
|
144
|
+
exists: existsSync,
|
|
145
|
+
read_file: (path) => readFileSync(path, 'utf8')
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Everything `gitops_sync` does before it fetches from GitHub, in order:
|
|
149
|
+
*
|
|
150
|
+
* 1. resolves the config's repos from `repos status <keys…> --json` (local
|
|
151
|
+
* refs), refusing a private repo when the host package is public
|
|
152
|
+
* 2. checks each repo is ready to generate from (`check_gen_readiness`): on
|
|
153
|
+
* its registry branch, clean, and idle, unless `allow_dirty` — refusing
|
|
154
|
+
* before any network. With `check`, that report is the whole run: its
|
|
155
|
+
* warnings are logged, and it throws when a real run would refuse
|
|
156
|
+
* 3. reads `SECRET_GITHUB_API_TOKEN`
|
|
157
|
+
* 4. fetches the repos from origin (`repos status <keys…> --fetch --json`,
|
|
158
|
+
* which writes remote-tracking refs and nothing else) and checks them
|
|
159
|
+
* again, warning on a followed branch not in sync with origin and a
|
|
160
|
+
* failed fetch
|
|
161
|
+
* 5. warns on each npm repo the library analysis can't fully read: no
|
|
162
|
+
* `node_modules`, or no `.svelte-kit/tsconfig.json` when its tsconfig
|
|
163
|
+
* extends it (external types then read as `any`) — it installs nothing
|
|
164
|
+
* 6. loads each repo's library as it sits
|
|
165
|
+
*
|
|
166
|
+
* @returns the loaded repos and the token, or `null` when `check` passed
|
|
167
|
+
* @throws {TaskError} if resolving fails, a repo isn't ready, or the token is missing
|
|
168
|
+
* @nodocs
|
|
169
|
+
*/
|
|
170
|
+
export const prepare_gitops_sync = async (options, deps = {}) => {
|
|
171
|
+
const { config, registry, host, check = false, allow_dirty = false, log } = options;
|
|
172
|
+
const { repos_ops, load_repos, load_token, exists, read_file } = {
|
|
173
|
+
...default_gitops_sync_deps,
|
|
174
|
+
...deps
|
|
175
|
+
};
|
|
176
|
+
const repos_command = to_repos_command(registry);
|
|
177
|
+
const { config_path, gitops_config, report } = await resolve_gitops_repos({
|
|
178
|
+
config,
|
|
179
|
+
registry,
|
|
180
|
+
host,
|
|
181
|
+
log,
|
|
182
|
+
repos_ops
|
|
183
|
+
});
|
|
184
|
+
const keys = gitops_config.repos;
|
|
185
|
+
const local = check_gen_readiness({ report, keys, allow_dirty, repos_command });
|
|
186
|
+
if (check) {
|
|
187
|
+
log_gen_warnings(local.warnings, log);
|
|
188
|
+
if (!local.ok)
|
|
189
|
+
throw new TaskError(local.message);
|
|
190
|
+
log.info(st('green', `all ${keys.length} repos are ready to generate the site data from`));
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
if (!local.ok)
|
|
194
|
+
throw new TaskError(local.message);
|
|
195
|
+
const token = load_token();
|
|
196
|
+
if (!token) {
|
|
197
|
+
throw new TaskError('the env var SECRET_GITHUB_API_TOKEN was not found');
|
|
198
|
+
}
|
|
199
|
+
log.info(`fetching ${keys.length} repos from origin`);
|
|
200
|
+
const fetched = await load_repos_status({ keys, registry, fetch: true, repos_ops });
|
|
201
|
+
if (!fetched.ok) {
|
|
202
|
+
throw new TaskError(`fetching the repos failed: ${fetched.message}`);
|
|
203
|
+
}
|
|
204
|
+
const resolved = local_repos_resolve({ keys, report: fetched.report, host, registry });
|
|
205
|
+
if (!resolved.ok) {
|
|
206
|
+
throw new TaskError(`${config_path}: ${resolved.message}`);
|
|
207
|
+
}
|
|
208
|
+
const checked = check_gen_readiness({
|
|
209
|
+
report: fetched.report,
|
|
210
|
+
keys,
|
|
211
|
+
allow_dirty,
|
|
212
|
+
repos_command
|
|
213
|
+
});
|
|
214
|
+
log_gen_warnings(checked.warnings, log);
|
|
215
|
+
if (!checked.ok)
|
|
216
|
+
throw new TaskError(checked.message);
|
|
217
|
+
const local_repo_paths = resolved.value;
|
|
218
|
+
const gaps = local_repo_paths
|
|
219
|
+
.map((p) => ({ key: p.repo_name, missing: analysis_setup_gaps(p.repo_dir, exists, read_file) }))
|
|
220
|
+
.filter((g) => g.missing.length > 0);
|
|
221
|
+
if (gaps.length > 0) {
|
|
222
|
+
log.warn(st('yellow', "the library analysis reads these repos without their dependencies' types, so external types read as `any` — `npm install` and `gro sync` in each fixes it:"));
|
|
223
|
+
for (const { key, missing } of gaps) {
|
|
224
|
+
log.warn(st('yellow', ` ${key}: no ${missing.join(' or ')}`));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const local_repos = await load_repos({ local_repo_paths, log });
|
|
228
|
+
return { local_repos, token };
|
|
229
|
+
};
|
|
230
|
+
const log_gen_warnings = (warnings, log) => {
|
|
231
|
+
if (warnings.length === 0)
|
|
232
|
+
return;
|
|
233
|
+
log.warn(st('yellow', "read as they sit, beside origin's CI:"));
|
|
234
|
+
for (const line of warnings)
|
|
235
|
+
log.warn(st('yellow', ` ${line}`));
|
|
236
|
+
};
|
|
237
|
+
/**
|
|
238
|
+
* What an npm repo lacks for the library analysis to resolve its dependencies'
|
|
239
|
+
* types: `node_modules`, and `.svelte-kit/tsconfig.json` when its
|
|
240
|
+
* `tsconfig.json` extends it. Empty for a repo without a `package.json`.
|
|
241
|
+
*/
|
|
242
|
+
const analysis_setup_gaps = (repo_dir, exists, read_file) => {
|
|
243
|
+
if (!exists(join(repo_dir, 'package.json')))
|
|
244
|
+
return [];
|
|
245
|
+
const missing = [];
|
|
246
|
+
if (!exists(join(repo_dir, 'node_modules')))
|
|
247
|
+
missing.push('`node_modules`');
|
|
248
|
+
const tsconfig_path = join(repo_dir, 'tsconfig.json');
|
|
249
|
+
const svelte_kit_tsconfig = '.svelte-kit/tsconfig.json';
|
|
250
|
+
if (exists(tsconfig_path) &&
|
|
251
|
+
read_file(tsconfig_path).includes(svelte_kit_tsconfig) &&
|
|
252
|
+
!exists(join(repo_dir, svelte_kit_tsconfig))) {
|
|
253
|
+
missing.push(`\`${svelte_kit_tsconfig}\``);
|
|
254
|
+
}
|
|
255
|
+
return missing;
|
|
130
256
|
};
|
|
@@ -1,83 +1,110 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared initialization logic for all gitops tasks.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* -
|
|
8
|
-
*
|
|
4
|
+
* `resolve_gitops_repos()` loads the config's registry keys, runs
|
|
5
|
+
* `repos status <keys…> --json`, and resolves each key to its checkout.
|
|
6
|
+
* `get_gitops_ready()` then loads each repo's library as its working tree
|
|
7
|
+
* sits. `gate_publish_readiness()` is the read-only gate a real publish runs
|
|
8
|
+
* before its prompt, and `log_readiness_block()` the diagnostics' report of
|
|
9
|
+
* repos not at rest (both over `repo_readiness.ts`).
|
|
9
10
|
*
|
|
10
11
|
* Used by: `gitops_sync.task.ts`, `gitops_analyze.task.ts`, `gitops_plan.task.ts`,
|
|
11
|
-
* `gitops_publish.task.ts`, and `
|
|
12
|
+
* `gitops_publish.task.ts`, `gitops_validate.task.ts`, and `gitops_run.task.ts`.
|
|
12
13
|
*
|
|
13
|
-
* Accepts `
|
|
14
|
-
*
|
|
14
|
+
* Accepts `repos_ops` to support testing via the operations pattern (see
|
|
15
|
+
* `operations.ts` for dependency injection details).
|
|
15
16
|
*
|
|
16
17
|
* @module
|
|
17
18
|
*/
|
|
18
19
|
import type { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
19
20
|
import { type GitopsConfig } from './gitops_config.js';
|
|
20
|
-
import { type LocalRepo } from './local_repo.js';
|
|
21
|
-
import type {
|
|
22
|
-
|
|
21
|
+
import { type LocalRepo, type LocalRepoPath } from './local_repo.js';
|
|
22
|
+
import type { ReposStatusReport } from './repos_status.js';
|
|
23
|
+
import type { ReposOperations } from './operations.js';
|
|
24
|
+
export interface ResolveGitopsReposOptions {
|
|
25
|
+
/** Path to the gitops config, absolute or relative to the cwd. */
|
|
23
26
|
config: string;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
log?: Logger;
|
|
27
|
-
git_ops?: GitOperations;
|
|
28
|
-
npm_ops?: NpmOperations;
|
|
29
|
-
parallel?: boolean;
|
|
30
|
-
concurrency?: number;
|
|
27
|
+
/** A `repos.toml` to use instead of the one `repos` finds walking up from the cwd. */
|
|
28
|
+
registry?: string;
|
|
31
29
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* sit on disk — the safe default for read-only diagnostics. Defaults to `true`.
|
|
30
|
+
* The package whose generated data the run writes; when it's public, a
|
|
31
|
+
* private repo in the config fails the resolve.
|
|
35
32
|
*/
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
host?: {
|
|
34
|
+
name: string;
|
|
35
|
+
private: boolean;
|
|
36
|
+
};
|
|
37
|
+
log?: Logger;
|
|
38
|
+
repos_ops?: ReposOperations;
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* 1. Loads and normalizes config from `gitops.config.ts`
|
|
45
|
-
* 2. Resolves local repo paths (creates missing with `--download`)
|
|
46
|
-
* 3. If `sync`, switches branches and pulls latest changes (in parallel by default)
|
|
47
|
-
* 4. If `sync`, auto-installs deps if `package.json` changed during pull
|
|
41
|
+
* Resolves the gitops config's repos through `repos status`: loads the
|
|
42
|
+
* config's registry keys, reports on them, and resolves each to its checkout,
|
|
43
|
+
* in config order. Reads nothing but git state and writes nothing.
|
|
48
44
|
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* install, or clean-workspace check.
|
|
52
|
-
*
|
|
53
|
-
* Priority for path resolution:
|
|
54
|
-
* - `dir` argument (explicit override)
|
|
55
|
-
* - Config `repos_dir` setting
|
|
56
|
-
* - `DEFAULT_REPOS_DIR` constant
|
|
57
|
-
*
|
|
58
|
-
* @param options.git_ops - for testing (defaults to real git operations)
|
|
59
|
-
* @param options.npm_ops - for testing (defaults to real npm operations)
|
|
60
|
-
* @param options.parallel - whether to load repos in parallel (default: true)
|
|
61
|
-
* @param options.concurrency - max concurrent repo loads (default: 5)
|
|
62
|
-
* @param options.sync - sync working trees before loading (default: true)
|
|
63
|
-
* @param options.allow_dirty - when syncing, tolerate uncommitted changes (default: false)
|
|
64
|
-
* @returns initialized config and fully loaded repos ready for operations
|
|
65
|
-
* @throws {TaskError} if config loading or repo resolution fails
|
|
45
|
+
* @returns the config, the `repos status` report, and each repo's path and entry
|
|
46
|
+
* @throws {TaskError} if the config is missing, invalid, or lists no repos, `repos status` fails, or any configured repo is unknown, a reference, missing, not a repo, unprobed, or private under a public `host`
|
|
66
47
|
*/
|
|
67
|
-
export declare const
|
|
48
|
+
export declare const resolve_gitops_repos: (options: ResolveGitopsReposOptions) => Promise<{
|
|
68
49
|
config_path: string;
|
|
69
|
-
repos_dir: string;
|
|
70
50
|
gitops_config: GitopsConfig;
|
|
51
|
+
report: ReposStatusReport;
|
|
52
|
+
local_repo_paths: Array<LocalRepoPath>;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Central initialization function for the gitops tasks that load libraries:
|
|
56
|
+
* resolves the config's repos through `repos status` (`resolve_gitops_repos`),
|
|
57
|
+
* then loads each repo's library as its working tree sits (`local_repos_load`).
|
|
58
|
+
* Moves no ref; gro caches each library at `.gro/library.json` in its repo, at
|
|
59
|
+
* a clean commit.
|
|
60
|
+
*
|
|
61
|
+
* @returns the loaded repos, in config order
|
|
62
|
+
* @throws {TaskError} if resolving the repos or loading them fails
|
|
63
|
+
*/
|
|
64
|
+
export declare const get_gitops_ready: (options: ResolveGitopsReposOptions) => Promise<{
|
|
71
65
|
local_repos: Array<LocalRepo>;
|
|
72
66
|
}>;
|
|
73
|
-
export interface
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
export interface GatePublishReadinessOptions {
|
|
68
|
+
/** The loaded repos; the npm ones are gated. */
|
|
69
|
+
local_repos: ReadonlyArray<LocalRepo>;
|
|
70
|
+
/** A `repos.toml` to use instead of the one `repos` finds walking up from the cwd. */
|
|
71
|
+
registry?: string;
|
|
72
|
+
/**
|
|
73
|
+
* The package names the plan publishes, to say whether a repo's commits ahead
|
|
74
|
+
* of origin go out with its release or stay unpushed.
|
|
75
|
+
*/
|
|
76
|
+
publishing?: ReadonlySet<string>;
|
|
77
|
+
log?: Logger;
|
|
78
|
+
repos_ops?: ReposOperations;
|
|
77
79
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
/**
|
|
81
|
+
* The readiness gate `gitops_publish --wetrun` runs before its confirmation
|
|
82
|
+
* prompt: fetches every npm repo from origin (`repos status <keys…> --fetch
|
|
83
|
+
* --json`, which writes remote-tracking refs and nothing else) and refuses
|
|
84
|
+
* unless each is ready (`check_publish_readiness`) — on its registry branch,
|
|
85
|
+
* clean, idle, in sync with origin or ahead of it, fetched without error, no
|
|
86
|
+
* other live session in its checkout, and nothing left to a person. Each
|
|
87
|
+
* ready repo ahead of origin is logged, saying whether its release push
|
|
88
|
+
* carries those commits or they stay unpushed.
|
|
89
|
+
*
|
|
90
|
+
* Every npm repo, not just those the plan publishes or rewrites: the plan
|
|
91
|
+
* reads each one's working tree (changesets, versions, dependency ranges), so
|
|
92
|
+
* a repo off its branch or behind origin can hide a changeset and leave the
|
|
93
|
+
* plan wrong about what to publish. Changes nothing.
|
|
94
|
+
*
|
|
95
|
+
* @param options - the loaded repos, the `--registry` if any, the package names the plan publishes, a logger, and the `repos` runner
|
|
96
|
+
* @throws {TaskError} if `repos status` fails or any npm repo isn't ready, naming each problem and its fix
|
|
97
|
+
*/
|
|
98
|
+
export declare const gate_publish_readiness: (options: GatePublishReadinessOptions) => Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Logs the diagnostics' readiness block as warnings (stderr, so a `--format
|
|
101
|
+
* json` or `markdown` document on stdout stays clean): each npm repo not at
|
|
102
|
+
* rest, and how. Logs nothing when every one is at rest. Reads the entries
|
|
103
|
+
* `repos status` already reported, from local refs.
|
|
104
|
+
*
|
|
105
|
+
* @param local_repos - the loaded repos; the npm ones are reported
|
|
106
|
+
* @param log - where the warnings go
|
|
107
|
+
* @param now - the current time in unix seconds (defaults to the clock)
|
|
108
|
+
*/
|
|
109
|
+
export declare const log_readiness_block: (local_repos: ReadonlyArray<LocalRepo>, log: Logger, now?: number) => void;
|
|
83
110
|
//# sourceMappingURL=gitops_task_helpers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gitops_task_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/gitops_task_helpers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"gitops_task_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../src/lib/gitops_task_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGtD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAIN,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGvD,MAAM,WAAW,yBAAyB;IACzC,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAChC,SAAS,yBAAyB,KAChC,OAAO,CAAC;IACV,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,YAAY,CAAC;IAC5B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;CACvC,CA0BA,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,gBAAgB,GAC5B,SAAS,yBAAyB,KAChC,OAAO,CAAC;IAAE,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;CAAE,CAI3C,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC3C,gDAAgD;IAChD,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACtC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,sBAAsB,GAClC,SAAS,2BAA2B,KAClC,OAAO,CAAC,IAAI,CAuBd,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,aAAa,aAAa,CAAC,SAAS,CAAC,EACrC,KAAK,MAAM,EACX,MAAK,MAAsC,KACzC,IAKF,CAAC"}
|