@fuzdev/fuz_gitops 0.78.1 â 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 +78 -24
- package/dist/ModulesDetail.svelte +15 -22
- package/dist/ModulesDetail.svelte.d.ts.map +1 -1
- package/dist/ModulesNav.svelte +4 -1
- package/dist/ModulesPage.svelte +1 -3
- package/dist/ModulesPage.svelte.d.ts.map +1 -1
- package/dist/PageHeader.svelte +2 -2
- package/dist/PageHeader.svelte.d.ts +0 -3
- package/dist/PageHeader.svelte.d.ts.map +1 -1
- package/dist/PullRequestsDetail.svelte +10 -9
- package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
- package/dist/PullRequestsPage.svelte +1 -3
- package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
- package/dist/ReposTable.svelte +27 -48
- package/dist/ReposTable.svelte.d.ts.map +1 -1
- package/dist/ReposTree.svelte +5 -19
- package/dist/ReposTree.svelte.d.ts.map +1 -1
- package/dist/ReposTreeNav.svelte +5 -7
- package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
- package/dist/TablePage.svelte +1 -3
- package/dist/TablePage.svelte.d.ts.map +1 -1
- package/dist/TreeItemPage.svelte +1 -3
- package/dist/TreeItemPage.svelte.d.ts.map +1 -1
- package/dist/TreePage.svelte +1 -3
- package/dist/TreePage.svelte.d.ts.map +1 -1
- 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 +37 -80
- package/dist/dependency_updater.d.ts +1 -1
- package/dist/dependency_updater.d.ts.map +1 -1
- package/dist/dependency_updater.js +6 -1
- 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.js +1 -1
- 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 +15 -6
- 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 +43 -30
- 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 +80 -58
- 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 +187 -102
- 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 +174 -160
- 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 +154 -30
- 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 +15 -22
- package/dist/graph_validation.d.ts +16 -27
- package/dist/graph_validation.d.ts.map +1 -1
- package/dist/graph_validation.js +23 -64
- package/dist/local_repo.d.ts +50 -62
- package/dist/local_repo.d.ts.map +1 -1
- package/dist/local_repo.js +80 -193
- 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 +115 -51
- package/dist/npm_registry.d.ts +23 -19
- package/dist/npm_registry.d.ts.map +1 -1
- package/dist/npm_registry.js +20 -47
- 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 +104 -121
- 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_steps.d.ts +2 -4
- package/dist/publish_steps.d.ts.map +1 -1
- package/dist/publish_steps.js +2 -6
- package/dist/publishing_event.d.ts +2 -8
- package/dist/publishing_event.d.ts.map +1 -1
- package/dist/publishing_event.js +5 -4
- 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 +14 -12
- package/dist/publishing_plan.d.ts +16 -1
- package/dist/publishing_plan.d.ts.map +1 -1
- package/dist/publishing_plan.js +328 -250
- 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 +21 -14
- 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/package.json +7 -27
- package/src/lib/ci_reconcile.ts +7 -11
- package/src/lib/dependency_graph.ts +45 -97
- package/src/lib/dependency_updater.ts +7 -1
- package/src/lib/fetch_repo_data.ts +66 -29
- package/src/lib/fs_fetch_value_cache.ts +1 -1
- package/src/lib/git_operations.ts +15 -187
- package/src/lib/github.ts +20 -8
- package/src/lib/github_helpers.ts +5 -12
- package/src/lib/gitops_analyze.task.ts +79 -41
- package/src/lib/gitops_config.ts +88 -137
- package/src/lib/gitops_constants.ts +6 -4
- package/src/lib/gitops_plan.task.ts +113 -61
- package/src/lib/gitops_publish.task.ts +255 -122
- package/src/lib/gitops_run.task.ts +250 -178
- package/src/lib/gitops_sync.task.ts +208 -33
- package/src/lib/gitops_task_helpers.ts +166 -110
- package/src/lib/gitops_validate.task.ts +17 -27
- package/src/lib/graph_validation.ts +25 -86
- package/src/lib/local_repo.ts +109 -316
- package/src/lib/log_helpers.ts +8 -18
- package/src/lib/multi_repo_publisher.ts +138 -53
- package/src/lib/npm_registry.ts +37 -62
- package/src/lib/operations.ts +78 -150
- package/src/lib/operations_defaults.ts +108 -154
- package/src/lib/output_helpers.ts +55 -3
- package/src/lib/preflight_checks.ts +47 -183
- package/src/lib/publish_steps.ts +15 -13
- package/src/lib/publishing_event.ts +5 -4
- package/src/lib/publishing_event_handler.ts +18 -16
- package/src/lib/publishing_plan.ts +451 -287
- package/src/lib/publishing_plan_logging.ts +32 -23
- package/src/lib/repo.svelte.ts +8 -0
- 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/dist/config_reconcile.d.ts +0 -46
- package/dist/config_reconcile.d.ts.map +0 -1
- package/dist/config_reconcile.js +0 -64
- 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 -98
- package/src/lib/paths.ts +0 -6
- package/src/lib/repo_ops.ts +0 -216
- package/src/lib/resolved_gitops_config.ts +0 -27
|
@@ -2,13 +2,11 @@ import type { Task } from '@fuzdev/gro';
|
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { styleText as st } from 'node:util';
|
|
4
4
|
|
|
5
|
-
import { get_gitops_ready } from './gitops_task_helpers.ts';
|
|
6
|
-
import { analyze_repos
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
type PublishingPlan
|
|
11
|
-
} from './publishing_plan.ts';
|
|
5
|
+
import { get_gitops_ready, log_readiness_block } from './gitops_task_helpers.ts';
|
|
6
|
+
import { analyze_repos } from './graph_validation.ts';
|
|
7
|
+
import type { DependencyAnalysis } from './dependency_graph.ts';
|
|
8
|
+
import { generate_publishing_plan, type PublishingPlan } from './publishing_plan.ts';
|
|
9
|
+
import { log_publishing_plan } from './publishing_plan_logging.ts';
|
|
12
10
|
import { execute_publishing_plan, type PublishingOptions } from './multi_repo_publisher.ts';
|
|
13
11
|
import { log_dependency_analysis } from './log_helpers.ts';
|
|
14
12
|
import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.ts';
|
|
@@ -20,18 +18,14 @@ export const Args = z.strictObject({
|
|
|
20
18
|
.string()
|
|
21
19
|
.meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
|
|
22
20
|
.default(GITOPS_CONFIG_PATH_DEFAULT),
|
|
23
|
-
|
|
21
|
+
registry: z
|
|
24
22
|
.string()
|
|
25
|
-
.meta({ description: 'path containing the repos, defaults to the parent of the config dir' })
|
|
26
|
-
.optional(),
|
|
27
|
-
verbose: z.boolean().meta({ description: 'show additional details' }).default(false),
|
|
28
|
-
sync: z
|
|
29
|
-
.boolean()
|
|
30
23
|
.meta({
|
|
31
24
|
description:
|
|
32
|
-
'
|
|
25
|
+
'path to the repos.toml registry, when `repos` would not find it walking up from the cwd'
|
|
33
26
|
})
|
|
34
|
-
.
|
|
27
|
+
.optional(),
|
|
28
|
+
verbose: z.boolean().meta({ description: 'show additional details' }).default(false)
|
|
35
29
|
});
|
|
36
30
|
export type Args = z.infer<typeof Args>;
|
|
37
31
|
|
|
@@ -41,7 +35,7 @@ export const task: Task<Args> = {
|
|
|
41
35
|
summary:
|
|
42
36
|
'validate gitops configuration by running all read-only commands and checking for issues',
|
|
43
37
|
run: async ({ args, log }) => {
|
|
44
|
-
const { config,
|
|
38
|
+
const { config, registry, verbose } = args;
|
|
45
39
|
|
|
46
40
|
log.info(st('cyan', 'Running Gitops Validation Suite'));
|
|
47
41
|
log.info(st('dim', 'This runs all read-only commands and checks for consistency.'));
|
|
@@ -59,10 +53,11 @@ export const task: Task<Args> = {
|
|
|
59
53
|
|
|
60
54
|
const start_time = Date.now();
|
|
61
55
|
|
|
62
|
-
// Load repos once (shared by all commands)
|
|
56
|
+
// Load repos once (shared by all commands), as they sit, and say which aren't at rest
|
|
63
57
|
log.info(st('dim', 'Loading repositories...'));
|
|
64
|
-
const { local_repos } = await get_gitops_ready({ config,
|
|
58
|
+
const { local_repos } = await get_gitops_ready({ config, registry, log });
|
|
65
59
|
log.info(st('dim', ` Found ${local_repos.length} local repos`));
|
|
60
|
+
log_readiness_block(local_repos, log);
|
|
66
61
|
|
|
67
62
|
// 1. Run gitops_analyze
|
|
68
63
|
log.info(st('yellow', 'Running gitops_analyze...'));
|
|
@@ -203,21 +198,16 @@ export const task: Task<Args> = {
|
|
|
203
198
|
log.error(st('red', ` â gitops_publish (dry run) failed: ${error}`));
|
|
204
199
|
}
|
|
205
200
|
|
|
206
|
-
// 4. Reconcile each repo's declared `ci` against actual workflow files on disk.
|
|
201
|
+
// 4. Reconcile each repo's registry-declared `ci` against actual workflow files on disk.
|
|
207
202
|
log.info(st('yellow', 'Running ci_reconcile...'));
|
|
208
203
|
const ci_start = Date.now();
|
|
209
204
|
try {
|
|
210
205
|
const ci_drift = reconcile_ci(
|
|
211
206
|
local_repos.map((r) => ({
|
|
212
|
-
repo_url: r.
|
|
213
|
-
ci: r.
|
|
207
|
+
repo_url: r.entry.url,
|
|
208
|
+
ci: r.entry.ci,
|
|
214
209
|
has_workflows: repo_has_workflows(r.repo_dir),
|
|
215
|
-
|
|
216
|
-
// throws in `local_repos_ensure` before we reach here â so `checkable` is
|
|
217
|
-
// always `true` today. The gate exists for a future caller that loads a
|
|
218
|
-
// partial set; until then the skip path is inert and untested.
|
|
219
|
-
checkable: true,
|
|
220
|
-
archived: r.repo_config.archived
|
|
210
|
+
archived: r.entry.archived
|
|
221
211
|
}))
|
|
222
212
|
);
|
|
223
213
|
const ci_duration = Date.now() - ci_start;
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Dependency graph validation shared by the publishing plan and the analysis tasks.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Builds the graph, detects cycles by type, and computes the publishing order,
|
|
5
|
+
* reporting cycles and sort failures in the result rather than throwing, so
|
|
6
|
+
* each caller decides how to surface them: the plan turns them into errors,
|
|
7
|
+
* `gitops_analyze` and `gitops_validate` format them.
|
|
7
8
|
*
|
|
8
|
-
*
|
|
9
|
-
* reporting, while publish must throw on production cycles.
|
|
10
|
-
*
|
|
11
|
-
* See also: `dependency_graph.ts` for core graph data structure and algorithms.
|
|
9
|
+
* See also: `dependency_graph.ts` for the core graph data structure and algorithms.
|
|
12
10
|
*
|
|
13
11
|
* @module
|
|
14
12
|
*/
|
|
15
13
|
|
|
16
|
-
import type
|
|
17
|
-
import { TaskError } from '@fuzdev/gro';
|
|
18
|
-
import { styleText as st } from 'node:util';
|
|
19
|
-
|
|
20
|
-
import { DependencyGraph, DependencyGraphBuilder } from './dependency_graph.ts';
|
|
14
|
+
import { DependencyGraph, type DependencyAnalysis } from './dependency_graph.ts';
|
|
21
15
|
import { repo_is_npm, type LocalRepo } from './local_repo.ts';
|
|
22
16
|
|
|
23
17
|
export interface GraphValidationResult {
|
|
@@ -25,79 +19,29 @@ export interface GraphValidationResult {
|
|
|
25
19
|
publishing_order: Array<string>;
|
|
26
20
|
production_cycles: Array<Array<string>>;
|
|
27
21
|
dev_cycles: Array<Array<string>>;
|
|
28
|
-
|
|
22
|
+
/** Why the topological sort failed, when it did; `publishing_order` is then empty. */
|
|
23
|
+
sort_error?: string;
|
|
29
24
|
}
|
|
30
25
|
|
|
31
26
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
27
|
+
* Builds the dependency graph, detects cycles, and computes the publishing order
|
|
28
|
+
* (prod/peer dependencies only, so dev cycles don't block it).
|
|
34
29
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @returns
|
|
39
|
-
* @throws {TaskError} if production cycles detected and `throw_on_prod_cycles` is true
|
|
30
|
+
* Never throws on cycles: a production/peer cycle leaves `publishing_order` empty
|
|
31
|
+
* and sets `sort_error`, and the caller reports it.
|
|
32
|
+
*
|
|
33
|
+
* @returns the graph, publishing order, and detected cycles
|
|
40
34
|
*/
|
|
41
|
-
export const validate_dependency_graph = (
|
|
42
|
-
repos
|
|
43
|
-
options: {
|
|
44
|
-
log?: Logger;
|
|
45
|
-
throw_on_prod_cycles?: boolean;
|
|
46
|
-
log_cycles?: boolean;
|
|
47
|
-
log_order?: boolean;
|
|
48
|
-
} = {}
|
|
49
|
-
): GraphValidationResult => {
|
|
50
|
-
const { log, throw_on_prod_cycles = true, log_cycles = true, log_order = true } = options;
|
|
51
|
-
|
|
52
|
-
// Build dependency graph
|
|
53
|
-
log?.info('đ Analyzing dependencies...');
|
|
54
|
-
const builder = new DependencyGraphBuilder();
|
|
55
|
-
const graph = builder.build_from_repos(repos);
|
|
56
|
-
|
|
57
|
-
// Check for cycles
|
|
35
|
+
export const validate_dependency_graph = (repos: Array<LocalRepo>): GraphValidationResult => {
|
|
36
|
+
const graph = new DependencyGraph(repos);
|
|
58
37
|
const { production_cycles, dev_cycles } = graph.detect_cycles_by_type();
|
|
59
38
|
|
|
60
|
-
// Log production cycles
|
|
61
|
-
if (production_cycles.length > 0 && log_cycles) {
|
|
62
|
-
log?.error(st('red', 'â Production/peer dependency cycles detected:'));
|
|
63
|
-
for (const cycle of production_cycles) {
|
|
64
|
-
log?.error(` ${cycle.join(' â ')}`);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (throw_on_prod_cycles) {
|
|
68
|
-
throw new TaskError(
|
|
69
|
-
`Cannot publish with production/peer dependency cycles. ` +
|
|
70
|
-
`These must be resolved before publishing.`
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Log dev cycles (informational, not an error)
|
|
76
|
-
if (dev_cycles.length > 0 && log_cycles) {
|
|
77
|
-
log?.info(st('dim', 'âšī¸ Dev dependency cycles detected (this is normal):'));
|
|
78
|
-
for (const cycle of dev_cycles) {
|
|
79
|
-
log?.info(st('dim', ` ${cycle.join(' â ')}`));
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Compute publishing order
|
|
84
39
|
let publishing_order: Array<string>;
|
|
85
40
|
let sort_error: string | undefined;
|
|
86
41
|
try {
|
|
87
42
|
publishing_order = graph.topological_sort(true); // exclude dev deps to break cycles
|
|
88
|
-
if (log_order && publishing_order.length > 0) {
|
|
89
|
-
log?.info(` Publishing order: ${publishing_order.join(' â ')}`);
|
|
90
|
-
}
|
|
91
43
|
} catch (error) {
|
|
92
|
-
// Capture the sort error message for callers to report
|
|
93
44
|
sort_error = 'Failed to compute publishing order: ' + error;
|
|
94
|
-
|
|
95
|
-
// If topological sort fails (due to cycles), return empty array
|
|
96
|
-
// Only throw if production cycles exist AND throw_on_prod_cycles is true
|
|
97
|
-
if (production_cycles.length > 0 && throw_on_prod_cycles) {
|
|
98
|
-
throw new TaskError(sort_error);
|
|
99
|
-
}
|
|
100
|
-
// Otherwise, return empty publishing order (let caller handle it)
|
|
101
45
|
publishing_order = [];
|
|
102
46
|
}
|
|
103
47
|
|
|
@@ -110,9 +54,6 @@ export const validate_dependency_graph = (
|
|
|
110
54
|
};
|
|
111
55
|
};
|
|
112
56
|
|
|
113
|
-
/** Cycles, wildcard deps, and missing peers produced by `DependencyGraphBuilder.analyze`. */
|
|
114
|
-
export type DependencyAnalysis = ReturnType<DependencyGraphBuilder['analyze']>;
|
|
115
|
-
|
|
116
57
|
export interface RepoAnalysis {
|
|
117
58
|
graph: DependencyGraph;
|
|
118
59
|
analysis: DependencyAnalysis;
|
|
@@ -123,16 +64,14 @@ export interface RepoAnalysis {
|
|
|
123
64
|
/**
|
|
124
65
|
* Builds the dependency graph and runs cycle/wildcard analysis, tolerating cycles
|
|
125
66
|
* (reports rather than throws). The shared core of `gitops_analyze` and
|
|
126
|
-
* `gitops_validate`, which format the result themselves
|
|
127
|
-
* (no `log`) to avoid emitting a redundant "Analyzing dependencies" line.
|
|
67
|
+
* `gitops_validate`, which format the result themselves.
|
|
128
68
|
*/
|
|
129
69
|
export const analyze_repos = (repos: Array<LocalRepo>): RepoAnalysis => {
|
|
130
|
-
//
|
|
131
|
-
const { graph, publishing_order
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
return { graph, analysis, publishing_order: order.length > 0 ? order : null };
|
|
70
|
+
// only npm packages form the dependency graph; non-npm repos (e.g. cargo) are excluded
|
|
71
|
+
const { graph, publishing_order } = validate_dependency_graph(repos.filter(repo_is_npm));
|
|
72
|
+
return {
|
|
73
|
+
graph,
|
|
74
|
+
analysis: graph.analyze(),
|
|
75
|
+
publishing_order: publishing_order.length > 0 ? publishing_order : null
|
|
76
|
+
};
|
|
138
77
|
};
|