repopo 0.4.0 → 0.5.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +37 -18
  3. package/THIRD-PARTY-LICENSES.txt +21 -11
  4. package/esm/api.d.ts +2 -0
  5. package/esm/api.d.ts.map +1 -0
  6. package/esm/api.js +2 -0
  7. package/esm/api.js.map +1 -0
  8. package/esm/baseCommand.d.ts +13 -43
  9. package/esm/baseCommand.d.ts.map +1 -1
  10. package/esm/baseCommand.js +27 -62
  11. package/esm/baseCommand.js.map +1 -1
  12. package/esm/commands/check.d.ts +2 -8
  13. package/esm/commands/check.d.ts.map +1 -1
  14. package/esm/commands/check.js +79 -87
  15. package/esm/commands/check.js.map +1 -1
  16. package/esm/commands/list.d.ts +1 -2
  17. package/esm/commands/list.d.ts.map +1 -1
  18. package/esm/commands/list.js +5 -6
  19. package/esm/commands/list.js.map +1 -1
  20. package/esm/config.d.ts +10 -5
  21. package/esm/config.d.ts.map +1 -1
  22. package/esm/config.js.map +1 -1
  23. package/esm/context.d.ts +29 -0
  24. package/esm/context.d.ts.map +1 -0
  25. package/esm/context.js +2 -0
  26. package/esm/context.js.map +1 -0
  27. package/esm/index.d.ts +11 -4
  28. package/esm/index.d.ts.map +1 -1
  29. package/esm/index.js +8 -0
  30. package/esm/index.js.map +1 -1
  31. package/esm/perf.d.ts.map +1 -1
  32. package/esm/perf.js +1 -5
  33. package/esm/perf.js.map +1 -1
  34. package/esm/policies/HtmlFileHeaders.d.ts +8 -0
  35. package/esm/policies/HtmlFileHeaders.d.ts.map +1 -0
  36. package/esm/policies/HtmlFileHeaders.js +17 -0
  37. package/esm/policies/HtmlFileHeaders.js.map +1 -0
  38. package/esm/policies/JsTsFileHeaders.d.ts +8 -0
  39. package/esm/policies/JsTsFileHeaders.d.ts.map +1 -0
  40. package/esm/policies/JsTsFileHeaders.js +24 -0
  41. package/esm/policies/JsTsFileHeaders.js.map +1 -0
  42. package/esm/policies/NoJsFileExtensions.d.ts +2 -0
  43. package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
  44. package/esm/policies/NoJsFileExtensions.js +2 -0
  45. package/esm/policies/NoJsFileExtensions.js.map +1 -1
  46. package/esm/policies/PackageJsonProperties.d.ts +6 -8
  47. package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
  48. package/esm/policies/PackageJsonProperties.js +37 -40
  49. package/esm/policies/PackageJsonProperties.js.map +1 -1
  50. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +3 -2
  51. package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
  52. package/esm/policies/PackageJsonRepoDirectoryProperty.js +40 -37
  53. package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
  54. package/esm/policies/PackageJsonSorted.d.ts +7 -0
  55. package/esm/policies/PackageJsonSorted.d.ts.map +1 -0
  56. package/esm/policies/PackageJsonSorted.js +45 -0
  57. package/esm/policies/PackageJsonSorted.js.map +1 -0
  58. package/esm/policies/PackageScripts.d.ts +7 -0
  59. package/esm/policies/PackageScripts.d.ts.map +1 -0
  60. package/esm/policies/PackageScripts.js +25 -0
  61. package/esm/policies/PackageScripts.js.map +1 -0
  62. package/esm/policies/constants.d.ts +5 -0
  63. package/esm/policies/constants.d.ts.map +1 -0
  64. package/esm/policies/constants.js +5 -0
  65. package/esm/policies/constants.js.map +1 -0
  66. package/esm/policies.d.ts +7 -0
  67. package/esm/policies.d.ts.map +1 -0
  68. package/esm/policies.js +7 -0
  69. package/esm/policies.js.map +1 -0
  70. package/esm/policy.d.ts +31 -13
  71. package/esm/policy.d.ts.map +1 -1
  72. package/esm/policy.js +8 -20
  73. package/esm/policy.js.map +1 -1
  74. package/esm/policyGenerators/generateFileHeaderPolicy.d.ts +45 -0
  75. package/esm/policyGenerators/generateFileHeaderPolicy.d.ts.map +1 -0
  76. package/esm/policyGenerators/generateFileHeaderPolicy.js +61 -0
  77. package/esm/policyGenerators/generateFileHeaderPolicy.js.map +1 -0
  78. package/esm/policyGenerators/generatePackagePolicy.d.ts +9 -0
  79. package/esm/policyGenerators/generatePackagePolicy.d.ts.map +1 -0
  80. package/esm/policyGenerators/generatePackagePolicy.js +20 -0
  81. package/esm/policyGenerators/generatePackagePolicy.js.map +1 -0
  82. package/esm/tsdoc-metadata.json +1 -1
  83. package/oclif.manifest.json +45 -53
  84. package/package.json +39 -21
  85. package/esm/policies/PackageJsonSortedPolicy.d.ts +0 -6
  86. package/esm/policies/PackageJsonSortedPolicy.d.ts.map +0 -1
  87. package/esm/policies/PackageJsonSortedPolicy.js +0 -49
  88. package/esm/policies/PackageJsonSortedPolicy.js.map +0 -1
  89. package/esm/policies/SortTsconfigs.d.ts +0 -10
  90. package/esm/policies/SortTsconfigs.d.ts.map +0 -1
  91. package/esm/policies/SortTsconfigs.js +0 -33
  92. package/esm/policies/SortTsconfigs.js.map +0 -1
@@ -1,11 +1,9 @@
1
- import fs from "node:fs";
2
1
  import { EOL as newline } from "node:os";
3
2
  import { Flags } from "@oclif/core";
4
3
  import { StringBuilder } from "@rushstack/node-core-library";
5
4
  import path from "pathe";
6
5
  import chalk from "picocolors";
7
- import { BaseRepopoCommand, } from "../baseCommand.js";
8
- import { DefaultPolicyConfig } from "../config.js";
6
+ import { BaseRepopoCommand } from "../baseCommand.js";
9
7
  import { logStats, runWithPerf } from "../perf.js";
10
8
  import { isPolicyFixResult } from "../policy.js";
11
9
  /**
@@ -32,17 +30,10 @@ export class CheckPolicy extends BaseRepopoCommand {
32
30
  }),
33
31
  ...BaseRepopoCommand.flags,
34
32
  };
35
- processed = 0;
36
- count = 0;
37
- defaultConfig = DefaultPolicyConfig;
38
- async init() {
39
- await super.init();
33
+ async run() {
40
34
  if (this.flags.fix) {
41
35
  this.info("Resolving errors if possible.");
42
36
  }
43
- }
44
- async run() {
45
- // list the handlers then exit
46
37
  const config = this.commandConfig;
47
38
  const policies = config?.policies ?? [];
48
39
  this.verbose(`${policies.length} policies loaded.`);
@@ -60,17 +51,10 @@ export class CheckPolicy extends BaseRepopoCommand {
60
51
  const gitFiles = (await this.git.raw("ls-files", "-co", "--exclude-standard", "--full-name")) ?? "";
61
52
  filePathsToCheck.push(...gitFiles.split("\n"));
62
53
  }
63
- try {
64
- const context = this.getContext();
65
- await this.executePolicy(filePathsToCheck, context);
66
- }
67
- catch (error) {
68
- this.error(`Command context was undefined - fatal error: ${error}`, {
69
- exit: 100,
70
- });
71
- }
54
+ await this.executeAllPolicies(filePathsToCheck);
72
55
  }
73
- async executePolicy(pathsToCheck, commandContext) {
56
+ async executeAllPolicies(pathsToCheck) {
57
+ const commandContext = await this.getContext();
74
58
  try {
75
59
  for (const pathToCheck of pathsToCheck) {
76
60
  // eslint-disable-next-line no-await-in-loop
@@ -78,7 +62,9 @@ export class CheckPolicy extends BaseRepopoCommand {
78
62
  }
79
63
  }
80
64
  finally {
81
- logStats(commandContext.perfStats, this);
65
+ if (!this.flags.quiet) {
66
+ logStats(commandContext.perfStats, this);
67
+ }
82
68
  }
83
69
  }
84
70
  /**
@@ -87,87 +73,93 @@ export class CheckPolicy extends BaseRepopoCommand {
87
73
  * decision for all handlers.
88
74
  */
89
75
  async routeToHandlers(file, commandContext) {
90
- const { policies, excludePoliciesForFiles, gitRoot, perfStats } = commandContext;
76
+ const { policies, gitRoot } = commandContext;
91
77
  // Use the repo-relative path so that regexes that specify string start (^) will match repo paths.
92
78
  // Replace \ in result with / in case OS is Windows.
93
79
  const relPath = path.relative(gitRoot, file).replace(/\\/g, "/");
94
- const config = this.commandConfig;
95
- await Promise.all(policies
96
- .filter((handler) => handler.match.test(relPath))
97
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
98
- .map(async (policy) => {
99
- // doing exclusion per handler
100
- const exclusions = excludePoliciesForFiles.get(policy.name);
101
- if (exclusions !== undefined &&
102
- !exclusions.every((regex) => !regex.test(relPath))) {
103
- this.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);
104
- return;
105
- }
106
- const result = await runWithPerf(policy.name, "handle", perfStats, async () => policy.handler({
107
- file: relPath,
108
- root: gitRoot,
109
- resolve: this.flags.fix,
110
- config: config?.policySettings?.[policy.name],
111
- }));
112
- if (result === true) {
113
- return;
114
- }
115
- const messages = new StringBuilder();
116
- if (isPolicyFixResult(result)) {
117
- if (result.resolved) {
118
- messages.append(`Resolved ${policy.name} policy failure for file: ${result.file}`);
119
- }
120
- else {
121
- messages.append(`Error when trying to fix ${policy.name} policy failure in ${result.file}`);
122
- process.exitCode = 1;
123
- }
80
+ const filteredPolicies = policies.filter((handler) => handler.match.test(relPath));
81
+ const resultsP = [];
82
+ for (const policy of filteredPolicies) {
83
+ resultsP.push(this.runPolicyOnFile(relPath, policy));
84
+ }
85
+ await Promise.all(resultsP);
86
+ }
87
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: FIXME
88
+ async runPolicyOnFile(relPath,
89
+ // policies: RepoPolicy[],
90
+ policy) {
91
+ const context = await this.getContext();
92
+ const { excludePoliciesForFiles, perfStats, gitRoot } = context;
93
+ // doing exclusion per handler
94
+ const exclusions = excludePoliciesForFiles.get(policy.name);
95
+ if (exclusions !== undefined &&
96
+ !exclusions.every((regex) => !regex.test(relPath))) {
97
+ this.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);
98
+ return;
99
+ }
100
+ const result = await runWithPerf(policy.name, "handle", perfStats, async () => policy.handler({
101
+ file: relPath,
102
+ root: gitRoot,
103
+ resolve: this.flags.fix,
104
+ config: this.commandConfig?.perPolicyConfig?.[policy.name
105
+ // biome-ignore lint/suspicious/noExplicitAny: FIXME
106
+ ],
107
+ }));
108
+ if (result === true) {
109
+ return;
110
+ }
111
+ const messages = new StringBuilder();
112
+ if (isPolicyFixResult(result)) {
113
+ if (result.resolved) {
114
+ messages.append(`Resolved ${policy.name} policy failure for file: ${result.file}`);
124
115
  }
125
116
  else {
126
- // result must be a PolicyFailureResult; check if there is a standalone resolver.
127
- const { resolver } = policy;
128
- if (this.flags.fix && resolver !== undefined) {
129
- // Resolve the failure
130
- messages.append(`${newline}attempting to resolve: ${relPath}`);
131
- const resolveResult = await runWithPerf(policy.name, "resolve", perfStats, async () => resolver({ file: relPath, root: gitRoot }));
132
- if (resolveResult.errorMessage !== undefined &&
133
- resolveResult.errorMessage !== "") {
134
- messages.append(newline + resolveResult.errorMessage);
135
- }
136
- if (!resolveResult.resolved) {
137
- process.exitCode = 1;
138
- }
117
+ messages.append(`Error when trying to fix ${policy.name} policy failure in ${result.file}`);
118
+ process.exitCode = 1;
119
+ }
120
+ }
121
+ else {
122
+ // result must be a PolicyFailureResult; check if there is a standalone resolver.
123
+ const { resolver } = policy;
124
+ if (this.flags.fix && resolver !== undefined) {
125
+ // Resolve the failure
126
+ messages.append(`${newline}attempting to resolve: ${relPath}`);
127
+ const resolveResult = await runWithPerf(policy.name, "resolve", perfStats, async () => resolver({ file: relPath, root: gitRoot }));
128
+ if (resolveResult.errorMessage !== undefined &&
129
+ resolveResult.errorMessage !== "") {
130
+ messages.append(newline + resolveResult.errorMessage);
139
131
  }
140
- else {
141
- // No resolver, or fix is false, so we're in the full failure case.
142
- const autoFixable = result.autoFixable
143
- ? chalk.green(" (autofixable)")
144
- : "";
145
- messages.append(`'${policy.name}' policy failure${autoFixable}: ${result.file}`);
146
- messages.append(result.errorMessage === undefined
147
- ? ""
148
- : `${newline}${result.errorMessage}`);
132
+ if (!resolveResult.resolved) {
149
133
  process.exitCode = 1;
150
134
  }
151
135
  }
152
- if ((process.exitCode ?? 0) === 0) {
153
- this.info(messages.toString());
154
- }
155
136
  else {
156
- this.warning(messages.toString());
137
+ // No resolver, or fix is false, so we're in the full failure case.
138
+ const autoFixable = result.autoFixable
139
+ ? chalk.green(" (autofixable)")
140
+ : "";
141
+ messages.append(`'${chalk.bold(policy.name)}' policy failure${autoFixable}: ${result.file}`);
142
+ messages.append(result.errorMessage === undefined
143
+ ? ""
144
+ : `${newline}\t${result.errorMessage}`);
145
+ process.exitCode = 1;
157
146
  }
158
- }));
147
+ }
148
+ if ((process.exitCode ?? 0) === 0) {
149
+ this.info(messages.toString());
150
+ }
151
+ else {
152
+ this.warning(messages.toString());
153
+ }
159
154
  }
160
155
  /**
161
156
  * Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,
162
157
  * routes the file to the appropriate handlers.
163
158
  */
164
159
  async checkOrExcludeFile(inputPath, commandContext) {
165
- const { excludeFiles: exclusions, gitRoot, pathRegex } = commandContext;
160
+ const { excludeFiles: exclusions, gitRoot, perfStats } = commandContext;
166
161
  const filePath = path.join(gitRoot, inputPath).trim().replace(/\\/g, "/");
167
- if (!(pathRegex.test(inputPath) && fs.existsSync(filePath))) {
168
- return;
169
- }
170
- this.count++;
162
+ perfStats.count++;
171
163
  if (!exclusions.every((value) => !value.test(inputPath))) {
172
164
  this.verbose(`Excluded all handlers: ${inputPath}`);
173
165
  return;
@@ -176,9 +168,9 @@ export class CheckPolicy extends BaseRepopoCommand {
176
168
  await this.routeToHandlers(filePath, commandContext);
177
169
  }
178
170
  catch (error) {
179
- throw new Error(`Error routing ${filePath} to handler: ${error}`);
171
+ throw new Error(`Error routing ${filePath} to handler: ${error}\nStack:\n${error.stack}`);
180
172
  }
181
- this.processed++;
173
+ perfStats.processed++;
182
174
  }
183
175
  }
184
176
  async function readStdin() {
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport { EOL as newline } from \"node:os\";\nimport { Flags } from \"@oclif/core\";\nimport { StringBuilder } from \"@rushstack/node-core-library\";\nimport path from \"pathe\";\nimport chalk from \"picocolors\";\n\nimport {\n\tBaseRepopoCommand,\n\ttype PolicyCommandContext,\n} from \"../baseCommand.js\";\nimport { DefaultPolicyConfig } from \"../config.js\";\nimport { logStats, runWithPerf } from \"../perf.js\";\nimport { isPolicyFixResult } from \"../policy.js\";\n\n/**\n * This tool enforces policies across the code base via a series of handler functions. The handler functions are\n * associated with a regular expression, and all files matching that expression are passed to the handler function.\n *\n * By default, the list of files to check comes from `git ls-files. You can also pipe in file names from stdin. For\n * example:\n *\n * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`\n */\nexport class CheckPolicy<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof CheckPolicy.args;\n\t\tflags: typeof CheckPolicy.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tstatic override readonly summary =\n\t\t\"Checks and applies policies to the files in the repository.\";\n\n\tstatic override readonly flags = {\n\t\tfix: Flags.boolean({\n\t\t\taliases: [\"resolve\"],\n\t\t\tdescription: \"Fix errors if possible.\",\n\t\t\trequired: false,\n\t\t\tchar: \"f\",\n\t\t}),\n\t\tstdin: Flags.boolean({\n\t\t\tdescription: \"Read list of files from stdin.\",\n\t\t\trequired: false,\n\t\t}),\n\t\t...BaseRepopoCommand.flags,\n\t} as const;\n\n\tprivate processed = 0;\n\tprivate count = 0;\n\n\tpublic override defaultConfig = DefaultPolicyConfig;\n\n\tpublic override async init(): Promise<void> {\n\t\tawait super.init();\n\n\t\tif (this.flags.fix) {\n\t\t\tthis.info(\"Resolving errors if possible.\");\n\t\t}\n\t}\n\n\tpublic override async run(): Promise<void> {\n\t\t// list the handlers then exit\n\t\tconst config = this.commandConfig;\n\t\tconst policies = config?.policies ?? [];\n\t\tthis.verbose(`${policies.length} policies loaded.`);\n\t\tfor (const h of policies) {\n\t\t\tthis.verbose(h.name);\n\t\t}\n\n\t\tconst filePathsToCheck: string[] = [];\n\n\t\tif (this.flags.stdin) {\n\t\t\tconst stdInput = await readStdin();\n\n\t\t\tif (stdInput !== undefined) {\n\t\t\t\tfilePathsToCheck.push(...stdInput.split(\"\\n\"));\n\t\t\t}\n\t\t} else {\n\t\t\tconst gitFiles =\n\t\t\t\t(await this.git.raw(\n\t\t\t\t\t\"ls-files\",\n\t\t\t\t\t\"-co\",\n\t\t\t\t\t\"--exclude-standard\",\n\t\t\t\t\t\"--full-name\",\n\t\t\t\t)) ?? \"\";\n\n\t\t\tfilePathsToCheck.push(...gitFiles.split(\"\\n\"));\n\t\t}\n\n\t\ttry {\n\t\t\tconst context = this.getContext();\n\t\t\tawait this.executePolicy(filePathsToCheck, context);\n\t\t} catch (error) {\n\t\t\tthis.error(`Command context was undefined - fatal error: ${error}`, {\n\t\t\t\texit: 100,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async executePolicy(\n\t\tpathsToCheck: string[],\n\t\tcommandContext: PolicyCommandContext,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tfor (const pathToCheck of pathsToCheck) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tawait this.checkOrExcludeFile(pathToCheck, commandContext);\n\t\t\t}\n\t\t} finally {\n\t\t\tlogStats(commandContext.perfStats, this);\n\t\t}\n\t}\n\n\t/**\n\t * Routes files to their handlers and resolvers by regex testing their full paths. If a file fails a policy that has a\n\t * resolver, the resolver will be invoked as well. Synchronizes the output, exit codes, and resolve\n\t * decision for all handlers.\n\t */\n\tprivate async routeToHandlers(\n\t\tfile: string,\n\t\tcommandContext: PolicyCommandContext,\n\t): Promise<void> {\n\t\tconst { policies, excludePoliciesForFiles, gitRoot, perfStats } =\n\t\t\tcommandContext;\n\n\t\t// Use the repo-relative path so that regexes that specify string start (^) will match repo paths.\n\t\t// Replace \\ in result with / in case OS is Windows.\n\t\tconst relPath = path.relative(gitRoot, file).replace(/\\\\/g, \"/\");\n\t\tconst config = this.commandConfig;\n\n\t\tawait Promise.all(\n\t\t\tpolicies\n\t\t\t\t.filter((handler) => handler.match.test(relPath))\n\t\t\t\t// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>\n\t\t\t\t.map(async (policy): Promise<void> => {\n\t\t\t\t\t// doing exclusion per handler\n\t\t\t\t\tconst exclusions = excludePoliciesForFiles.get(policy.name);\n\t\t\t\t\tif (\n\t\t\t\t\t\texclusions !== undefined &&\n\t\t\t\t\t\t!exclusions.every((regex) => !regex.test(relPath))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await runWithPerf(\n\t\t\t\t\t\tpolicy.name,\n\t\t\t\t\t\t\"handle\",\n\t\t\t\t\t\tperfStats,\n\t\t\t\t\t\tasync () =>\n\t\t\t\t\t\t\tpolicy.handler({\n\t\t\t\t\t\t\t\tfile: relPath,\n\t\t\t\t\t\t\t\troot: gitRoot,\n\t\t\t\t\t\t\t\tresolve: this.flags.fix,\n\t\t\t\t\t\t\t\tconfig: config?.policySettings?.[policy.name],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (result === true) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst messages = new StringBuilder();\n\t\t\t\t\tif (isPolicyFixResult(result)) {\n\t\t\t\t\t\tif (result.resolved) {\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`Resolved ${policy.name} policy failure for file: ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`Error when trying to fix ${policy.name} policy failure in ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// result must be a PolicyFailureResult; check if there is a standalone resolver.\n\t\t\t\t\t\tconst { resolver } = policy;\n\n\t\t\t\t\t\tif (this.flags.fix && resolver !== undefined) {\n\t\t\t\t\t\t\t// Resolve the failure\n\t\t\t\t\t\t\tmessages.append(`${newline}attempting to resolve: ${relPath}`);\n\t\t\t\t\t\t\tconst resolveResult = await runWithPerf(\n\t\t\t\t\t\t\t\tpolicy.name,\n\t\t\t\t\t\t\t\t\"resolve\",\n\t\t\t\t\t\t\t\tperfStats,\n\t\t\t\t\t\t\t\tasync () => resolver({ file: relPath, root: gitRoot }),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tresolveResult.errorMessage !== undefined &&\n\t\t\t\t\t\t\t\tresolveResult.errorMessage !== \"\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tmessages.append(newline + resolveResult.errorMessage);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!resolveResult.resolved) {\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// No resolver, or fix is false, so we're in the full failure case.\n\t\t\t\t\t\t\tconst autoFixable = result.autoFixable\n\t\t\t\t\t\t\t\t? chalk.green(\" (autofixable)\")\n\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`'${policy.name}' policy failure${autoFixable}: ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\tresult.errorMessage === undefined\n\t\t\t\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t\t\t\t: `${newline}${result.errorMessage}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((process.exitCode ?? 0) === 0) {\n\t\t\t\t\t\tthis.info(messages.toString());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.warning(messages.toString());\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,\n\t * routes the file to the appropriate handlers.\n\t */\n\tprivate async checkOrExcludeFile(\n\t\tinputPath: string,\n\t\tcommandContext: PolicyCommandContext,\n\t): Promise<void> {\n\t\tconst { excludeFiles: exclusions, gitRoot, pathRegex } = commandContext;\n\n\t\tconst filePath = path.join(gitRoot, inputPath).trim().replace(/\\\\/g, \"/\");\n\n\t\tif (!(pathRegex.test(inputPath) && fs.existsSync(filePath))) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.count++;\n\t\tif (!exclusions.every((value) => !value.test(inputPath))) {\n\t\t\tthis.verbose(`Excluded all handlers: ${inputPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.routeToHandlers(filePath, commandContext);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(`Error routing ${filePath} to handler: ${error}`);\n\t\t}\n\n\t\tthis.processed++;\n\t}\n}\n\nasync function readStdin(): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\tconst stdin = process.stdin;\n\t\tstdin.setEncoding(\"utf8\");\n\n\t\tlet data = \"\";\n\t\tstdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\n\t\tstdin.on(\"end\", () => {\n\t\t\tresolve(data);\n\t\t});\n\n\t\tif (stdin.isTTY) {\n\t\t\tresolve(\"\");\n\t\t}\n\t});\n}\n"]}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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","sourcesContent":["import { EOL as newline } from \"node:os\";\nimport { Flags } from \"@oclif/core\";\nimport { StringBuilder } from \"@rushstack/node-core-library\";\nimport path from \"pathe\";\nimport chalk from \"picocolors\";\n\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport type { RepopoCommandContext } from \"../context.js\";\nimport { logStats, runWithPerf } from \"../perf.js\";\nimport { type RepoPolicy, isPolicyFixResult } from \"../policy.js\";\n\n/**\n * This tool enforces policies across the code base via a series of handler functions. The handler functions are\n * associated with a regular expression, and all files matching that expression are passed to the handler function.\n *\n * By default, the list of files to check comes from `git ls-files. You can also pipe in file names from stdin. For\n * example:\n *\n * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`\n */\nexport class CheckPolicy<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof CheckPolicy.args;\n\t\tflags: typeof CheckPolicy.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tstatic override readonly summary =\n\t\t\"Checks and applies policies to the files in the repository.\";\n\n\tstatic override readonly flags = {\n\t\tfix: Flags.boolean({\n\t\t\taliases: [\"resolve\"],\n\t\t\tdescription: \"Fix errors if possible.\",\n\t\t\trequired: false,\n\t\t\tchar: \"f\",\n\t\t}),\n\t\tstdin: Flags.boolean({\n\t\t\tdescription: \"Read list of files from stdin.\",\n\t\t\trequired: false,\n\t\t}),\n\t\t...BaseRepopoCommand.flags,\n\t} as const;\n\n\tpublic override async run(): Promise<void> {\n\t\tif (this.flags.fix) {\n\t\t\tthis.info(\"Resolving errors if possible.\");\n\t\t}\n\n\t\tconst config = this.commandConfig;\n\t\tconst policies = config?.policies ?? [];\n\t\tthis.verbose(`${policies.length} policies loaded.`);\n\t\tfor (const h of policies) {\n\t\t\tthis.verbose(h.name);\n\t\t}\n\n\t\tconst filePathsToCheck: string[] = [];\n\n\t\tif (this.flags.stdin) {\n\t\t\tconst stdInput = await readStdin();\n\n\t\t\tif (stdInput !== undefined) {\n\t\t\t\tfilePathsToCheck.push(...stdInput.split(\"\\n\"));\n\t\t\t}\n\t\t} else {\n\t\t\tconst gitFiles =\n\t\t\t\t(await this.git.raw(\n\t\t\t\t\t\"ls-files\",\n\t\t\t\t\t\"-co\",\n\t\t\t\t\t\"--exclude-standard\",\n\t\t\t\t\t\"--full-name\",\n\t\t\t\t)) ?? \"\";\n\n\t\t\tfilePathsToCheck.push(...gitFiles.split(\"\\n\"));\n\t\t}\n\n\t\tawait this.executeAllPolicies(filePathsToCheck);\n\t}\n\n\tprivate async executeAllPolicies(pathsToCheck: string[]): Promise<void> {\n\t\tconst commandContext: RepopoCommandContext = await this.getContext();\n\n\t\ttry {\n\t\t\tfor (const pathToCheck of pathsToCheck) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tawait this.checkOrExcludeFile(pathToCheck, commandContext);\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!this.flags.quiet) {\n\t\t\t\tlogStats(commandContext.perfStats, this);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Routes files to their handlers and resolvers by regex testing their full paths. If a file fails a policy that has a\n\t * resolver, the resolver will be invoked as well. Synchronizes the output, exit codes, and resolve\n\t * decision for all handlers.\n\t */\n\tprivate async routeToHandlers(\n\t\tfile: string,\n\t\tcommandContext: RepopoCommandContext,\n\t): Promise<void> {\n\t\tconst { policies, gitRoot } = commandContext;\n\n\t\t// Use the repo-relative path so that regexes that specify string start (^) will match repo paths.\n\t\t// Replace \\ in result with / in case OS is Windows.\n\t\tconst relPath = path.relative(gitRoot, file).replace(/\\\\/g, \"/\");\n\n\t\tconst filteredPolicies = policies.filter((handler) =>\n\t\t\thandler.match.test(relPath),\n\t\t);\n\n\t\tconst resultsP: Promise<void>[] = [];\n\n\t\tfor (const policy of filteredPolicies) {\n\t\t\tresultsP.push(this.runPolicyOnFile(relPath, policy));\n\t\t}\n\n\t\tawait Promise.all(resultsP);\n\t}\n\n\t// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: FIXME\n\tprivate async runPolicyOnFile(\n\t\trelPath: string,\n\t\t// policies: RepoPolicy[],\n\t\tpolicy: RepoPolicy,\n\t): Promise<void> {\n\t\tconst context = await this.getContext();\n\t\tconst { excludePoliciesForFiles, perfStats, gitRoot } = context;\n\n\t\t// doing exclusion per handler\n\t\tconst exclusions = excludePoliciesForFiles.get(policy.name);\n\t\tif (\n\t\t\texclusions !== undefined &&\n\t\t\t!exclusions.every((regex) => !regex.test(relPath))\n\t\t) {\n\t\t\tthis.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst result = await runWithPerf(\n\t\t\tpolicy.name,\n\t\t\t\"handle\",\n\t\t\tperfStats,\n\t\t\tasync () =>\n\t\t\t\tpolicy.handler({\n\t\t\t\t\tfile: relPath,\n\t\t\t\t\troot: gitRoot,\n\t\t\t\t\tresolve: this.flags.fix,\n\t\t\t\t\tconfig: this.commandConfig?.perPolicyConfig?.[\n\t\t\t\t\t\tpolicy.name\n\t\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: FIXME\n\t\t\t\t\t] as any,\n\t\t\t\t}),\n\t\t);\n\n\t\tif (result === true) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst messages = new StringBuilder();\n\t\tif (isPolicyFixResult(result)) {\n\t\t\tif (result.resolved) {\n\t\t\t\tmessages.append(\n\t\t\t\t\t`Resolved ${policy.name} policy failure for file: ${result.file}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tmessages.append(\n\t\t\t\t\t`Error when trying to fix ${policy.name} policy failure in ${result.file}`,\n\t\t\t\t);\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t}\n\t\t} else {\n\t\t\t// result must be a PolicyFailureResult; check if there is a standalone resolver.\n\t\t\tconst { resolver } = policy;\n\n\t\t\tif (this.flags.fix && resolver !== undefined) {\n\t\t\t\t// Resolve the failure\n\t\t\t\tmessages.append(`${newline}attempting to resolve: ${relPath}`);\n\t\t\t\tconst resolveResult = await runWithPerf(\n\t\t\t\t\tpolicy.name,\n\t\t\t\t\t\"resolve\",\n\t\t\t\t\tperfStats,\n\t\t\t\t\tasync () => resolver({ file: relPath, root: gitRoot }),\n\t\t\t\t);\n\n\t\t\t\tif (\n\t\t\t\t\tresolveResult.errorMessage !== undefined &&\n\t\t\t\t\tresolveResult.errorMessage !== \"\"\n\t\t\t\t) {\n\t\t\t\t\tmessages.append(newline + resolveResult.errorMessage);\n\t\t\t\t}\n\n\t\t\t\tif (!resolveResult.resolved) {\n\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// No resolver, or fix is false, so we're in the full failure case.\n\t\t\t\tconst autoFixable = result.autoFixable\n\t\t\t\t\t? chalk.green(\" (autofixable)\")\n\t\t\t\t\t: \"\";\n\t\t\t\tmessages.append(\n\t\t\t\t\t`'${chalk.bold(policy.name)}' policy failure${autoFixable}: ${result.file}`,\n\t\t\t\t);\n\t\t\t\tmessages.append(\n\t\t\t\t\tresult.errorMessage === undefined\n\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t: `${newline}\\t${result.errorMessage}`,\n\t\t\t\t);\n\t\t\t\tprocess.exitCode = 1;\n\t\t\t}\n\t\t}\n\n\t\tif ((process.exitCode ?? 0) === 0) {\n\t\t\tthis.info(messages.toString());\n\t\t} else {\n\t\t\tthis.warning(messages.toString());\n\t\t}\n\t}\n\n\t/**\n\t * Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,\n\t * routes the file to the appropriate handlers.\n\t */\n\tprivate async checkOrExcludeFile(\n\t\tinputPath: string,\n\t\tcommandContext: RepopoCommandContext,\n\t): Promise<void> {\n\t\tconst { excludeFiles: exclusions, gitRoot, perfStats } = commandContext;\n\n\t\tconst filePath = path.join(gitRoot, inputPath).trim().replace(/\\\\/g, \"/\");\n\n\t\tperfStats.count++;\n\t\tif (!exclusions.every((value) => !value.test(inputPath))) {\n\t\t\tthis.verbose(`Excluded all handlers: ${inputPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.routeToHandlers(filePath, commandContext);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(\n\t\t\t\t`Error routing ${filePath} to handler: ${error}\\nStack:\\n${(error as Error).stack}`,\n\t\t\t);\n\t\t}\n\n\t\tperfStats.processed++;\n\t}\n}\n\nasync function readStdin(): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\tconst stdin = process.stdin;\n\t\tstdin.setEncoding(\"utf8\");\n\n\t\tlet data = \"\";\n\t\tstdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\n\t\tstdin.on(\"end\", () => {\n\t\t\tresolve(data);\n\t\t});\n\n\t\tif (stdin.isTTY) {\n\t\t\tresolve(\"\");\n\t\t}\n\t});\n}\n"]}
@@ -1,5 +1,4 @@
1
1
  import { BaseRepopoCommand } from "../baseCommand.js";
2
- import type { RepoPolicy } from "../policy.js";
3
2
  /**
4
3
  * This command lists all the policies configured to run.
5
4
  */
@@ -8,6 +7,6 @@ export declare class ListCommand<T extends typeof BaseRepopoCommand & {
8
7
  flags: typeof ListCommand.flags;
9
8
  }> extends BaseRepopoCommand<T> {
10
9
  static readonly summary = "Lists the policies configured to run.";
11
- run(): Promise<RepoPolicy[]>;
10
+ run(): Promise<void>;
12
11
  }
13
12
  //# sourceMappingURL=list.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;GAEG;AACH,qBAAa,WAAW,CACvB,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,WAAW,CAAC,KAAK,CAAC;CAChC,CACA,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC7B,gBAAyB,OAAO,2CAA2C;IAGrD,GAAG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;CAUlD"}
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;GAEG;AACH,qBAAa,WAAW,CACvB,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,WAAW,CAAC,KAAK,CAAC;CAChC,CACA,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC7B,gBAAyB,OAAO,2CAA2C;IAGrD,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ1C"}
@@ -1,19 +1,18 @@
1
- import chalk from "picocolors";
2
1
  import { BaseRepopoCommand } from "../baseCommand.js";
2
+ import { DefaultPolicies } from "../policy.js";
3
3
  /**
4
4
  * This command lists all the policies configured to run.
5
5
  */
6
6
  export class ListCommand extends BaseRepopoCommand {
7
7
  static summary = "Lists the policies configured to run.";
8
- // biome-ignore lint/suspicious/useAwait: inherited method
8
+ // biome-ignore lint/suspicious/useAwait: overridden method
9
9
  async run() {
10
- const { policies } = this.getContext();
10
+ const policies = this.commandConfig?.policies ?? DefaultPolicies;
11
11
  // list the handlers then exit
12
- this.log(`${policies.length} POLICIES ENABLED`);
13
12
  for (const h of policies) {
14
- this.log(`${chalk.bold(h.name)} (auto-fix: ${h.resolver !== undefined})`);
13
+ this.log(`${h.name}\nresolver: ${h.resolver !== undefined}\n`);
15
14
  }
16
- return policies;
15
+ this.log(`${policies.length} TOTAL POLICY HANDLERS`);
17
16
  }
18
17
  }
19
18
  //# sourceMappingURL=list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAE/B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;GAEG;AACH,MAAM,OAAO,WAKX,SAAQ,iBAAoB;IAC7B,MAAM,CAAmB,OAAO,GAAG,uCAAuC,CAAC;IAE3E,0DAA0D;IAC1C,KAAK,CAAC,GAAG;QACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAEvC,8BAA8B;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,mBAAmB,CAAC,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,KAAK,SAAS,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC","sourcesContent":["import chalk from \"picocolors\";\n\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport type { RepoPolicy } from \"../policy.js\";\n\n/**\n * This command lists all the policies configured to run.\n */\nexport class ListCommand<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof ListCommand.args;\n\t\tflags: typeof ListCommand.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tstatic override readonly summary = \"Lists the policies configured to run.\";\n\n\t// biome-ignore lint/suspicious/useAwait: inherited method\n\tpublic override async run(): Promise<RepoPolicy[]> {\n\t\tconst { policies } = this.getContext();\n\n\t\t// list the handlers then exit\n\t\tthis.log(`${policies.length} POLICIES ENABLED`);\n\t\tfor (const h of policies) {\n\t\t\tthis.log(`${chalk.bold(h.name)} (auto-fix: ${h.resolver !== undefined})`);\n\t\t}\n\t\treturn policies;\n\t}\n}\n"]}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C;;GAEG;AACH,MAAM,OAAO,WAKX,SAAQ,iBAAoB;IAC7B,MAAM,CAAmB,OAAO,GAAG,uCAAuC,CAAC;IAE3E,2DAA2D;IAC3C,KAAK,CAAC,GAAG;QACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,EAAE,QAAQ,IAAI,eAAe,CAAC;QACjE,8BAA8B;QAC9B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,eAAe,CAAC,CAAC,QAAQ,KAAK,SAAS,IAAI,CAAC,CAAC;QAChE,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,wBAAwB,CAAC,CAAC;IACtD,CAAC","sourcesContent":["import { BaseRepopoCommand } from \"../baseCommand.js\";\nimport { DefaultPolicies } from \"../policy.js\";\n\n/**\n * This command lists all the policies configured to run.\n */\nexport class ListCommand<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof ListCommand.args;\n\t\tflags: typeof ListCommand.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tstatic override readonly summary = \"Lists the policies configured to run.\";\n\n\t// biome-ignore lint/suspicious/useAwait: overridden method\n\tpublic override async run(): Promise<void> {\n\t\tconst policies = this.commandConfig?.policies ?? DefaultPolicies;\n\t\t// list the handlers then exit\n\t\tfor (const h of policies) {\n\t\t\tthis.log(`${h.name}\\nresolver: ${h.resolver !== undefined}\\n`);\n\t\t}\n\t\tthis.log(`${policies.length} TOTAL POLICY HANDLERS`);\n\t}\n}\n"]}
package/esm/config.d.ts CHANGED
@@ -9,11 +9,16 @@ export type PerPolicySettings = ({
9
9
  /**
10
10
  * @alpha
11
11
  */
12
- export interface PolicyConfig {
12
+ /**
13
+ * @alpha
14
+ */
15
+ export interface RepopoConfig {
13
16
  /**
14
- * An array of policies that are enabled. If this is `undefined`, then all {@link DefaultPolicies} will be enabled.
17
+ * An array of policies that are enabled.
18
+ *
19
+ * See `DefaultPolicies` for the policies that will be enabled by default if this is `undefined`.
15
20
  */
16
- policies?: RepoPolicy[];
21
+ policies?: RepoPolicy<any>[];
17
22
  /**
18
23
  * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded
19
24
  * from policy.
@@ -24,12 +29,12 @@ export interface PolicyConfig {
24
29
  * exclude that rule from being checked.
25
30
  */
26
31
  excludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;
27
- policySettings?: PerPolicySettings | undefined;
32
+ perPolicyConfig?: PerPolicySettings | undefined;
28
33
  }
29
34
  /**
30
35
  * The default config applied when no config is found.
31
36
  *
32
37
  * @alpha
33
38
  */
34
- export declare const DefaultPolicyConfig: PolicyConfig;
39
+ export declare const DefaultPolicyConfig: RepopoConfig;
35
40
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAC1B,CAAC;IACD,qBAAqB,EAAE,6BAA6B,CAAC;CACpD,GAAG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,GAChC,SAAS,CAAC;AAEb;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IAExB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEnC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAElE,cAAc,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC/C;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAIjC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAC1B,CAAC;IACD,qBAAqB,EAAE,6BAA6B,CAAC;CACpD,GAAG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,GAChC,SAAS,CAAC;AAEb;;GAEG;AACH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;;;OAIG;IAGH,QAAQ,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;IAE7B;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEnC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAGlE,eAAe,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAChD;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAIjC,CAAC"}
package/esm/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAoC,MAAM,aAAa,CAAC;AAmChF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAChD,QAAQ,EAAE,eAAe;IACzB,YAAY,EAAE,EAAE;IAChB,uBAAuB,EAAE,EAAE;CAC3B,CAAC","sourcesContent":["import type { PackageJsonPropertiesSettings } from \"./policies/PackageJsonProperties.js\";\nimport { DefaultPolicies, type PolicyName, type RepoPolicy } from \"./policy.js\";\n\n/**\n * @alpha\n */\nexport type PerPolicySettings =\n\t| ({\n\t\t\tPackageJsonProperties: PackageJsonPropertiesSettings;\n\t } & Record<PolicyName, unknown>)\n\t| undefined;\n\n/**\n * @alpha\n */\nexport interface PolicyConfig {\n\t/**\n\t * An array of policies that are enabled. If this is `undefined`, then all {@link DefaultPolicies} will be enabled.\n\t */\n\tpolicies?: RepoPolicy[];\n\n\t/**\n\t * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded\n\t * from policy.\n\t */\n\texcludeFiles?: (string | RegExp)[];\n\n\t/**\n\t * An object with a policy name as keys that map to an array of strings/regular expressions to\n\t * exclude that rule from being checked.\n\t */\n\texcludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;\n\n\tpolicySettings?: PerPolicySettings | undefined;\n}\n\n/**\n * The default config applied when no config is found.\n *\n * @alpha\n */\nexport const DefaultPolicyConfig: PolicyConfig = {\n\tpolicies: DefaultPolicies,\n\texcludeFiles: [],\n\texcludePoliciesForFiles: {},\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAoC,MAAM,aAAa,CAAC;AA2ChF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAChD,QAAQ,EAAE,eAAe;IACzB,YAAY,EAAE,EAAE;IAChB,uBAAuB,EAAE,EAAE;CAC3B,CAAC","sourcesContent":["import type { PackageJsonPropertiesSettings } from \"./policies/PackageJsonProperties.js\";\nimport { DefaultPolicies, type PolicyName, type RepoPolicy } from \"./policy.js\";\n\n/**\n * @alpha\n */\nexport type PerPolicySettings =\n\t| ({\n\t\t\tPackageJsonProperties: PackageJsonPropertiesSettings;\n\t } & Record<PolicyName, unknown>)\n\t| undefined;\n\n/**\n * @alpha\n */\n/**\n * @alpha\n */\nexport interface RepopoConfig {\n\t/**\n\t * An array of policies that are enabled.\n\t *\n\t * See `DefaultPolicies` for the policies that will be enabled by default if this is `undefined`.\n\t */\n\n\t// biome-ignore lint/suspicious/noExplicitAny: FIXME\n\tpolicies?: RepoPolicy<any>[];\n\n\t/**\n\t * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded\n\t * from policy.\n\t */\n\texcludeFiles?: (string | RegExp)[];\n\n\t/**\n\t * An object with a policy name as keys that map to an array of strings/regular expressions to\n\t * exclude that rule from being checked.\n\t */\n\texcludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;\n\n\t// TODO: The type of this argument would ideally be a union of all types Record<Name of RepoPolicy, C of RepoPolicy>\n\tperPolicyConfig?: PerPolicySettings | undefined;\n}\n\n/**\n * The default config applied when no config is found.\n *\n * @alpha\n */\nexport const DefaultPolicyConfig: RepopoConfig = {\n\tpolicies: DefaultPolicies,\n\texcludeFiles: [],\n\texcludePoliciesForFiles: {},\n};\n"]}
@@ -0,0 +1,29 @@
1
+ import type { PolicyHandlerPerfStats } from "./perf.js";
2
+ import type { PolicyName, RepoPolicy } from "./policy.js";
3
+ export type ExcludedPolicyFileMap = Map<PolicyName, RegExp[]>;
4
+ /**
5
+ * Contextual data available to all Repopo commands.
6
+ */
7
+ export interface RepopoCommandContext {
8
+ /**
9
+ * A list of regular expressions used to exclude files from all handlers.
10
+ */
11
+ excludeFiles: RegExp[];
12
+ /**
13
+ * A list of handlers to apply to selected files.
14
+ */
15
+ policies: RepoPolicy[];
16
+ /**
17
+ * A per-handler list of regular expressions used to exclude files from specific handlers.
18
+ */
19
+ excludePoliciesForFiles: ExcludedPolicyFileMap;
20
+ /**
21
+ * Path to the root of the git repo.
22
+ */
23
+ gitRoot: string;
24
+ /**
25
+ * Stores performance data for each handler. Used to collect and display performance stats.
26
+ */
27
+ perfStats: PolicyHandlerPerfStats;
28
+ }
29
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC;AAE9D;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB;;OAEG;IACH,QAAQ,EAAE,UAAU,EAAE,CAAC;IAEvB;;OAEG;IACH,uBAAuB,EAAE,qBAAqB,CAAC;IAE/C;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,sBAAsB,CAAC;CAClC"}
package/esm/context.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"","sourcesContent":["import type { PolicyHandlerPerfStats } from \"./perf.js\";\nimport type { PolicyName, RepoPolicy } from \"./policy.js\";\n\nexport type ExcludedPolicyFileMap = Map<PolicyName, RegExp[]>;\n\n/**\n * Contextual data available to all Repopo commands.\n */\nexport interface RepopoCommandContext {\n\t/**\n\t * A list of regular expressions used to exclude files from all handlers.\n\t */\n\texcludeFiles: RegExp[];\n\n\t/**\n\t * A list of handlers to apply to selected files.\n\t */\n\tpolicies: RepoPolicy[];\n\n\t/**\n\t * A per-handler list of regular expressions used to exclude files from specific handlers.\n\t */\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\n\t/**\n\t * Path to the root of the git repo.\n\t */\n\tgitRoot: string;\n\n\t/**\n\t * Stores performance data for each handler. Used to collect and display performance stats.\n\t */\n\tperfStats: PolicyHandlerPerfStats;\n}\n"]}
package/esm/index.d.ts CHANGED
@@ -1,6 +1,13 @@
1
1
  export { run } from "@oclif/core";
2
- export type { PolicyFailure, PolicyFixResult, PolicyFunctionArguments, PolicyHandler, PolicyName, PolicyStandaloneResolver, RepoPolicy, } from "./policy.js";
3
- export { DefaultPolicies } from "./policy.js";
4
- export type { PolicyConfig, PerPolicySettings, } from "./config.js";
5
- export type { PackageJsonPropertiesSettings, PackageJsonProperty, } from "./policies/PackageJsonProperties.js";
2
+ export type { DefaultPolicyConfigType, PolicyFailure, PolicyFixResult, PolicyFunctionArguments, PolicyHandler, PolicyName, PolicyStandaloneResolver, RepoPolicy, } from "./policy.js";
3
+ export { DefaultPolicies, type PackageJsonHandler } from "./policy.js";
4
+ export { JsTsFileHeaders } from "./policies/JsTsFileHeaders.js";
5
+ export { NoJsFileExtensions } from "./policies/NoJsFileExtensions.js";
6
+ export { PackageJsonProperties, type PackageJsonPropertiesSettings, } from "./policies/PackageJsonProperties.js";
7
+ export { PackageJsonRepoDirectoryProperty } from "./policies/PackageJsonRepoDirectoryProperty.js";
8
+ export { PackageJsonSorted } from "./policies/PackageJsonSorted.js";
9
+ export { PackageScripts } from "./policies/PackageScripts.js";
10
+ export type { PerPolicySettings, RepopoConfig, } from "./config.js";
11
+ export { generatePackagePolicy } from "./policyGenerators/generatePackagePolicy.js";
12
+ export { generateFileHeaderPolicy, type FileHeaderGeneratorConfig, type FileHeaderPolicyConfig, } from "./policyGenerators/generateFileHeaderPolicy.js";
6
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,YAAY,EACX,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,UAAU,EACV,wBAAwB,EACxB,UAAU,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,YAAY,EACZ,iBAAiB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,6BAA6B,EAC7B,mBAAmB,GACnB,MAAM,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,YAAY,EACX,uBAAuB,EACvB,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,UAAU,EACV,wBAAwB,EACxB,UAAU,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EACN,qBAAqB,EACrB,KAAK,6BAA6B,GAClC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAE9D,YAAY,EACX,iBAAiB,EACjB,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EACN,wBAAwB,EACxB,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,GAC3B,MAAM,gDAAgD,CAAC"}
package/esm/index.js CHANGED
@@ -1,3 +1,11 @@
1
1
  export { run } from "@oclif/core";
2
2
  export { DefaultPolicies } from "./policy.js";
3
+ export { JsTsFileHeaders } from "./policies/JsTsFileHeaders.js";
4
+ export { NoJsFileExtensions } from "./policies/NoJsFileExtensions.js";
5
+ export { PackageJsonProperties, } from "./policies/PackageJsonProperties.js";
6
+ export { PackageJsonRepoDirectoryProperty } from "./policies/PackageJsonRepoDirectoryProperty.js";
7
+ export { PackageJsonSorted } from "./policies/PackageJsonSorted.js";
8
+ export { PackageScripts } from "./policies/PackageScripts.js";
9
+ export { generatePackagePolicy } from "./policyGenerators/generatePackagePolicy.js";
10
+ export { generateFileHeaderPolicy, } from "./policyGenerators/generateFileHeaderPolicy.js";
3
11
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAWlC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export { run } from \"@oclif/core\";\n\nexport type {\n\tPolicyFailure,\n\tPolicyFixResult,\n\tPolicyFunctionArguments,\n\tPolicyHandler,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n\tRepoPolicy,\n} from \"./policy.js\";\nexport { DefaultPolicies } from \"./policy.js\";\nexport type {\n\tPolicyConfig,\n\tPerPolicySettings,\n} from \"./config.js\";\nexport type {\n\tPackageJsonPropertiesSettings,\n\tPackageJsonProperty,\n} from \"./policies/PackageJsonProperties.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAYlC,OAAO,EAAE,eAAe,EAA2B,MAAM,aAAa,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EACN,qBAAqB,GAErB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAM9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,6CAA6C,CAAC;AACpF,OAAO,EACN,wBAAwB,GAGxB,MAAM,gDAAgD,CAAC","sourcesContent":["export { run } from \"@oclif/core\";\n\nexport type {\n\tDefaultPolicyConfigType,\n\tPolicyFailure,\n\tPolicyFixResult,\n\tPolicyFunctionArguments,\n\tPolicyHandler,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n\tRepoPolicy,\n} from \"./policy.js\";\nexport { DefaultPolicies, type PackageJsonHandler } from \"./policy.js\";\nexport { JsTsFileHeaders } from \"./policies/JsTsFileHeaders.js\";\nexport { NoJsFileExtensions } from \"./policies/NoJsFileExtensions.js\";\nexport {\n\tPackageJsonProperties,\n\ttype PackageJsonPropertiesSettings,\n} from \"./policies/PackageJsonProperties.js\";\nexport { PackageJsonRepoDirectoryProperty } from \"./policies/PackageJsonRepoDirectoryProperty.js\";\nexport { PackageJsonSorted } from \"./policies/PackageJsonSorted.js\";\nexport { PackageScripts } from \"./policies/PackageScripts.js\";\n\nexport type {\n\tPerPolicySettings,\n\tRepopoConfig,\n} from \"./config.js\";\nexport { generatePackagePolicy } from \"./policyGenerators/generatePackagePolicy.js\";\nexport {\n\tgenerateFileHeaderPolicy,\n\ttype FileHeaderGeneratorConfig,\n\ttype FileHeaderPolicyConfig,\n} from \"./policyGenerators/generateFileHeaderPolicy.js\";\n"]}
package/esm/perf.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAOhD,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,wBAAgB,YAAY,IAAI,sBAAsB,CAMrD;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,sBAAsB,EAC7B,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAYzE"}
1
+ {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,wBAAgB,YAAY,IAAI,sBAAsB,CAMrD;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,sBAAsB,EAC7B,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAYzE"}
package/esm/perf.js CHANGED
@@ -1,7 +1,3 @@
1
- /**
2
- * Stores performance data for each handler. Used to collect and display performance stats.
3
- */
4
- const handlerPerformanceData = new Map();
5
1
  export function newPerfStats() {
6
2
  return {
7
3
  count: 0,
@@ -21,7 +17,7 @@ export async function runWithPerf(name, action, stats, run) {
21
17
  }
22
18
  export function logStats(stats, log) {
23
19
  log.log(`Statistics: ${stats.processed} processed, ${stats.count - stats.processed} excluded, ${stats.count} total`);
24
- for (const [action, handlerPerf] of handlerPerformanceData.entries()) {
20
+ for (const [action, handlerPerf] of stats.data.entries()) {
25
21
  log.log(`Performance for "${action}":`);
26
22
  for (const [handler, dur] of handlerPerf.entries()) {
27
23
  log.log(`\t${handler}: ${dur}ms`);
package/esm/perf.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAyC,CAAC;AAQhF,MAAM,UAAU,YAAY;IAC3B,OAAO;QACN,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,IAAI,GAAG,EAAyC;KACtD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,IAAY,EACZ,MAAoB,EACpB,KAA6B,EAC7B,GAAqB;IAErB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;IACtE,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAE1B,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAA6B,EAAE,GAAW;IAClE,GAAG,CAAC,GAAG,CACN,eAAe,KAAK,CAAC,SAAS,eAC7B,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SACrB,cAAc,KAAK,CAAC,KAAK,QAAQ,CACjC,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,sBAAsB,CAAC,OAAO,EAAE,EAAE,CAAC;QACtE,GAAG,CAAC,GAAG,CAAC,oBAAoB,MAAM,IAAI,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,KAAK,GAAG,IAAI,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import type { Logger } from \"@tylerbu/cli-api\";\nimport type { PolicyName } from \"./policy.js\";\n\nexport type PolicyAction = \"handle\" | \"resolve\";\n\n/**\n * Stores performance data for each handler. Used to collect and display performance stats.\n */\nconst handlerPerformanceData = new Map<PolicyAction, Map<PolicyName, number>>();\n\nexport interface PolicyHandlerPerfStats {\n\tcount: number;\n\tprocessed: number;\n\tdata: Map<PolicyAction, Map<PolicyName, number>>;\n}\n\nexport function newPerfStats(): PolicyHandlerPerfStats {\n\treturn {\n\t\tcount: 0,\n\t\tprocessed: 0,\n\t\tdata: new Map<PolicyAction, Map<PolicyName, number>>(),\n\t};\n}\n\nexport async function runWithPerf<T>(\n\tname: string,\n\taction: PolicyAction,\n\tstats: PolicyHandlerPerfStats,\n\trun: () => Promise<T>,\n): Promise<T> {\n\tconst actionMap = stats.data.get(action) ?? new Map<string, number>();\n\tlet dur = actionMap.get(name) ?? 0;\n\n\tconst start = Date.now();\n\tconst result = await run();\n\tdur += Date.now() - start;\n\n\tactionMap.set(name, dur);\n\tstats.data.set(action, actionMap);\n\treturn result;\n}\n\nexport function logStats(stats: PolicyHandlerPerfStats, log: Logger): void {\n\tlog.log(\n\t\t`Statistics: ${stats.processed} processed, ${\n\t\t\tstats.count - stats.processed\n\t\t} excluded, ${stats.count} total`,\n\t);\n\tfor (const [action, handlerPerf] of handlerPerformanceData.entries()) {\n\t\tlog.log(`Performance for \"${action}\":`);\n\t\tfor (const [handler, dur] of handlerPerf.entries()) {\n\t\t\tlog.log(`\\t${handler}: ${dur}ms`);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAWA,MAAM,UAAU,YAAY;IAC3B,OAAO;QACN,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,IAAI,GAAG,EAAyC;KACtD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,IAAY,EACZ,MAAoB,EACpB,KAA6B,EAC7B,GAAqB;IAErB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;IACtE,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAE1B,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAA6B,EAAE,GAAW;IAClE,GAAG,CAAC,GAAG,CACN,eAAe,KAAK,CAAC,SAAS,eAC7B,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SACrB,cAAc,KAAK,CAAC,KAAK,QAAQ,CACjC,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC;QAC1D,GAAG,CAAC,GAAG,CAAC,oBAAoB,MAAM,IAAI,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,KAAK,GAAG,IAAI,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import type { Logger } from \"@tylerbu/cli-api\";\nimport type { PolicyName } from \"./policy.js\";\n\nexport type PolicyAction = \"handle\" | \"resolve\";\n\nexport interface PolicyHandlerPerfStats {\n\tcount: number;\n\tprocessed: number;\n\tdata: Map<PolicyAction, Map<PolicyName, number>>;\n}\n\nexport function newPerfStats(): PolicyHandlerPerfStats {\n\treturn {\n\t\tcount: 0,\n\t\tprocessed: 0,\n\t\tdata: new Map<PolicyAction, Map<PolicyName, number>>(),\n\t};\n}\n\nexport async function runWithPerf<T>(\n\tname: string,\n\taction: PolicyAction,\n\tstats: PolicyHandlerPerfStats,\n\trun: () => Promise<T>,\n): Promise<T> {\n\tconst actionMap = stats.data.get(action) ?? new Map<string, number>();\n\tlet dur = actionMap.get(name) ?? 0;\n\n\tconst start = Date.now();\n\tconst result = await run();\n\tdur += Date.now() - start;\n\n\tactionMap.set(name, dur);\n\tstats.data.set(action, actionMap);\n\treturn result;\n}\n\nexport function logStats(stats: PolicyHandlerPerfStats, log: Logger): void {\n\tlog.log(\n\t\t`Statistics: ${stats.processed} processed, ${\n\t\t\tstats.count - stats.processed\n\t\t} excluded, ${stats.count} total`,\n\t);\n\tfor (const [action, handlerPerf] of stats.data.entries()) {\n\t\tlog.log(`Performance for \"${action}\":`);\n\t\tfor (const [handler, dur] of handlerPerf.entries()) {\n\t\t\tlog.log(`\\t${handler}: ${dur}ms`);\n\t\t}\n\t}\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { type FileHeaderPolicyConfig } from "../policyGenerators/generateFileHeaderPolicy.js";
2
+ /**
3
+ * A RepoPolicy that checks that HTML files have the configured header comment.
4
+ *
5
+ * @alpha
6
+ */
7
+ export declare const HtmlFileHeaders: import("../policy.js").RepoPolicy<FileHeaderPolicyConfig>;
8
+ //# sourceMappingURL=HtmlFileHeaders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HtmlFileHeaders.d.ts","sourceRoot":"","sources":["../../src/policies/HtmlFileHeaders.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,sBAAsB,EAE3B,MAAM,iDAAiD,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,eAAe,2DAc1B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { EOL as newline } from "node:os";
2
+ import { generateFileHeaderPolicy, } from "../policyGenerators/generateFileHeaderPolicy.js";
3
+ /**
4
+ * A RepoPolicy that checks that HTML files have the configured header comment.
5
+ *
6
+ * @alpha
7
+ */
8
+ export const HtmlFileHeaders = generateFileHeaderPolicy("HtmlFileHeaders", {
9
+ match: /(^|\/)[^/]+\.[mc]?[jt]sx?$/i,
10
+ lineStart: /<!-- /, // Lines begin with '<!-- '
11
+ lineEnd: / -->\r?\n/, // Lines end with ' -->' followed by CRLF or LF
12
+ replacer: (content, { headerText }) => {
13
+ const newContent = `<!-- ${headerText.replace(newline, ` -->${newline}<!-- `)} -->${newline}${newline}${content}`;
14
+ return newContent;
15
+ },
16
+ });
17
+ //# sourceMappingURL=HtmlFileHeaders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HtmlFileHeaders.js","sourceRoot":"","sources":["../../src/policies/HtmlFileHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAEN,wBAAwB,GACxB,MAAM,iDAAiD,CAAC;AAEzD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,wBAAwB,CAAC,iBAAiB,EAAE;IAC1E,KAAK,EAAE,6BAA6B;IACpC,SAAS,EAAE,OAAO,EAAE,2BAA2B;IAC/C,OAAO,EAAE,WAAW,EAAE,+CAA+C;IACrE,QAAQ,EAAE,CACT,OAAe,EACf,EAAE,UAAU,EAA0B,EAC7B,EAAE;QACX,MAAM,UAAU,GAAG,QAAQ,UAAU,CAAC,OAAO,CAC5C,OAAO,EACP,OAAO,OAAO,OAAO,CACrB,OAAO,OAAO,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;QACtC,OAAO,UAAU,CAAC;IACnB,CAAC;CACD,CAAC,CAAC","sourcesContent":["import { EOL as newline } from \"node:os\";\nimport {\n\ttype FileHeaderPolicyConfig,\n\tgenerateFileHeaderPolicy,\n} from \"../policyGenerators/generateFileHeaderPolicy.js\";\n\n/**\n * A RepoPolicy that checks that HTML files have the configured header comment.\n *\n * @alpha\n */\nexport const HtmlFileHeaders = generateFileHeaderPolicy(\"HtmlFileHeaders\", {\n\tmatch: /(^|\\/)[^/]+\\.[mc]?[jt]sx?$/i,\n\tlineStart: /<!-- /, // Lines begin with '<!-- '\n\tlineEnd: / -->\\r?\\n/, // Lines end with ' -->' followed by CRLF or LF\n\treplacer: (\n\t\tcontent: string,\n\t\t{ headerText }: FileHeaderPolicyConfig,\n\t): string => {\n\t\tconst newContent = `<!-- ${headerText.replace(\n\t\t\tnewline,\n\t\t\t` -->${newline}<!-- `,\n\t\t)} -->${newline}${newline}${content}`;\n\t\treturn newContent;\n\t},\n});\n"]}
@@ -0,0 +1,8 @@
1
+ import { type FileHeaderPolicyConfig } from "../policyGenerators/generateFileHeaderPolicy.js";
2
+ /**
3
+ * A RepoPolicy that checks that JavaScript and TypeScript source files have the configured header comment
4
+ *
5
+ * @alpha
6
+ */
7
+ export declare const JsTsFileHeaders: import("../policy.js").RepoPolicy<FileHeaderPolicyConfig>;
8
+ //# sourceMappingURL=JsTsFileHeaders.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JsTsFileHeaders.d.ts","sourceRoot":"","sources":["../../src/policies/JsTsFileHeaders.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,sBAAsB,EAE3B,MAAM,iDAAiD,CAAC;AAkBzD;;;;GAIG;AACH,eAAO,MAAM,eAAe,2DAO1B,CAAC"}