@fuzdev/fuz_gitops 0.77.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.
Files changed (162) hide show
  1. package/README.md +25 -5
  2. package/dist/ModulesDetail.svelte +14 -12
  3. package/dist/ModulesDetail.svelte.d.ts.map +1 -1
  4. package/dist/ModulesNav.svelte +6 -6
  5. package/dist/ModulesNav.svelte.d.ts.map +1 -1
  6. package/dist/ModulesPage.svelte +2 -2
  7. package/dist/ModulesPage.svelte.d.ts.map +1 -1
  8. package/dist/PageFooter.svelte +2 -2
  9. package/dist/PageHeader.svelte +5 -5
  10. package/dist/PageHeader.svelte.d.ts +1 -1
  11. package/dist/PageHeader.svelte.d.ts.map +1 -1
  12. package/dist/PullRequestsDetail.svelte +25 -17
  13. package/dist/PullRequestsDetail.svelte.d.ts.map +1 -1
  14. package/dist/PullRequestsPage.svelte +3 -3
  15. package/dist/PullRequestsPage.svelte.d.ts.map +1 -1
  16. package/dist/ReposTable.svelte +24 -15
  17. package/dist/ReposTable.svelte.d.ts.map +1 -1
  18. package/dist/ReposTree.svelte +8 -6
  19. package/dist/ReposTree.svelte.d.ts.map +1 -1
  20. package/dist/ReposTreeNav.svelte +10 -11
  21. package/dist/ReposTreeNav.svelte.d.ts.map +1 -1
  22. package/dist/TablePage.svelte +2 -2
  23. package/dist/TablePage.svelte.d.ts.map +1 -1
  24. package/dist/TreeItemPage.svelte +2 -2
  25. package/dist/TreeItemPage.svelte.d.ts.map +1 -1
  26. package/dist/TreePage.svelte +2 -2
  27. package/dist/TreePage.svelte.d.ts.map +1 -1
  28. package/dist/cargo_toml.d.ts +33 -0
  29. package/dist/cargo_toml.d.ts.map +1 -0
  30. package/dist/cargo_toml.js +74 -0
  31. package/dist/changeset_generator.d.ts +1 -1
  32. package/dist/changeset_generator.d.ts.map +1 -1
  33. package/dist/changeset_generator.js +2 -2
  34. package/dist/changeset_reader.d.ts +1 -1
  35. package/dist/changeset_reader.d.ts.map +1 -1
  36. package/dist/changeset_reader.js +3 -3
  37. package/dist/config_reconcile.d.ts.map +1 -1
  38. package/dist/config_reconcile.js +6 -2
  39. package/dist/dependency_graph.d.ts +2 -2
  40. package/dist/dependency_graph.d.ts.map +1 -1
  41. package/dist/dependency_graph.js +9 -9
  42. package/dist/dependency_updater.d.ts +1 -1
  43. package/dist/dependency_updater.d.ts.map +1 -1
  44. package/dist/dependency_updater.js +8 -8
  45. package/dist/fetch_repo_data.d.ts +2 -2
  46. package/dist/fetch_repo_data.d.ts.map +1 -1
  47. package/dist/fetch_repo_data.js +4 -4
  48. package/dist/fs_fetch_value_cache.d.ts +1 -1
  49. package/dist/fs_fetch_value_cache.d.ts.map +1 -1
  50. package/dist/fs_fetch_value_cache.js +5 -5
  51. package/dist/git_operations.d.ts +1 -1
  52. package/dist/git_operations.d.ts.map +1 -1
  53. package/dist/git_operations.js +2 -2
  54. package/dist/github.d.ts +2 -2
  55. package/dist/github.d.ts.map +1 -1
  56. package/dist/github.js +7 -7
  57. package/dist/github_helpers.d.ts.map +1 -1
  58. package/dist/github_helpers.js +1 -1
  59. package/dist/gitops_analyze.task.d.ts.map +1 -1
  60. package/dist/gitops_analyze.task.js +21 -14
  61. package/dist/gitops_config.d.ts +2 -2
  62. package/dist/gitops_config.d.ts.map +1 -1
  63. package/dist/gitops_config.js +5 -5
  64. package/dist/gitops_plan.task.d.ts.map +1 -1
  65. package/dist/gitops_plan.task.js +8 -8
  66. package/dist/gitops_publish.task.d.ts.map +1 -1
  67. package/dist/gitops_publish.task.js +15 -12
  68. package/dist/gitops_run.task.d.ts.map +1 -1
  69. package/dist/gitops_run.task.js +10 -10
  70. package/dist/gitops_sync.task.d.ts.map +1 -1
  71. package/dist/gitops_sync.task.js +15 -13
  72. package/dist/gitops_task_helpers.d.ts +1 -1
  73. package/dist/gitops_task_helpers.d.ts.map +1 -1
  74. package/dist/gitops_task_helpers.js +4 -4
  75. package/dist/gitops_validate.task.d.ts.map +1 -1
  76. package/dist/gitops_validate.task.js +14 -14
  77. package/dist/graph_validation.d.ts +2 -2
  78. package/dist/graph_validation.d.ts.map +1 -1
  79. package/dist/graph_validation.js +5 -3
  80. package/dist/local_repo.d.ts +21 -7
  81. package/dist/local_repo.d.ts.map +1 -1
  82. package/dist/local_repo.js +64 -16
  83. package/dist/log_helpers.d.ts +1 -1
  84. package/dist/log_helpers.d.ts.map +1 -1
  85. package/dist/multi_repo_publisher.d.ts +3 -3
  86. package/dist/multi_repo_publisher.d.ts.map +1 -1
  87. package/dist/multi_repo_publisher.js +24 -20
  88. package/dist/npm_registry.d.ts +1 -1
  89. package/dist/npm_registry.d.ts.map +1 -1
  90. package/dist/npm_registry.js +4 -4
  91. package/dist/operations.d.ts +4 -4
  92. package/dist/operations.d.ts.map +1 -1
  93. package/dist/operations_defaults.d.ts.map +1 -1
  94. package/dist/operations_defaults.js +16 -16
  95. package/dist/output_helpers.d.ts +1 -1
  96. package/dist/output_helpers.d.ts.map +1 -1
  97. package/dist/preflight_checks.d.ts +2 -2
  98. package/dist/preflight_checks.d.ts.map +1 -1
  99. package/dist/preflight_checks.js +5 -5
  100. package/dist/publish_gate.d.ts.map +1 -1
  101. package/dist/publish_steps.d.ts.map +1 -1
  102. package/dist/publish_steps.js +4 -4
  103. package/dist/publishing_event.d.ts.map +1 -1
  104. package/dist/publishing_event.js +16 -14
  105. package/dist/publishing_event_handler.d.ts.map +1 -1
  106. package/dist/publishing_event_handler.js +6 -6
  107. package/dist/publishing_plan.d.ts +3 -3
  108. package/dist/publishing_plan.d.ts.map +1 -1
  109. package/dist/publishing_plan.js +25 -15
  110. package/dist/publishing_plan_helpers.d.ts.map +1 -1
  111. package/dist/publishing_plan_helpers.js +3 -3
  112. package/dist/publishing_plan_logging.d.ts +1 -1
  113. package/dist/publishing_plan_logging.d.ts.map +1 -1
  114. package/dist/publishing_plan_logging.js +2 -2
  115. package/dist/repo.svelte.d.ts +5 -5
  116. package/dist/repo.svelte.d.ts.map +1 -1
  117. package/dist/repo.svelte.js +2 -2
  118. package/dist/repo_ops.js +2 -2
  119. package/dist/resolved_gitops_config.d.ts.map +1 -1
  120. package/dist/resolved_gitops_config.js +1 -1
  121. package/dist/version_utils.js +1 -1
  122. package/package.json +16 -15
  123. package/src/lib/cargo_toml.ts +82 -0
  124. package/src/lib/changeset_generator.ts +20 -20
  125. package/src/lib/changeset_reader.ts +18 -18
  126. package/src/lib/ci_reconcile.ts +5 -5
  127. package/src/lib/config_reconcile.ts +8 -4
  128. package/src/lib/dependency_graph.ts +28 -28
  129. package/src/lib/dependency_updater.ts +30 -30
  130. package/src/lib/fetch_repo_data.ts +11 -11
  131. package/src/lib/fs_fetch_value_cache.ts +14 -10
  132. package/src/lib/git_operations.ts +31 -31
  133. package/src/lib/github.ts +19 -19
  134. package/src/lib/github_helpers.ts +6 -6
  135. package/src/lib/gitops_analyze.task.ts +56 -48
  136. package/src/lib/gitops_config.ts +14 -14
  137. package/src/lib/gitops_plan.task.ts +32 -32
  138. package/src/lib/gitops_publish.task.ts +52 -49
  139. package/src/lib/gitops_run.task.ts +29 -29
  140. package/src/lib/gitops_sync.task.ts +39 -30
  141. package/src/lib/gitops_task_helpers.ts +21 -21
  142. package/src/lib/gitops_validate.task.ts +38 -38
  143. package/src/lib/graph_validation.ts +14 -13
  144. package/src/lib/local_repo.ts +130 -64
  145. package/src/lib/log_helpers.ts +15 -15
  146. package/src/lib/multi_repo_publisher.ts +75 -74
  147. package/src/lib/npm_registry.ts +13 -13
  148. package/src/lib/operations.ts +50 -39
  149. package/src/lib/operations_defaults.ts +108 -106
  150. package/src/lib/output_helpers.ts +4 -4
  151. package/src/lib/preflight_checks.ts +28 -28
  152. package/src/lib/publish_gate.ts +7 -9
  153. package/src/lib/publish_steps.ts +15 -15
  154. package/src/lib/publishing_event.ts +22 -20
  155. package/src/lib/publishing_event_handler.ts +8 -8
  156. package/src/lib/publishing_plan.ts +69 -57
  157. package/src/lib/publishing_plan_helpers.ts +16 -12
  158. package/src/lib/publishing_plan_logging.ts +23 -23
  159. package/src/lib/repo.svelte.ts +8 -8
  160. package/src/lib/repo_ops.ts +12 -12
  161. package/src/lib/resolved_gitops_config.ts +5 -5
  162. package/src/lib/version_utils.ts +3 -3
@@ -1,18 +1,18 @@
1
- import {TaskError, type Task} from '@fuzdev/gro';
2
- import {z} from 'zod';
3
- import {readFile, writeFile} from 'node:fs/promises';
4
- import {format_file} from '@fuzdev/gro/format_file.js';
5
- import {basename, resolve} from 'node:path';
6
- import {print_path} from '@fuzdev/gro/paths.js';
7
- import {load_from_env} from '@fuzdev/gro/env.js';
8
- import {package_json_load} from '@fuzdev/gro/package_json.js';
9
- import {existsSync} from 'node:fs';
10
- import {compactReplacer} from 'svelte-docinfo';
11
-
12
- import {fetch_repo_data} from './fetch_repo_data.js';
13
- import {create_fs_fetch_value_cache} from './fs_fetch_value_cache.js';
14
- import {get_gitops_ready} from './gitops_task_helpers.js';
15
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
1
+ import { TaskError, type Task } from '@fuzdev/gro';
2
+ import { z } from 'zod';
3
+ import { readFile, writeFile } from 'node:fs/promises';
4
+ import { format_file } from '@fuzdev/gro/format_file.ts';
5
+ import { basename, resolve } from 'node:path';
6
+ import { print_path } from '@fuzdev/gro/paths.ts';
7
+ import { load_from_env } from '@fuzdev/gro/env.ts';
8
+ import { package_json_load } from '@fuzdev/gro/package_json.ts';
9
+ import { existsSync } from 'node:fs';
10
+ import { compactReplacer } from 'svelte-docinfo';
11
+
12
+ import { fetch_repo_data } from './fetch_repo_data.ts';
13
+ import { create_fs_fetch_value_cache } from './fs_fetch_value_cache.ts';
14
+ import { get_gitops_ready } from './gitops_task_helpers.ts';
15
+ import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.ts';
16
16
 
17
17
  // TODO add flag to ignore or invalidate cache -- no-cache? clean?
18
18
 
@@ -20,28 +20,28 @@ import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
20
20
  export const Args = z.strictObject({
21
21
  config: z
22
22
  .string()
23
- .meta({description: 'path to the gitops config file, absolute or relative to the cwd'})
23
+ .meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
24
24
  .default(GITOPS_CONFIG_PATH_DEFAULT),
25
25
  dir: z
26
26
  .string()
27
- .meta({description: 'path containing the repos, defaults to the parent of the config dir'})
27
+ .meta({ description: 'path containing the repos, defaults to the parent of the config dir' })
28
28
  .optional(),
29
29
  outdir: z
30
30
  .string()
31
- .meta({description: 'path to the directory for the generated files, defaults to $routes/'})
31
+ .meta({ description: 'path to the directory for the generated files, defaults to $routes/' })
32
32
  .optional(),
33
- download: z.boolean().meta({description: 'download all missing local repos'}).default(false),
33
+ download: z.boolean().meta({ description: 'download all missing local repos' }).default(false),
34
34
  check: z
35
35
  .boolean()
36
- .meta({description: 'check repos are ready without fetching remote data'})
36
+ .meta({ description: 'check repos are ready without fetching remote data' })
37
37
  .default(false),
38
38
  allow_dirty: z
39
39
  .boolean()
40
40
  .meta({
41
41
  description:
42
- 'sync (switch branch, pull) tolerating uncommitted changes instead of failing on a dirty workspace',
42
+ 'sync (switch branch, pull) tolerating uncommitted changes instead of failing on a dirty workspace'
43
43
  })
44
- .default(false),
44
+ .default(false)
45
45
  });
46
46
  export type Args = z.infer<typeof Args>;
47
47
 
@@ -53,17 +53,26 @@ export type Args = z.infer<typeof Args>;
53
53
  export const task: Task<Args> = {
54
54
  Args,
55
55
  summary: 'syncs local repos and generates UI data from repo metadata',
56
- run: async ({args, log, svelte_config, invoke_task}) => {
57
- const {config, dir, outdir = svelte_config.routes_path, download, check, allow_dirty} = args;
56
+ run: async (ctx) => {
57
+ const { args, log, invoke_task } = ctx;
58
+ // `ctx.svelte_config` is a lazy getter, so it's only read when `outdir` isn't provided
59
+ const {
60
+ config,
61
+ dir,
62
+ outdir = (await ctx.svelte_config).routes_path,
63
+ download,
64
+ check,
65
+ allow_dirty
66
+ } = args;
58
67
 
59
68
  // `gitops_sync` is the task whose job is to mutate working trees, so it always syncs.
60
- const {local_repos} = await get_gitops_ready({
69
+ const { local_repos } = await get_gitops_ready({
61
70
  config,
62
71
  dir,
63
72
  download,
64
73
  sync: true,
65
74
  allow_dirty,
66
- log,
75
+ log
67
76
  });
68
77
 
69
78
  const outfile_json = resolve(outdir, 'repos.json');
@@ -96,8 +105,8 @@ export const task: Task<Args> = {
96
105
  log.info(`generating ${outfile_json} and ${outfile_ts}`);
97
106
 
98
107
  // Generate repos.json with the raw data
99
- const json_contents = await format_file(JSON.stringify(repos_json, compactReplacer), {
100
- filepath: outfile_json,
108
+ const json_contents = format_file(JSON.stringify(repos_json, compactReplacer), {
109
+ lang: 'json'
101
110
  });
102
111
  const existing_json = existsSync(outfile_json) ? await readFile(outfile_json, 'utf8') : '';
103
112
  const json_changed = existing_json !== json_contents;
@@ -123,7 +132,7 @@ export const task: Task<Args> = {
123
132
  export const repos_json: Array<RepoJson> = json as unknown as Array<RepoJson>;
124
133
  `;
125
134
  // TODO think about possibly using the `gen` functionality in this task, not sure what the API design could look like
126
- const formatted_ts = await format_file(ts_contents, {filepath: outfile_ts});
135
+ const formatted_ts = format_file(ts_contents, { filepath: outfile_ts });
127
136
  const existing_ts = existsSync(outfile_ts) ? await readFile(outfile_ts, 'utf8') : '';
128
137
  if (existing_ts === formatted_ts) {
129
138
  log.info(`no changes to ${print_path(outfile_ts)}`);
@@ -142,5 +151,5 @@ export const task: Task<Args> = {
142
151
  } else {
143
152
  log.info('repos cache did not change');
144
153
  }
145
- },
154
+ }
146
155
  };
@@ -16,17 +16,17 @@
16
16
  * @module
17
17
  */
18
18
 
19
- import {TaskError} from '@fuzdev/gro';
20
- import {styleText as st} from 'node:util';
21
- import {resolve, dirname} from 'node:path';
22
- import {print_path} from '@fuzdev/gro/paths.js';
23
- import type {Logger} from '@fuzdev/fuz_util/log.js';
19
+ import { TaskError } from '@fuzdev/gro';
20
+ import { styleText as st } from 'node:util';
21
+ import { resolve, dirname } from 'node:path';
22
+ import { print_path } from '@fuzdev/gro/paths.ts';
23
+ import type { Logger } from '@fuzdev/fuz_util/log.ts';
24
24
 
25
- import {load_gitops_config, type GitopsConfig} from './gitops_config.js';
26
- import {local_repos_load, local_repos_ensure, type LocalRepo} from './local_repo.js';
27
- import {resolve_gitops_config} from './resolved_gitops_config.js';
28
- import {DEFAULT_REPOS_DIR} from './paths.js';
29
- import type {GitOperations, NpmOperations} from './operations.js';
25
+ import { load_gitops_config, type GitopsConfig } from './gitops_config.ts';
26
+ import { local_repos_load, local_repos_ensure, type LocalRepo } from './local_repo.ts';
27
+ import { resolve_gitops_config } from './resolved_gitops_config.ts';
28
+ import { DEFAULT_REPOS_DIR } from './paths.ts';
29
+ import type { GitOperations, NpmOperations } from './operations.ts';
30
30
 
31
31
  export interface GetGitopsReadyOptions {
32
32
  config: string;
@@ -75,14 +75,14 @@ export interface GetGitopsReadyOptions {
75
75
  * @throws {TaskError} if config loading or repo resolution fails
76
76
  */
77
77
  export const get_gitops_ready = async (
78
- options: GetGitopsReadyOptions,
78
+ options: GetGitopsReadyOptions
79
79
  ): Promise<{
80
80
  config_path: string;
81
81
  repos_dir: string;
82
82
  gitops_config: GitopsConfig;
83
83
  local_repos: Array<LocalRepo>;
84
84
  }> => {
85
- const {config, dir, download, log, git_ops, npm_ops, parallel, concurrency, sync, allow_dirty} =
85
+ const { config, dir, download, log, git_ops, npm_ops, parallel, concurrency, sync, allow_dirty } =
86
86
  options;
87
87
  const config_path = resolve(config);
88
88
  const gitops_config = await import_gitops_config(config_path);
@@ -91,12 +91,12 @@ export const get_gitops_ready = async (
91
91
  const repos_dir = resolve_gitops_paths({
92
92
  config,
93
93
  dir,
94
- config_repos_dir: gitops_config.repos_dir,
94
+ config_repos_dir: gitops_config.repos_dir
95
95
  }).repos_dir;
96
96
 
97
97
  log?.info(
98
98
  `resolving gitops configs on the filesystem in ${repos_dir}`,
99
- gitops_config.repos.map((r) => r.repo_url),
99
+ gitops_config.repos.map((r) => r.repo_url)
100
100
  );
101
101
  const resolved_config = resolve_gitops_config(gitops_config, repos_dir);
102
102
 
@@ -106,7 +106,7 @@ export const get_gitops_ready = async (
106
106
  gitops_config,
107
107
  download,
108
108
  log,
109
- npm_ops,
109
+ npm_ops
110
110
  });
111
111
 
112
112
  const local_repos = await local_repos_load({
@@ -117,10 +117,10 @@ export const get_gitops_ready = async (
117
117
  parallel,
118
118
  concurrency,
119
119
  sync,
120
- allow_dirty,
120
+ allow_dirty
121
121
  });
122
122
 
123
- return {config_path, repos_dir, gitops_config, local_repos};
123
+ return { config_path, repos_dir, gitops_config, local_repos };
124
124
  };
125
125
 
126
126
  export interface ResolveGitopsPathsOptions {
@@ -130,9 +130,9 @@ export interface ResolveGitopsPathsOptions {
130
130
  }
131
131
 
132
132
  export const resolve_gitops_paths = (
133
- options: ResolveGitopsPathsOptions,
134
- ): {config_path: string; repos_dir: string} => {
135
- const {config, dir, config_repos_dir} = options;
133
+ options: ResolveGitopsPathsOptions
134
+ ): { config_path: string; repos_dir: string } => {
135
+ const { config, dir, config_repos_dir } = options;
136
136
  const config_path = resolve(config);
137
137
  const config_dir = dirname(config_path);
138
138
 
@@ -144,7 +144,7 @@ export const resolve_gitops_paths = (
144
144
  ? resolve(config_dir, config_repos_dir)
145
145
  : resolve(config_dir, DEFAULT_REPOS_DIR);
146
146
 
147
- return {config_path, repos_dir};
147
+ return { config_path, repos_dir };
148
148
  };
149
149
 
150
150
  export const import_gitops_config = async (config_path: string): Promise<GitopsConfig> => {
@@ -1,37 +1,37 @@
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.js';
6
- import {analyze_repos, type DependencyAnalysis} from './graph_validation.js';
5
+ import { get_gitops_ready } from './gitops_task_helpers.ts';
6
+ import { analyze_repos, type DependencyAnalysis } from './graph_validation.ts';
7
7
  import {
8
8
  generate_publishing_plan,
9
9
  log_publishing_plan,
10
- type PublishingPlan,
11
- } from './publishing_plan.js';
12
- import {execute_publishing_plan, type PublishingOptions} from './multi_repo_publisher.js';
13
- import {log_dependency_analysis} from './log_helpers.js';
14
- import {GITOPS_CONFIG_PATH_DEFAULT} from './gitops_constants.js';
15
- import {reconcile_ci, repo_has_workflows} from './ci_reconcile.js';
10
+ type PublishingPlan
11
+ } from './publishing_plan.ts';
12
+ import { execute_publishing_plan, type PublishingOptions } from './multi_repo_publisher.ts';
13
+ import { log_dependency_analysis } from './log_helpers.ts';
14
+ import { GITOPS_CONFIG_PATH_DEFAULT } from './gitops_constants.ts';
15
+ import { reconcile_ci, repo_has_workflows } from './ci_reconcile.ts';
16
16
 
17
17
  /** @nodocs */
18
18
  export const Args = z.strictObject({
19
19
  config: z
20
20
  .string()
21
- .meta({description: 'path to the gitops config file, absolute or relative to the cwd'})
21
+ .meta({ description: 'path to the gitops config file, absolute or relative to the cwd' })
22
22
  .default(GITOPS_CONFIG_PATH_DEFAULT),
23
23
  dir: z
24
24
  .string()
25
- .meta({description: 'path containing the repos, defaults to the parent of the config dir'})
25
+ .meta({ description: 'path containing the repos, defaults to the parent of the config dir' })
26
26
  .optional(),
27
- verbose: z.boolean().meta({description: 'show additional details'}).default(false),
27
+ verbose: z.boolean().meta({ description: 'show additional details' }).default(false),
28
28
  sync: z
29
29
  .boolean()
30
30
  .meta({
31
31
  description:
32
- 'sync repos (switch branch, pull, install) before validating instead of reading the working tree as-is',
32
+ 'sync repos (switch branch, pull, install) before validating instead of reading the working tree as-is'
33
33
  })
34
- .default(false),
34
+ .default(false)
35
35
  });
36
36
  export type Args = z.infer<typeof Args>;
37
37
 
@@ -40,8 +40,8 @@ export const task: Task<Args> = {
40
40
  Args,
41
41
  summary:
42
42
  'validate gitops configuration by running all read-only commands and checking for issues',
43
- run: async ({args, log}) => {
44
- const {config, dir, verbose, sync} = args;
43
+ run: async ({ args, log }) => {
44
+ const { config, dir, verbose, sync } = args;
45
45
 
46
46
  log.info(st('cyan', 'Running Gitops Validation Suite'));
47
47
  log.info(st('dim', 'This runs all read-only commands and checks for consistency.'));
@@ -61,7 +61,7 @@ export const task: Task<Args> = {
61
61
 
62
62
  // Load repos once (shared by all commands); read the working tree as-is unless `--sync`
63
63
  log.info(st('dim', 'Loading repositories...'));
64
- const {local_repos} = await get_gitops_ready({config, dir, download: false, sync, log});
64
+ const { local_repos } = await get_gitops_ready({ config, dir, download: false, sync, log });
65
65
  log.info(st('dim', ` Found ${local_repos.length} local repos`));
66
66
 
67
67
  // 1. Run gitops_analyze
@@ -69,7 +69,7 @@ export const task: Task<Args> = {
69
69
  const analyze_start = Date.now();
70
70
  try {
71
71
  // Build dependency graph and analyze cycles/wildcards (tolerating cycles)
72
- const {analysis} = analyze_repos(local_repos);
72
+ const { analysis } = analyze_repos(local_repos);
73
73
 
74
74
  const analyze_duration = Date.now() - analyze_start;
75
75
 
@@ -93,7 +93,7 @@ export const task: Task<Args> = {
93
93
  duration: analyze_duration,
94
94
  warning_details,
95
95
  info_details,
96
- analysis,
96
+ analysis
97
97
  });
98
98
 
99
99
  log.info(st('green', ` ✓ gitops_analyze completed in ${analyze_duration}ms`));
@@ -111,7 +111,7 @@ export const task: Task<Args> = {
111
111
  success: false,
112
112
  warnings: 0,
113
113
  errors: 1,
114
- duration: analyze_duration,
114
+ duration: analyze_duration
115
115
  });
116
116
  log.error(st('red', ` ✗ gitops_analyze failed: ${error}`));
117
117
  }
@@ -121,7 +121,7 @@ export const task: Task<Args> = {
121
121
  log.info(st('yellow', 'Running gitops_plan...'));
122
122
  const plan_start = Date.now();
123
123
  try {
124
- const plan = await generate_publishing_plan(local_repos, {verbose});
124
+ const plan = await generate_publishing_plan(local_repos, { verbose });
125
125
  publishing_plan = plan;
126
126
  const plan_duration = Date.now() - plan_start;
127
127
 
@@ -133,12 +133,12 @@ export const task: Task<Args> = {
133
133
  success: errors === 0,
134
134
  warnings,
135
135
  errors,
136
- duration: plan_duration,
136
+ duration: plan_duration
137
137
  });
138
138
 
139
139
  log.info(st('green', ` ✓ gitops_plan completed in ${plan_duration}ms`));
140
140
  if (verbose) {
141
- log_publishing_plan(plan, log, {verbose});
141
+ log_publishing_plan(plan, log, { verbose });
142
142
  }
143
143
  if (warnings > 0) {
144
144
  log.warn(st('yellow', ` ⚠️ Found ${warnings} warning(s)`));
@@ -153,7 +153,7 @@ export const task: Task<Args> = {
153
153
  success: false,
154
154
  warnings: 0,
155
155
  errors: 1,
156
- duration: plan_duration,
156
+ duration: plan_duration
157
157
  });
158
158
  log.error(st('red', ` ✗ gitops_plan failed: ${error}`));
159
159
  }
@@ -164,14 +164,14 @@ export const task: Task<Args> = {
164
164
  try {
165
165
  const options: PublishingOptions = {
166
166
  wetrun: false,
167
- log: undefined, // Silent for validation
167
+ log: undefined // Silent for validation
168
168
  };
169
169
 
170
170
  // Reuse the plan from step 2 (regenerate only if that step failed to produce one).
171
171
  const result = await execute_publishing_plan(
172
172
  local_repos,
173
- publishing_plan ?? (await generate_publishing_plan(local_repos, {verbose})),
174
- options,
173
+ publishing_plan ?? (await generate_publishing_plan(local_repos, { verbose })),
174
+ options
175
175
  );
176
176
  const dry_duration = Date.now() - dry_start;
177
177
 
@@ -184,7 +184,7 @@ export const task: Task<Args> = {
184
184
  success: result.ok,
185
185
  warnings: 0,
186
186
  errors,
187
- duration: dry_duration,
187
+ duration: dry_duration
188
188
  });
189
189
 
190
190
  log.info(st('green', ` ✓ gitops_publish (dry run) completed in ${dry_duration}ms`));
@@ -198,7 +198,7 @@ export const task: Task<Args> = {
198
198
  success: false,
199
199
  warnings: 0,
200
200
  errors: 1,
201
- duration: dry_duration,
201
+ duration: dry_duration
202
202
  });
203
203
  log.error(st('red', ` ✗ gitops_publish (dry run) failed: ${error}`));
204
204
  }
@@ -217,21 +217,21 @@ export const task: Task<Args> = {
217
217
  // always `true` today. The gate exists for a future caller that loads a
218
218
  // partial set; until then the skip path is inert and untested.
219
219
  checkable: true,
220
- archived: r.repo_config.archived,
221
- })),
220
+ archived: r.repo_config.archived
221
+ }))
222
222
  );
223
223
  const ci_duration = Date.now() - ci_start;
224
224
  const drift_details = ci_drift.map((d) =>
225
225
  d.kind === 'missing_ci'
226
226
  ? `${d.repo_url}: ci=true but no workflow files`
227
- : `${d.repo_url}: ci=false but workflow files present`,
227
+ : `${d.repo_url}: ci=false but workflow files present`
228
228
  );
229
229
  results.push({
230
230
  command: 'ci_reconcile',
231
231
  success: ci_drift.length === 0,
232
232
  warnings: 0,
233
233
  errors: ci_drift.length,
234
- duration: ci_duration,
234
+ duration: ci_duration
235
235
  });
236
236
  if (ci_drift.length === 0) {
237
237
  log.info(st('green', ` ✓ ci_reconcile completed in ${ci_duration}ms`));
@@ -248,7 +248,7 @@ export const task: Task<Args> = {
248
248
  success: false,
249
249
  warnings: 0,
250
250
  errors: 1,
251
- duration: ci_duration,
251
+ duration: ci_duration
252
252
  });
253
253
  log.error(st('red', ` ✗ ci_reconcile failed: ${error}`));
254
254
  }
@@ -295,7 +295,7 @@ export const task: Task<Args> = {
295
295
  log.info(st('green', '✓ All validation checks passed'));
296
296
  if (total_warnings > 0) {
297
297
  log.warn(
298
- st('yellow', `⚠️ Note: ${total_warnings} warning(s) found - review output above.`),
298
+ st('yellow', `⚠️ Note: ${total_warnings} warning(s) found - review output above.`)
299
299
  );
300
300
  }
301
301
  } else {
@@ -305,5 +305,5 @@ export const task: Task<Args> = {
305
305
  log.error(st('red', '❌ Validation failed - review the errors above.'));
306
306
  throw new Error('Validation failed');
307
307
  }
308
- },
308
+ }
309
309
  };
@@ -13,12 +13,12 @@
13
13
  * @module
14
14
  */
15
15
 
16
- import type {Logger} from '@fuzdev/fuz_util/log.js';
17
- import {TaskError} from '@fuzdev/gro';
18
- import {styleText as st} from 'node:util';
16
+ import type { Logger } from '@fuzdev/fuz_util/log.ts';
17
+ import { TaskError } from '@fuzdev/gro';
18
+ import { styleText as st } from 'node:util';
19
19
 
20
- import {DependencyGraph, DependencyGraphBuilder} from './dependency_graph.js';
21
- import type {LocalRepo} from './local_repo.js';
20
+ import { DependencyGraph, DependencyGraphBuilder } from './dependency_graph.ts';
21
+ import { repo_is_npm, type LocalRepo } from './local_repo.ts';
22
22
 
23
23
  export interface GraphValidationResult {
24
24
  graph: DependencyGraph;
@@ -45,9 +45,9 @@ export const validate_dependency_graph = (
45
45
  throw_on_prod_cycles?: boolean;
46
46
  log_cycles?: boolean;
47
47
  log_order?: boolean;
48
- } = {},
48
+ } = {}
49
49
  ): GraphValidationResult => {
50
- const {log, throw_on_prod_cycles = true, log_cycles = true, log_order = true} = options;
50
+ const { log, throw_on_prod_cycles = true, log_cycles = true, log_order = true } = options;
51
51
 
52
52
  // Build dependency graph
53
53
  log?.info('📊 Analyzing dependencies...');
@@ -55,7 +55,7 @@ export const validate_dependency_graph = (
55
55
  const graph = builder.build_from_repos(repos);
56
56
 
57
57
  // Check for cycles
58
- const {production_cycles, dev_cycles} = graph.detect_cycles_by_type();
58
+ const { production_cycles, dev_cycles } = graph.detect_cycles_by_type();
59
59
 
60
60
  // Log production cycles
61
61
  if (production_cycles.length > 0 && log_cycles) {
@@ -67,7 +67,7 @@ export const validate_dependency_graph = (
67
67
  if (throw_on_prod_cycles) {
68
68
  throw new TaskError(
69
69
  `Cannot publish with production/peer dependency cycles. ` +
70
- `These must be resolved before publishing.`,
70
+ `These must be resolved before publishing.`
71
71
  );
72
72
  }
73
73
  }
@@ -106,7 +106,7 @@ export const validate_dependency_graph = (
106
106
  publishing_order,
107
107
  production_cycles,
108
108
  dev_cycles,
109
- sort_error,
109
+ sort_error
110
110
  };
111
111
  };
112
112
 
@@ -127,11 +127,12 @@ export interface RepoAnalysis {
127
127
  * (no `log`) to avoid emitting a redundant "Analyzing dependencies" line.
128
128
  */
129
129
  export const analyze_repos = (repos: Array<LocalRepo>): RepoAnalysis => {
130
- const {graph, publishing_order: order} = validate_dependency_graph(repos, {
130
+ // Only npm packages form the dependency graph; non-npm repos (e.g. cargo) are excluded.
131
+ const { graph, publishing_order: order } = validate_dependency_graph(repos.filter(repo_is_npm), {
131
132
  throw_on_prod_cycles: false, // report, don't throw
132
133
  log_cycles: false, // callers format their own cycle output
133
- log_order: false,
134
+ log_order: false
134
135
  });
135
136
  const analysis = new DependencyGraphBuilder().analyze(graph);
136
- return {graph, analysis, publishing_order: order.length > 0 ? order : null};
137
+ return { graph, analysis, publishing_order: order.length > 0 ? order : null };
137
138
  };