repopo 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -0
- package/README.md +3 -5
- package/THIRD-PARTY-LICENSES.txt +2 -2
- package/esm/baseCommand.d.ts.map +1 -1
- package/esm/baseCommand.js +7 -8
- package/esm/baseCommand.js.map +1 -1
- package/esm/commands/check.d.ts +17 -6
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +134 -94
- package/esm/commands/check.js.map +1 -1
- package/esm/config.d.ts +4 -15
- package/esm/config.d.ts.map +1 -1
- package/esm/config.js +3 -2
- package/esm/config.js.map +1 -1
- package/esm/context.d.ts +3 -3
- package/esm/context.d.ts.map +1 -1
- package/esm/context.js.map +1 -1
- package/esm/generators.d.ts +21 -0
- package/esm/generators.d.ts.map +1 -0
- package/esm/generators.js +2 -0
- package/esm/generators.js.map +1 -0
- package/esm/index.d.ts +5 -11
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +3 -9
- package/esm/index.js.map +1 -1
- package/esm/makePolicy.d.ts +9 -0
- package/esm/makePolicy.d.ts.map +1 -0
- package/esm/makePolicy.js +28 -0
- package/esm/makePolicy.js.map +1 -0
- package/esm/policies/HtmlFileHeaders.d.ts +2 -2
- package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
- package/esm/policies/HtmlFileHeaders.js +2 -2
- package/esm/policies/HtmlFileHeaders.js.map +1 -1
- package/esm/policies/JsTsFileHeaders.d.ts +2 -2
- package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
- package/esm/policies/JsTsFileHeaders.js +2 -2
- package/esm/policies/JsTsFileHeaders.js.map +1 -1
- package/esm/policies/NoJsFileExtensions.d.ts +2 -2
- package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
- package/esm/policies/NoJsFileExtensions.js +13 -15
- package/esm/policies/NoJsFileExtensions.js.map +1 -1
- package/esm/policies/PackageJsonProperties.d.ts +1 -1
- package/esm/policies/PackageJsonProperties.d.ts.map +1 -1
- package/esm/policies/PackageJsonProperties.js +3 -3
- package/esm/policies/PackageJsonProperties.js.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.js +2 -2
- package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
- package/esm/policies/PackageJsonSorted.d.ts +1 -1
- package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
- package/esm/policies/PackageJsonSorted.js +2 -2
- package/esm/policies/PackageJsonSorted.js.map +1 -1
- package/esm/policies/PackageScripts.d.ts +1 -1
- package/esm/policies/PackageScripts.d.ts.map +1 -1
- package/esm/policies/PackageScripts.js +2 -2
- package/esm/policies/PackageScripts.js.map +1 -1
- package/esm/policies.d.ts +4 -3
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +4 -3
- package/esm/policies.js.map +1 -1
- package/esm/policy.d.ts +40 -13
- package/esm/policy.d.ts.map +1 -1
- package/esm/policy.js +18 -7
- package/esm/policy.js.map +1 -1
- package/esm/{policyGenerators/generateFileHeaderPolicy.d.ts → policyDefiners/defineFileHeaderPolicy.d.ts} +4 -4
- package/esm/policyDefiners/defineFileHeaderPolicy.d.ts.map +1 -0
- package/esm/{policyGenerators/generateFileHeaderPolicy.js → policyDefiners/defineFileHeaderPolicy.js} +3 -3
- package/esm/policyDefiners/defineFileHeaderPolicy.js.map +1 -0
- package/esm/policyDefiners/definePackagePolicy.d.ts +15 -0
- package/esm/policyDefiners/definePackagePolicy.d.ts.map +1 -0
- package/esm/{policyGenerators/generatePackagePolicy.js → policyDefiners/definePackagePolicy.js} +2 -2
- package/esm/policyDefiners/definePackagePolicy.js.map +1 -0
- package/esm/tsdoc-metadata.json +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +10 -12
- package/esm/policyGenerators/generateFileHeaderPolicy.d.ts.map +0 -1
- package/esm/policyGenerators/generateFileHeaderPolicy.js.map +0 -1
- package/esm/policyGenerators/generatePackagePolicy.d.ts +0 -9
- package/esm/policyGenerators/generatePackagePolicy.d.ts.map +0 -1
- package/esm/policyGenerators/generatePackagePolicy.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,40 @@
|
|
|
1
1
|
# repopo
|
|
2
2
|
|
|
3
|
+
## 0.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Configuration changes _[`#224`](https://github.com/tylerbutler/tools-monorepo/pull/224) [`2b7db34`](https://github.com/tylerbutler/tools-monorepo/commit/2b7db343d74ab2e518ab2f232f47ea365ca784b8) [@tylerbutler](https://github.com/tylerbutler)_
|
|
8
|
+
|
|
9
|
+
The configuration for repopo has changed a lot in this release. The goal is to improve the typing of config and make it
|
|
10
|
+
easier to configure things in one place.
|
|
11
|
+
|
|
12
|
+
Policies are now declared as `PolicyDefinition`, and are then combined with a configuration (if the policy has
|
|
13
|
+
configuration) using `makePolicy` to form a `PolicyInstance`, which is the primary type used internally.
|
|
14
|
+
|
|
15
|
+
Generators now generate `PolicyDefinition`s, and can be used directly inline with `makePolicy`.
|
|
16
|
+
|
|
17
|
+
- Export policies from /policies entrypoint only _[`#224`](https://github.com/tylerbutler/tools-monorepo/pull/224) [`2b7db34`](https://github.com/tylerbutler/tools-monorepo/commit/2b7db343d74ab2e518ab2f232f47ea365ca784b8) [@tylerbutler](https://github.com/tylerbutler)_
|
|
18
|
+
|
|
19
|
+
Policies included with repopo are now exported from `repopo/policies`.
|
|
20
|
+
|
|
21
|
+
### Patch Changes
|
|
22
|
+
|
|
23
|
+
- Update package metadata _[`#221`](https://github.com/tylerbutler/tools-monorepo/pull/221) [`9e5225a`](https://github.com/tylerbutler/tools-monorepo/commit/9e5225abfb67af1575af13dff60830d8da28eafd) [@tylerbutler](https://github.com/tylerbutler)_
|
|
24
|
+
|
|
25
|
+
<details><summary>Updated 2 dependencies</summary>
|
|
26
|
+
|
|
27
|
+
<small>
|
|
28
|
+
|
|
29
|
+
[`9e5225a`](https://github.com/tylerbutler/tools-monorepo/commit/9e5225abfb67af1575af13dff60830d8da28eafd)
|
|
30
|
+
|
|
31
|
+
</small>
|
|
32
|
+
|
|
33
|
+
- `@tylerbu/fundamentals@0.2.2`
|
|
34
|
+
- `@tylerbu/cli-api@0.7.2`
|
|
35
|
+
|
|
36
|
+
</details>
|
|
37
|
+
|
|
3
38
|
## 0.5.0
|
|
4
39
|
|
|
5
40
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -24,14 +24,12 @@ By default, all files in the repo are checked. You can exclude files completely
|
|
|
24
24
|
d `excludeFiles` setting. It should be an array of strings/regular expressions. Paths that match any of these
|
|
25
25
|
expressions will be completely excluded from all policies.
|
|
26
26
|
|
|
27
|
-
You can exclude files from individual policies as well
|
|
28
|
-
|
|
29
|
-
any of these expressions will be excluded from that policy only.
|
|
27
|
+
You can exclude files from individual policies as well by configuring the `excludeFiles` setting when calling
|
|
28
|
+
`makePolicy`.
|
|
30
29
|
|
|
31
30
|
## Configuring individual policies
|
|
32
31
|
|
|
33
|
-
Individual policies can be configured
|
|
34
|
-
policy settings as the value.
|
|
32
|
+
Individual policies can be configured by passing configuration settings to a `PolicyDefinition` in `makePolicy`.
|
|
35
33
|
|
|
36
34
|
# Included policies
|
|
37
35
|
|
package/THIRD-PARTY-LICENSES.txt
CHANGED
|
@@ -27,7 +27,7 @@ OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHE
|
|
|
27
27
|
|
|
28
28
|
The following npm package may be included in this product:
|
|
29
29
|
|
|
30
|
-
- @rushstack/node-core-library@5.13.
|
|
30
|
+
- @rushstack/node-core-library@5.13.1
|
|
31
31
|
|
|
32
32
|
This package contains the following license:
|
|
33
33
|
|
|
@@ -124,7 +124,7 @@ MIT
|
|
|
124
124
|
|
|
125
125
|
The following npm packages may be included in this product:
|
|
126
126
|
|
|
127
|
-
- @oclif/core@4.
|
|
127
|
+
- @oclif/core@4.3.0
|
|
128
128
|
- @oclif/plugin-help@6.2.27
|
|
129
129
|
|
|
130
130
|
These packages each contain the following license:
|
package/esm/baseCommand.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseCommand.d.ts","sourceRoot":"","sources":["../src/baseCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,YAAY,CAAC;AACvD,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAyB,oBAAoB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"baseCommand.d.ts","sourceRoot":"","sources":["../src/baseCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,YAAY,CAAC;AACvD,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAyB,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAKhF;;GAEG;AACH,8BAAsB,iBAAiB,CACrC,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,iBAAiB,CAAC,IAAI,CAAC;IACpC,KAAK,EAAE,OAAO,iBAAiB,CAAC,KAAK,CAAC;CACtC,CAEF,SAAQ,iBAAiB,CAAC,CAAC,EAAE,YAAY,CACzC,YAAW,kBAAkB,CAAC,oBAAoB,CAAC,EAAE,WAAW;IAEhE,UAAmB,aAAa,eAAuB;IAEvD,gBAAyB,KAAK;gCAb2D,wBAE5E,wCACD,wBAAwB;MAYzB;IAEX,OAAO,CAAC,IAAI,CAAwB;IACpC,IAAW,GAAG,IAAI,SAAS,CAK1B;IAEqB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3C,OAAO,CAAC,QAAQ,CAAmC;IAGtC,UAAU,IAAI,OAAO,CAAC,oBAAoB,CAAC;CAMxD"}
|
package/esm/baseCommand.js
CHANGED
|
@@ -2,6 +2,7 @@ import { CommandWithConfig, } from "@tylerbu/cli-api";
|
|
|
2
2
|
import { findGitRootSync } from "@tylerbu/fundamentals/git";
|
|
3
3
|
import { simpleGit } from "simple-git";
|
|
4
4
|
import { DefaultPolicyConfig } from "./config.js";
|
|
5
|
+
import { makePolicy } from "./makePolicy.js";
|
|
5
6
|
import { newPerfStats } from "./perf.js";
|
|
6
7
|
import { DefaultPolicies } from "./policy.js";
|
|
7
8
|
/**
|
|
@@ -22,19 +23,17 @@ export class BaseRepopoCommand extends CommandWithConfig {
|
|
|
22
23
|
async init() {
|
|
23
24
|
await super.init();
|
|
24
25
|
const excludeFiles = this.commandConfig?.excludeFiles?.map((e) => new RegExp(e, "i")) ?? [];
|
|
25
|
-
const excludePoliciesForFilesRaw = this.commandConfig?.excludePoliciesForFiles;
|
|
26
26
|
const excludePoliciesForFiles = new Map();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
excludePoliciesForFiles.set(policyName, regexes);
|
|
31
|
-
}
|
|
27
|
+
for (const policy of this.commandConfig?.policies ?? []) {
|
|
28
|
+
const regexes = policy.excludeFiles?.map((e) => new RegExp(e, "i")) ?? [];
|
|
29
|
+
excludePoliciesForFiles.set(policy.name, regexes);
|
|
32
30
|
}
|
|
33
31
|
const gitRoot = findGitRootSync();
|
|
34
32
|
this._git = simpleGit({ baseDir: gitRoot });
|
|
35
33
|
this._context = {
|
|
36
|
-
excludeFiles,
|
|
37
|
-
policies: this.commandConfig?.policies ??
|
|
34
|
+
excludeFromAll: excludeFiles,
|
|
35
|
+
policies: this.commandConfig?.policies ??
|
|
36
|
+
DefaultPolicies.map((p) => makePolicy(p)),
|
|
38
37
|
excludePoliciesForFiles,
|
|
39
38
|
gitRoot,
|
|
40
39
|
perfStats: newPerfStats(),
|
package/esm/baseCommand.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"baseCommand.js","sourceRoot":"","sources":["../src/baseCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,GAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,OAAgB,iBAMrB,SAAQ,iBAAkC;IAGvB,aAAa,GAAG,mBAAmB,CAAC;IAEvD,MAAM,CAAmB,KAAK,GAAG;QAChC,GAAG,iBAAiB,CAAC,KAAK;KACjB,CAAC;IAEH,IAAI,CAAwB;IACpC,IAAW,GAAG;QACb,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAEe,KAAK,CAAC,IAAI;QACzB,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,MAAM,YAAY,GACjB,IAAI,CAAC,aAAa,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAExE,MAAM,
|
|
1
|
+
{"version":3,"file":"baseCommand.js","sourceRoot":"","sources":["../src/baseCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,GAGjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAkB,SAAS,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAqB,MAAM,aAAa,CAAC;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C;;GAEG;AACH,MAAM,OAAgB,iBAMrB,SAAQ,iBAAkC;IAGvB,aAAa,GAAG,mBAAmB,CAAC;IAEvD,MAAM,CAAmB,KAAK,GAAG;QAChC,GAAG,iBAAiB,CAAC,KAAK;KACjB,CAAC;IAEH,IAAI,CAAwB;IACpC,IAAW,GAAG;QACb,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,IAAI,CAAC,IAAI,CAAC;IAClB,CAAC;IAEe,KAAK,CAAC,IAAI;QACzB,MAAM,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnB,MAAM,YAAY,GACjB,IAAI,CAAC,aAAa,EAAE,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAExE,MAAM,uBAAuB,GAA0B,IAAI,GAAG,EAAE,CAAC;QACjE,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,aAAa,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC;YACzD,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC1E,uBAAuB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,OAAO,GAAG,eAAe,EAAE,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,GAAG;YACf,cAAc,EAAE,YAAY;YAC5B,QAAQ,EACP,IAAI,CAAC,aAAa,EAAE,QAAQ;gBAC5B,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;YAC1C,uBAAuB;YACvB,OAAO;YACP,SAAS,EAAE,YAAY,EAAE;SACzB,CAAC;IACH,CAAC;IAEO,QAAQ,CAAmC;IAEnD,yEAAyE;IAClE,KAAK,CAAC,UAAU;QACtB,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC;IACtB,CAAC","sourcesContent":["import {\n\tCommandWithConfig,\n\ttype CommandWithContext,\n\ttype RequiresGit,\n} from \"@tylerbu/cli-api\";\nimport { findGitRootSync } from \"@tylerbu/fundamentals/git\";\nimport { type SimpleGit, simpleGit } from \"simple-git\";\nimport { DefaultPolicyConfig, type RepopoConfig } from \"./config.js\";\nimport type { ExcludedPolicyFileMap, RepopoCommandContext } from \"./context.js\";\nimport { makePolicy } from \"./makePolicy.js\";\nimport { newPerfStats } from \"./perf.js\";\nimport { DefaultPolicies } from \"./policy.js\";\n\n/**\n * This class is the base for all repopo commands. It contains common flags and config loading.\n */\nexport abstract class BaseRepopoCommand<\n\t\tT extends typeof BaseRepopoCommand & {\n\t\t\targs: typeof CommandWithConfig.args;\n\t\t\tflags: typeof CommandWithConfig.flags;\n\t\t},\n\t>\n\textends CommandWithConfig<T, RepopoConfig>\n\timplements CommandWithContext<RepopoCommandContext>, RequiresGit\n{\n\tprotected override defaultConfig = DefaultPolicyConfig;\n\n\tstatic override readonly flags = {\n\t\t...CommandWithConfig.flags,\n\t} as const;\n\n\tprivate _git: SimpleGit | undefined;\n\tpublic get git(): SimpleGit {\n\t\tif (this._git === undefined) {\n\t\t\tthrow new Error(\"git property is undefined\");\n\t\t}\n\t\treturn this._git;\n\t}\n\n\tpublic override async init(): Promise<void> {\n\t\tawait super.init();\n\n\t\tconst excludeFiles: RegExp[] =\n\t\t\tthis.commandConfig?.excludeFiles?.map((e) => new RegExp(e, \"i\")) ?? [];\n\n\t\tconst excludePoliciesForFiles: ExcludedPolicyFileMap = new Map();\n\t\tfor (const policy of this.commandConfig?.policies ?? []) {\n\t\t\tconst regexes = policy.excludeFiles?.map((e) => new RegExp(e, \"i\")) ?? [];\n\t\t\texcludePoliciesForFiles.set(policy.name, regexes);\n\t\t}\n\n\t\tconst gitRoot = findGitRootSync();\n\t\tthis._git = simpleGit({ baseDir: gitRoot });\n\t\tthis._context = {\n\t\t\texcludeFromAll: excludeFiles,\n\t\t\tpolicies:\n\t\t\t\tthis.commandConfig?.policies ??\n\t\t\t\tDefaultPolicies.map((p) => makePolicy(p)),\n\t\t\texcludePoliciesForFiles,\n\t\t\tgitRoot,\n\t\t\tperfStats: newPerfStats(),\n\t\t};\n\t}\n\n\tprivate _context: RepopoCommandContext | undefined;\n\n\t// biome-ignore lint/suspicious/useAwait: interface defines this as async\n\tpublic async getContext(): Promise<RepopoCommandContext> {\n\t\tif (this._context === undefined) {\n\t\t\tthrow new Error(\"Context not initialized.\");\n\t\t}\n\t\treturn this._context;\n\t}\n}\n"]}
|
package/esm/commands/check.d.ts
CHANGED
|
@@ -19,18 +19,29 @@ export declare class CheckPolicy<T extends typeof BaseRepopoCommand & {
|
|
|
19
19
|
readonly stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
20
20
|
};
|
|
21
21
|
run(): Promise<void>;
|
|
22
|
-
private executeAllPolicies;
|
|
23
22
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* Executes all policies against the provided paths.
|
|
24
|
+
*
|
|
25
|
+
* @param pathsToCheck - All paths that should be checked. Paths should be relative to the repository root.
|
|
26
|
+
* @param context - The context.
|
|
27
27
|
*/
|
|
28
|
-
private
|
|
29
|
-
private runPolicyOnFile;
|
|
28
|
+
private checkAllFiles;
|
|
30
29
|
/**
|
|
31
30
|
* Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,
|
|
32
31
|
* routes the file to the appropriate handlers.
|
|
32
|
+
*
|
|
33
|
+
* @param relPath - A git repo-relative path to a file.
|
|
33
34
|
*/
|
|
34
35
|
private checkOrExcludeFile;
|
|
36
|
+
private routeToPolicies;
|
|
37
|
+
private runPolicyOnFile;
|
|
38
|
+
private isPolicyExcluded;
|
|
39
|
+
private executePolicyHandler;
|
|
40
|
+
private handlePolicyResult;
|
|
41
|
+
private handleFixResult;
|
|
42
|
+
private handleFailureResult;
|
|
43
|
+
private attemptResolution;
|
|
44
|
+
private logPolicyFailure;
|
|
45
|
+
private logMessages;
|
|
35
46
|
}
|
|
36
47
|
//# sourceMappingURL=check.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAYtD;;;;;;;;GAQG;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,iEAC+B;IAE/D,gBAAyB,KAAK;gCAjBiB,wBAAwB,wCACvE,wBAAsB;;;MA4BX;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAwD1C;;;;;OAKG;YACW,aAAa;IAe3B;;;;;OAKG;YACW,kBAAkB;YAkBlB,eAAe;YA4Bf,eAAe;IAsC7B,OAAO,CAAC,gBAAgB;YAYV,oBAAoB;YAsBpB,kBAAkB;IAwBhC,OAAO,CAAC,eAAe;YAoBT,mBAAmB;YAyBnB,iBAAiB;IAyB/B,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,WAAW;CAOnB"}
|
package/esm/commands/check.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { EOL as newline } from "node:os";
|
|
2
2
|
import { Flags } from "@oclif/core";
|
|
3
3
|
import { StringBuilder } from "@rushstack/node-core-library";
|
|
4
|
-
import path from "pathe";
|
|
5
4
|
import chalk from "picocolors";
|
|
6
5
|
import { BaseRepopoCommand } from "../baseCommand.js";
|
|
7
6
|
import { logStats, runWithPerf } from "../perf.js";
|
|
8
|
-
import { isPolicyFixResult } from "../policy.js";
|
|
7
|
+
import { isPolicyFixResult, } from "../policy.js";
|
|
9
8
|
/**
|
|
10
9
|
* This tool enforces policies across the code base via a series of handler functions. The handler functions are
|
|
11
10
|
* associated with a regular expression, and all files matching that expression are passed to the handler function.
|
|
@@ -44,133 +43,174 @@ export class CheckPolicy extends BaseRepopoCommand {
|
|
|
44
43
|
if (this.flags.stdin) {
|
|
45
44
|
const stdInput = await readStdin();
|
|
46
45
|
if (stdInput !== undefined) {
|
|
47
|
-
filePathsToCheck.push(...stdInput
|
|
46
|
+
filePathsToCheck.push(...stdInput
|
|
47
|
+
.replace(
|
|
48
|
+
// normalize slashes in case they're windows paths
|
|
49
|
+
/\\/g, "/")
|
|
50
|
+
.split("\n"));
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
else {
|
|
51
|
-
const gitFiles = (await this.git.raw("ls-files",
|
|
52
|
-
|
|
54
|
+
const gitFiles = (await this.git.raw("ls-files",
|
|
55
|
+
// include staged files and untracked files
|
|
56
|
+
"-co",
|
|
57
|
+
// exclude gitignored files and other standard ignore rules
|
|
58
|
+
"--exclude-standard",
|
|
59
|
+
// Outputs paths relative to the root of the repository, regardless of the current working directory.
|
|
60
|
+
"--full-name")) ?? "";
|
|
61
|
+
filePathsToCheck.push(...gitFiles
|
|
62
|
+
.replace(
|
|
63
|
+
// normalize slashes in case they're windows paths
|
|
64
|
+
/\\/g, "/")
|
|
65
|
+
.split("\n"));
|
|
53
66
|
}
|
|
54
|
-
await this.
|
|
67
|
+
const context = await this.getContext();
|
|
68
|
+
await this.checkAllFiles(filePathsToCheck, context);
|
|
55
69
|
}
|
|
56
|
-
|
|
57
|
-
|
|
70
|
+
/**
|
|
71
|
+
* Executes all policies against the provided paths.
|
|
72
|
+
*
|
|
73
|
+
* @param pathsToCheck - All paths that should be checked. Paths should be relative to the repository root.
|
|
74
|
+
* @param context - The context.
|
|
75
|
+
*/
|
|
76
|
+
async checkAllFiles(pathsToCheck, context) {
|
|
58
77
|
try {
|
|
59
78
|
for (const pathToCheck of pathsToCheck) {
|
|
60
|
-
|
|
61
|
-
await this.checkOrExcludeFile(pathToCheck, commandContext);
|
|
79
|
+
await this.checkOrExcludeFile(pathToCheck, context);
|
|
62
80
|
}
|
|
63
81
|
}
|
|
64
82
|
finally {
|
|
65
83
|
if (!this.flags.quiet) {
|
|
66
|
-
logStats(
|
|
84
|
+
logStats(context.perfStats, this);
|
|
67
85
|
}
|
|
68
86
|
}
|
|
69
87
|
}
|
|
70
88
|
/**
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
89
|
+
* Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,
|
|
90
|
+
* routes the file to the appropriate handlers.
|
|
91
|
+
*
|
|
92
|
+
* @param relPath - A git repo-relative path to a file.
|
|
74
93
|
*/
|
|
75
|
-
async
|
|
76
|
-
const {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
await Promise.all(resultsP);
|
|
94
|
+
async checkOrExcludeFile(relPath, context) {
|
|
95
|
+
const { perfStats } = context;
|
|
96
|
+
perfStats.count++;
|
|
97
|
+
try {
|
|
98
|
+
await this.routeToPolicies(relPath, context);
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
throw new Error(`Error routing ${relPath} to handler: ${error}\nStack:\n${error.stack}`);
|
|
102
|
+
}
|
|
103
|
+
perfStats.processed++;
|
|
86
104
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
105
|
+
async routeToPolicies(relPath, context) {
|
|
106
|
+
const { policies, excludeFromAll } = context;
|
|
107
|
+
// Check exclusions
|
|
108
|
+
if (excludeFromAll.some((regex) => regex.test(relPath))) {
|
|
109
|
+
this.verbose(`Excluded all handlers: ${relPath}`);
|
|
110
|
+
return; // Early return for excluded files
|
|
111
|
+
}
|
|
112
|
+
// Run all matching policies
|
|
113
|
+
const matchingPolicies = policies.filter((policy) => policy.match.test(relPath));
|
|
114
|
+
// for(const policy of matchingPolicies) {
|
|
115
|
+
// bars.addFile(policy.name,
|
|
116
|
+
// }
|
|
117
|
+
await Promise.all(matchingPolicies.map(async (policy) => {
|
|
118
|
+
return await this.runPolicyOnFile(relPath, policy, context);
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
async runPolicyOnFile(relPath, policy, context) {
|
|
92
122
|
const { excludePoliciesForFiles, perfStats, gitRoot } = context;
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
if (exclusions !== undefined &&
|
|
96
|
-
!exclusions.every((regex) => !regex.test(relPath))) {
|
|
123
|
+
// Check if the policy is excluded for the file
|
|
124
|
+
if (this.isPolicyExcluded(relPath, policy, excludePoliciesForFiles)) {
|
|
97
125
|
this.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);
|
|
98
126
|
return;
|
|
99
127
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
128
|
+
try {
|
|
129
|
+
// Execute the policy handler
|
|
130
|
+
const result = await this.executePolicyHandler(relPath, policy, perfStats, gitRoot);
|
|
131
|
+
// Handle the result of the policy execution
|
|
132
|
+
await this.handlePolicyResult(result, relPath, policy, perfStats, gitRoot);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
// Log and rethrow the error for higher-level handling
|
|
136
|
+
this.error(`Error executing policy '${policy.name}' for file '${relPath}': ${error}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
isPolicyExcluded(relPath, policy, excludePoliciesForFiles) {
|
|
140
|
+
return (excludePoliciesForFiles
|
|
141
|
+
.get(policy.name)
|
|
142
|
+
?.some((regex) => regex.test(relPath)) ?? false);
|
|
143
|
+
}
|
|
144
|
+
async executePolicyHandler(relPath, policy, perfStats, gitRoot) {
|
|
145
|
+
try {
|
|
146
|
+
return await runWithPerf(policy.name, "handle", perfStats, () => policy.handler({
|
|
147
|
+
file: relPath,
|
|
148
|
+
root: gitRoot,
|
|
149
|
+
resolve: this.flags.fix,
|
|
150
|
+
config: policy.config,
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
this.error(`Error in policy handler '${policy.name}' for file '${relPath}': ${error}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async handlePolicyResult(result, relPath, policy, perfStats, gitRoot) {
|
|
108
158
|
if (result === true) {
|
|
109
159
|
return;
|
|
110
160
|
}
|
|
111
|
-
const messages = new StringBuilder();
|
|
112
161
|
if (isPolicyFixResult(result)) {
|
|
113
|
-
|
|
114
|
-
messages.append(`Resolved ${policy.name} policy failure for file: ${result.file}`);
|
|
115
|
-
}
|
|
116
|
-
else {
|
|
117
|
-
messages.append(`Error when trying to fix ${policy.name} policy failure in ${result.file}`);
|
|
118
|
-
process.exitCode = 1;
|
|
119
|
-
}
|
|
162
|
+
this.handleFixResult(result, policy);
|
|
120
163
|
}
|
|
121
164
|
else {
|
|
122
|
-
|
|
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);
|
|
131
|
-
}
|
|
132
|
-
if (!resolveResult.resolved) {
|
|
133
|
-
process.exitCode = 1;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
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;
|
|
146
|
-
}
|
|
165
|
+
await this.handleFailureResult(result, relPath, policy, perfStats, gitRoot);
|
|
147
166
|
}
|
|
148
|
-
|
|
149
|
-
|
|
167
|
+
}
|
|
168
|
+
handleFixResult(result, policy) {
|
|
169
|
+
const messages = new StringBuilder();
|
|
170
|
+
if (result.resolved) {
|
|
171
|
+
messages.append(`Resolved ${policy.name} policy failure for file: ${result.file}`);
|
|
150
172
|
}
|
|
151
173
|
else {
|
|
152
|
-
|
|
174
|
+
messages.append(`Error fixing ${policy.name} policy failure in ${result.file}`);
|
|
175
|
+
process.exitCode = 1;
|
|
153
176
|
}
|
|
177
|
+
this.logMessages(messages);
|
|
154
178
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
async checkOrExcludeFile(inputPath, commandContext) {
|
|
160
|
-
const { excludeFiles: exclusions, gitRoot, perfStats } = commandContext;
|
|
161
|
-
const filePath = path.join(gitRoot, inputPath).trim().replace(/\\/g, "/");
|
|
162
|
-
perfStats.count++;
|
|
163
|
-
if (!exclusions.every((value) => !value.test(inputPath))) {
|
|
164
|
-
this.verbose(`Excluded all handlers: ${inputPath}`);
|
|
165
|
-
return;
|
|
179
|
+
async handleFailureResult(result, relPath, policy, perfStats, gitRoot) {
|
|
180
|
+
const messages = new StringBuilder();
|
|
181
|
+
if (this.flags.fix && policy.resolver) {
|
|
182
|
+
await this.attemptResolution(relPath, policy, policy.resolver, perfStats, gitRoot, messages);
|
|
166
183
|
}
|
|
167
|
-
|
|
168
|
-
|
|
184
|
+
else {
|
|
185
|
+
this.logPolicyFailure(result, policy, messages);
|
|
169
186
|
}
|
|
170
|
-
|
|
171
|
-
|
|
187
|
+
this.logMessages(messages);
|
|
188
|
+
}
|
|
189
|
+
async attemptResolution(relPath, policy, resolver, perfStats, gitRoot, messages) {
|
|
190
|
+
messages.append(`${newline}Attempting to resolve: ${relPath}`);
|
|
191
|
+
const resolveResult = await runWithPerf(policy.name, "resolve", perfStats, () => resolver({ file: relPath, root: gitRoot }));
|
|
192
|
+
if (!resolveResult.resolved) {
|
|
193
|
+
process.exitCode = 1;
|
|
194
|
+
}
|
|
195
|
+
if (resolveResult.errorMessage) {
|
|
196
|
+
messages.append(newline + resolveResult.errorMessage);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
logPolicyFailure(result, policy, messages) {
|
|
200
|
+
const autoFixable = result.autoFixable ? chalk.green(" (autofixable)") : "";
|
|
201
|
+
messages.append(`'${chalk.bold(policy.name)}' policy failure${autoFixable}: ${result.file}`);
|
|
202
|
+
if (result.errorMessage) {
|
|
203
|
+
messages.append(`${newline}\t${result.errorMessage}`);
|
|
204
|
+
}
|
|
205
|
+
process.exitCode = 1;
|
|
206
|
+
}
|
|
207
|
+
logMessages(messages) {
|
|
208
|
+
if ((process.exitCode ?? 0) === 0) {
|
|
209
|
+
this.info(messages.toString());
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
this.warning(messages.toString());
|
|
172
213
|
}
|
|
173
|
-
perfStats.processed++;
|
|
174
214
|
}
|
|
175
215
|
}
|
|
176
216
|
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 { 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
|
+
{"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 chalk from \"picocolors\";\n\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport type { RepopoCommandContext } from \"../context.js\";\nimport { type PolicyHandlerPerfStats, logStats, runWithPerf } from \"../perf.js\";\nimport {\n\ttype PolicyFailure,\n\ttype PolicyFixResult,\n\ttype PolicyHandlerResult,\n\ttype PolicyInstance,\n\ttype PolicyStandaloneResolver,\n\tisPolicyFixResult,\n} 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(\n\t\t\t\t\t...stdInput\n\t\t\t\t\t\t.replace(\n\t\t\t\t\t\t\t// normalize slashes in case they're windows paths\n\t\t\t\t\t\t\t/\\\\/g,\n\t\t\t\t\t\t\t\"/\",\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.split(\"\\n\"),\n\t\t\t\t);\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// include staged files and untracked files\n\t\t\t\t\t\"-co\",\n\t\t\t\t\t// exclude gitignored files and other standard ignore rules\n\t\t\t\t\t\"--exclude-standard\",\n\t\t\t\t\t// Outputs paths relative to the root of the repository, regardless of the current working directory.\n\t\t\t\t\t\"--full-name\",\n\t\t\t\t)) ?? \"\";\n\n\t\t\tfilePathsToCheck.push(\n\t\t\t\t...gitFiles\n\t\t\t\t\t.replace(\n\t\t\t\t\t\t// normalize slashes in case they're windows paths\n\t\t\t\t\t\t/\\\\/g,\n\t\t\t\t\t\t\"/\",\n\t\t\t\t\t)\n\t\t\t\t\t.split(\"\\n\"),\n\t\t\t);\n\t\t}\n\n\t\tconst context: RepopoCommandContext = await this.getContext();\n\n\t\tawait this.checkAllFiles(filePathsToCheck, context);\n\t}\n\n\t/**\n\t * Executes all policies against the provided paths.\n\t *\n\t * @param pathsToCheck - All paths that should be checked. Paths should be relative to the repository root.\n\t * @param context - The context.\n\t */\n\tprivate async checkAllFiles(\n\t\tpathsToCheck: string[],\n\t\tcontext: RepopoCommandContext,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tfor (const pathToCheck of pathsToCheck) {\n\t\t\t\tawait this.checkOrExcludeFile(pathToCheck, context);\n\t\t\t}\n\t\t} finally {\n\t\t\tif (!this.flags.quiet) {\n\t\t\t\tlogStats(context.perfStats, this);\n\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\t * @param relPath - A git repo-relative path to a file.\n\t */\n\tprivate async checkOrExcludeFile(\n\t\trelPath: string,\n\t\tcontext: RepopoCommandContext,\n\t): Promise<void> {\n\t\tconst { perfStats } = context;\n\t\tperfStats.count++;\n\n\t\ttry {\n\t\t\tawait this.routeToPolicies(relPath, context);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(\n\t\t\t\t`Error routing ${relPath} 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\tprivate async routeToPolicies(\n\t\trelPath: string,\n\t\tcontext: RepopoCommandContext,\n\t): Promise<void> {\n\t\tconst { policies, excludeFromAll } = context;\n\n\t\t// Check exclusions\n\t\tif (excludeFromAll.some((regex) => regex.test(relPath))) {\n\t\t\tthis.verbose(`Excluded all handlers: ${relPath}`);\n\t\t\treturn; // Early return for excluded files\n\t\t}\n\n\t\t// Run all matching policies\n\t\tconst matchingPolicies = policies.filter((policy) =>\n\t\t\tpolicy.match.test(relPath),\n\t\t);\n\n\t\t// for(const policy of matchingPolicies) {\n\t\t// \tbars.addFile(policy.name,\n\t\t// }\n\n\t\tawait Promise.all(\n\t\t\tmatchingPolicies.map(async (policy) => {\n\t\t\t\treturn await this.runPolicyOnFile(relPath, policy, context);\n\t\t\t}),\n\t\t);\n\t}\n\n\tprivate async runPolicyOnFile(\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\tcontext: RepopoCommandContext,\n\t): Promise<void> {\n\t\tconst { excludePoliciesForFiles, perfStats, gitRoot } = context;\n\n\t\t// Check if the policy is excluded for the file\n\t\tif (this.isPolicyExcluded(relPath, policy, excludePoliciesForFiles)) {\n\t\t\tthis.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\t// Execute the policy handler\n\t\t\tconst result = await this.executePolicyHandler(\n\t\t\t\trelPath,\n\t\t\t\tpolicy,\n\t\t\t\tperfStats,\n\t\t\t\tgitRoot,\n\t\t\t);\n\n\t\t\t// Handle the result of the policy execution\n\t\t\tawait this.handlePolicyResult(\n\t\t\t\tresult,\n\t\t\t\trelPath,\n\t\t\t\tpolicy,\n\t\t\t\tperfStats,\n\t\t\t\tgitRoot,\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\t// Log and rethrow the error for higher-level handling\n\t\t\tthis.error(\n\t\t\t\t`Error executing policy '${policy.name}' for file '${relPath}': ${error}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate isPolicyExcluded(\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\texcludePoliciesForFiles: Map<string, RegExp[]>,\n\t): boolean {\n\t\treturn (\n\t\t\texcludePoliciesForFiles\n\t\t\t\t.get(policy.name)\n\t\t\t\t?.some((regex) => regex.test(relPath)) ?? false\n\t\t);\n\t}\n\n\tprivate async executePolicyHandler(\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\tperfStats: PolicyHandlerPerfStats,\n\t\tgitRoot: string,\n\t): Promise<PolicyHandlerResult> {\n\t\ttry {\n\t\t\treturn await runWithPerf(policy.name, \"handle\", perfStats, () =>\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: policy.config,\n\t\t\t\t}),\n\t\t\t);\n\t\t} catch (error: unknown) {\n\t\t\tthis.error(\n\t\t\t\t`Error in policy handler '${policy.name}' for file '${relPath}': ${error}`,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate async handlePolicyResult(\n\t\tresult: PolicyHandlerResult,\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\tperfStats: PolicyHandlerPerfStats,\n\t\tgitRoot: string,\n\t): Promise<void> {\n\t\tif (result === true) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (isPolicyFixResult(result)) {\n\t\t\tthis.handleFixResult(result, policy);\n\t\t} else {\n\t\t\tawait this.handleFailureResult(\n\t\t\t\tresult,\n\t\t\t\trelPath,\n\t\t\t\tpolicy,\n\t\t\t\tperfStats,\n\t\t\t\tgitRoot,\n\t\t\t);\n\t\t}\n\t}\n\n\tprivate handleFixResult(\n\t\tresult: PolicyFixResult,\n\t\tpolicy: PolicyInstance,\n\t): void {\n\t\tconst messages = new StringBuilder();\n\n\t\tif (result.resolved) {\n\t\t\tmessages.append(\n\t\t\t\t`Resolved ${policy.name} policy failure for file: ${result.file}`,\n\t\t\t);\n\t\t} else {\n\t\t\tmessages.append(\n\t\t\t\t`Error fixing ${policy.name} policy failure in ${result.file}`,\n\t\t\t);\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\n\t\tthis.logMessages(messages);\n\t}\n\n\tprivate async handleFailureResult(\n\t\tresult: PolicyFailure,\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\tperfStats: PolicyHandlerPerfStats,\n\t\tgitRoot: string,\n\t): Promise<void> {\n\t\tconst messages = new StringBuilder();\n\n\t\tif (this.flags.fix && policy.resolver) {\n\t\t\tawait this.attemptResolution(\n\t\t\t\trelPath,\n\t\t\t\tpolicy,\n\t\t\t\tpolicy.resolver,\n\t\t\t\tperfStats,\n\t\t\t\tgitRoot,\n\t\t\t\tmessages,\n\t\t\t);\n\t\t} else {\n\t\t\tthis.logPolicyFailure(result, policy, messages);\n\t\t}\n\n\t\tthis.logMessages(messages);\n\t}\n\n\tprivate async attemptResolution(\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\tresolver: PolicyStandaloneResolver,\n\t\tperfStats: PolicyHandlerPerfStats,\n\t\tgitRoot: string,\n\t\tmessages: StringBuilder,\n\t): Promise<void> {\n\t\tmessages.append(`${newline}Attempting to resolve: ${relPath}`);\n\t\tconst resolveResult = await runWithPerf(\n\t\t\tpolicy.name,\n\t\t\t\"resolve\",\n\t\t\tperfStats,\n\t\t\t() => resolver({ file: relPath, root: gitRoot }),\n\t\t);\n\n\t\tif (!resolveResult.resolved) {\n\t\t\tprocess.exitCode = 1;\n\t\t}\n\n\t\tif (resolveResult.errorMessage) {\n\t\t\tmessages.append(newline + resolveResult.errorMessage);\n\t\t}\n\t}\n\n\tprivate logPolicyFailure(\n\t\tresult: PolicyFailure,\n\t\tpolicy: PolicyInstance,\n\t\tmessages: StringBuilder,\n\t): void {\n\t\tconst autoFixable = result.autoFixable ? chalk.green(\" (autofixable)\") : \"\";\n\t\tmessages.append(\n\t\t\t`'${chalk.bold(policy.name)}' policy failure${autoFixable}: ${result.file}`,\n\t\t);\n\t\tif (result.errorMessage) {\n\t\t\tmessages.append(`${newline}\\t${result.errorMessage}`);\n\t\t}\n\t\tprocess.exitCode = 1;\n\t}\n\tprivate logMessages(messages: StringBuilder): void {\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\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"]}
|
package/esm/config.d.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import { type
|
|
3
|
-
/**
|
|
4
|
-
* @alpha
|
|
5
|
-
*/
|
|
6
|
-
export type PerPolicySettings = ({
|
|
7
|
-
PackageJsonProperties: PackageJsonPropertiesSettings;
|
|
8
|
-
} & Record<PolicyName, unknown>) | undefined;
|
|
1
|
+
import type { PolicyCreator } from "./generators.js";
|
|
2
|
+
import { type PolicyInstance } from "./policy.js";
|
|
9
3
|
/**
|
|
10
4
|
* @alpha
|
|
11
5
|
*/
|
|
6
|
+
export type PolicyList = PolicyCreator[];
|
|
12
7
|
/**
|
|
13
8
|
* @alpha
|
|
14
9
|
*/
|
|
@@ -18,18 +13,12 @@ export interface RepopoConfig {
|
|
|
18
13
|
*
|
|
19
14
|
* See `DefaultPolicies` for the policies that will be enabled by default if this is `undefined`.
|
|
20
15
|
*/
|
|
21
|
-
policies?:
|
|
16
|
+
policies?: PolicyInstance<any>[];
|
|
22
17
|
/**
|
|
23
18
|
* An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded
|
|
24
19
|
* from policy.
|
|
25
20
|
*/
|
|
26
21
|
excludeFiles?: (string | RegExp)[];
|
|
27
|
-
/**
|
|
28
|
-
* An object with a policy name as keys that map to an array of strings/regular expressions to
|
|
29
|
-
* exclude that rule from being checked.
|
|
30
|
-
*/
|
|
31
|
-
excludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;
|
|
32
|
-
perPolicyConfig?: PerPolicySettings | undefined;
|
|
33
22
|
}
|
|
34
23
|
/**
|
|
35
24
|
* The default config applied when no config is found.
|
package/esm/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEnE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;;;OAIG;IAEH,QAAQ,CAAC,EAAE,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;IAEjC;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;CACnC;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAIjC,CAAC"}
|
package/esm/config.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { makePolicy } from "./makePolicy.js";
|
|
1
2
|
import { DefaultPolicies } from "./policy.js";
|
|
2
3
|
/**
|
|
3
4
|
* The default config applied when no config is found.
|
|
@@ -5,8 +6,8 @@ import { DefaultPolicies } from "./policy.js";
|
|
|
5
6
|
* @alpha
|
|
6
7
|
*/
|
|
7
8
|
export const DefaultPolicyConfig = {
|
|
8
|
-
policies: DefaultPolicies,
|
|
9
|
+
policies: DefaultPolicies.map((p) => makePolicy(p)),
|
|
9
10
|
excludeFiles: [],
|
|
10
|
-
excludePoliciesForFiles: {},
|
|
11
|
+
// excludePoliciesForFiles: {},
|
|
11
12
|
};
|
|
12
13
|
//# sourceMappingURL=config.js.map
|
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,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAuB,MAAM,aAAa,CAAC;AA0BnE;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAChD,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACnD,YAAY,EAAE,EAAE;IAChB,+BAA+B;CAC/B,CAAC","sourcesContent":["import type { PolicyCreator } from \"./generators.js\";\nimport { makePolicy } from \"./makePolicy.js\";\nimport { DefaultPolicies, type PolicyInstance } from \"./policy.js\";\n\n/**\n * @alpha\n */\nexport type PolicyList = PolicyCreator[];\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\t// biome-ignore lint/suspicious/noExplicitAny: FIXME\n\tpolicies?: PolicyInstance<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\n/**\n * The default config applied when no config is found.\n *\n * @alpha\n */\nexport const DefaultPolicyConfig: RepopoConfig = {\n\tpolicies: DefaultPolicies.map((p) => makePolicy(p)),\n\texcludeFiles: [],\n\t// excludePoliciesForFiles: {},\n};\n"]}
|