@aspruyt/xfg 3.13.1 → 4.0.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 (190) hide show
  1. package/README.md +1 -4
  2. package/dist/cli/index.d.ts +1 -4
  3. package/dist/cli/index.js +0 -2
  4. package/dist/cli/program.js +7 -14
  5. package/dist/cli/{settings/results-collector.d.ts → results-collector.d.ts} +1 -1
  6. package/dist/cli/{settings/results-collector.js → results-collector.js} +2 -1
  7. package/dist/cli/settings-report-builder.d.ts +1 -3
  8. package/dist/cli/sync-command.d.ts +3 -26
  9. package/dist/cli/sync-command.js +312 -179
  10. package/dist/cli/types.d.ts +68 -41
  11. package/dist/cli/types.js +1 -12
  12. package/dist/config/errors.d.ts +9 -0
  13. package/dist/config/errors.js +11 -0
  14. package/dist/config/file-reference-resolver.d.ts +2 -1
  15. package/dist/config/file-reference-resolver.js +10 -8
  16. package/dist/config/formatter.d.ts +3 -2
  17. package/dist/config/index.d.ts +4 -6
  18. package/dist/config/index.js +4 -8
  19. package/dist/config/loader.js +4 -2
  20. package/dist/config/merge.d.ts +0 -9
  21. package/dist/config/merge.js +2 -7
  22. package/dist/config/normalizer.d.ts +4 -0
  23. package/dist/config/normalizer.js +61 -110
  24. package/dist/config/types.d.ts +15 -19
  25. package/dist/config/types.js +1 -1
  26. package/dist/config/validator.d.ts +0 -9
  27. package/dist/config/validator.js +297 -391
  28. package/dist/config/validators/file-validator.d.ts +2 -8
  29. package/dist/config/validators/file-validator.js +6 -17
  30. package/dist/config/validators/index.d.ts +3 -3
  31. package/dist/config/validators/index.js +3 -3
  32. package/dist/config/validators/repo-settings-validator.d.ts +0 -6
  33. package/dist/config/validators/repo-settings-validator.js +9 -9
  34. package/dist/config/validators/ruleset-validator.d.ts +0 -14
  35. package/dist/config/validators/ruleset-validator.js +28 -28
  36. package/dist/index.d.ts +2 -2
  37. package/dist/index.js +1 -1
  38. package/dist/lifecycle/ado-migration-source.js +2 -1
  39. package/dist/lifecycle/github-lifecycle-provider.d.ts +15 -5
  40. package/dist/lifecycle/github-lifecycle-provider.js +101 -81
  41. package/dist/lifecycle/index.d.ts +2 -6
  42. package/dist/lifecycle/index.js +0 -4
  43. package/dist/lifecycle/lifecycle-formatter.d.ts +2 -1
  44. package/dist/lifecycle/lifecycle-formatter.js +4 -0
  45. package/dist/lifecycle/lifecycle-helpers.d.ts +3 -2
  46. package/dist/lifecycle/repo-lifecycle-manager.js +4 -11
  47. package/dist/lifecycle/types.d.ts +0 -8
  48. package/dist/output/github-summary.d.ts +5 -0
  49. package/dist/output/github-summary.js +9 -2
  50. package/dist/output/index.d.ts +2 -2
  51. package/dist/output/index.js +1 -1
  52. package/dist/output/lifecycle-report.js +5 -23
  53. package/dist/output/settings-report.d.ts +14 -3
  54. package/dist/output/settings-report.js +137 -197
  55. package/dist/output/summary-utils.d.ts +1 -1
  56. package/dist/output/summary-utils.js +2 -1
  57. package/dist/output/sync-report.js +5 -8
  58. package/dist/output/unified-summary.d.ts +2 -1
  59. package/dist/output/unified-summary.js +71 -133
  60. package/dist/settings/base-processor.d.ts +67 -0
  61. package/dist/settings/base-processor.js +91 -0
  62. package/dist/settings/index.d.ts +4 -3
  63. package/dist/settings/index.js +3 -3
  64. package/dist/settings/labels/converter.d.ts +2 -1
  65. package/dist/settings/labels/diff.d.ts +2 -2
  66. package/dist/settings/labels/diff.js +15 -19
  67. package/dist/settings/labels/github-labels-strategy.d.ts +9 -18
  68. package/dist/settings/labels/github-labels-strategy.js +17 -73
  69. package/dist/settings/labels/index.d.ts +2 -6
  70. package/dist/settings/labels/index.js +1 -9
  71. package/dist/settings/labels/processor.d.ts +6 -40
  72. package/dist/settings/labels/processor.js +62 -165
  73. package/dist/settings/labels/types.d.ts +5 -8
  74. package/dist/settings/repo-settings/formatter.d.ts +2 -2
  75. package/dist/settings/repo-settings/formatter.js +6 -6
  76. package/dist/settings/repo-settings/github-repo-settings-strategy.d.ts +11 -12
  77. package/dist/settings/repo-settings/github-repo-settings-strategy.js +32 -79
  78. package/dist/settings/repo-settings/index.d.ts +2 -5
  79. package/dist/settings/repo-settings/index.js +1 -9
  80. package/dist/settings/repo-settings/processor.d.ts +6 -27
  81. package/dist/settings/repo-settings/processor.js +51 -104
  82. package/dist/settings/repo-settings/types.d.ts +7 -9
  83. package/dist/settings/rulesets/diff-algorithm.d.ts +0 -4
  84. package/dist/settings/rulesets/diff-algorithm.js +1 -10
  85. package/dist/settings/rulesets/diff.d.ts +3 -3
  86. package/dist/settings/rulesets/diff.js +8 -29
  87. package/dist/settings/rulesets/formatter.d.ts +1 -3
  88. package/dist/settings/rulesets/formatter.js +1 -8
  89. package/dist/settings/rulesets/github-ruleset-strategy.d.ts +11 -51
  90. package/dist/settings/rulesets/github-ruleset-strategy.js +24 -85
  91. package/dist/settings/rulesets/index.d.ts +3 -6
  92. package/dist/settings/rulesets/index.js +5 -9
  93. package/dist/settings/rulesets/processor.d.ts +8 -43
  94. package/dist/settings/rulesets/processor.js +58 -166
  95. package/dist/settings/rulesets/types.d.ts +35 -6
  96. package/dist/shared/command-executor.d.ts +2 -22
  97. package/dist/shared/command-executor.js +8 -7
  98. package/dist/shared/env.d.ts +0 -8
  99. package/dist/shared/env.js +14 -70
  100. package/dist/shared/file-status.d.ts +2 -0
  101. package/dist/shared/file-status.js +13 -0
  102. package/dist/shared/gh-api-utils.d.ts +46 -0
  103. package/dist/shared/gh-api-utils.js +107 -0
  104. package/dist/shared/index.d.ts +5 -5
  105. package/dist/shared/index.js +3 -3
  106. package/dist/shared/interpolation-engine.d.ts +31 -0
  107. package/dist/shared/interpolation-engine.js +50 -0
  108. package/dist/shared/logger.d.ts +3 -7
  109. package/dist/shared/logger.js +4 -1
  110. package/dist/shared/repo-detector.d.ts +17 -2
  111. package/dist/shared/repo-detector.js +27 -0
  112. package/dist/shared/retry-utils.d.ts +9 -17
  113. package/dist/shared/retry-utils.js +22 -28
  114. package/dist/shared/sanitize-utils.d.ts +0 -7
  115. package/dist/shared/sanitize-utils.js +0 -7
  116. package/dist/shared/shell-utils.d.ts +1 -0
  117. package/dist/shared/shell-utils.js +3 -0
  118. package/dist/shared/string-utils.d.ts +4 -0
  119. package/dist/shared/string-utils.js +6 -0
  120. package/dist/shared/type-guards.d.ts +17 -0
  121. package/dist/shared/type-guards.js +26 -0
  122. package/dist/shared/workspace-utils.d.ts +0 -4
  123. package/dist/shared/workspace-utils.js +0 -4
  124. package/dist/{sync → shared}/xfg-template.d.ts +3 -2
  125. package/dist/{sync → shared}/xfg-template.js +13 -54
  126. package/dist/sync/auth-options-builder.d.ts +4 -5
  127. package/dist/sync/auth-options-builder.js +15 -26
  128. package/dist/sync/branch-manager.d.ts +5 -0
  129. package/dist/sync/branch-manager.js +12 -10
  130. package/dist/sync/commit-push-manager.d.ts +1 -1
  131. package/dist/sync/commit-push-manager.js +22 -18
  132. package/dist/sync/diff-utils.d.ts +4 -9
  133. package/dist/sync/diff-utils.js +2 -19
  134. package/dist/sync/file-sync-orchestrator.js +9 -8
  135. package/dist/sync/file-writer.d.ts +2 -1
  136. package/dist/sync/file-writer.js +3 -6
  137. package/dist/sync/index.d.ts +2 -16
  138. package/dist/sync/index.js +0 -20
  139. package/dist/sync/manifest-manager.d.ts +4 -0
  140. package/dist/sync/manifest-manager.js +5 -1
  141. package/dist/sync/manifest.d.ts +11 -84
  142. package/dist/sync/manifest.js +50 -215
  143. package/dist/sync/pr-merge-handler.d.ts +2 -6
  144. package/dist/sync/pr-merge-handler.js +6 -3
  145. package/dist/sync/repository-processor.d.ts +2 -8
  146. package/dist/sync/repository-processor.js +21 -63
  147. package/dist/sync/repository-session.js +5 -14
  148. package/dist/sync/sync-workflow.js +31 -38
  149. package/dist/sync/types.d.ts +43 -182
  150. package/dist/vcs/authenticated-git-ops.d.ts +27 -70
  151. package/dist/vcs/authenticated-git-ops.js +70 -96
  152. package/dist/vcs/azure-pr-strategy.d.ts +6 -4
  153. package/dist/vcs/azure-pr-strategy.js +34 -82
  154. package/dist/vcs/branch-utils.d.ts +6 -0
  155. package/dist/vcs/branch-utils.js +29 -0
  156. package/dist/vcs/commit-strategy-selector.d.ts +5 -0
  157. package/dist/vcs/commit-strategy-selector.js +10 -0
  158. package/dist/vcs/git-commit-strategy.js +1 -2
  159. package/dist/vcs/git-ops.d.ts +15 -59
  160. package/dist/vcs/git-ops.js +46 -110
  161. package/dist/vcs/github-app-token-manager.d.ts +0 -6
  162. package/dist/vcs/github-app-token-manager.js +5 -12
  163. package/dist/vcs/github-pr-strategy.d.ts +5 -5
  164. package/dist/vcs/github-pr-strategy.js +44 -122
  165. package/dist/vcs/gitlab-pr-strategy.d.ts +6 -4
  166. package/dist/vcs/gitlab-pr-strategy.js +39 -87
  167. package/dist/vcs/graphql-commit-strategy.d.ts +3 -4
  168. package/dist/vcs/graphql-commit-strategy.js +45 -63
  169. package/dist/vcs/index.d.ts +3 -16
  170. package/dist/vcs/index.js +2 -33
  171. package/dist/vcs/pr-creator.d.ts +9 -9
  172. package/dist/vcs/pr-creator.js +11 -10
  173. package/dist/vcs/pr-strategy-factory.d.ts +5 -0
  174. package/dist/vcs/pr-strategy-factory.js +17 -0
  175. package/dist/vcs/pr-strategy.d.ts +13 -26
  176. package/dist/vcs/pr-strategy.js +20 -25
  177. package/dist/vcs/types.d.ts +87 -21
  178. package/package.json +2 -1
  179. package/dist/cli/settings/lifecycle-checks.d.ts +0 -11
  180. package/dist/cli/settings/lifecycle-checks.js +0 -64
  181. package/dist/cli/settings/process-labels.d.ts +0 -9
  182. package/dist/cli/settings/process-labels.js +0 -125
  183. package/dist/cli/settings/process-repo-settings.d.ts +0 -9
  184. package/dist/cli/settings/process-repo-settings.js +0 -80
  185. package/dist/cli/settings/process-rulesets.d.ts +0 -9
  186. package/dist/cli/settings/process-rulesets.js +0 -118
  187. package/dist/cli/settings-command.d.ts +0 -11
  188. package/dist/cli/settings-command.js +0 -90
  189. package/dist/sync/manifest-strategy.d.ts +0 -21
  190. package/dist/sync/manifest-strategy.js +0 -67
@@ -1,118 +0,0 @@
1
- import { resolve, join } from "node:path";
2
- import chalk from "chalk";
3
- import { parseGitUrl, getRepoDisplayName, isGitHubRepo, } from "../../shared/repo-detector.js";
4
- import { logger } from "../../shared/logger.js";
5
- import { generateWorkspaceName } from "../../shared/workspace-utils.js";
6
- import { buildErrorResult } from "../../output/summary-utils.js";
7
- import { getManagedRulesets, parseManifestContent, MANIFEST_FILENAME, } from "../../sync/manifest.js";
8
- import { defaultExecutor } from "../../shared/command-executor.js";
9
- import { escapeShellArg } from "../../shared/shell-utils.js";
10
- /**
11
- * Process rulesets for all configured repositories.
12
- */
13
- export async function processRulesets(repos, config, options, processor, repoProcessor, results, collector, lifecycleSkipped) {
14
- for (let i = 0; i < repos.length; i++) {
15
- const repoConfig = repos[i];
16
- if (lifecycleSkipped.has(repoConfig.git)) {
17
- continue;
18
- }
19
- let repoInfo;
20
- try {
21
- repoInfo = parseGitUrl(repoConfig.git, {
22
- githubHosts: config.githubHosts,
23
- });
24
- }
25
- catch (error) {
26
- logger.error(i + 1, repoConfig.git, String(error));
27
- results.push(buildErrorResult(repoConfig.git, error));
28
- collector.appendError(repoConfig.git, error);
29
- continue;
30
- }
31
- const repoName = getRepoDisplayName(repoInfo);
32
- if (!isGitHubRepo(repoInfo)) {
33
- logger.skip(i + 1, repoName, "GitHub Rulesets only supported for GitHub repos");
34
- continue;
35
- }
36
- const managedRulesets = await fetchManagedRulesets(repoInfo, config.id);
37
- try {
38
- logger.progress(i + 1, repoName, "Processing rulesets...");
39
- const result = await processor.process(repoConfig, repoInfo, {
40
- configId: config.id,
41
- dryRun: options.dryRun,
42
- managedRulesets,
43
- noDelete: options.noDelete,
44
- });
45
- if (result.planOutput && result.planOutput.lines.length > 0) {
46
- logger.info("");
47
- logger.info(chalk.bold(`${repoName} - Rulesets:`));
48
- for (const line of result.planOutput.lines) {
49
- logger.info(line);
50
- }
51
- }
52
- if (result.skipped) {
53
- logger.skip(i + 1, repoName, result.message);
54
- }
55
- else if (result.success) {
56
- logger.success(i + 1, repoName, result.message);
57
- if (result.manifestUpdate &&
58
- result.manifestUpdate.rulesets.length > 0) {
59
- const workDir = resolve(join(options.workDir ?? "./tmp", generateWorkspaceName(i)));
60
- logger.progress(i + 1, repoName, "Updating manifest...");
61
- const manifestResult = await repoProcessor.updateManifestOnly(repoInfo, repoConfig, {
62
- branchName: "chore/sync-rulesets",
63
- workDir,
64
- configId: config.id,
65
- dryRun: options.dryRun,
66
- retries: options.retries,
67
- }, result.manifestUpdate);
68
- if (!manifestResult.success && !manifestResult.skipped) {
69
- logger.info(`Warning: Failed to update manifest for ${repoName}: ${manifestResult.message}`);
70
- }
71
- }
72
- }
73
- else {
74
- logger.error(i + 1, repoName, result.message);
75
- collector.appendError(repoName, result.message);
76
- }
77
- results.push({
78
- repoName,
79
- status: result.skipped
80
- ? "skipped"
81
- : result.success
82
- ? "succeeded"
83
- : "failed",
84
- message: result.message,
85
- rulesetPlanDetails: result.planOutput?.entries,
86
- });
87
- if (!result.skipped) {
88
- collector.getOrCreate(repoName).rulesetResult = result;
89
- }
90
- }
91
- catch (error) {
92
- logger.error(i + 1, repoName, String(error));
93
- results.push(buildErrorResult(repoName, error));
94
- collector.appendError(repoName, error);
95
- }
96
- }
97
- }
98
- /**
99
- * Fetches the managed rulesets list from a remote GitHub repo's manifest.
100
- * Returns an empty array if the manifest doesn't exist or can't be read.
101
- *
102
- * Uses the project's ICommandExecutor + escapeShellArg pattern for safe
103
- * command execution. All inputs are from parsed config (owner/repo), not
104
- * user input.
105
- */
106
- async function fetchManagedRulesets(repoInfo, configId) {
107
- try {
108
- const endpoint = `/repos/${repoInfo.owner}/${repoInfo.repo}/contents/${MANIFEST_FILENAME}`;
109
- const command = `gh api ${escapeShellArg(endpoint)} --jq '.content'`;
110
- const base64Content = await defaultExecutor.exec(command, process.cwd());
111
- const content = Buffer.from(base64Content.trim(), "base64").toString("utf-8");
112
- const manifest = parseManifestContent(content);
113
- return getManagedRulesets(manifest, configId);
114
- }
115
- catch {
116
- return [];
117
- }
118
- }
@@ -1,11 +0,0 @@
1
- import { SharedOptions } from "./sync-command.js";
2
- import { ProcessorFactory, RulesetProcessorFactory, RepoSettingsProcessorFactory, LabelsProcessorFactory } from "./types.js";
3
- import { type IRepoLifecycleManager } from "../lifecycle/index.js";
4
- /**
5
- * Options for the settings command.
6
- */
7
- export type SettingsOptions = SharedOptions;
8
- /**
9
- * Run the settings command - manages GitHub Rulesets, repo settings, and labels.
10
- */
11
- export declare function runSettings(options: SettingsOptions, processorFactory?: RulesetProcessorFactory, repoProcessorFactory?: ProcessorFactory, repoSettingsProcessorFactory?: RepoSettingsProcessorFactory, lifecycleManager?: IRepoLifecycleManager, labelsProcessorFactory?: LabelsProcessorFactory): Promise<void>;
@@ -1,90 +0,0 @@
1
- import { resolve } from "node:path";
2
- import { existsSync } from "node:fs";
3
- import { loadRawConfig, normalizeConfig } from "../config/index.js";
4
- import { validateForSettings } from "../config/validator.js";
5
- import { hasGitHubAppCredentials, GitHubAppTokenManager, } from "../vcs/index.js";
6
- import { logger } from "../shared/logger.js";
7
- import { formatSettingsReportCLI } from "../output/settings-report.js";
8
- import { writeUnifiedSummary } from "../output/unified-summary.js";
9
- import { buildSettingsReport } from "./settings-report-builder.js";
10
- import { defaultProcessorFactory, defaultRulesetProcessorFactory, defaultRepoSettingsProcessorFactory, defaultLabelsProcessorFactory, } from "./types.js";
11
- import { RepoLifecycleManager, } from "../lifecycle/index.js";
12
- import { ResultsCollector } from "./settings/results-collector.js";
13
- import { runLifecycleChecks } from "./settings/lifecycle-checks.js";
14
- import { processRulesets } from "./settings/process-rulesets.js";
15
- import { processRepoSettings } from "./settings/process-repo-settings.js";
16
- import { processLabels } from "./settings/process-labels.js";
17
- /**
18
- * Run the settings command - manages GitHub Rulesets, repo settings, and labels.
19
- */
20
- export async function runSettings(options, processorFactory = defaultRulesetProcessorFactory, repoProcessorFactory = defaultProcessorFactory, repoSettingsProcessorFactory = defaultRepoSettingsProcessorFactory, lifecycleManager, labelsProcessorFactory = defaultLabelsProcessorFactory) {
21
- const configPath = resolve(options.config);
22
- if (!existsSync(configPath)) {
23
- console.error(`Config file not found: ${configPath}`);
24
- process.exit(1);
25
- }
26
- console.log(`Loading config from: ${configPath}`);
27
- if (options.dryRun) {
28
- console.log("Running in DRY RUN mode - no changes will be made\n");
29
- }
30
- const rawConfig = loadRawConfig(configPath);
31
- try {
32
- validateForSettings(rawConfig);
33
- }
34
- catch (error) {
35
- console.error(error instanceof Error ? error.message : String(error));
36
- process.exit(1);
37
- }
38
- const config = normalizeConfig(rawConfig);
39
- const reposWithRulesets = config.repos.filter((r) => r.settings?.rulesets && Object.keys(r.settings.rulesets).length > 0);
40
- const reposWithRepoSettings = config.repos.filter((r) => r.settings?.repo && Object.keys(r.settings.repo).length > 0);
41
- const reposWithLabels = config.repos.filter((r) => r.settings?.labels && Object.keys(r.settings.labels).length > 0);
42
- if (reposWithRulesets.length === 0 &&
43
- reposWithRepoSettings.length === 0 &&
44
- reposWithLabels.length === 0) {
45
- console.log("No settings configured. Add settings.rulesets, settings.repo, or settings.labels to your config.");
46
- return;
47
- }
48
- if (reposWithRulesets.length > 0) {
49
- console.log(`Found ${reposWithRulesets.length} repositories with rulesets`);
50
- }
51
- if (reposWithRepoSettings.length > 0) {
52
- console.log(`Found ${reposWithRepoSettings.length} repositories with repo settings`);
53
- }
54
- if (reposWithLabels.length > 0) {
55
- console.log(`Found ${reposWithLabels.length} repositories with labels`);
56
- }
57
- console.log("");
58
- logger.setTotal(reposWithRulesets.length +
59
- reposWithRepoSettings.length +
60
- reposWithLabels.length);
61
- const processor = processorFactory();
62
- const repoProcessor = repoProcessorFactory();
63
- const lm = lifecycleManager ?? new RepoLifecycleManager(undefined, options.retries);
64
- const tokenManager = hasGitHubAppCredentials()
65
- ? new GitHubAppTokenManager(process.env.XFG_GITHUB_APP_ID, process.env.XFG_GITHUB_APP_PRIVATE_KEY)
66
- : null;
67
- const results = [];
68
- const collector = new ResultsCollector();
69
- // Pre-check lifecycle for all unique repos before processing
70
- const allRepos = [
71
- ...reposWithRulesets,
72
- ...reposWithRepoSettings,
73
- ...reposWithLabels,
74
- ];
75
- const lifecycleSkipped = await runLifecycleChecks(allRepos, config, options, lm, results, collector, tokenManager);
76
- await processRulesets(reposWithRulesets, config, options, processor, repoProcessor, results, collector, lifecycleSkipped);
77
- await processRepoSettings(reposWithRepoSettings, config, options, repoSettingsProcessorFactory, results, collector, lifecycleSkipped, reposWithRulesets.length);
78
- await processLabels(reposWithLabels, config, options, labelsProcessorFactory(), repoProcessor, results, collector, lifecycleSkipped, reposWithRulesets.length + reposWithRepoSettings.length);
79
- console.log("");
80
- const report = buildSettingsReport(collector.getAll());
81
- const lines = formatSettingsReportCLI(report);
82
- for (const line of lines) {
83
- console.log(line);
84
- }
85
- writeUnifiedSummary({ settings: report, dryRun: options.dryRun ?? false });
86
- const hasErrors = report.repos.some((r) => r.error);
87
- if (hasErrors) {
88
- process.exit(1);
89
- }
90
- }
@@ -1,21 +0,0 @@
1
- import type { RepoConfig } from "../config/types.js";
2
- import type { RepoInfo } from "../shared/repo-detector.js";
3
- import type { ILogger } from "../shared/logger.js";
4
- import type { IWorkStrategy, WorkResult, SessionContext, ProcessorOptions } from "./types.js";
5
- /**
6
- * Parameters for manifest-only updates
7
- */
8
- export interface ManifestUpdateParams {
9
- rulesets?: string[];
10
- labels?: string[];
11
- }
12
- /**
13
- * Strategy that only updates the manifest with ruleset tracking.
14
- * Used by updateManifestOnly() for settings command ruleset sync.
15
- */
16
- export declare class ManifestStrategy implements IWorkStrategy {
17
- private readonly params;
18
- private readonly log;
19
- constructor(params: ManifestUpdateParams, log: ILogger);
20
- execute(_repoConfig: RepoConfig, _repoInfo: RepoInfo, _session: SessionContext, options: ProcessorOptions): Promise<WorkResult | null>;
21
- }
@@ -1,67 +0,0 @@
1
- import { loadManifest, saveManifest, updateManifestRulesets, updateManifestLabels, MANIFEST_FILENAME, } from "./manifest.js";
2
- /**
3
- * Strategy that only updates the manifest with ruleset tracking.
4
- * Used by updateManifestOnly() for settings command ruleset sync.
5
- */
6
- export class ManifestStrategy {
7
- params;
8
- log;
9
- constructor(params, log) {
10
- this.params = params;
11
- this.log = log;
12
- }
13
- async execute(_repoConfig, _repoInfo, _session, options) {
14
- const { workDir, dryRun, configId } = options;
15
- // Load and update manifest
16
- const existingManifest = loadManifest(workDir);
17
- let newManifest = existingManifest;
18
- // Apply rulesets update if present
19
- if (this.params.rulesets) {
20
- const rulesetsWithDeleteOrphaned = new Map(this.params.rulesets.map((name) => [name, true]));
21
- const result = updateManifestRulesets(newManifest, configId, rulesetsWithDeleteOrphaned);
22
- newManifest = result.manifest;
23
- }
24
- // Apply labels update if present
25
- if (this.params.labels) {
26
- const labelsWithDeleteOrphaned = new Map(this.params.labels.map((name) => [name, true]));
27
- const result = updateManifestLabels(newManifest, configId, labelsWithDeleteOrphaned);
28
- newManifest = result.manifest;
29
- }
30
- // Check if changed
31
- const existingConfigs = existingManifest?.configs ?? {};
32
- if (JSON.stringify(existingConfigs) === JSON.stringify(newManifest.configs)) {
33
- return null;
34
- }
35
- // Build dynamic commit message
36
- const parts = [];
37
- if (this.params.rulesets)
38
- parts.push("ruleset");
39
- if (this.params.labels)
40
- parts.push("labels");
41
- const trackingType = parts.join("/");
42
- if (dryRun) {
43
- this.log.info(`Would update ${MANIFEST_FILENAME} with ${trackingType} tracking`);
44
- }
45
- else {
46
- saveManifest(workDir, newManifest);
47
- }
48
- const fileChanges = new Map([
49
- [
50
- MANIFEST_FILENAME,
51
- {
52
- fileName: MANIFEST_FILENAME,
53
- content: JSON.stringify(newManifest, null, 2) + "\n",
54
- action: "update",
55
- },
56
- ],
57
- ]);
58
- return {
59
- fileChanges,
60
- changedFiles: [
61
- { fileName: MANIFEST_FILENAME, action: "update" },
62
- ],
63
- commitMessage: `chore: update manifest with ${trackingType} tracking`,
64
- fileChangeDetails: [{ path: MANIFEST_FILENAME, action: "update" }],
65
- };
66
- }
67
- }