repopo 0.6.0 → 0.7.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 +52 -0
- package/THIRD-PARTY-LICENSES.txt +6 -6
- package/esm/baseCommand.d.ts.map +1 -1
- package/esm/baseCommand.js +0 -1
- package/esm/baseCommand.js.map +1 -1
- package/esm/commands/check.d.ts.map +1 -1
- package/esm/commands/check.js +33 -21
- package/esm/commands/check.js.map +1 -1
- package/esm/commands/list.d.ts.map +1 -1
- package/esm/commands/list.js +0 -1
- package/esm/commands/list.js.map +1 -1
- package/esm/index.d.ts +2 -2
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +1 -1
- package/esm/index.js.map +1 -1
- package/esm/policies/HtmlFileHeaders.d.ts.map +1 -1
- package/esm/policies/HtmlFileHeaders.js.map +1 -1
- package/esm/policies/JsTsFileHeaders.d.ts.map +1 -1
- package/esm/policies/JsTsFileHeaders.js.map +1 -1
- package/esm/policies/LicenseFileExists.d.ts +20 -0
- package/esm/policies/LicenseFileExists.d.ts.map +1 -0
- package/esm/policies/LicenseFileExists.js +40 -0
- package/esm/policies/LicenseFileExists.js.map +1 -0
- package/esm/policies/NoJsFileExtensions.d.ts.map +1 -1
- package/esm/policies/NoJsFileExtensions.js +1 -3
- package/esm/policies/NoJsFileExtensions.js.map +1 -1
- package/esm/policies/NoLargeBinaryFiles.d.ts +30 -0
- package/esm/policies/NoLargeBinaryFiles.d.ts.map +1 -0
- package/esm/policies/NoLargeBinaryFiles.js +118 -0
- package/esm/policies/NoLargeBinaryFiles.js.map +1 -0
- package/esm/policies/PackageJsonRepoDirectoryProperty.d.ts.map +1 -1
- package/esm/policies/PackageJsonRepoDirectoryProperty.js +22 -23
- package/esm/policies/PackageJsonRepoDirectoryProperty.js.map +1 -1
- package/esm/policies/PackageJsonSorted.d.ts.map +1 -1
- package/esm/policies/PackageJsonSorted.js +1 -0
- package/esm/policies/PackageJsonSorted.js.map +1 -1
- package/esm/policies/PackageScripts.d.ts +25 -2
- package/esm/policies/PackageScripts.d.ts.map +1 -1
- package/esm/policies/PackageScripts.js +46 -9
- package/esm/policies/PackageScripts.js.map +1 -1
- package/esm/policies/RequiredGitignorePatterns.d.ts +24 -0
- package/esm/policies/RequiredGitignorePatterns.d.ts.map +1 -0
- package/esm/policies/RequiredGitignorePatterns.js +166 -0
- package/esm/policies/RequiredGitignorePatterns.js.map +1 -0
- package/esm/policies.d.ts +5 -1
- package/esm/policies.d.ts.map +1 -1
- package/esm/policies.js +5 -1
- package/esm/policies.js.map +1 -1
- package/esm/tsdoc-metadata.json +1 -1
- package/oclif.manifest.json +1 -1
- package/package.json +35 -28
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,57 @@
|
|
|
1
1
|
# repopo
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add configurable PackageScripts policy _[`#376`](https://github.com/tylerbutler/tools-monorepo/pull/376) [`c17462a`](https://github.com/tylerbutler/tools-monorepo/commit/c17462a8af35a8bfbb528f29825a0ef177923946) [@tylerbutler](https://github.com/tylerbutler)_
|
|
8
|
+
|
|
9
|
+
Enhances the `PackageScripts` policy with flexible configuration options to enforce package.json script requirements across your repository. The policy now supports two validation modes:
|
|
10
|
+
|
|
11
|
+
1. **Required Scripts (`must`)**: Specify scripts that must be present in all package.json files
|
|
12
|
+
2. **Mutually Exclusive Scripts (`mutuallyExclusive`)**: Define groups of scripts where exactly one from each group must exist
|
|
13
|
+
|
|
14
|
+
Example configuration:
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
makePolicy(PackageScripts, {
|
|
18
|
+
must: ["build", "clean"],
|
|
19
|
+
mutuallyExclusive: [
|
|
20
|
+
["test", "test:unit"], // Either "test" or "test:unit", not both
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The policy validates that:
|
|
26
|
+
|
|
27
|
+
- All scripts in the `must` array are present
|
|
28
|
+
- For each group in `mutuallyExclusive`, exactly one script from that group exists (not zero, not multiple)
|
|
29
|
+
|
|
30
|
+
This is useful for enforcing consistent npm script conventions across monorepo packages while allowing flexibility where needed.
|
|
31
|
+
|
|
32
|
+
- New built-in policies _[`#308`](https://github.com/tylerbutler/tools-monorepo/pull/308) [`1856d58`](https://github.com/tylerbutler/tools-monorepo/commit/1856d582fb92692447b02c89cdb45dcd3c5f7370) [@tylerbutler](https://github.com/tylerbutler)_
|
|
33
|
+
|
|
34
|
+
Added three new policies for repository quality and safety:
|
|
35
|
+
|
|
36
|
+
- **LicenseFileExists**: Ensures a LICENSE file exists in the repository root (essential for open source projects)
|
|
37
|
+
- **NoLargeBinaryFiles**: Prevents large binary files from being committed (default 10MB max, suggests Git LFS for large assets)
|
|
38
|
+
- **RequiredGitignorePatterns**: Validates .gitignore contains required patterns to prevent committing sensitive files, dependencies, and build artifacts (auto-fixable)
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
<details><summary>Updated 2 dependencies</summary>
|
|
43
|
+
|
|
44
|
+
<small>
|
|
45
|
+
|
|
46
|
+
[`b0d8cb9`](https://github.com/tylerbutler/tools-monorepo/commit/b0d8cb9a9ee27a0b778ee58055bcbdd7d6d9b4eb) [`08e571f`](https://github.com/tylerbutler/tools-monorepo/commit/08e571f028e868d5db1c337e51804f5884cd2f4a) [`08e571f`](https://github.com/tylerbutler/tools-monorepo/commit/08e571f028e868d5db1c337e51804f5884cd2f4a)
|
|
47
|
+
|
|
48
|
+
</small>
|
|
49
|
+
|
|
50
|
+
- `@tylerbu/cli-api@0.8.0`
|
|
51
|
+
- `@tylerbu/fundamentals@0.3.0`
|
|
52
|
+
|
|
53
|
+
</details>
|
|
54
|
+
|
|
3
55
|
## 0.6.0
|
|
4
56
|
|
|
5
57
|
### Minor Changes
|
package/THIRD-PARTY-LICENSES.txt
CHANGED
|
@@ -3,7 +3,7 @@ https://www.npmjs.com/package/generate-license-file
|
|
|
3
3
|
|
|
4
4
|
The following npm package may be included in this product:
|
|
5
5
|
|
|
6
|
-
- jsonfile@6.
|
|
6
|
+
- jsonfile@6.2.0
|
|
7
7
|
|
|
8
8
|
This package contains the following license:
|
|
9
9
|
|
|
@@ -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.
|
|
30
|
+
- @rushstack/node-core-library@5.18.0
|
|
31
31
|
|
|
32
32
|
This package contains the following license:
|
|
33
33
|
|
|
@@ -60,7 +60,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
|
60
60
|
|
|
61
61
|
The following npm package may be included in this product:
|
|
62
62
|
|
|
63
|
-
- @fluid-tools/build-infrastructure@0.
|
|
63
|
+
- @fluid-tools/build-infrastructure@0.60.0
|
|
64
64
|
|
|
65
65
|
This package contains the following license:
|
|
66
66
|
|
|
@@ -114,7 +114,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
114
114
|
|
|
115
115
|
The following npm package may be included in this product:
|
|
116
116
|
|
|
117
|
-
- simple-git@3.
|
|
117
|
+
- simple-git@3.30.0
|
|
118
118
|
|
|
119
119
|
This package contains the following license:
|
|
120
120
|
|
|
@@ -124,8 +124,8 @@ MIT
|
|
|
124
124
|
|
|
125
125
|
The following npm packages may be included in this product:
|
|
126
126
|
|
|
127
|
-
- @oclif/core@4.
|
|
128
|
-
- @oclif/plugin-help@6.2.
|
|
127
|
+
- @oclif/core@4.8.0
|
|
128
|
+
- @oclif/plugin-help@6.2.35
|
|
129
129
|
|
|
130
130
|
These packages each contain the following license:
|
|
131
131
|
|
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;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,
|
|
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,gBAAgC,KAAK;;MAE1B;IAEX,OAAO,CAAC,IAAI,CAAwB;IACpC,IAAW,GAAG,IAAI,SAAS,CAK1B;IAEqB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB3C,OAAO,CAAC,QAAQ,CAAmC;IAEtC,UAAU,IAAI,OAAO,CAAC,oBAAoB,CAAC;CAMxD"}
|
package/esm/baseCommand.js
CHANGED
|
@@ -40,7 +40,6 @@ export class BaseRepopoCommand extends CommandWithConfig {
|
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
42
|
_context;
|
|
43
|
-
// biome-ignore lint/suspicious/useAwait: interface defines this as async
|
|
44
43
|
async getContext() {
|
|
45
44
|
if (this._context === undefined) {
|
|
46
45
|
throw new Error("Context not initialized.");
|
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,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;
|
|
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;IAEhD,MAAM,CAAmB,KAAK,GAAG;QACvC,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;IAE5C,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\tpublic static 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\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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAgCtD;;;;;;;;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,gBAAgC,OAAO,iEACwB;IAE/D,gBAAgC,KAAK;;;;MAY1B;IAEW,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAwD1C;;;;;OAKG;YACW,aAAa;IAe3B;;;;;OAKG;YACW,kBAAkB;YAmBlB,eAAe;YAsCf,eAAe;IAwC7B,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,10 +1,27 @@
|
|
|
1
1
|
import { EOL as newline } from "node:os";
|
|
2
|
+
import process from "node:process";
|
|
2
3
|
import { Flags } from "@oclif/core";
|
|
3
4
|
import { StringBuilder } from "@rushstack/node-core-library";
|
|
4
5
|
import chalk from "picocolors";
|
|
5
6
|
import { BaseRepopoCommand } from "../baseCommand.js";
|
|
6
7
|
import { logStats, runWithPerf } from "../perf.js";
|
|
7
8
|
import { isPolicyFixResult, } from "../policy.js";
|
|
9
|
+
async function readStdin() {
|
|
10
|
+
return new Promise((resolve) => {
|
|
11
|
+
const stdin = process.stdin;
|
|
12
|
+
stdin.setEncoding("utf8");
|
|
13
|
+
let data = "";
|
|
14
|
+
stdin.on("data", (chunk) => {
|
|
15
|
+
data += chunk;
|
|
16
|
+
});
|
|
17
|
+
stdin.on("end", () => {
|
|
18
|
+
resolve(data);
|
|
19
|
+
});
|
|
20
|
+
if (stdin.isTTY) {
|
|
21
|
+
resolve("");
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
8
25
|
/**
|
|
9
26
|
* This tool enforces policies across the code base via a series of handler functions. The handler functions are
|
|
10
27
|
* associated with a regular expression, and all files matching that expression are passed to the handler function.
|
|
@@ -95,35 +112,45 @@ export class CheckPolicy extends BaseRepopoCommand {
|
|
|
95
112
|
const { perfStats } = context;
|
|
96
113
|
perfStats.count++;
|
|
97
114
|
try {
|
|
98
|
-
await this.routeToPolicies(relPath, context);
|
|
115
|
+
const wasProcessed = await this.routeToPolicies(relPath, context);
|
|
116
|
+
if (wasProcessed) {
|
|
117
|
+
perfStats.processed++;
|
|
118
|
+
}
|
|
99
119
|
}
|
|
100
120
|
catch (error) {
|
|
101
121
|
throw new Error(`Error routing ${relPath} to handler: ${error}\nStack:\n${error.stack}`);
|
|
102
122
|
}
|
|
103
|
-
perfStats.processed++;
|
|
104
123
|
}
|
|
105
124
|
async routeToPolicies(relPath, context) {
|
|
106
125
|
const { policies, excludeFromAll } = context;
|
|
107
126
|
// Check exclusions
|
|
108
127
|
if (excludeFromAll.some((regex) => regex.test(relPath))) {
|
|
109
128
|
this.verbose(`Excluded all handlers: ${relPath}`);
|
|
110
|
-
return; //
|
|
129
|
+
return false; // File was excluded from all policies
|
|
111
130
|
}
|
|
112
131
|
// Run all matching policies
|
|
113
132
|
const matchingPolicies = policies.filter((policy) => policy.match.test(relPath));
|
|
114
133
|
// for(const policy of matchingPolicies) {
|
|
115
134
|
// bars.addFile(policy.name,
|
|
116
135
|
// }
|
|
117
|
-
|
|
136
|
+
// If no policies match this file, it's still considered processed
|
|
137
|
+
// (we examined it and determined no policies apply)
|
|
138
|
+
if (matchingPolicies.length === 0) {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
const results = await Promise.all(matchingPolicies.map(async (policy) => {
|
|
118
142
|
return await this.runPolicyOnFile(relPath, policy, context);
|
|
119
143
|
}));
|
|
144
|
+
// File is considered processed if at least one policy ran on it
|
|
145
|
+
// If all matching policies excluded it, count as excluded
|
|
146
|
+
return results.some((ran) => ran);
|
|
120
147
|
}
|
|
121
148
|
async runPolicyOnFile(relPath, policy, context) {
|
|
122
149
|
const { excludePoliciesForFiles, perfStats, gitRoot } = context;
|
|
123
150
|
// Check if the policy is excluded for the file
|
|
124
151
|
if (this.isPolicyExcluded(relPath, policy, excludePoliciesForFiles)) {
|
|
125
152
|
this.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);
|
|
126
|
-
return;
|
|
153
|
+
return false; // Policy didn't run on this file
|
|
127
154
|
}
|
|
128
155
|
try {
|
|
129
156
|
// Execute the policy handler
|
|
@@ -135,6 +162,7 @@ export class CheckPolicy extends BaseRepopoCommand {
|
|
|
135
162
|
// Log and rethrow the error for higher-level handling
|
|
136
163
|
this.error(`Error executing policy '${policy.name}' for file '${relPath}': ${error}`);
|
|
137
164
|
}
|
|
165
|
+
return true; // Policy ran (successfully or with error)
|
|
138
166
|
}
|
|
139
167
|
isPolicyExcluded(relPath, policy, excludePoliciesForFiles) {
|
|
140
168
|
return (excludePoliciesForFiles
|
|
@@ -213,20 +241,4 @@ export class CheckPolicy extends BaseRepopoCommand {
|
|
|
213
241
|
}
|
|
214
242
|
}
|
|
215
243
|
}
|
|
216
|
-
async function readStdin() {
|
|
217
|
-
return new Promise((resolve) => {
|
|
218
|
-
const stdin = process.stdin;
|
|
219
|
-
stdin.setEncoding("utf8");
|
|
220
|
-
let data = "";
|
|
221
|
-
stdin.on("data", (chunk) => {
|
|
222
|
-
data += chunk;
|
|
223
|
-
});
|
|
224
|
-
stdin.on("end", () => {
|
|
225
|
-
resolve(data);
|
|
226
|
-
});
|
|
227
|
-
if (stdin.isTTY) {
|
|
228
|
-
resolve("");
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
244
|
//# sourceMappingURL=check.js.map
|
|
@@ -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 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"]}
|
|
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 process from \"node:process\";\nimport { Flags } from \"@oclif/core\";\nimport { StringBuilder } from \"@rushstack/node-core-library\";\nimport chalk from \"picocolors\";\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport type { RepopoCommandContext } from \"../context.js\";\nimport { logStats, type PolicyHandlerPerfStats, runWithPerf } from \"../perf.js\";\nimport {\n\tisPolicyFixResult,\n\ttype PolicyFailure,\n\ttype PolicyFixResult,\n\ttype PolicyHandlerResult,\n\ttype PolicyInstance,\n\ttype PolicyStandaloneResolver,\n} from \"../policy.js\";\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\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\tpublic static override readonly summary =\n\t\t\"Checks and applies policies to the files in the repository.\";\n\n\tpublic static 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\tconst wasProcessed = await this.routeToPolicies(relPath, context);\n\t\t\tif (wasProcessed) {\n\t\t\t\tperfStats.processed++;\n\t\t\t}\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\t}\n\n\tprivate async routeToPolicies(\n\t\trelPath: string,\n\t\tcontext: RepopoCommandContext,\n\t): Promise<boolean> {\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 false; // File was excluded from all policies\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\t// If no policies match this file, it's still considered processed\n\t\t// (we examined it and determined no policies apply)\n\t\tif (matchingPolicies.length === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst results = await 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\n\t\t// File is considered processed if at least one policy ran on it\n\t\t// If all matching policies excluded it, count as excluded\n\t\treturn results.some((ran) => ran);\n\t}\n\n\tprivate async runPolicyOnFile(\n\t\trelPath: string,\n\t\tpolicy: PolicyInstance,\n\t\tcontext: RepopoCommandContext,\n\t): Promise<boolean> {\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 false; // Policy didn't run on this file\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\n\t\treturn true; // Policy ran (successfully or with error)\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"]}
|
|
@@ -1 +1 @@
|
|
|
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,
|
|
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,gBAAgC,OAAO,2CACE;IAEnB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ1C"}
|
package/esm/commands/list.js
CHANGED
|
@@ -5,7 +5,6 @@ import { DefaultPolicies } from "../policy.js";
|
|
|
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: overridden method
|
|
9
8
|
async run() {
|
|
10
9
|
const policies = this.commandConfig?.policies ?? DefaultPolicies;
|
|
11
10
|
// list the handlers then exit
|
package/esm/commands/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;
|
|
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;IACtB,MAAM,CAAmB,OAAO,GACtC,uCAAuC,CAAC;IAEzB,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\tpublic static override readonly summary =\n\t\t\"Lists the policies configured to run.\";\n\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/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { run } from "@oclif/core";
|
|
2
|
-
export type { PolicyFailure, PolicyFixResult, PolicyFunctionArguments, PolicyHandler, PolicyInstance, PolicyInstanceSettings, PolicyHandlerResult, PolicyName, PolicyStandaloneResolver, PolicyDefinition, } from "./policy.js";
|
|
3
2
|
export type { RepopoConfig, } from "./config.js";
|
|
4
3
|
export { makePolicy } from "./makePolicy.js";
|
|
5
|
-
export {
|
|
4
|
+
export type { PolicyDefinition, PolicyFailure, PolicyFixResult, PolicyFunctionArguments, PolicyHandler, PolicyHandlerResult, PolicyInstance, PolicyInstanceSettings, PolicyName, PolicyStandaloneResolver, } from "./policy.js";
|
|
6
5
|
export { defineFileHeaderPolicy as generateFileHeaderPolicy, type FileHeaderGeneratorConfig, type FileHeaderPolicyConfig, } from "./policyDefiners/defineFileHeaderPolicy.js";
|
|
6
|
+
export { definePackagePolicy as generatePackagePolicy, type PackageJsonHandler, } from "./policyDefiners/definePackagePolicy.js";
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,YAAY,EAEX,YAAY,GACZ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EACX,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,mBAAmB,EACnB,cAAc,EACd,sBAAsB,EACtB,UAAU,EACV,wBAAwB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,sBAAsB,IAAI,wBAAwB,EAClD,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,GAC3B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,mBAAmB,IAAI,qBAAqB,EAC5C,KAAK,kBAAkB,GACvB,MAAM,yCAAyC,CAAC"}
|
package/esm/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { run } from "@oclif/core";
|
|
2
2
|
export { makePolicy } from "./makePolicy.js";
|
|
3
|
-
export { definePackagePolicy as generatePackagePolicy, } from "./policyDefiners/definePackagePolicy.js";
|
|
4
3
|
export { defineFileHeaderPolicy as generateFileHeaderPolicy, } from "./policyDefiners/defineFileHeaderPolicy.js";
|
|
4
|
+
export { definePackagePolicy as generatePackagePolicy, } from "./policyDefiners/definePackagePolicy.js";
|
|
5
5
|
//# 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;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAKlC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAa7C,OAAO,EACN,sBAAsB,IAAI,wBAAwB,GAGlD,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,mBAAmB,IAAI,qBAAqB,GAE5C,MAAM,yCAAyC,CAAC","sourcesContent":["export { run } from \"@oclif/core\";\nexport type {\n\t// PolicyList,\n\tRepopoConfig,\n} from \"./config.js\";\nexport { makePolicy } from \"./makePolicy.js\";\nexport type {\n\tPolicyDefinition,\n\tPolicyFailure,\n\tPolicyFixResult,\n\tPolicyFunctionArguments,\n\tPolicyHandler,\n\tPolicyHandlerResult,\n\tPolicyInstance,\n\tPolicyInstanceSettings,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n} from \"./policy.js\";\nexport {\n\tdefineFileHeaderPolicy as generateFileHeaderPolicy,\n\ttype FileHeaderGeneratorConfig,\n\ttype FileHeaderPolicyConfig,\n} from \"./policyDefiners/defineFileHeaderPolicy.js\";\nexport {\n\tdefinePackagePolicy as generatePackagePolicy,\n\ttype PackageJsonHandler,\n} from \"./policyDefiners/definePackagePolicy.js\";\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HtmlFileHeaders.d.ts","sourceRoot":"","sources":["../../src/policies/HtmlFileHeaders.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"HtmlFileHeaders.d.ts","sourceRoot":"","sources":["../../src/policies/HtmlFileHeaders.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,6CAA6C,CAAC;AAErD;;;;GAIG;AACH,eAAO,MAAM,eAAe,iEAc1B,CAAC"}
|
|
@@ -1 +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,
|
|
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,EACN,sBAAsB,GAEtB,MAAM,6CAA6C,CAAC;AAErD;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC,iBAAiB,EAAE;IACxE,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\tdefineFileHeaderPolicy,\n\ttype FileHeaderPolicyConfig,\n} from \"../policyDefiners/defineFileHeaderPolicy.js\";\n\n/**\n * A RepoPolicy that checks that HTML files have the configured header comment.\n *\n * @alpha\n */\nexport const HtmlFileHeaders = defineFileHeaderPolicy(\"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"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsTsFileHeaders.d.ts","sourceRoot":"","sources":["../../src/policies/JsTsFileHeaders.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"JsTsFileHeaders.d.ts","sourceRoot":"","sources":["../../src/policies/JsTsFileHeaders.ts"],"names":[],"mappings":"AACA,OAAO,EAEN,KAAK,sBAAsB,EAC3B,MAAM,6CAA6C,CAAC;AAkBrD;;;;GAIG;AACH,eAAO,MAAM,eAAe,iEAO1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JsTsFileHeaders.js","sourceRoot":"","sources":["../../src/policies/JsTsFileHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"JsTsFileHeaders.js","sourceRoot":"","sources":["../../src/policies/JsTsFileHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EACN,sBAAsB,GAEtB,MAAM,6CAA6C,CAAC;AAErD,MAAM,YAAY,GAAG,CACpB,WAAmB,EACnB,EAAE,UAAU,EAA0B,EAC7B,EAAE;IACX,qCAAqC;IACrC,MAAM,SAAS,GACd,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC;QAC3D,CAAC,CAAC,OAAO;QACT,CAAC,CAAC,OAAO,GAAG,OAAO,CAAC;IACtB,MAAM,UAAU,GAAG,MAAM,OAAO,MAAM,UAAU,CAAC,OAAO,CACvD,OAAO,EACP,GAAG,OAAO,KAAK,CACf,GAAG,OAAO,MAAM,SAAS,GAAG,WAAW,EAAE,CAAC;IAC3C,OAAO,UAAU,CAAC;AACnB,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,sBAAsB,CAAC,iBAAiB,EAAE;IACxE,KAAK,EAAE,6BAA6B;IACpC,WAAW,EAAE,4BAA4B,EAAE,kDAAkD;IAC7F,SAAS,EAAE,MAAM,EAAE,qCAAqC;IACxD,OAAO,EAAE,OAAO,EAAE,uCAAuC;IACzD,SAAS,EAAE,iBAAiB,EAAE,0EAA0E;IACxG,QAAQ,EAAE,YAAY;CACtB,CAAC,CAAC","sourcesContent":["import { EOL as newline } from \"node:os\";\nimport {\n\tdefineFileHeaderPolicy,\n\ttype FileHeaderPolicyConfig,\n} from \"../policyDefiners/defineFileHeaderPolicy.js\";\n\nconst jsTsReplacer = (\n\tprevContent: string,\n\t{ headerText }: FileHeaderPolicyConfig,\n): string => {\n\t// prepend header to existing content\n\tconst separator =\n\t\tprevContent.startsWith(\"\\r\") || prevContent.startsWith(\"\\n\")\n\t\t\t? newline\n\t\t\t: newline + newline;\n\tconst newContent = `/*!${newline} * ${headerText.replace(\n\t\tnewline,\n\t\t`${newline} * `,\n\t)}${newline} */${separator}${prevContent}`;\n\treturn newContent;\n};\n\n/**\n * A RepoPolicy that checks that JavaScript and TypeScript source files have the configured header comment\n *\n * @alpha\n */\nexport const JsTsFileHeaders = defineFileHeaderPolicy(\"JsTsFileHeaders\", {\n\tmatch: /(^|\\/)[^/]+\\.[mc]?[jt]sx?$/i,\n\theaderStart: /(#![^\\n]*\\r?\\n)?\\/\\*!\\r?\\n/, // Begins with optional hashbang followed by '/*!'\n\tlineStart: / \\* /, // Subsequent lines begins with ' * '\n\tlineEnd: /\\r?\\n/, // Subsequent lines end with CRLF or LF\n\theaderEnd: / \\*\\/\\r?\\n\\r?\\n/, // Header ends with ' */' on a line by itself, followed by another newline\n\treplacer: jsTsReplacer,\n});\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { PolicyDefinition } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Policy settings for the LicenseFileExists repo policy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface LicenseFileExistsSettings {
|
|
8
|
+
/**
|
|
9
|
+
* Array of acceptable license file names. Defaults to common variations.
|
|
10
|
+
*/
|
|
11
|
+
acceptedNames?: string[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A repo policy that checks that a LICENSE file exists in the repository root.
|
|
15
|
+
* This is essential for open source projects to clarify usage rights and obligations.
|
|
16
|
+
*
|
|
17
|
+
* @alpha
|
|
18
|
+
*/
|
|
19
|
+
export declare const LicenseFileExists: PolicyDefinition<LicenseFileExistsSettings>;
|
|
20
|
+
//# sourceMappingURL=LicenseFileExists.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LicenseFileExists.d.ts","sourceRoot":"","sources":["../../src/policies/LicenseFileExists.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACzC;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAgBD;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,CAAC,yBAAyB,CA0BxE,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import path from "pathe";
|
|
3
|
+
import { makePolicyDefinition } from "../makePolicy.js";
|
|
4
|
+
/**
|
|
5
|
+
* Default license file names to check for.
|
|
6
|
+
*/
|
|
7
|
+
const DEFAULT_LICENSE_NAMES = [
|
|
8
|
+
"LICENSE",
|
|
9
|
+
"LICENSE.txt",
|
|
10
|
+
"LICENSE.md",
|
|
11
|
+
"LICENSE.rst",
|
|
12
|
+
"LICENCE",
|
|
13
|
+
"LICENCE.txt",
|
|
14
|
+
"LICENCE.md",
|
|
15
|
+
"LICENCE.rst",
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* A repo policy that checks that a LICENSE file exists in the repository root.
|
|
19
|
+
* This is essential for open source projects to clarify usage rights and obligations.
|
|
20
|
+
*
|
|
21
|
+
* @alpha
|
|
22
|
+
*/
|
|
23
|
+
export const LicenseFileExists = makePolicyDefinition("LicenseFileExists",
|
|
24
|
+
// Only trigger on package.json to check once per repository
|
|
25
|
+
/^package\.json$/, async ({ root, config }) => {
|
|
26
|
+
const acceptedNames = config?.acceptedNames ?? DEFAULT_LICENSE_NAMES;
|
|
27
|
+
// Check if any of the accepted license files exist in the root
|
|
28
|
+
const hasLicenseFile = acceptedNames.some((name) => existsSync(path.join(root, name)));
|
|
29
|
+
if (hasLicenseFile) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
const result = {
|
|
33
|
+
name: LicenseFileExists.name,
|
|
34
|
+
file: ".", // Report against repository root
|
|
35
|
+
autoFixable: false,
|
|
36
|
+
errorMessage: `No LICENSE file found in repository root. Expected one of: ${acceptedNames.join(", ")}`,
|
|
37
|
+
};
|
|
38
|
+
return result;
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=LicenseFileExists.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LicenseFileExists.js","sourceRoot":"","sources":["../../src/policies/LicenseFileExists.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,IAAI,MAAM,OAAO,CAAC;AACzB,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAexD;;GAEG;AACH,MAAM,qBAAqB,GAAG;IAC7B,SAAS;IACT,aAAa;IACb,YAAY;IACZ,aAAa;IACb,SAAS;IACT,aAAa;IACb,YAAY;IACZ,aAAa;CACb,CAAC;AAEF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAC7B,oBAAoB,CACnB,mBAAmB;AACnB,4DAA4D;AAC5D,iBAAiB,EACjB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;IAC1B,MAAM,aAAa,GAAG,MAAM,EAAE,aAAa,IAAI,qBAAqB,CAAC;IAErE,+DAA+D;IAC/D,MAAM,cAAc,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAClD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CACjC,CAAC;IAEF,IAAI,cAAc,EAAE,CAAC;QACpB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,MAAM,MAAM,GAAkB;QAC7B,IAAI,EAAE,iBAAiB,CAAC,IAAI;QAC5B,IAAI,EAAE,GAAG,EAAE,iCAAiC;QAC5C,WAAW,EAAE,KAAK;QAClB,YAAY,EAAE,8DAA8D,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KACtG,CAAC;IAEF,OAAO,MAAM,CAAC;AACf,CAAC,CACD,CAAC","sourcesContent":["import { existsSync } from \"node:fs\";\nimport path from \"pathe\";\nimport { makePolicyDefinition } from \"../makePolicy.js\";\nimport type { PolicyDefinition, PolicyFailure } from \"../policy.js\";\n\n/**\n * Policy settings for the LicenseFileExists repo policy.\n *\n * @alpha\n */\nexport interface LicenseFileExistsSettings {\n\t/**\n\t * Array of acceptable license file names. Defaults to common variations.\n\t */\n\tacceptedNames?: string[];\n}\n\n/**\n * Default license file names to check for.\n */\nconst DEFAULT_LICENSE_NAMES = [\n\t\"LICENSE\",\n\t\"LICENSE.txt\",\n\t\"LICENSE.md\",\n\t\"LICENSE.rst\",\n\t\"LICENCE\",\n\t\"LICENCE.txt\",\n\t\"LICENCE.md\",\n\t\"LICENCE.rst\",\n];\n\n/**\n * A repo policy that checks that a LICENSE file exists in the repository root.\n * This is essential for open source projects to clarify usage rights and obligations.\n *\n * @alpha\n */\nexport const LicenseFileExists: PolicyDefinition<LicenseFileExistsSettings> =\n\tmakePolicyDefinition(\n\t\t\"LicenseFileExists\",\n\t\t// Only trigger on package.json to check once per repository\n\t\t/^package\\.json$/,\n\t\tasync ({ root, config }) => {\n\t\t\tconst acceptedNames = config?.acceptedNames ?? DEFAULT_LICENSE_NAMES;\n\n\t\t\t// Check if any of the accepted license files exist in the root\n\t\t\tconst hasLicenseFile = acceptedNames.some((name) =>\n\t\t\t\texistsSync(path.join(root, name)),\n\t\t\t);\n\n\t\t\tif (hasLicenseFile) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tconst result: PolicyFailure = {\n\t\t\t\tname: LicenseFileExists.name,\n\t\t\t\tfile: \".\", // Report against repository root\n\t\t\t\tautoFixable: false,\n\t\t\t\terrorMessage: `No LICENSE file found in repository root. Expected one of: ${acceptedNames.join(\", \")}`,\n\t\t\t};\n\n\t\t\treturn result;\n\t\t},\n\t);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NoJsFileExtensions.d.ts","sourceRoot":"","sources":["../../src/policies/NoJsFileExtensions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"NoJsFileExtensions.d.ts","sourceRoot":"","sources":["../../src/policies/NoJsFileExtensions.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAEpE;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAchC,CAAC"}
|
|
@@ -8,9 +8,7 @@ import { makePolicyDefinition } from "../makePolicy.js";
|
|
|
8
8
|
*
|
|
9
9
|
* @alpha
|
|
10
10
|
*/
|
|
11
|
-
export const NoJsFileExtensions = makePolicyDefinition("NoJsFileExtensions", /(^|\/)[^/]+\.js$/i,
|
|
12
|
-
// biome-ignore lint/suspicious/useAwait: <explanation>
|
|
13
|
-
async ({ file }) => {
|
|
11
|
+
export const NoJsFileExtensions = makePolicyDefinition("NoJsFileExtensions", /(^|\/)[^/]+\.js$/i, async ({ file }) => {
|
|
14
12
|
// Any match is considered a failure.
|
|
15
13
|
const result = {
|
|
16
14
|
name: NoJsFileExtensions.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NoJsFileExtensions.js","sourceRoot":"","sources":["../../src/policies/NoJsFileExtensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAqB,oBAAoB,CACvE,oBAAoB,EACpB,mBAAmB
|
|
1
|
+
{"version":3,"file":"NoJsFileExtensions.js","sourceRoot":"","sources":["../../src/policies/NoJsFileExtensions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAGxD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAqB,oBAAoB,CACvE,oBAAoB,EACpB,mBAAmB,EACnB,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;IAClB,qCAAqC;IACrC,MAAM,MAAM,GAAkB;QAC7B,IAAI,EAAE,kBAAkB,CAAC,IAAI;QAC7B,IAAI;QACJ,WAAW,EAAE,KAAK;QAClB,YAAY,EACX,iIAAiI;KAClI,CAAC;IACF,OAAO,MAAM,CAAC;AACf,CAAC,CACD,CAAC","sourcesContent":["import { makePolicyDefinition } from \"../makePolicy.js\";\nimport type { PolicyDefinition, PolicyFailure } from \"../policy.js\";\n\n/**\n * A repo policy that checks for JavaScript source files that just use the .js file extension. Such files may be\n * interpreted by node as either CommonJS or ESM based on the `type` field in the nearest package.json file. This\n * can create unexpected behavior for JS files; changing the package.json nearest to one will change how the JS\n * is processed by node. Using explicit file extensions reduces ambiguity and ensures a CJS file isn't suddenly treated\n * like an ESM file.\n *\n * @alpha\n */\nexport const NoJsFileExtensions: PolicyDefinition = makePolicyDefinition(\n\t\"NoJsFileExtensions\",\n\t/(^|\\/)[^/]+\\.js$/i,\n\tasync ({ file }) => {\n\t\t// Any match is considered a failure.\n\t\tconst result: PolicyFailure = {\n\t\t\tname: NoJsFileExtensions.name,\n\t\t\tfile,\n\t\t\tautoFixable: false,\n\t\t\terrorMessage:\n\t\t\t\t\"JavaScript files should have a .cjs or .mjs file extension based on the module format of the file. Rename the file accordingly.\",\n\t\t};\n\t\treturn result;\n\t},\n);\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PolicyDefinition } from "../policy.js";
|
|
2
|
+
/**
|
|
3
|
+
* Policy settings for the NoLargeBinaryFiles repo policy.
|
|
4
|
+
*
|
|
5
|
+
* @alpha
|
|
6
|
+
*/
|
|
7
|
+
export interface NoLargeBinaryFilesSettings {
|
|
8
|
+
/**
|
|
9
|
+
* Maximum file size in bytes. Defaults to 10MB.
|
|
10
|
+
*/
|
|
11
|
+
maxSizeBytes?: number;
|
|
12
|
+
/**
|
|
13
|
+
* File extensions to exclude from size checking.
|
|
14
|
+
* Useful for known large files that should be allowed.
|
|
15
|
+
*/
|
|
16
|
+
excludeExtensions?: string[];
|
|
17
|
+
/**
|
|
18
|
+
* File patterns to exclude from size checking.
|
|
19
|
+
* Uses glob-style patterns.
|
|
20
|
+
*/
|
|
21
|
+
excludePatterns?: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* A repo policy that prevents large binary files from being committed to the repository.
|
|
25
|
+
* Large files can bloat the repository and slow down clones. Consider using Git LFS for large assets.
|
|
26
|
+
*
|
|
27
|
+
* @alpha
|
|
28
|
+
*/
|
|
29
|
+
export declare const NoLargeBinaryFiles: PolicyDefinition<NoLargeBinaryFilesSettings>;
|
|
30
|
+
//# sourceMappingURL=NoLargeBinaryFiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NoLargeBinaryFiles.d.ts","sourceRoot":"","sources":["../../src/policies/NoLargeBinaryFiles.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAiB,MAAM,cAAc,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,0BAA0B;IAC1C;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE7B;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AA2FD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,EAAE,gBAAgB,CAAC,0BAA0B,CA0C1E,CAAC"}
|