@fuzdev/fuz_gitops 0.78.0 → 0.78.1
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 +20 -0
- package/dist/ModulesDetail.svelte +14 -12
- package/dist/ModulesDetail.svelte.d.ts.map +1 -1
- package/dist/ModulesNav.svelte +6 -6
- package/dist/ModulesNav.svelte.d.ts.map +1 -1
- package/dist/ModulesPage.svelte +2 -2
- package/dist/ModulesPage.svelte.d.ts.map +1 -1
- package/dist/PageFooter.svelte +2 -2
- package/dist/PageHeader.svelte +5 -5
- package/dist/PageHeader.svelte.d.ts.map +1 -1
- package/dist/PullRequestsDetail.svelte +25 -17
- package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
- package/dist/PullRequestsPage.svelte +3 -3
- package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
- package/dist/ReposTable.svelte +24 -15
- package/dist/ReposTable.svelte.d.ts.map +1 -1
- package/dist/ReposTree.svelte +8 -6
- package/dist/ReposTree.svelte.d.ts.map +1 -1
- package/dist/ReposTreeNav.svelte +10 -11
- package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
- package/dist/TablePage.svelte +2 -2
- package/dist/TablePage.svelte.d.ts.map +1 -1
- package/dist/TreeItemPage.svelte +2 -2
- package/dist/TreeItemPage.svelte.d.ts.map +1 -1
- package/dist/TreePage.svelte +2 -2
- 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/config_reconcile.d.ts.map +1 -1
- package/dist/config_reconcile.js +6 -2
- package/dist/dependency_graph.d.ts.map +1 -1
- package/dist/dependency_graph.js +5 -5
- package/dist/dependency_updater.d.ts.map +1 -1
- package/dist/dependency_updater.js +8 -8
- package/dist/fetch_repo_data.d.ts.map +1 -1
- package/dist/fetch_repo_data.js +3 -3
- package/dist/fs_fetch_value_cache.d.ts.map +1 -1
- package/dist/fs_fetch_value_cache.js +2 -2
- package/dist/git_operations.d.ts.map +1 -1
- package/dist/git_operations.js +1 -1
- package/dist/github.d.ts.map +1 -1
- package/dist/github.js +6 -6
- package/dist/github_helpers.d.ts.map +1 -1
- package/dist/gitops_analyze.task.d.ts.map +1 -1
- package/dist/gitops_analyze.task.js +7 -7
- package/dist/gitops_config.d.ts.map +1 -1
- package/dist/gitops_config.js +4 -4
- package/dist/gitops_plan.task.d.ts.map +1 -1
- package/dist/gitops_plan.task.js +8 -8
- package/dist/gitops_publish.task.d.ts.map +1 -1
- package/dist/gitops_publish.task.js +15 -12
- package/dist/gitops_run.task.d.ts.map +1 -1
- package/dist/gitops_run.task.js +8 -8
- package/dist/gitops_sync.task.d.ts.map +1 -1
- package/dist/gitops_sync.task.js +11 -9
- package/dist/gitops_task_helpers.d.ts.map +1 -1
- package/dist/gitops_task_helpers.js +3 -3
- package/dist/gitops_validate.task.d.ts.map +1 -1
- package/dist/gitops_validate.task.js +14 -14
- package/dist/graph_validation.d.ts.map +1 -1
- package/dist/graph_validation.js +2 -2
- package/dist/local_repo.d.ts +4 -4
- package/dist/local_repo.d.ts.map +1 -1
- package/dist/local_repo.js +13 -13
- package/dist/log_helpers.d.ts.map +1 -1
- package/dist/multi_repo_publisher.d.ts.map +1 -1
- package/dist/multi_repo_publisher.js +19 -19
- package/dist/npm_registry.d.ts.map +1 -1
- package/dist/npm_registry.js +2 -2
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations_defaults.d.ts.map +1 -1
- package/dist/operations_defaults.js +12 -12
- package/dist/output_helpers.d.ts.map +1 -1
- package/dist/preflight_checks.d.ts +1 -1
- package/dist/preflight_checks.d.ts.map +1 -1
- package/dist/preflight_checks.js +4 -4
- package/dist/publish_gate.d.ts.map +1 -1
- package/dist/publish_steps.d.ts.map +1 -1
- package/dist/publish_steps.js +3 -3
- package/dist/publishing_event.d.ts.map +1 -1
- package/dist/publishing_event.js +16 -14
- package/dist/publishing_event_handler.d.ts.map +1 -1
- package/dist/publishing_event_handler.js +6 -6
- package/dist/publishing_plan.d.ts.map +1 -1
- package/dist/publishing_plan.js +14 -14
- 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.map +1 -1
- package/dist/publishing_plan_logging.js +2 -2
- package/dist/repo.svelte.d.ts.map +1 -1
- package/dist/repo_ops.js +2 -2
- package/dist/resolved_gitops_config.d.ts.map +1 -1
- package/dist/resolved_gitops_config.js +1 -1
- package/dist/version_utils.js +1 -1
- package/package.json +16 -15
- 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 +5 -5
- package/src/lib/config_reconcile.ts +8 -4
- package/src/lib/dependency_graph.ts +26 -26
- package/src/lib/dependency_updater.ts +29 -29
- package/src/lib/fetch_repo_data.ts +11 -11
- package/src/lib/fs_fetch_value_cache.ts +14 -10
- package/src/lib/git_operations.ts +30 -30
- package/src/lib/github.ts +19 -19
- package/src/lib/github_helpers.ts +6 -6
- package/src/lib/gitops_analyze.task.ts +40 -40
- package/src/lib/gitops_config.ts +14 -14
- package/src/lib/gitops_plan.task.ts +31 -31
- package/src/lib/gitops_publish.task.ts +51 -48
- package/src/lib/gitops_run.task.ts +29 -29
- package/src/lib/gitops_sync.task.ts +39 -30
- package/src/lib/gitops_task_helpers.ts +21 -21
- package/src/lib/gitops_validate.task.ts +37 -37
- package/src/lib/graph_validation.ts +13 -13
- package/src/lib/local_repo.ts +70 -70
- package/src/lib/log_helpers.ts +15 -15
- package/src/lib/multi_repo_publisher.ts +67 -70
- package/src/lib/npm_registry.ts +13 -13
- package/src/lib/operations.ts +49 -38
- package/src/lib/operations_defaults.ts +106 -104
- package/src/lib/output_helpers.ts +4 -4
- package/src/lib/preflight_checks.ts +26 -26
- package/src/lib/publish_gate.ts +7 -9
- package/src/lib/publish_steps.ts +15 -15
- package/src/lib/publishing_event.ts +22 -20
- package/src/lib/publishing_event_handler.ts +8 -8
- package/src/lib/publishing_plan.ts +55 -55
- package/src/lib/publishing_plan_helpers.ts +16 -12
- package/src/lib/publishing_plan_logging.ts +22 -22
- package/src/lib/repo.svelte.ts +8 -8
- package/src/lib/repo_ops.ts +12 -12
- package/src/lib/resolved_gitops_config.ts +5 -5
- package/src/lib/version_utils.ts +3 -3
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
import type {Task} from '@fuzdev/gro';
|
|
2
|
-
import {z} from 'zod';
|
|
3
|
-
import {styleText as st} from 'node:util';
|
|
4
|
-
import type {Logger} from '@fuzdev/fuz_util/log.ts';
|
|
1
|
+
import type { Task } from '@fuzdev/gro';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { styleText as st } from 'node:util';
|
|
4
|
+
import type { Logger } from '@fuzdev/fuz_util/log.ts';
|
|
5
5
|
|
|
6
|
-
import {get_gitops_ready} from './gitops_task_helpers.ts';
|
|
7
|
-
import type {DependencyGraph} from './dependency_graph.ts';
|
|
8
|
-
import {repo_is_npm} from './local_repo.ts';
|
|
9
|
-
import {analyze_repos, type DependencyAnalysis} from './graph_validation.ts';
|
|
6
|
+
import { get_gitops_ready } from './gitops_task_helpers.ts';
|
|
7
|
+
import type { DependencyGraph } from './dependency_graph.ts';
|
|
8
|
+
import { repo_is_npm } from './local_repo.ts';
|
|
9
|
+
import { analyze_repos, type DependencyAnalysis } from './graph_validation.ts';
|
|
10
10
|
import {
|
|
11
11
|
format_wildcard_dependencies,
|
|
12
12
|
format_dev_cycles,
|
|
13
|
-
format_production_cycles
|
|
13
|
+
format_production_cycles
|
|
14
14
|
} from './log_helpers.ts';
|
|
15
|
-
import {format_and_output, type OutputFormatters} from './output_helpers.ts';
|
|
16
|
-
import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
|
|
15
|
+
import { format_and_output, type OutputFormatters } from './output_helpers.ts';
|
|
16
|
+
import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.ts';
|
|
17
17
|
|
|
18
18
|
/** @nodocs */
|
|
19
19
|
export const Args = z.strictObject({
|
|
20
20
|
config: z
|
|
21
21
|
.string()
|
|
22
|
-
.meta({description: 'path to the gitops config file, absolute or relative to the cwd'})
|
|
22
|
+
.meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
|
|
23
23
|
.default(GITOPS_CONFIG_PATH_DEFAULT),
|
|
24
24
|
dir: z
|
|
25
25
|
.string()
|
|
26
|
-
.meta({description: 'path containing the repos, defaults to the parent of the config dir'})
|
|
26
|
+
.meta({ description: 'path containing the repos, defaults to the parent of the config dir' })
|
|
27
27
|
.optional(),
|
|
28
28
|
format: z
|
|
29
29
|
.enum(['stdout', 'json', 'markdown'])
|
|
30
|
-
.meta({description: 'output format'})
|
|
30
|
+
.meta({ description: 'output format' })
|
|
31
31
|
.default('stdout'),
|
|
32
|
-
outfile: z.string().meta({description: 'write output to file instead of logging'}).optional(),
|
|
32
|
+
outfile: z.string().meta({ description: 'write output to file instead of logging' }).optional(),
|
|
33
33
|
sync: z
|
|
34
34
|
.boolean()
|
|
35
35
|
.meta({
|
|
36
36
|
description:
|
|
37
|
-
'sync repos (switch branch, pull, install) before analyzing instead of reading the working tree as-is'
|
|
37
|
+
'sync repos (switch branch, pull, install) before analyzing instead of reading the working tree as-is'
|
|
38
38
|
})
|
|
39
|
-
.default(false)
|
|
39
|
+
.default(false)
|
|
40
40
|
});
|
|
41
41
|
export type Args = z.infer<typeof Args>;
|
|
42
42
|
|
|
@@ -44,11 +44,11 @@ export type Args = z.infer<typeof Args>;
|
|
|
44
44
|
export const task: Task<Args> = {
|
|
45
45
|
Args,
|
|
46
46
|
summary: 'analyze dependency structure and relationships across repos',
|
|
47
|
-
run: async ({args, log}) => {
|
|
48
|
-
const {config, dir, format, outfile, sync} = args;
|
|
47
|
+
run: async ({ args, log }) => {
|
|
48
|
+
const { config, dir, format, outfile, sync } = args;
|
|
49
49
|
|
|
50
50
|
// Get repos ready (without downloading); read the working tree as-is unless `--sync`
|
|
51
|
-
const {local_repos} = await get_gitops_ready({config, dir, download: false, sync, log});
|
|
51
|
+
const { local_repos } = await get_gitops_ready({ config, dir, download: false, sync, log });
|
|
52
52
|
|
|
53
53
|
// Only npm packages form the dependency graph; note any non-npm repos (e.g. cargo)
|
|
54
54
|
// that are excluded so the omission isn't silent.
|
|
@@ -58,23 +58,23 @@ export const task: Task<Args> = {
|
|
|
58
58
|
st(
|
|
59
59
|
'dim',
|
|
60
60
|
`excluding ${non_npm_repos.length} non-npm repo(s) from analysis (dashboard-only): ` +
|
|
61
|
-
non_npm_repos.map((r) => r.library.name).join(', ')
|
|
62
|
-
)
|
|
61
|
+
non_npm_repos.map((r) => r.library.name).join(', ')
|
|
62
|
+
)
|
|
63
63
|
);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// Build the dependency graph and analyze cycles/wildcards (tolerating cycles)
|
|
67
|
-
const {graph, analysis, publishing_order} = analyze_repos(local_repos);
|
|
67
|
+
const { graph, analysis, publishing_order } = analyze_repos(local_repos);
|
|
68
68
|
|
|
69
69
|
// Format and output using output_helpers
|
|
70
70
|
const data = {
|
|
71
71
|
graph,
|
|
72
72
|
analysis,
|
|
73
|
-
publishing_order
|
|
73
|
+
publishing_order
|
|
74
74
|
};
|
|
75
75
|
|
|
76
|
-
await format_and_output(data, create_formatters(), {format, outfile, log});
|
|
77
|
-
}
|
|
76
|
+
await format_and_output(data, create_formatters(), { format, outfile, log });
|
|
77
|
+
}
|
|
78
78
|
};
|
|
79
79
|
|
|
80
80
|
// Data type for analysis output
|
|
@@ -88,32 +88,32 @@ interface AnalysisData {
|
|
|
88
88
|
const create_formatters = (): OutputFormatters<AnalysisData> => ({
|
|
89
89
|
json: (data) => format_json(data.graph, data.analysis, data.publishing_order),
|
|
90
90
|
markdown: (data) => format_markdown(data.graph, data.analysis, data.publishing_order),
|
|
91
|
-
stdout: (data, log) => format_stdout(data.graph, data.analysis, data.publishing_order, log)
|
|
91
|
+
stdout: (data, log) => format_stdout(data.graph, data.analysis, data.publishing_order, log)
|
|
92
92
|
});
|
|
93
93
|
|
|
94
94
|
// Helper to calculate common statistics
|
|
95
95
|
const calculate_stats = (graph: DependencyGraph) => {
|
|
96
96
|
const total_deps = Array.from(graph.nodes.values()).reduce(
|
|
97
97
|
(sum, node) => sum + node.dependencies.size,
|
|
98
|
-
0
|
|
98
|
+
0
|
|
99
99
|
);
|
|
100
100
|
const internal_deps = Array.from(graph.nodes.values()).reduce(
|
|
101
101
|
(sum, node) =>
|
|
102
102
|
sum + Array.from(node.dependencies.keys()).filter((name) => graph.nodes.has(name)).length,
|
|
103
|
-
0
|
|
103
|
+
0
|
|
104
104
|
);
|
|
105
|
-
return {total_deps, internal_deps};
|
|
105
|
+
return { total_deps, internal_deps };
|
|
106
106
|
};
|
|
107
107
|
|
|
108
108
|
const format_json = (
|
|
109
109
|
graph: DependencyGraph,
|
|
110
110
|
analysis: DependencyAnalysis,
|
|
111
|
-
publishing_order: Array<string> | null
|
|
111
|
+
publishing_order: Array<string> | null
|
|
112
112
|
): string => {
|
|
113
113
|
const output = {
|
|
114
114
|
graph: graph.toJSON(),
|
|
115
115
|
analysis,
|
|
116
|
-
publishing_order
|
|
116
|
+
publishing_order
|
|
117
117
|
};
|
|
118
118
|
return JSON.stringify(output, null, 2);
|
|
119
119
|
};
|
|
@@ -121,12 +121,12 @@ const format_json = (
|
|
|
121
121
|
const format_markdown = (
|
|
122
122
|
graph: DependencyGraph,
|
|
123
123
|
analysis: DependencyAnalysis,
|
|
124
|
-
publishing_order: Array<string> | null
|
|
124
|
+
publishing_order: Array<string> | null
|
|
125
125
|
): Array<string> => {
|
|
126
126
|
const lines: Array<string> = ['# Dependency Analysis'];
|
|
127
127
|
|
|
128
128
|
// Summary stats
|
|
129
|
-
const {total_deps, internal_deps} = calculate_stats(graph);
|
|
129
|
+
const { total_deps, internal_deps } = calculate_stats(graph);
|
|
130
130
|
|
|
131
131
|
lines.push('', '## Summary', '');
|
|
132
132
|
lines.push(`- **Total packages**: ${graph.nodes.size}`);
|
|
@@ -170,7 +170,7 @@ const format_markdown = (
|
|
|
170
170
|
lines.push('', '## ⚠️ Wildcard Dependencies', '');
|
|
171
171
|
lines.push('| Package | Dependency | Version |');
|
|
172
172
|
lines.push('|---------|------------|---------|');
|
|
173
|
-
for (const {pkg, dep, version} of analysis.wildcard_deps) {
|
|
173
|
+
for (const { pkg, dep, version } of analysis.wildcard_deps) {
|
|
174
174
|
lines.push(`| \`${pkg}\` | \`${dep}\` | \`${version}\` |`);
|
|
175
175
|
}
|
|
176
176
|
}
|
|
@@ -179,7 +179,7 @@ const format_markdown = (
|
|
|
179
179
|
lines.push('', '## Internal Dependencies', '');
|
|
180
180
|
for (const node of graph.nodes.values()) {
|
|
181
181
|
const internal_deps = Array.from(node.dependencies.entries()).filter(([name]) =>
|
|
182
|
-
graph.nodes.has(name)
|
|
182
|
+
graph.nodes.has(name)
|
|
183
183
|
);
|
|
184
184
|
if (internal_deps.length > 0) {
|
|
185
185
|
lines.push(`- **${node.name}**`);
|
|
@@ -197,7 +197,7 @@ const format_stdout = (
|
|
|
197
197
|
graph: DependencyGraph,
|
|
198
198
|
analysis: DependencyAnalysis,
|
|
199
199
|
publishing_order: Array<string> | null,
|
|
200
|
-
log: Logger
|
|
200
|
+
log: Logger
|
|
201
201
|
): void => {
|
|
202
202
|
log.info(st('cyan', `📊 Analyzing ${graph.nodes.size} repositories...`));
|
|
203
203
|
|
|
@@ -216,14 +216,14 @@ const format_stdout = (
|
|
|
216
216
|
log.info(st('yellow', 'Dependency relationships:'));
|
|
217
217
|
for (const node of graph.nodes.values()) {
|
|
218
218
|
const internal_deps = Array.from(node.dependencies.entries()).filter(([name]) =>
|
|
219
|
-
graph.nodes.has(name)
|
|
219
|
+
graph.nodes.has(name)
|
|
220
220
|
);
|
|
221
221
|
if (internal_deps.length > 0) {
|
|
222
222
|
log.info(` ${st('cyan', node.name)}`);
|
|
223
223
|
for (const [dep_name, spec] of internal_deps) {
|
|
224
224
|
const type_color = spec.type === 'peer' ? 'magenta' : spec.type === 'dev' ? 'dim' : 'white';
|
|
225
225
|
log.info(
|
|
226
|
-
` ${st(type_color, '→')} ${dep_name} ${st('dim', `(${spec.type}: ${spec.version})`)}
|
|
226
|
+
` ${st(type_color, '→')} ${dep_name} ${st('dim', `(${spec.type}: ${spec.version})`)}`
|
|
227
227
|
);
|
|
228
228
|
}
|
|
229
229
|
}
|
|
@@ -252,7 +252,7 @@ const format_stdout = (
|
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
// Summary
|
|
255
|
-
const {total_deps, internal_deps} = calculate_stats(graph);
|
|
255
|
+
const { total_deps, internal_deps } = calculate_stats(graph);
|
|
256
256
|
|
|
257
257
|
log.info('');
|
|
258
258
|
log.info(st('cyan', 'Summary:'));
|
package/src/lib/gitops_config.ts
CHANGED
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
* @module
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import type {Url} from '@fuzdev/fuz_util/url.ts';
|
|
15
|
-
import {existsSync} from 'node:fs';
|
|
16
|
-
import {strip_end} from '@fuzdev/fuz_util/string.ts';
|
|
17
|
-
import type {GitBranch} from '@fuzdev/fuz_util/git.ts';
|
|
14
|
+
import type { Url } from '@fuzdev/fuz_util/url.ts';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { strip_end } from '@fuzdev/fuz_util/string.ts';
|
|
17
|
+
import type { GitBranch } from '@fuzdev/fuz_util/git.ts';
|
|
18
18
|
|
|
19
|
-
import {DEFAULT_REPOS_DIR} from './paths.ts';
|
|
19
|
+
import { DEFAULT_REPOS_DIR } from './paths.ts';
|
|
20
20
|
|
|
21
21
|
export interface GitopsConfig {
|
|
22
22
|
repos: Array<GitopsRepoConfig>;
|
|
@@ -24,7 +24,7 @@ export interface GitopsConfig {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
export type CreateGitopsConfig = (
|
|
27
|
-
base_config: GitopsConfig
|
|
27
|
+
base_config: GitopsConfig
|
|
28
28
|
) => RawGitopsConfig | Promise<RawGitopsConfig>;
|
|
29
29
|
|
|
30
30
|
export interface RawGitopsConfig {
|
|
@@ -99,7 +99,7 @@ export interface RawGitopsRepoConfig {
|
|
|
99
99
|
|
|
100
100
|
export const create_empty_gitops_config = (): GitopsConfig => ({
|
|
101
101
|
repos: [],
|
|
102
|
-
repos_dir: DEFAULT_REPOS_DIR
|
|
102
|
+
repos_dir: DEFAULT_REPOS_DIR
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
/**
|
|
@@ -110,11 +110,11 @@ export const normalize_gitops_config = (raw_config: RawGitopsConfig): GitopsConf
|
|
|
110
110
|
const empty_config = create_empty_gitops_config();
|
|
111
111
|
// All of the raw config properties are optional,
|
|
112
112
|
// so fall back to the empty values when `undefined`.
|
|
113
|
-
const {repos, repos_dir} = raw_config;
|
|
113
|
+
const { repos, repos_dir } = raw_config;
|
|
114
114
|
return {
|
|
115
115
|
repos: repos ? repos.map((r) => parse_fuz_repo_config(r)) : empty_config.repos,
|
|
116
116
|
// Default to two dirs up from config if not specified
|
|
117
|
-
repos_dir: repos_dir ?? DEFAULT_REPOS_DIR
|
|
117
|
+
repos_dir: repos_dir ?? DEFAULT_REPOS_DIR
|
|
118
118
|
};
|
|
119
119
|
};
|
|
120
120
|
|
|
@@ -126,7 +126,7 @@ const parse_fuz_repo_config = (r: Url | RawGitopsRepoConfig): GitopsRepoConfig =
|
|
|
126
126
|
branch: 'main' as GitBranch, // TODO @zts use flavored for GitBranch
|
|
127
127
|
visibility: 'public',
|
|
128
128
|
ci: true,
|
|
129
|
-
archived: false
|
|
129
|
+
archived: false
|
|
130
130
|
};
|
|
131
131
|
}
|
|
132
132
|
const visibility = r.visibility ?? 'public';
|
|
@@ -136,7 +136,7 @@ const parse_fuz_repo_config = (r: Url | RawGitopsRepoConfig): GitopsRepoConfig =
|
|
|
136
136
|
branch: r.branch ?? ('main' as GitBranch), // TODO @zts use flavored for GitBranch
|
|
137
137
|
visibility,
|
|
138
138
|
ci: r.ci ?? visibility === 'public',
|
|
139
|
-
archived: r.archived ?? false
|
|
139
|
+
archived: r.archived ?? false
|
|
140
140
|
};
|
|
141
141
|
};
|
|
142
142
|
|
|
@@ -155,20 +155,20 @@ export const load_gitops_config = async (config_path: string): Promise<GitopsCon
|
|
|
155
155
|
return normalize_gitops_config(
|
|
156
156
|
typeof config_module.default === 'function'
|
|
157
157
|
? await config_module.default(create_empty_gitops_config())
|
|
158
|
-
: config_module.default
|
|
158
|
+
: config_module.default
|
|
159
159
|
);
|
|
160
160
|
};
|
|
161
161
|
|
|
162
162
|
export const validate_gitops_config_module: (
|
|
163
163
|
config_module: any,
|
|
164
|
-
config_path: string
|
|
164
|
+
config_path: string
|
|
165
165
|
) => asserts config_module is GitopsConfigModule = (config_module, config_path) => {
|
|
166
166
|
const config = config_module.default;
|
|
167
167
|
if (!config) {
|
|
168
168
|
throw Error(`Invalid Fuz config module at ${config_path}: expected a default export`);
|
|
169
169
|
} else if (!(typeof config === 'function' || typeof config === 'object')) {
|
|
170
170
|
throw Error(
|
|
171
|
-
`Invalid Fuz config module at ${config_path}: the default export must be a function or object
|
|
171
|
+
`Invalid Fuz config module at ${config_path}: the default export must be a function or object`
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
174
|
};
|
|
@@ -1,40 +1,40 @@
|
|
|
1
|
-
import type {Task} from '@fuzdev/gro';
|
|
2
|
-
import {z} from 'zod';
|
|
3
|
-
import {styleText as st} from 'node:util';
|
|
1
|
+
import type { Task } from '@fuzdev/gro';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { styleText as st } from 'node:util';
|
|
4
4
|
|
|
5
|
-
import {get_gitops_ready} from './gitops_task_helpers.ts';
|
|
5
|
+
import { get_gitops_ready } from './gitops_task_helpers.ts';
|
|
6
6
|
import {
|
|
7
7
|
generate_publishing_plan,
|
|
8
8
|
log_publishing_plan,
|
|
9
9
|
type PublishingPlan,
|
|
10
|
-
type LogPlanOptions
|
|
10
|
+
type LogPlanOptions
|
|
11
11
|
} from './publishing_plan.ts';
|
|
12
|
-
import {format_and_output, type OutputFormatters} from './output_helpers.ts';
|
|
13
|
-
import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.ts';
|
|
12
|
+
import { format_and_output, type OutputFormatters } from './output_helpers.ts';
|
|
13
|
+
import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.ts';
|
|
14
14
|
|
|
15
15
|
/** @nodocs */
|
|
16
16
|
export const Args = z.strictObject({
|
|
17
17
|
config: z
|
|
18
18
|
.string()
|
|
19
|
-
.meta({description: 'path to the gitops config file, absolute or relative to the cwd'})
|
|
19
|
+
.meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
|
|
20
20
|
.default(GITOPS_CONFIG_PATH_DEFAULT),
|
|
21
21
|
dir: z
|
|
22
22
|
.string()
|
|
23
|
-
.meta({description: 'path containing the repos, defaults to the parent of the config dir'})
|
|
23
|
+
.meta({ description: 'path containing the repos, defaults to the parent of the config dir' })
|
|
24
24
|
.optional(),
|
|
25
25
|
format: z
|
|
26
26
|
.enum(['stdout', 'json', 'markdown'])
|
|
27
|
-
.meta({description: 'output format'})
|
|
27
|
+
.meta({ description: 'output format' })
|
|
28
28
|
.default('stdout'),
|
|
29
|
-
outfile: z.string().meta({description: 'write output to file instead of logging'}).optional(),
|
|
30
|
-
verbose: z.boolean().meta({description: 'show additional details'}).default(false),
|
|
29
|
+
outfile: z.string().meta({ description: 'write output to file instead of logging' }).optional(),
|
|
30
|
+
verbose: z.boolean().meta({ description: 'show additional details' }).default(false),
|
|
31
31
|
sync: z
|
|
32
32
|
.boolean()
|
|
33
33
|
.meta({
|
|
34
34
|
description:
|
|
35
|
-
'sync repos (switch branch, pull, install) before planning instead of reading the working tree as-is'
|
|
35
|
+
'sync repos (switch branch, pull, install) before planning instead of reading the working tree as-is'
|
|
36
36
|
})
|
|
37
|
-
.default(false)
|
|
37
|
+
.default(false)
|
|
38
38
|
});
|
|
39
39
|
export type Args = z.infer<typeof Args>;
|
|
40
40
|
|
|
@@ -52,18 +52,18 @@ export type Args = z.infer<typeof Args>;
|
|
|
52
52
|
export const task: Task<Args> = {
|
|
53
53
|
summary: 'generate a publishing plan based on changesets',
|
|
54
54
|
Args,
|
|
55
|
-
run: async ({args, log}): Promise<void> => {
|
|
56
|
-
const {dir, config, format, outfile, verbose, sync} = args;
|
|
55
|
+
run: async ({ args, log }): Promise<void> => {
|
|
56
|
+
const { dir, config, format, outfile, verbose, sync } = args;
|
|
57
57
|
|
|
58
58
|
log.info(st('cyan', 'Generating multi-repo publishing plan...'));
|
|
59
59
|
|
|
60
60
|
// Load local repos; read the working tree as-is unless `--sync`
|
|
61
|
-
const {local_repos} = await get_gitops_ready({
|
|
61
|
+
const { local_repos } = await get_gitops_ready({
|
|
62
62
|
config,
|
|
63
63
|
dir,
|
|
64
64
|
download: false, // Don't download if missing
|
|
65
65
|
sync,
|
|
66
|
-
log
|
|
66
|
+
log
|
|
67
67
|
});
|
|
68
68
|
|
|
69
69
|
if (local_repos.length === 0) {
|
|
@@ -74,20 +74,20 @@ export const task: Task<Args> = {
|
|
|
74
74
|
log.info(` Found ${local_repos.length} local repos`);
|
|
75
75
|
|
|
76
76
|
// Generate publishing plan
|
|
77
|
-
const plan = await generate_publishing_plan(local_repos, {log, verbose});
|
|
77
|
+
const plan = await generate_publishing_plan(local_repos, { log, verbose });
|
|
78
78
|
|
|
79
79
|
// Format and output using output_helpers
|
|
80
|
-
await format_and_output(plan, create_plan_formatters({verbose}), {format, outfile, log});
|
|
80
|
+
await format_and_output(plan, create_plan_formatters({ verbose }), { format, outfile, log });
|
|
81
81
|
|
|
82
82
|
// Exit with error if there are blocking issues
|
|
83
83
|
if (plan.errors.length > 0) {
|
|
84
84
|
throw new Error('Publishing plan found errors that would block publishing');
|
|
85
85
|
}
|
|
86
|
-
}
|
|
86
|
+
}
|
|
87
87
|
};
|
|
88
88
|
|
|
89
89
|
const create_plan_formatters = (
|
|
90
|
-
options: LogPlanOptions = {}
|
|
90
|
+
options: LogPlanOptions = {}
|
|
91
91
|
): OutputFormatters<PublishingPlan> => ({
|
|
92
92
|
json: (plan) => {
|
|
93
93
|
const output = {
|
|
@@ -97,12 +97,12 @@ const create_plan_formatters = (
|
|
|
97
97
|
breaking_cascades: Object.fromEntries(plan.breaking_cascades),
|
|
98
98
|
warnings: plan.warnings,
|
|
99
99
|
info: plan.info,
|
|
100
|
-
errors: plan.errors
|
|
100
|
+
errors: plan.errors
|
|
101
101
|
};
|
|
102
102
|
return JSON.stringify(output, null, 2);
|
|
103
103
|
},
|
|
104
104
|
markdown: (plan) => format_plan_as_markdown(plan),
|
|
105
|
-
stdout: (plan, log) => log_publishing_plan(plan, log, options)
|
|
105
|
+
stdout: (plan, log) => log_publishing_plan(plan, log, options)
|
|
106
106
|
});
|
|
107
107
|
|
|
108
108
|
const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
@@ -114,7 +114,7 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
|
114
114
|
breaking_cascades,
|
|
115
115
|
warnings,
|
|
116
116
|
info,
|
|
117
|
-
errors
|
|
117
|
+
errors
|
|
118
118
|
} = plan;
|
|
119
119
|
|
|
120
120
|
lines.push('# Publishing Plan');
|
|
@@ -141,7 +141,7 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
|
141
141
|
// Version changes
|
|
142
142
|
if (version_changes.length > 0) {
|
|
143
143
|
const with_changesets = version_changes.filter(
|
|
144
|
-
(vc) => vc.has_changesets && !vc.needs_bump_escalation
|
|
144
|
+
(vc) => vc.has_changesets && !vc.needs_bump_escalation
|
|
145
145
|
);
|
|
146
146
|
const with_escalation = version_changes.filter((vc) => vc.needs_bump_escalation);
|
|
147
147
|
const with_auto_changesets = version_changes.filter((vc) => vc.will_generate_changeset);
|
|
@@ -154,7 +154,7 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
|
154
154
|
for (const change of with_changesets) {
|
|
155
155
|
const is_major = change.bump_type === 'major' ? '💥 Yes' : 'No';
|
|
156
156
|
lines.push(
|
|
157
|
-
`| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${is_major}
|
|
157
|
+
`| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${is_major} |`
|
|
158
158
|
);
|
|
159
159
|
}
|
|
160
160
|
lines.push('');
|
|
@@ -168,12 +168,12 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
|
168
168
|
for (const change of with_escalation) {
|
|
169
169
|
const is_major = change.bump_type === 'major' ? '💥 Yes' : 'No';
|
|
170
170
|
lines.push(
|
|
171
|
-
`| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.existing_bump} | ${change.required_bump} | ${is_major}
|
|
171
|
+
`| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.existing_bump} | ${change.required_bump} | ${is_major} |`
|
|
172
172
|
);
|
|
173
173
|
}
|
|
174
174
|
lines.push('');
|
|
175
175
|
lines.push(
|
|
176
|
-
'> ⬆️ These packages have changesets, but dependencies require a larger version bump.'
|
|
176
|
+
'> ⬆️ These packages have changesets, but dependencies require a larger version bump.'
|
|
177
177
|
);
|
|
178
178
|
lines.push('');
|
|
179
179
|
}
|
|
@@ -186,7 +186,7 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
|
186
186
|
for (const change of with_auto_changesets) {
|
|
187
187
|
const is_major = change.bump_type === 'major' ? '💥 Yes' : 'No';
|
|
188
188
|
lines.push(
|
|
189
|
-
`| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${is_major}
|
|
189
|
+
`| \`${change.package_name}\` | ${change.from} | ${change.to} | ${change.bump_type} | ${is_major} |`
|
|
190
190
|
);
|
|
191
191
|
}
|
|
192
192
|
lines.push('');
|
|
@@ -234,7 +234,7 @@ const format_plan_as_markdown = (plan: PublishingPlan): Array<string> => {
|
|
|
234
234
|
? 'peer'
|
|
235
235
|
: 'dev';
|
|
236
236
|
lines.push(
|
|
237
|
-
`- "${update.updated_dependency}": "${update.current_version}" # ${type_label}
|
|
237
|
+
`- "${update.updated_dependency}": "${update.current_version}" # ${type_label}`
|
|
238
238
|
);
|
|
239
239
|
lines.push(`+ "${update.updated_dependency}": "${update.new_version}" # ${type_label}`);
|
|
240
240
|
}
|