repopo 0.2.2 → 0.3.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 CHANGED
@@ -1,5 +1,28 @@
1
1
  # repopo
2
2
 
3
+ ## 0.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - New command: `list` _[`#132`](https://github.com/tylerbutler/tools-monorepo/pull/132) [`1fa083d`](https://github.com/tylerbutler/tools-monorepo/commit/1fa083dd64499d108411326377a4463ad6acb040) [@tylerbutler](https://github.com/tylerbutler)_
8
+
9
+ The `repopo list` command lists the policies that are enabled in the repo.
10
+
11
+ ### Patch Changes
12
+
13
+ <details><summary>Updated 2 dependencies</summary>
14
+
15
+ <small>
16
+
17
+ [`f803610`](https://github.com/tylerbutler/tools-monorepo/commit/f803610f64936c5d49d862b2f4240ea248fe3f76)
18
+
19
+ </small>
20
+
21
+ - `@tylerbu/cli-api@0.5.0`
22
+ - `sort-tsconfig@0.1.2`
23
+
24
+ </details>
25
+
3
26
  ## 0.2.2
4
27
 
5
28
  ### Patch Changes
package/README.md CHANGED
@@ -76,6 +76,7 @@ field is a string instead of an object the package will be ignored.
76
76
 
77
77
  <!-- commands -->
78
78
  * [`repopo check`](#repopo-check)
79
+ * [`repopo list`](#repopo-list)
79
80
 
80
81
  ## `repopo check`
81
82
 
@@ -83,7 +84,7 @@ Checks and applies policies to the files in the repository.
83
84
 
84
85
  ```
85
86
  USAGE
86
- $ repopo check [-v | --quiet] [-f] [-D <value>... | -d <value>] [-p <value>] [--stdin]
87
+ $ repopo check [-f] [--stdin] [-D <value>... | -d <value>] [-p <value>]
87
88
 
88
89
  FLAGS
89
90
  -D, --excludePolicy=<value>... Exclude policies by name. Can be specified multiple times to exclude multiple
@@ -93,11 +94,25 @@ FLAGS
93
94
  -f, --fix Fix errors if possible.
94
95
  -p, --path=<value> Filter file paths by <regex>.
95
96
  --stdin Read list of files from stdin.
96
-
97
- LOGGING FLAGS
98
- -v, --verbose Enable verbose logging.
99
- --quiet Disable all logging.
100
97
  ```
101
98
 
102
99
  _See code: [src/commands/check.ts](https://github.com/tylerbutler/tools-monorepo/blob/main/packages/repopo/src/commands/check.ts)_
100
+
101
+ ## `repopo list`
102
+
103
+ Lists the policies configured to run.
104
+
105
+ ```
106
+ USAGE
107
+ $ repopo list [-D <value>... | -d <value>] [-p <value>]
108
+
109
+ FLAGS
110
+ -D, --excludePolicy=<value>... Exclude policies by name. Can be specified multiple times to exclude multiple
111
+ policies.
112
+ -d, --policy=<value> Filter policies to apply by <regex>. Only policies with a name matching the regex will
113
+ be applied.
114
+ -p, --path=<value> Filter file paths by <regex>.
115
+ ```
116
+
117
+ _See code: [src/commands/list.ts](https://github.com/tylerbutler/tools-monorepo/blob/main/packages/repopo/src/commands/list.ts)_
103
118
  <!-- commandsstop -->
@@ -0,0 +1,52 @@
1
+ import { GitCommand } from "@tylerbu/cli-api";
2
+ import type { PolicyConfig } from "./config.js";
3
+ import { type PolicyHandlerPerfStats } from "./perf.js";
4
+ import { type PolicyName, type RepoPolicy } from "./policy.js";
5
+ /**
6
+ * A convenience interface used to pass commonly used parameters between functions.
7
+ */
8
+ export interface PolicyCommandContext {
9
+ /**
10
+ * A regular expression used to filter selected files.
11
+ */
12
+ pathRegex: RegExp;
13
+ /**
14
+ * A list of regular expressions used to exclude files from all handlers.
15
+ */
16
+ excludeFiles: RegExp[];
17
+ /**
18
+ * A list of handlers to apply to selected files.
19
+ */
20
+ policies: RepoPolicy[];
21
+ /**
22
+ * A per-handler list of regular expressions used to exclude files from specific handlers.
23
+ */
24
+ excludePoliciesForFiles: ExcludedPolicyFileMap;
25
+ /**
26
+ * Path to the root of the git repo.
27
+ */
28
+ gitRoot: string;
29
+ /**
30
+ * Performance information for each handler.
31
+ */
32
+ perfStats: PolicyHandlerPerfStats;
33
+ }
34
+ /**
35
+ * This command lists all the policies configured to run.
36
+ */
37
+ export declare abstract class BaseRepopoCommand<T extends typeof BaseRepopoCommand & {
38
+ args: typeof GitCommand.args;
39
+ flags: typeof GitCommand.flags;
40
+ }> extends GitCommand<T, PolicyConfig> {
41
+ static readonly flags: {
42
+ readonly config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
43
+ readonly policy: import("@oclif/core/interfaces").OptionFlag<RegExp | undefined, import("@oclif/core/interfaces").CustomOptions>;
44
+ readonly excludePolicy: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
45
+ readonly path: import("@oclif/core/interfaces").OptionFlag<RegExp | undefined, import("@oclif/core/interfaces").CustomOptions>;
46
+ };
47
+ private context;
48
+ protected getContext(): PolicyCommandContext;
49
+ init(): Promise<void>;
50
+ }
51
+ export type ExcludedPolicyFileMap = Map<PolicyName, RegExp[]>;
52
+ //# sourceMappingURL=baseCommand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseCommand.d.ts","sourceRoot":"","sources":["../src/baseCommand.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAA2B,MAAM,kBAAkB,CAAC;AAEvE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,KAAK,sBAAsB,EAAgB,MAAM,WAAW,CAAC;AACtE,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAIhF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;IAEvB;;OAEG;IACH,QAAQ,EAAE,UAAU,EAAE,CAAC;IAEvB;;OAEG;IACH,uBAAuB,EAAE,qBAAqB,CAAC;IAE/C;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,SAAS,EAAE,sBAAsB,CAAC;CAClC;AAED;;GAEG;AACH,8BAAsB,iBAAiB,CACtC,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAC7B,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAC/B,CACA,SAAQ,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC;IACpC,gBAAyB,KAAK;gCAlCmB,wBAAwB,wCAKtE,wBAAuB;;;;MAiDf;IAEX,OAAO,CAAC,OAAO,CAAmC;IAElD,SAAS,CAAC,UAAU,IAAI,oBAAoB;IAOtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAoD3C;AAED,MAAM,MAAM,qBAAqB,GAAG,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { Flags } from "@oclif/core";
2
+ import { GitCommand, RegExpFlag, findGitRoot } from "@tylerbu/cli-api";
3
+ import { newPerfStats } from "./perf.js";
4
+ import { DefaultPolicies } from "./policy.js";
5
+ const DEFAULT_PATH_REGEX = /.?/;
6
+ /**
7
+ * This command lists all the policies configured to run.
8
+ */
9
+ export class BaseRepopoCommand extends GitCommand {
10
+ static flags = {
11
+ policy: RegExpFlag({
12
+ description: "Filter policies to apply by <regex>. Only policies with a name matching the regex will be applied.",
13
+ required: false,
14
+ char: "d",
15
+ }),
16
+ excludePolicy: Flags.string({
17
+ char: "D",
18
+ description: "Exclude policies by name. Can be specified multiple times to exclude multiple policies.",
19
+ exclusive: ["policy"],
20
+ multiple: true,
21
+ }),
22
+ path: RegExpFlag({
23
+ description: "Filter file paths by <regex>.",
24
+ required: false,
25
+ char: "p",
26
+ }),
27
+ ...GitCommand.flags,
28
+ };
29
+ context;
30
+ getContext() {
31
+ if (this.context === undefined) {
32
+ throw new Error("context undefined");
33
+ }
34
+ return this.context;
35
+ }
36
+ async init() {
37
+ await super.init();
38
+ const { flags } = this;
39
+ const config = await this.loadConfig();
40
+ let policies = config?.policies ?? DefaultPolicies;
41
+ policies =
42
+ policies.filter((h) => {
43
+ if (flags.excludePolicy === undefined ||
44
+ flags.excludePolicy.length === 0) {
45
+ return true;
46
+ }
47
+ const shouldRun = flags.excludePolicy?.includes(h.name) === false;
48
+ if (!shouldRun) {
49
+ this.info(`Disabled policy: ${h.name}`);
50
+ }
51
+ return shouldRun;
52
+ }) ?? [];
53
+ if (flags.policy !== undefined) {
54
+ this.info(`Filtering handlers by regex: ${flags.policy}`);
55
+ policies = policies.filter((h) => flags.policy?.test(h.name));
56
+ }
57
+ const excludeFiles = config?.excludeFiles?.map((e) => toRegExp(e)) ?? [];
58
+ const excludePoliciesForFilesRaw = config?.excludePoliciesForFiles;
59
+ const excludePoliciesForFiles = new Map();
60
+ if (excludePoliciesForFilesRaw) {
61
+ for (const [policyName, filters] of Object.entries(excludePoliciesForFilesRaw)) {
62
+ const regexes = filters.map((e) => toRegExp(e));
63
+ excludePoliciesForFiles.set(policyName, regexes);
64
+ }
65
+ }
66
+ const gitRoot = await findGitRoot();
67
+ const pathRegex = this.flags.path ?? DEFAULT_PATH_REGEX;
68
+ if (this.flags.path !== undefined) {
69
+ this.info(`Filtering file paths by regex: ${pathRegex}`);
70
+ }
71
+ this.context = {
72
+ pathRegex,
73
+ excludeFiles,
74
+ policies,
75
+ excludePoliciesForFiles,
76
+ gitRoot,
77
+ perfStats: newPerfStats(),
78
+ };
79
+ }
80
+ }
81
+ function toRegExp(input) {
82
+ if (typeof input === "string") {
83
+ return new RegExp(input, "i");
84
+ }
85
+ return input;
86
+ }
87
+ //# sourceMappingURL=baseCommand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseCommand.js","sourceRoot":"","sources":["../src/baseCommand.ts"],"names":[],"mappings":"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","sourcesContent":["import { Flags } from \"@oclif/core\";\nimport { GitCommand, RegExpFlag, findGitRoot } from \"@tylerbu/cli-api\";\n\nimport type { PolicyConfig } from \"./config.js\";\nimport { type PolicyHandlerPerfStats, newPerfStats } from \"./perf.js\";\nimport { DefaultPolicies, type PolicyName, type RepoPolicy } from \"./policy.js\";\n\nconst DEFAULT_PATH_REGEX = /.?/;\n\n/**\n * A convenience interface used to pass commonly used parameters between functions.\n */\nexport interface PolicyCommandContext {\n\t/**\n\t * A regular expression used to filter selected files.\n\t */\n\tpathRegex: RegExp;\n\n\t/**\n\t * A list of regular expressions used to exclude files from all handlers.\n\t */\n\texcludeFiles: RegExp[];\n\n\t/**\n\t * A list of handlers to apply to selected files.\n\t */\n\tpolicies: RepoPolicy[];\n\n\t/**\n\t * A per-handler list of regular expressions used to exclude files from specific handlers.\n\t */\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\n\t/**\n\t * Path to the root of the git repo.\n\t */\n\tgitRoot: string;\n\n\t/**\n\t * Performance information for each handler.\n\t */\n\tperfStats: PolicyHandlerPerfStats;\n}\n\n/**\n * This command lists all the policies configured to run.\n */\nexport abstract class BaseRepopoCommand<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof GitCommand.args;\n\t\tflags: typeof GitCommand.flags;\n\t},\n> extends GitCommand<T, PolicyConfig> {\n\tstatic override readonly flags = {\n\t\tpolicy: RegExpFlag({\n\t\t\tdescription:\n\t\t\t\t\"Filter policies to apply by <regex>. Only policies with a name matching the regex will be applied.\",\n\t\t\trequired: false,\n\t\t\tchar: \"d\",\n\t\t}),\n\t\texcludePolicy: Flags.string({\n\t\t\tchar: \"D\",\n\t\t\tdescription:\n\t\t\t\t\"Exclude policies by name. Can be specified multiple times to exclude multiple policies.\",\n\t\t\texclusive: [\"policy\"],\n\t\t\tmultiple: true,\n\t\t}),\n\t\tpath: RegExpFlag({\n\t\t\tdescription: \"Filter file paths by <regex>.\",\n\t\t\trequired: false,\n\t\t\tchar: \"p\",\n\t\t}),\n\t\t...GitCommand.flags,\n\t} as const;\n\n\tprivate context: PolicyCommandContext | undefined;\n\n\tprotected getContext(): PolicyCommandContext {\n\t\tif (this.context === undefined) {\n\t\t\tthrow new Error(\"context undefined\");\n\t\t}\n\t\treturn this.context;\n\t}\n\n\tpublic override async init(): Promise<void> {\n\t\tawait super.init();\n\t\tconst { flags } = this;\n\t\tconst config = await this.loadConfig();\n\t\tlet policies = config?.policies ?? DefaultPolicies;\n\t\tpolicies =\n\t\t\tpolicies.filter((h) => {\n\t\t\t\tif (\n\t\t\t\t\tflags.excludePolicy === undefined ||\n\t\t\t\t\tflags.excludePolicy.length === 0\n\t\t\t\t) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tconst shouldRun = flags.excludePolicy?.includes(h.name) === false;\n\t\t\t\tif (!shouldRun) {\n\t\t\t\t\tthis.info(`Disabled policy: ${h.name}`);\n\t\t\t\t}\n\t\t\t\treturn shouldRun;\n\t\t\t}) ?? [];\n\t\tif (flags.policy !== undefined) {\n\t\t\tthis.info(`Filtering handlers by regex: ${flags.policy}`);\n\t\t\tpolicies = policies.filter((h) => flags.policy?.test(h.name));\n\t\t}\n\n\t\tconst excludeFiles: RegExp[] =\n\t\t\tconfig?.excludeFiles?.map((e) => toRegExp(e)) ?? [];\n\t\tconst excludePoliciesForFilesRaw = config?.excludePoliciesForFiles;\n\t\tconst excludePoliciesForFiles: ExcludedPolicyFileMap = new Map();\n\t\tif (excludePoliciesForFilesRaw) {\n\t\t\tfor (const [policyName, filters] of Object.entries(\n\t\t\t\texcludePoliciesForFilesRaw,\n\t\t\t)) {\n\t\t\t\tconst regexes = filters.map((e) => toRegExp(e));\n\t\t\t\texcludePoliciesForFiles.set(policyName, regexes);\n\t\t\t}\n\t\t}\n\t\tconst gitRoot = await findGitRoot();\n\n\t\tconst pathRegex = this.flags.path ?? DEFAULT_PATH_REGEX;\n\t\tif (this.flags.path !== undefined) {\n\t\t\tthis.info(`Filtering file paths by regex: ${pathRegex}`);\n\t\t}\n\n\t\tthis.context = {\n\t\t\tpathRegex,\n\t\t\texcludeFiles,\n\t\t\tpolicies,\n\t\t\texcludePoliciesForFiles,\n\t\t\tgitRoot,\n\t\t\tperfStats: newPerfStats(),\n\t\t};\n\t}\n}\n\nexport type ExcludedPolicyFileMap = Map<PolicyName, RegExp[]>;\n\nfunction toRegExp(input: string | RegExp): RegExp {\n\tif (typeof input === \"string\") {\n\t\treturn new RegExp(input, \"i\");\n\t}\n\treturn input;\n}\n"]}
@@ -1,5 +1,4 @@
1
- import { GitCommand } from "@tylerbu/cli-api";
2
- import { type PolicyConfig } from "../config.js";
1
+ import { BaseRepopoCommand } from "../baseCommand.js";
3
2
  /**
4
3
  * This tool enforces policies across the code base via a series of handler functions. The handler functions are
5
4
  * associated with a regular expression, and all files matching that expression are passed to the handler function.
@@ -9,24 +8,22 @@ import { type PolicyConfig } from "../config.js";
9
8
  *
10
9
  * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`
11
10
  */
12
- export declare class CheckPolicy extends GitCommand<typeof CheckPolicy & {
13
- args: typeof GitCommand.args;
14
- flags: typeof GitCommand.flags;
15
- }, PolicyConfig> {
11
+ export declare class CheckPolicy<T extends typeof BaseRepopoCommand & {
12
+ args: typeof CheckPolicy.args;
13
+ flags: typeof CheckPolicy.flags;
14
+ }> extends BaseRepopoCommand<T> {
16
15
  static readonly summary = "Checks and applies policies to the files in the repository.";
17
16
  static readonly flags: {
18
17
  readonly config: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
19
- readonly fix: import("@oclif/core/interfaces").BooleanFlag<boolean>;
20
18
  readonly policy: import("@oclif/core/interfaces").OptionFlag<RegExp | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
19
  readonly excludePolicy: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
22
20
  readonly path: import("@oclif/core/interfaces").OptionFlag<RegExp | undefined, import("@oclif/core/interfaces").CustomOptions>;
21
+ readonly fix: import("@oclif/core/interfaces").BooleanFlag<boolean>;
23
22
  readonly stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
24
23
  };
25
24
  private processed;
26
25
  private count;
27
- private commandContext;
28
- get defaultConfig(): import("type-fest").SetOptional<Required<PolicyConfig>, "policies" | "policySettings">;
29
- protected loadConfig(): Promise<PolicyConfig>;
26
+ get defaultConfig(): import("../config.js").PolicyConfig;
30
27
  init(): Promise<void>;
31
28
  run(): Promise<void>;
32
29
  private executePolicy;
@@ -36,7 +33,6 @@ export declare class CheckPolicy extends GitCommand<typeof CheckPolicy & {
36
33
  * decision for all handlers.
37
34
  */
38
35
  private routeToHandlers;
39
- private logStats;
40
36
  /**
41
37
  * Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,
42
38
  * routes the file to the appropriate handlers.
@@ -1 +1 @@
1
- {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAA2B,MAAM,kBAAkB,CAAC;AAGvE,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,cAAc,CAAC;AAoDtE;;;;;;;;GAQG;AACH,qBAAa,WAAY,SAAQ,UAAU,CAC1C,OAAO,WAAW,GAAG;IACpB,IAAI,EAAE,OAAO,UAAU,CAAC,IAAI,CAAC;IAC7B,KAAK,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CAC/B,EACD,YAAY,CACZ;IACA,gBAAyB,OAAO,iEAC+B;IAE/D,gBAAyB,KAAK;gCA7De,wBAAwB,wCAGrD,wBAAwB;;;;;;MAwF7B;IAEX,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,KAAK,CAAK;IAElB,OAAO,CAAC,cAAc,CAAwC;IAE9D,IAAoB,aAAa,2FAEhC;cAEwB,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC;IAuBtC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA6DrB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAmE5B,aAAa;IAc3B;;;;OAIG;YACW,eAAe;IAwG7B,OAAO,CAAC,QAAQ;IAchB;;;OAGG;YACW,kBAAkB;CA0BhC"}
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAOA,OAAO,EACN,iBAAiB,EAEjB,MAAM,mBAAmB,CAAC;AAK3B;;;;;;;;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;gCAhBO,wBAAwB,wCAAwC,wBAE/F;;;;;;MA0BK;IAEX,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,KAAK,CAAK;IAElB,IAAW,aAAa,wCAEvB;IAEqB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAQrB,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;YAuC5B,aAAa;IAc3B;;;;OAIG;YACW,eAAe;IA0G7B;;;OAGG;YACW,kBAAkB;CA0BhC"}
@@ -3,15 +3,11 @@ import { EOL as newline } from "node:os";
3
3
  import path from "node:path";
4
4
  import { Flags } from "@oclif/core";
5
5
  import { StringBuilder } from "@rushstack/node-core-library";
6
- import { GitCommand, RegExpFlag, findGitRoot } from "@tylerbu/cli-api";
7
6
  import chalk from "chalk";
8
- import { cosmiconfig } from "cosmiconfig";
7
+ import { BaseRepopoCommand, } from "../baseCommand.js";
9
8
  import { DefaultPolicyConfig } from "../config.js";
10
- import { DefaultPolicies, isPolicyFixResult, } from "../policy.js";
11
- /**
12
- * Stores performance data for each handler. Used to collect and display performance stats.
13
- */
14
- const handlerPerformanceData = new Map();
9
+ import { logStats, runWithPerf } from "../perf.js";
10
+ import { isPolicyFixResult } from "../policy.js";
15
11
  /**
16
12
  * This tool enforces policies across the code base via a series of handler functions. The handler functions are
17
13
  * associated with a regular expression, and all files matching that expression are passed to the handler function.
@@ -21,7 +17,7 @@ const handlerPerformanceData = new Map();
21
17
  *
22
18
  * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`
23
19
  */
24
- export class CheckPolicy extends GitCommand {
20
+ export class CheckPolicy extends BaseRepopoCommand {
25
21
  static summary = "Checks and applies policies to the files in the repository.";
26
22
  static flags = {
27
23
  fix: Flags.boolean({
@@ -30,132 +26,32 @@ export class CheckPolicy extends GitCommand {
30
26
  required: false,
31
27
  char: "f",
32
28
  }),
33
- policy: RegExpFlag({
34
- description: "Filter policies to apply by <regex>. Only policies with a name matching the regex will be applied.",
35
- required: false,
36
- char: "d",
37
- }),
38
- excludePolicy: Flags.string({
39
- char: "D",
40
- description: "Exclude policies by name. Can be specified multiple times to exclude multiple policies.",
41
- exclusive: ["policy"],
42
- multiple: true,
43
- }),
44
- path: RegExpFlag({
45
- description: "Filter file paths by <regex>.",
46
- required: false,
47
- char: "p",
48
- }),
49
29
  stdin: Flags.boolean({
50
30
  description: "Read list of files from stdin.",
51
31
  required: false,
52
32
  }),
53
- ...GitCommand.flags,
33
+ ...BaseRepopoCommand.flags,
54
34
  };
55
35
  processed = 0;
56
36
  count = 0;
57
- // private policies: RepoPolicy[] | undefined;
58
- commandContext;
59
37
  get defaultConfig() {
60
38
  return DefaultPolicyConfig;
61
39
  }
62
- async loadConfig() {
63
- const gitRoot = await findGitRoot();
64
- // this.configPath ??= this.config.configDir; // path.join(this.config.configDir, "config.ts");
65
- const explorer = cosmiconfig(this.config.bin, {
66
- searchStrategy: "global",
67
- });
68
- this.verbose(`Looking for '${this.config.bin}' config at '${gitRoot}'`);
69
- const config = await explorer.search(gitRoot);
70
- if (config?.config !== undefined) {
71
- this.verbose(`Found config at ${config.filepath}`);
72
- }
73
- if (config?.config === undefined) {
74
- this.warning("No config found; using defaults.");
75
- }
76
- const finalConfig = config?.config ?? this.defaultConfig;
77
- if (finalConfig.includeDefaultPolicies === true) {
78
- finalConfig.policies ??= [];
79
- finalConfig.policies.push(...DefaultPolicies);
80
- }
81
- return finalConfig;
82
- }
83
40
  async init() {
84
41
  await super.init();
85
- let policies = this.commandConfig?.policies?.filter((h) => {
86
- if (this.flags.excludePolicy === undefined ||
87
- this.flags.excludePolicy.length === 0) {
88
- return true;
89
- }
90
- const shouldRun = this.flags.excludePolicy?.includes(h.name) === false;
91
- if (!shouldRun) {
92
- this.info(`Disabled policy: ${h.name}`);
93
- }
94
- return shouldRun;
95
- }) ?? [];
96
- // const pathRegex: RegExp =
97
- // this.flags.path === undefined ? /.?/ : new RegExp(this.flags.path, "i");
98
- if (this.flags.policy !== undefined) {
99
- this.info(`Filtering handlers by regex: ${this.flags.policy}`);
100
- policies = policies?.filter((h) => this.flags.policy?.test(h.name));
101
- }
102
- const pathRegex = this.flags.path ?? /.?/;
103
- if (this.flags.path !== undefined) {
104
- this.info(`Filtering file paths by regex: ${pathRegex}`);
105
- }
106
42
  if (this.flags.fix) {
107
43
  this.info("Resolving errors if possible.");
108
44
  }
109
- const excludeFiles = this.commandConfig?.excludeFiles?.map((e) => toRegExp(e)) ?? [];
110
- const excludePoliciesForFilesRaw = this.commandConfig?.excludePoliciesForFiles;
111
- const excludePoliciesForFiles = new Map();
112
- if (excludePoliciesForFilesRaw) {
113
- for (const [policyName, filters] of Object.entries(excludePoliciesForFilesRaw)) {
114
- const regexes = filters.map((e) => toRegExp(e));
115
- excludePoliciesForFiles.set(policyName, regexes);
116
- }
117
- }
118
- const gitRoot = await findGitRoot();
119
- this.commandContext = {
120
- pathRegex,
121
- excludeFiles,
122
- policies,
123
- excludePoliciesForFiles,
124
- gitRoot,
125
- };
126
45
  }
127
46
  async run() {
128
47
  // list the handlers then exit
129
- // if (this.flags.listHandlers) {
130
- // for (const h of handlersToRun) {
131
- // this.log(`${h.name}\nresolver: ${h.resolver !== undefined}\n`);
132
- // }
133
- // this.log(`${handlersToRun.length} TOTAL POLICY HANDLERS`);
134
- // this.exit(0);
135
- // }
136
- const policies = this.commandConfig?.policies ?? [];
48
+ const config = await this.loadConfig();
49
+ const policies = config?.policies ?? [];
137
50
  this.verbose(`${policies.length} policies loaded.`);
138
51
  for (const h of policies) {
139
52
  this.verbose(h.name);
140
53
  }
141
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
142
- // const rawExclusions: string[] =
143
- // this.flags.exclusions === undefined
144
- // ? manifest.policy?.exclusions
145
- // : await readJson(this.flags.exclusions);
146
- // const exclusions: RegExp[] = rawExclusions.map((e) => new RegExp(e, "i"));
147
- // const rawHandlerExclusions = manifest?.policy?.handlerExclusions;
148
- // const handlerExclusions: ExcludedPolicyFileMap = {};
149
- // if (rawHandlerExclusions) {
150
- // for (const rule of Object.keys(rawHandlerExclusions)) {
151
- // handlerExclusions[rule] = rawHandlerExclusions[rule].map(
152
- // (e) => new RegExp(e, "i"),
153
- // );
154
- // }
155
- // }
156
54
  const filePathsToCheck = [];
157
- // const context = await this.getContext();
158
- // const gitRoot = context.repo.resolvedRoot;
159
55
  if (this.flags.stdin) {
160
56
  const stdInput = await readStdin();
161
57
  if (stdInput !== undefined) {
@@ -163,16 +59,18 @@ export class CheckPolicy extends GitCommand {
163
59
  }
164
60
  }
165
61
  else {
166
- // const repo = new Repository({ baseDir: gitRoot });
167
62
  const gitFiles = (await this.git.raw("ls-files", "-co", "--exclude-standard", "--full-name")) ?? "";
168
63
  filePathsToCheck.push(...gitFiles.split("\n"));
169
64
  }
170
- if (this.commandContext === undefined) {
171
- this.error("Command context was undefined - fatal error.", {
65
+ try {
66
+ const context = this.getContext();
67
+ await this.executePolicy(filePathsToCheck, context);
68
+ }
69
+ catch (error) {
70
+ this.error(`Command context was undefined - fatal error: ${error}`, {
172
71
  exit: 100,
173
72
  });
174
73
  }
175
- await this.executePolicy(filePathsToCheck, this.commandContext);
176
74
  }
177
75
  async executePolicy(pathsToCheck, commandContext) {
178
76
  try {
@@ -182,7 +80,7 @@ export class CheckPolicy extends GitCommand {
182
80
  }
183
81
  }
184
82
  finally {
185
- this.logStats();
83
+ logStats(commandContext.perfStats, this);
186
84
  }
187
85
  }
188
86
  /**
@@ -191,12 +89,11 @@ export class CheckPolicy extends GitCommand {
191
89
  * decision for all handlers.
192
90
  */
193
91
  async routeToHandlers(file, commandContext) {
194
- const {
195
- // context,
196
- policies, excludePoliciesForFiles, gitRoot, } = commandContext;
92
+ const { policies, excludePoliciesForFiles, gitRoot, perfStats } = commandContext;
197
93
  // Use the repo-relative path so that regexes that specify string start (^) will match repo paths.
198
94
  // Replace \ in result with / in case OS is Windows.
199
95
  const relPath = path.relative(gitRoot, file).replace(/\\/g, "/");
96
+ const config = await this.loadConfig();
200
97
  await Promise.all(policies
201
98
  .filter((handler) => handler.match.test(relPath))
202
99
  // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>
@@ -208,11 +105,11 @@ export class CheckPolicy extends GitCommand {
208
105
  this.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);
209
106
  return;
210
107
  }
211
- const result = await runWithPerf(policy.name, "handle", async () => policy.handler({
108
+ const result = await runWithPerf(policy.name, "handle", perfStats, async () => policy.handler({
212
109
  file: relPath,
213
110
  root: gitRoot,
214
111
  resolve: this.flags.fix,
215
- config: this.commandConfig?.policySettings?.[policy.name],
112
+ config: config?.policySettings?.[policy.name],
216
113
  }));
217
114
  if (result === true) {
218
115
  return;
@@ -233,7 +130,7 @@ export class CheckPolicy extends GitCommand {
233
130
  if (this.flags.fix && resolver !== undefined) {
234
131
  // Resolve the failure
235
132
  messages.append(`${newline}attempting to resolve: ${relPath}`);
236
- const resolveResult = await runWithPerf(policy.name, "resolve", async () => resolver({ file: relPath, root: gitRoot }));
133
+ const resolveResult = await runWithPerf(policy.name, "resolve", perfStats, async () => resolver({ file: relPath, root: gitRoot }));
237
134
  if (resolveResult.errorMessage !== undefined &&
238
135
  resolveResult.errorMessage !== "") {
239
136
  messages.append(newline + resolveResult.errorMessage);
@@ -262,15 +159,6 @@ export class CheckPolicy extends GitCommand {
262
159
  }
263
160
  }));
264
161
  }
265
- logStats() {
266
- this.log(`Statistics: ${this.processed} processed, ${this.count - this.processed} excluded, ${this.count} total`);
267
- for (const [action, handlerPerf] of handlerPerformanceData.entries()) {
268
- this.log(`Performance for "${action}":`);
269
- for (const [handler, dur] of handlerPerf.entries()) {
270
- this.log(`\t${handler}: ${dur}ms`);
271
- }
272
- }
273
- }
274
162
  /**
275
163
  * Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,
276
164
  * routes the file to the appropriate handlers.
@@ -295,16 +183,6 @@ export class CheckPolicy extends GitCommand {
295
183
  this.processed++;
296
184
  }
297
185
  }
298
- async function runWithPerf(name, action, run) {
299
- const actionMap = handlerPerformanceData.get(action) ?? new Map();
300
- let dur = actionMap.get(name) ?? 0;
301
- const start = Date.now();
302
- const result = await run();
303
- dur += Date.now() - start;
304
- actionMap.set(name, dur);
305
- handlerPerformanceData.set(action, actionMap);
306
- return result;
307
- }
308
186
  async function readStdin() {
309
187
  return new Promise((resolve) => {
310
188
  const stdin = process.stdin;
@@ -321,10 +199,4 @@ async function readStdin() {
321
199
  }
322
200
  });
323
201
  }
324
- function toRegExp(input) {
325
- if (typeof input === "string") {
326
- return new RegExp(input, "i");
327
- }
328
- return input;
329
- }
330
202
  //# 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 fs from \"node:fs\";\nimport { EOL as newline } from \"node:os\";\nimport path from \"node:path\";\nimport { Flags } from \"@oclif/core\";\nimport { StringBuilder } from \"@rushstack/node-core-library\";\nimport { GitCommand, RegExpFlag, findGitRoot } from \"@tylerbu/cli-api\";\nimport chalk from \"chalk\";\nimport { type CosmiconfigResult, cosmiconfig } from \"cosmiconfig\";\nimport { DefaultPolicyConfig, type PolicyConfig } from \"../config.js\";\nimport {\n\tDefaultPolicies,\n\ttype PolicyName,\n\ttype RepoPolicy,\n\tisPolicyFixResult,\n} from \"../policy.js\";\n\ntype PolicyAction = \"handle\" | \"resolve\";\n\ntype ExcludedPolicyFileMap = Map<PolicyName, RegExp[]>; // Record<PolicyName, RegExp[]>\n\n/**\n * A convenience interface used to pass commonly used parameters to functions in this file.\n */\ninterface CheckPolicyCommandContext {\n\t/**\n\t * A regular expression used to filter selected files.\n\t */\n\tpathRegex: RegExp;\n\n\t/**\n\t * A list of regular expressions used to exclude files from all handlers.\n\t */\n\texcludeFiles: RegExp[];\n\n\t/**\n\t * A list of handlers to apply to selected files.\n\t */\n\tpolicies: RepoPolicy[];\n\n\t/**\n\t * A per-handler list of regular expressions used to exclude files from specific handlers.\n\t */\n\texcludePoliciesForFiles: ExcludedPolicyFileMap;\n\n\t/**\n\t * Path to the root of the git repo.\n\t */\n\tgitRoot: string;\n\n\t/**\n\t * The repo context.\n\t */\n\t// context: Context;\n}\n\n/**\n * Stores performance data for each handler. Used to collect and display performance stats.\n */\nconst handlerPerformanceData = new Map<PolicyAction, Map<string, number>>();\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 extends GitCommand<\n\ttypeof CheckPolicy & {\n\t\targs: typeof GitCommand.args;\n\t\tflags: typeof GitCommand.flags;\n\t},\n\tPolicyConfig\n> {\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\tpolicy: RegExpFlag({\n\t\t\tdescription:\n\t\t\t\t\"Filter policies to apply by <regex>. Only policies with a name matching the regex will be applied.\",\n\t\t\trequired: false,\n\t\t\tchar: \"d\",\n\t\t}),\n\t\texcludePolicy: Flags.string({\n\t\t\tchar: \"D\",\n\t\t\tdescription:\n\t\t\t\t\"Exclude policies by name. Can be specified multiple times to exclude multiple policies.\",\n\t\t\texclusive: [\"policy\"],\n\t\t\tmultiple: true,\n\t\t}),\n\t\tpath: RegExpFlag({\n\t\t\tdescription: \"Filter file paths by <regex>.\",\n\t\t\trequired: false,\n\t\t\tchar: \"p\",\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...GitCommand.flags,\n\t} as const;\n\n\tprivate processed = 0;\n\tprivate count = 0;\n\t// private policies: RepoPolicy[] | undefined;\n\tprivate commandContext: CheckPolicyCommandContext | undefined;\n\n\tpublic override get defaultConfig() {\n\t\treturn DefaultPolicyConfig;\n\t}\n\n\tprotected override async loadConfig(): Promise<PolicyConfig> {\n\t\tconst gitRoot = await findGitRoot();\n\t\t// this.configPath ??= this.config.configDir; // path.join(this.config.configDir, \"config.ts\");\n\t\tconst explorer = cosmiconfig(this.config.bin, {\n\t\t\tsearchStrategy: \"global\",\n\t\t});\n\t\tthis.verbose(`Looking for '${this.config.bin}' config at '${gitRoot}'`);\n\t\tconst config: CosmiconfigResult = await explorer.search(gitRoot);\n\t\tif (config?.config !== undefined) {\n\t\t\tthis.verbose(`Found config at ${config.filepath}`);\n\t\t}\n\t\tif (config?.config === undefined) {\n\t\t\tthis.warning(\"No config found; using defaults.\");\n\t\t}\n\t\tconst finalConfig: PolicyConfig = config?.config ?? this.defaultConfig;\n\t\tif (finalConfig.includeDefaultPolicies === true) {\n\t\t\tfinalConfig.policies ??= [];\n\t\t\tfinalConfig.policies.push(...DefaultPolicies);\n\t\t}\n\n\t\treturn finalConfig;\n\t}\n\n\tpublic override async init(): Promise<void> {\n\t\tawait super.init();\n\n\t\tlet policies =\n\t\t\tthis.commandConfig?.policies?.filter((h) => {\n\t\t\t\tif (\n\t\t\t\t\tthis.flags.excludePolicy === undefined ||\n\t\t\t\t\tthis.flags.excludePolicy.length === 0\n\t\t\t\t) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\tconst shouldRun = this.flags.excludePolicy?.includes(h.name) === false;\n\t\t\t\tif (!shouldRun) {\n\t\t\t\t\tthis.info(`Disabled policy: ${h.name}`);\n\t\t\t\t}\n\t\t\t\treturn shouldRun;\n\t\t\t}) ?? [];\n\n\t\t// const pathRegex: RegExp =\n\t\t// \tthis.flags.path === undefined ? /.?/ : new RegExp(this.flags.path, \"i\");\n\n\t\tif (this.flags.policy !== undefined) {\n\t\t\tthis.info(`Filtering handlers by regex: ${this.flags.policy}`);\n\t\t\tpolicies = policies?.filter((h) => this.flags.policy?.test(h.name));\n\t\t}\n\n\t\tconst pathRegex = this.flags.path ?? /.?/;\n\t\tif (this.flags.path !== undefined) {\n\t\t\tthis.info(`Filtering file paths by regex: ${pathRegex}`);\n\t\t}\n\n\t\tif (this.flags.fix) {\n\t\t\tthis.info(\"Resolving errors if possible.\");\n\t\t}\n\n\t\tconst excludeFiles: RegExp[] =\n\t\t\tthis.commandConfig?.excludeFiles?.map((e) => toRegExp(e)) ?? [];\n\n\t\tconst excludePoliciesForFilesRaw =\n\t\t\tthis.commandConfig?.excludePoliciesForFiles;\n\n\t\tconst excludePoliciesForFiles: ExcludedPolicyFileMap = new Map();\n\t\tif (excludePoliciesForFilesRaw) {\n\t\t\tfor (const [policyName, filters] of Object.entries(\n\t\t\t\texcludePoliciesForFilesRaw,\n\t\t\t)) {\n\t\t\t\tconst regexes = filters.map((e) => toRegExp(e));\n\t\t\t\texcludePoliciesForFiles.set(policyName, regexes);\n\t\t\t}\n\t\t}\n\n\t\tconst gitRoot = await findGitRoot();\n\t\tthis.commandContext = {\n\t\t\tpathRegex,\n\t\t\texcludeFiles,\n\t\t\tpolicies,\n\t\t\texcludePoliciesForFiles,\n\t\t\tgitRoot,\n\t\t};\n\t}\n\n\tpublic override async run(): Promise<void> {\n\t\t// list the handlers then exit\n\t\t// if (this.flags.listHandlers) {\n\t\t// \tfor (const h of handlersToRun) {\n\t\t// \t\tthis.log(`${h.name}\\nresolver: ${h.resolver !== undefined}\\n`);\n\t\t// \t}\n\t\t// \tthis.log(`${handlersToRun.length} TOTAL POLICY HANDLERS`);\n\t\t// \tthis.exit(0);\n\t\t// }\n\n\t\tconst policies = this.commandConfig?.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\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t// const rawExclusions: string[] =\n\t\t// \tthis.flags.exclusions === undefined\n\t\t// \t\t? manifest.policy?.exclusions\n\t\t// \t\t: await readJson(this.flags.exclusions);\n\n\t\t// const exclusions: RegExp[] = rawExclusions.map((e) => new RegExp(e, \"i\"));\n\n\t\t// const rawHandlerExclusions = manifest?.policy?.handlerExclusions;\n\n\t\t// const handlerExclusions: ExcludedPolicyFileMap = {};\n\t\t// if (rawHandlerExclusions) {\n\t\t// \tfor (const rule of Object.keys(rawHandlerExclusions)) {\n\t\t// \t\thandlerExclusions[rule] = rawHandlerExclusions[rule].map(\n\t\t// \t\t\t(e) => new RegExp(e, \"i\"),\n\t\t// \t\t);\n\t\t// \t}\n\t\t// }\n\n\t\tconst filePathsToCheck: string[] = [];\n\t\t// const context = await this.getContext();\n\t\t// const gitRoot = context.repo.resolvedRoot;\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\t// const repo = new Repository({ baseDir: gitRoot });\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\tif (this.commandContext === undefined) {\n\t\t\tthis.error(\"Command context was undefined - fatal error.\", {\n\t\t\t\texit: 100,\n\t\t\t});\n\t\t}\n\n\t\tawait this.executePolicy(filePathsToCheck, this.commandContext);\n\t}\n\n\tprivate async executePolicy(\n\t\tpathsToCheck: string[],\n\t\tcommandContext: CheckPolicyCommandContext,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tfor (const pathToCheck of pathsToCheck) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tawait this.checkOrExcludeFile(pathToCheck, commandContext);\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.logStats();\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: CheckPolicyCommandContext,\n\t): Promise<void> {\n\t\tconst {\n\t\t\t// context,\n\t\t\tpolicies,\n\t\t\texcludePoliciesForFiles,\n\t\t\tgitRoot,\n\t\t} = 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\tawait Promise.all(\n\t\t\tpolicies\n\t\t\t\t.filter((handler) => handler.match.test(relPath))\n\t\t\t\t// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>\n\t\t\t\t.map(async (policy): Promise<void> => {\n\t\t\t\t\t// doing exclusion per handler\n\t\t\t\t\tconst exclusions = excludePoliciesForFiles.get(policy.name);\n\t\t\t\t\tif (\n\t\t\t\t\t\texclusions !== undefined &&\n\t\t\t\t\t\t!exclusions.every((regex) => !regex.test(relPath))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await runWithPerf(policy.name, \"handle\", async () =>\n\t\t\t\t\t\tpolicy.handler({\n\t\t\t\t\t\t\tfile: relPath,\n\t\t\t\t\t\t\troot: gitRoot,\n\t\t\t\t\t\t\tresolve: this.flags.fix,\n\t\t\t\t\t\t\tconfig: this.commandConfig?.policySettings?.[policy.name],\n\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (result === true) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst messages = new StringBuilder();\n\t\t\t\t\tif (isPolicyFixResult(result)) {\n\t\t\t\t\t\tif (result.resolved) {\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`Resolved ${policy.name} policy failure for file: ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`Error when trying to fix ${policy.name} policy failure in ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// result must be a PolicyFailureResult; check if there is a standalone resolver.\n\t\t\t\t\t\tconst { resolver } = policy;\n\n\t\t\t\t\t\tif (this.flags.fix && resolver !== undefined) {\n\t\t\t\t\t\t\t// Resolve the failure\n\t\t\t\t\t\t\tmessages.append(`${newline}attempting to resolve: ${relPath}`);\n\t\t\t\t\t\t\tconst resolveResult = await runWithPerf(\n\t\t\t\t\t\t\t\tpolicy.name,\n\t\t\t\t\t\t\t\t\"resolve\",\n\t\t\t\t\t\t\t\tasync () => resolver({ file: relPath, root: gitRoot }),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tresolveResult.errorMessage !== undefined &&\n\t\t\t\t\t\t\t\tresolveResult.errorMessage !== \"\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tmessages.append(newline + resolveResult.errorMessage);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!resolveResult.resolved) {\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// No resolver, or fix is false, so we're in the full failure case.\n\t\t\t\t\t\t\tconst autoFixable = result.autoFixable\n\t\t\t\t\t\t\t\t? chalk.green(\" (autofixable)\")\n\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`'${policy.name}' policy failure${autoFixable}: ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\tresult.errorMessage === undefined\n\t\t\t\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t\t\t\t: `${newline}${result.errorMessage}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((process.exitCode ?? 0) === 0) {\n\t\t\t\t\t\tthis.info(messages.toString());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.warning(messages.toString());\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t);\n\t}\n\n\tprivate logStats(): void {\n\t\tthis.log(\n\t\t\t`Statistics: ${this.processed} processed, ${\n\t\t\t\tthis.count - this.processed\n\t\t\t} excluded, ${this.count} total`,\n\t\t);\n\t\tfor (const [action, handlerPerf] of handlerPerformanceData.entries()) {\n\t\t\tthis.log(`Performance for \"${action}\":`);\n\t\t\tfor (const [handler, dur] of handlerPerf.entries()) {\n\t\t\t\tthis.log(`\\t${handler}: ${dur}ms`);\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\tprivate async checkOrExcludeFile(\n\t\tinputPath: string,\n\t\tcommandContext: CheckPolicyCommandContext,\n\t): Promise<void> {\n\t\tconst { excludeFiles: exclusions, gitRoot, pathRegex } = commandContext;\n\n\t\tconst filePath = path.join(gitRoot, inputPath).trim().replace(/\\\\/g, \"/\");\n\n\t\tif (!(pathRegex.test(inputPath) && fs.existsSync(filePath))) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.count++;\n\t\tif (!exclusions.every((value) => !value.test(inputPath))) {\n\t\t\tthis.verbose(`Excluded all handlers: ${inputPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.routeToHandlers(filePath, commandContext);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(`Error routing ${filePath} to handler: ${error}`);\n\t\t}\n\n\t\tthis.processed++;\n\t}\n}\n\nasync function runWithPerf<T>(\n\tname: string,\n\taction: PolicyAction,\n\trun: () => Promise<T>,\n): Promise<T> {\n\tconst actionMap =\n\t\thandlerPerformanceData.get(action) ?? new Map<string, number>();\n\tlet dur = actionMap.get(name) ?? 0;\n\n\tconst start = Date.now();\n\tconst result = await run();\n\tdur += Date.now() - start;\n\n\tactionMap.set(name, dur);\n\thandlerPerformanceData.set(action, actionMap);\n\treturn result;\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\nfunction toRegExp(input: string | RegExp): RegExp {\n\tif (typeof input === \"string\") {\n\t\treturn new RegExp(input, \"i\");\n\t}\n\treturn input;\n}\n"]}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs\";\nimport { EOL as newline } from \"node:os\";\nimport path from \"node:path\";\nimport { Flags } from \"@oclif/core\";\nimport { StringBuilder } from \"@rushstack/node-core-library\";\nimport chalk from \"chalk\";\n\nimport {\n\tBaseRepopoCommand,\n\ttype PolicyCommandContext,\n} from \"../baseCommand.js\";\nimport { DefaultPolicyConfig } from \"../config.js\";\nimport { logStats, runWithPerf } from \"../perf.js\";\nimport { isPolicyFixResult } from \"../policy.js\";\n\n/**\n * This tool enforces policies across the code base via a series of handler functions. The handler functions are\n * associated with a regular expression, and all files matching that expression are passed to the handler function.\n *\n * By default, the list of files to check comes from `git ls-files. You can also pipe in file names from stdin. For\n * example:\n *\n * `git ls-files -co --exclude-standard --full-name | repopo check --stdin --verbose`\n */\nexport class CheckPolicy<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof CheckPolicy.args;\n\t\tflags: typeof CheckPolicy.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tstatic override readonly summary =\n\t\t\"Checks and applies policies to the files in the repository.\";\n\n\tstatic override readonly flags = {\n\t\tfix: Flags.boolean({\n\t\t\taliases: [\"resolve\"],\n\t\t\tdescription: \"Fix errors if possible.\",\n\t\t\trequired: false,\n\t\t\tchar: \"f\",\n\t\t}),\n\t\tstdin: Flags.boolean({\n\t\t\tdescription: \"Read list of files from stdin.\",\n\t\t\trequired: false,\n\t\t}),\n\t\t...BaseRepopoCommand.flags,\n\t} as const;\n\n\tprivate processed = 0;\n\tprivate count = 0;\n\n\tpublic get defaultConfig() {\n\t\treturn DefaultPolicyConfig;\n\t}\n\n\tpublic override async init(): Promise<void> {\n\t\tawait super.init();\n\n\t\tif (this.flags.fix) {\n\t\t\tthis.info(\"Resolving errors if possible.\");\n\t\t}\n\t}\n\n\tpublic override async run(): Promise<void> {\n\t\t// list the handlers then exit\n\t\tconst config = await this.loadConfig();\n\t\tconst policies = config?.policies ?? [];\n\t\tthis.verbose(`${policies.length} policies loaded.`);\n\t\tfor (const h of policies) {\n\t\t\tthis.verbose(h.name);\n\t\t}\n\n\t\tconst filePathsToCheck: string[] = [];\n\n\t\tif (this.flags.stdin) {\n\t\t\tconst stdInput = await readStdin();\n\n\t\t\tif (stdInput !== undefined) {\n\t\t\t\tfilePathsToCheck.push(...stdInput.split(\"\\n\"));\n\t\t\t}\n\t\t} else {\n\t\t\tconst gitFiles =\n\t\t\t\t(await this.git.raw(\n\t\t\t\t\t\"ls-files\",\n\t\t\t\t\t\"-co\",\n\t\t\t\t\t\"--exclude-standard\",\n\t\t\t\t\t\"--full-name\",\n\t\t\t\t)) ?? \"\";\n\n\t\t\tfilePathsToCheck.push(...gitFiles.split(\"\\n\"));\n\t\t}\n\n\t\ttry {\n\t\t\tconst context = this.getContext();\n\t\t\tawait this.executePolicy(filePathsToCheck, context);\n\t\t} catch (error) {\n\t\t\tthis.error(`Command context was undefined - fatal error: ${error}`, {\n\t\t\t\texit: 100,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async executePolicy(\n\t\tpathsToCheck: string[],\n\t\tcommandContext: PolicyCommandContext,\n\t): Promise<void> {\n\t\ttry {\n\t\t\tfor (const pathToCheck of pathsToCheck) {\n\t\t\t\t// eslint-disable-next-line no-await-in-loop\n\t\t\t\tawait this.checkOrExcludeFile(pathToCheck, commandContext);\n\t\t\t}\n\t\t} finally {\n\t\t\tlogStats(commandContext.perfStats, this);\n\t\t}\n\t}\n\n\t/**\n\t * Routes files to their handlers and resolvers by regex testing their full paths. If a file fails a policy that has a\n\t * resolver, the resolver will be invoked as well. Synchronizes the output, exit codes, and resolve\n\t * decision for all handlers.\n\t */\n\tprivate async routeToHandlers(\n\t\tfile: string,\n\t\tcommandContext: PolicyCommandContext,\n\t): Promise<void> {\n\t\tconst { policies, excludePoliciesForFiles, gitRoot, perfStats } =\n\t\t\tcommandContext;\n\n\t\t// Use the repo-relative path so that regexes that specify string start (^) will match repo paths.\n\t\t// Replace \\ in result with / in case OS is Windows.\n\t\tconst relPath = path.relative(gitRoot, file).replace(/\\\\/g, \"/\");\n\t\tconst config = await this.loadConfig();\n\n\t\tawait Promise.all(\n\t\t\tpolicies\n\t\t\t\t.filter((handler) => handler.match.test(relPath))\n\t\t\t\t// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: <explanation>\n\t\t\t\t.map(async (policy): Promise<void> => {\n\t\t\t\t\t// doing exclusion per handler\n\t\t\t\t\tconst exclusions = excludePoliciesForFiles.get(policy.name);\n\t\t\t\t\tif (\n\t\t\t\t\t\texclusions !== undefined &&\n\t\t\t\t\t\t!exclusions.every((regex) => !regex.test(relPath))\n\t\t\t\t\t) {\n\t\t\t\t\t\tthis.verbose(`Excluded from '${policy.name}' policy: ${relPath}`);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst result = await runWithPerf(\n\t\t\t\t\t\tpolicy.name,\n\t\t\t\t\t\t\"handle\",\n\t\t\t\t\t\tperfStats,\n\t\t\t\t\t\tasync () =>\n\t\t\t\t\t\t\tpolicy.handler({\n\t\t\t\t\t\t\t\tfile: relPath,\n\t\t\t\t\t\t\t\troot: gitRoot,\n\t\t\t\t\t\t\t\tresolve: this.flags.fix,\n\t\t\t\t\t\t\t\tconfig: config?.policySettings?.[policy.name],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t);\n\n\t\t\t\t\tif (result === true) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst messages = new StringBuilder();\n\t\t\t\t\tif (isPolicyFixResult(result)) {\n\t\t\t\t\t\tif (result.resolved) {\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`Resolved ${policy.name} policy failure for file: ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`Error when trying to fix ${policy.name} policy failure in ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// result must be a PolicyFailureResult; check if there is a standalone resolver.\n\t\t\t\t\t\tconst { resolver } = policy;\n\n\t\t\t\t\t\tif (this.flags.fix && resolver !== undefined) {\n\t\t\t\t\t\t\t// Resolve the failure\n\t\t\t\t\t\t\tmessages.append(`${newline}attempting to resolve: ${relPath}`);\n\t\t\t\t\t\t\tconst resolveResult = await runWithPerf(\n\t\t\t\t\t\t\t\tpolicy.name,\n\t\t\t\t\t\t\t\t\"resolve\",\n\t\t\t\t\t\t\t\tperfStats,\n\t\t\t\t\t\t\t\tasync () => resolver({ file: relPath, root: gitRoot }),\n\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\tresolveResult.errorMessage !== undefined &&\n\t\t\t\t\t\t\t\tresolveResult.errorMessage !== \"\"\n\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\tmessages.append(newline + resolveResult.errorMessage);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!resolveResult.resolved) {\n\t\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// No resolver, or fix is false, so we're in the full failure case.\n\t\t\t\t\t\t\tconst autoFixable = result.autoFixable\n\t\t\t\t\t\t\t\t? chalk.green(\" (autofixable)\")\n\t\t\t\t\t\t\t\t: \"\";\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\t`'${policy.name}' policy failure${autoFixable}: ${result.file}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tmessages.append(\n\t\t\t\t\t\t\t\tresult.errorMessage === undefined\n\t\t\t\t\t\t\t\t\t? \"\"\n\t\t\t\t\t\t\t\t\t: `${newline}${result.errorMessage}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tprocess.exitCode = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((process.exitCode ?? 0) === 0) {\n\t\t\t\t\t\tthis.info(messages.toString());\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.warning(messages.toString());\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t);\n\t}\n\n\t/**\n\t * Given a string that represents a path to a file in the repo, determines if the file should be checked, and if so,\n\t * routes the file to the appropriate handlers.\n\t */\n\tprivate async checkOrExcludeFile(\n\t\tinputPath: string,\n\t\tcommandContext: PolicyCommandContext,\n\t): Promise<void> {\n\t\tconst { excludeFiles: exclusions, gitRoot, pathRegex } = commandContext;\n\n\t\tconst filePath = path.join(gitRoot, inputPath).trim().replace(/\\\\/g, \"/\");\n\n\t\tif (!(pathRegex.test(inputPath) && fs.existsSync(filePath))) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.count++;\n\t\tif (!exclusions.every((value) => !value.test(inputPath))) {\n\t\t\tthis.verbose(`Excluded all handlers: ${inputPath}`);\n\t\t\treturn;\n\t\t}\n\n\t\ttry {\n\t\t\tawait this.routeToHandlers(filePath, commandContext);\n\t\t} catch (error: unknown) {\n\t\t\tthrow new Error(`Error routing ${filePath} to handler: ${error}`);\n\t\t}\n\n\t\tthis.processed++;\n\t}\n}\n\nasync function readStdin(): Promise<string> {\n\treturn new Promise((resolve) => {\n\t\tconst stdin = process.stdin;\n\t\tstdin.setEncoding(\"utf8\");\n\n\t\tlet data = \"\";\n\t\tstdin.on(\"data\", (chunk) => {\n\t\t\tdata += chunk;\n\t\t});\n\n\t\tstdin.on(\"end\", () => {\n\t\t\tresolve(data);\n\t\t});\n\n\t\tif (stdin.isTTY) {\n\t\t\tresolve(\"\");\n\t\t}\n\t});\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import { BaseRepopoCommand } from "../baseCommand.js";
2
+ import type { RepoPolicy } from "../policy.js";
3
+ /**
4
+ * This command lists all the policies configured to run.
5
+ */
6
+ export declare class ListCommand<T extends typeof BaseRepopoCommand & {
7
+ args: typeof ListCommand.args;
8
+ flags: typeof ListCommand.flags;
9
+ }> extends BaseRepopoCommand<T> {
10
+ static readonly summary = "Lists the policies configured to run.";
11
+ run(): Promise<RepoPolicy[]>;
12
+ }
13
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C;;GAEG;AACH,qBAAa,WAAW,CACvB,CAAC,SAAS,OAAO,iBAAiB,GAAG;IACpC,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,CAAC;IAC9B,KAAK,EAAE,OAAO,WAAW,CAAC,KAAK,CAAC;CAChC,CACA,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC7B,gBAAyB,OAAO,2CAA2C;IAGrD,GAAG,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;CAUlD"}
@@ -0,0 +1,19 @@
1
+ import chalk from "chalk";
2
+ import { BaseRepopoCommand } from "../baseCommand.js";
3
+ /**
4
+ * This command lists all the policies configured to run.
5
+ */
6
+ export class ListCommand extends BaseRepopoCommand {
7
+ static summary = "Lists the policies configured to run.";
8
+ // biome-ignore lint/suspicious/useAwait: inherited method
9
+ async run() {
10
+ const { policies } = this.getContext();
11
+ // list the handlers then exit
12
+ this.log(`${policies.length} POLICIES ENABLED`);
13
+ for (const h of policies) {
14
+ this.log(`${chalk.bold(h.name)} (auto-fix: ${h.resolver !== undefined})`);
15
+ }
16
+ return policies;
17
+ }
18
+ }
19
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAGtD;;GAEG;AACH,MAAM,OAAO,WAKX,SAAQ,iBAAoB;IAC7B,MAAM,CAAmB,OAAO,GAAG,uCAAuC,CAAC;IAE3E,0DAA0D;IAC1C,KAAK,CAAC,GAAG;QACxB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;QAEvC,8BAA8B;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,MAAM,mBAAmB,CAAC,CAAC;QAChD,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;YAC1B,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,KAAK,SAAS,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC","sourcesContent":["import chalk from \"chalk\";\n\nimport { BaseRepopoCommand } from \"../baseCommand.js\";\nimport type { RepoPolicy } from \"../policy.js\";\n\n/**\n * This command lists all the policies configured to run.\n */\nexport class ListCommand<\n\tT extends typeof BaseRepopoCommand & {\n\t\targs: typeof ListCommand.args;\n\t\tflags: typeof ListCommand.flags;\n\t},\n> extends BaseRepopoCommand<T> {\n\tstatic override readonly summary = \"Lists the policies configured to run.\";\n\n\t// biome-ignore lint/suspicious/useAwait: inherited method\n\tpublic override async run(): Promise<RepoPolicy[]> {\n\t\tconst { policies } = this.getContext();\n\n\t\t// list the handlers then exit\n\t\tthis.log(`${policies.length} POLICIES ENABLED`);\n\t\tfor (const h of policies) {\n\t\t\tthis.log(`${chalk.bold(h.name)} (auto-fix: ${h.resolver !== undefined})`);\n\t\t}\n\t\treturn policies;\n\t}\n}\n"]}
package/esm/config.d.ts CHANGED
@@ -1,6 +1,5 @@
1
- import type { RequireAtLeastOne, SetOptional } from "type-fest";
2
1
  import type { PackageJsonPropertiesSettings } from "./policies/PackageJsonProperties.js";
3
- import type { PolicyName, RepoPolicy } from "./policy.js";
2
+ import { type PolicyName, type RepoPolicy } from "./policy.js";
4
3
  /**
5
4
  * @alpha
6
5
  */
@@ -10,11 +9,14 @@ export type PerPolicySettings = ({
10
9
  /**
11
10
  * @alpha
12
11
  */
13
- export interface OptionalPolicyConfig {
12
+ export interface PolicyConfig {
13
+ /**
14
+ * An array of policies that are enabled. If this is `undefined`, then all {@link DefaultPolicies} will be enabled.
15
+ */
14
16
  policies?: RepoPolicy[];
15
17
  /**
16
- * An array of strings/regular expressions. Paths that match any of these expressions will be completely excluded from
17
- * policy.
18
+ * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded
19
+ * from policy.
18
20
  */
19
21
  excludeFiles?: (string | RegExp)[];
20
22
  /**
@@ -22,14 +24,12 @@ export interface OptionalPolicyConfig {
22
24
  * exclude that rule from being checked.
23
25
  */
24
26
  excludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;
25
- includeDefaultPolicies?: boolean;
26
27
  policySettings?: PerPolicySettings | undefined;
27
28
  }
28
29
  /**
29
- * A type representing policy configuration.
30
+ * The default config applied when no config is found.
30
31
  *
31
32
  * @alpha
32
33
  */
33
- export type PolicyConfig = RequireAtLeastOne<OptionalPolicyConfig, "policies" | "includeDefaultPolicies">;
34
- export declare const DefaultPolicyConfig: SetOptional<Required<PolicyConfig>, "policies" | "policySettings">;
34
+ export declare const DefaultPolicyConfig: PolicyConfig;
35
35
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAC1B,CAAC;IAED,qBAAqB,EAAE,6BAA6B,CAAC;CACpD,GAAG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,GAChC,SAAS,CAAC;AAEb;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IAExB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEnC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAClE,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,cAAc,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC/C;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,iBAAiB,CAC3C,oBAAoB,EACpB,UAAU,GAAG,wBAAwB,CACrC,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAChC,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAIhE,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AACzF,OAAO,EAAmB,KAAK,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAC1B,CAAC;IAED,qBAAqB,EAAE,6BAA6B,CAAC;CACpD,GAAG,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,GAChC,SAAS,CAAC;AAEb;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B;;OAEG;IACH,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IAExB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAEnC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAElE,cAAc,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;CAC/C;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,YAIjC,CAAC"}
package/esm/config.js CHANGED
@@ -1,6 +1,12 @@
1
+ import { DefaultPolicies } from "./policy.js";
2
+ /**
3
+ * The default config applied when no config is found.
4
+ *
5
+ * @alpha
6
+ */
1
7
  export const DefaultPolicyConfig = {
8
+ policies: DefaultPolicies,
2
9
  excludeFiles: [],
3
10
  excludePoliciesForFiles: {},
4
- includeDefaultPolicies: true,
5
11
  };
6
12
  //# 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":"AA8CA,MAAM,CAAC,MAAM,mBAAmB,GACqC;IACpE,YAAY,EAAE,EAAE;IAChB,uBAAuB,EAAE,EAAE;IAC3B,sBAAsB,EAAE,IAAI;CAC5B,CAAC","sourcesContent":["import type { RequireAtLeastOne, SetOptional } from \"type-fest\";\nimport type { PackageJsonPropertiesSettings } from \"./policies/PackageJsonProperties.js\";\nimport type { PolicyName, RepoPolicy } from \"./policy.js\";\n\n/**\n * @alpha\n */\nexport type PerPolicySettings =\n\t| ({\n\t\t\t// biome-ignore lint/style/useNamingConvention: key needs to match policy name\n\t\t\tPackageJsonProperties: PackageJsonPropertiesSettings;\n\t } & Record<PolicyName, unknown>)\n\t| undefined;\n\n/**\n * @alpha\n */\nexport interface OptionalPolicyConfig {\n\tpolicies?: RepoPolicy[];\n\n\t/**\n\t * An array of strings/regular expressions. Paths that match any of these expressions will be completely excluded from\n\t * policy.\n\t */\n\texcludeFiles?: (string | RegExp)[];\n\n\t/**\n\t * An object with a policy name as keys that map to an array of strings/regular expressions to\n\t * exclude that rule from being checked.\n\t */\n\texcludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;\n\tincludeDefaultPolicies?: boolean;\n\n\tpolicySettings?: PerPolicySettings | undefined;\n}\n\n/**\n * A type representing policy configuration.\n *\n * @alpha\n */\nexport type PolicyConfig = RequireAtLeastOne<\n\tOptionalPolicyConfig,\n\t\"policies\" | \"includeDefaultPolicies\"\n>;\n\nexport const DefaultPolicyConfig: // PolicyConfig\nSetOptional<Required<PolicyConfig>, \"policies\" | \"policySettings\"> = {\n\texcludeFiles: [],\n\texcludePoliciesForFiles: {},\n\tincludeDefaultPolicies: true,\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAoC,MAAM,aAAa,CAAC;AAoChF;;;;GAIG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAiB;IAChD,QAAQ,EAAE,eAAe;IACzB,YAAY,EAAE,EAAE;IAChB,uBAAuB,EAAE,EAAE;CAC3B,CAAC","sourcesContent":["import type { PackageJsonPropertiesSettings } from \"./policies/PackageJsonProperties.js\";\nimport { DefaultPolicies, type PolicyName, type RepoPolicy } from \"./policy.js\";\n\n/**\n * @alpha\n */\nexport type PerPolicySettings =\n\t| ({\n\t\t\t// biome-ignore lint/style/useNamingConvention: key needs to match policy name\n\t\t\tPackageJsonProperties: PackageJsonPropertiesSettings;\n\t } & Record<PolicyName, unknown>)\n\t| undefined;\n\n/**\n * @alpha\n */\nexport interface PolicyConfig {\n\t/**\n\t * An array of policies that are enabled. If this is `undefined`, then all {@link DefaultPolicies} will be enabled.\n\t */\n\tpolicies?: RepoPolicy[];\n\n\t/**\n\t * An array of strings/regular expressions. File paths that match any of these expressions will be completely excluded\n\t * from policy.\n\t */\n\texcludeFiles?: (string | RegExp)[];\n\n\t/**\n\t * An object with a policy name as keys that map to an array of strings/regular expressions to\n\t * exclude that rule from being checked.\n\t */\n\texcludePoliciesForFiles?: Record<PolicyName, (string | RegExp)[]>;\n\n\tpolicySettings?: PerPolicySettings | undefined;\n}\n\n/**\n * The default config applied when no config is found.\n *\n * @alpha\n */\nexport const DefaultPolicyConfig: PolicyConfig = {\n\tpolicies: DefaultPolicies,\n\texcludeFiles: [],\n\texcludePoliciesForFiles: {},\n};\n"]}
package/esm/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { run } from "@oclif/core";
2
2
  export type { PolicyFailure, PolicyFixResult, PolicyFunctionArguments, PolicyHandler, PolicyName, PolicyStandaloneResolver, RepoPolicy, } from "./policy.js";
3
3
  export { DefaultPolicies } from "./policy.js";
4
- export type { PolicyConfig, OptionalPolicyConfig, PerPolicySettings, } from "./config.js";
4
+ export type { PolicyConfig, PerPolicySettings, } from "./config.js";
5
5
  export type { PackageJsonPropertiesSettings, PackageJsonProperty, } from "./policies/PackageJsonProperties.js";
6
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,YAAY,EACX,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,UAAU,EACV,wBAAwB,EACxB,UAAU,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,6BAA6B,EAC7B,mBAAmB,GACnB,MAAM,qCAAqC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAElC,YAAY,EACX,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,aAAa,EACb,UAAU,EACV,wBAAwB,EACxB,UAAU,GACV,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EACX,YAAY,EACZ,iBAAiB,GACjB,MAAM,aAAa,CAAC;AACrB,YAAY,EACX,6BAA6B,EAC7B,mBAAmB,GACnB,MAAM,qCAAqC,CAAC"}
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAWlC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export { run } from \"@oclif/core\";\n\nexport type {\n\tPolicyFailure,\n\tPolicyFixResult,\n\tPolicyFunctionArguments,\n\tPolicyHandler,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n\tRepoPolicy,\n} from \"./policy.js\";\nexport { DefaultPolicies } from \"./policy.js\";\nexport type {\n\tPolicyConfig,\n\tOptionalPolicyConfig,\n\tPerPolicySettings,\n} from \"./config.js\";\nexport type {\n\tPackageJsonPropertiesSettings,\n\tPackageJsonProperty,\n} from \"./policies/PackageJsonProperties.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAWlC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC","sourcesContent":["export { run } from \"@oclif/core\";\n\nexport type {\n\tPolicyFailure,\n\tPolicyFixResult,\n\tPolicyFunctionArguments,\n\tPolicyHandler,\n\tPolicyName,\n\tPolicyStandaloneResolver,\n\tRepoPolicy,\n} from \"./policy.js\";\nexport { DefaultPolicies } from \"./policy.js\";\nexport type {\n\tPolicyConfig,\n\tPerPolicySettings,\n} from \"./config.js\";\nexport type {\n\tPackageJsonPropertiesSettings,\n\tPackageJsonProperty,\n} from \"./policies/PackageJsonProperties.js\";\n"]}
package/esm/perf.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { Logger } from "@tylerbu/cli-api";
2
+ import type { PolicyName } from "./policy.js";
3
+ export type PolicyAction = "handle" | "resolve";
4
+ export interface PolicyHandlerPerfStats {
5
+ count: number;
6
+ processed: number;
7
+ data: Map<PolicyAction, Map<PolicyName, number>>;
8
+ }
9
+ export declare function newPerfStats(): PolicyHandlerPerfStats;
10
+ export declare function runWithPerf<T>(name: string, action: PolicyAction, stats: PolicyHandlerPerfStats, run: () => Promise<T>): Promise<T>;
11
+ export declare function logStats(stats: PolicyHandlerPerfStats, log: Logger): void;
12
+ //# sourceMappingURL=perf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf.d.ts","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC;AAOhD,MAAM,WAAW,sBAAsB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,GAAG,CAAC,YAAY,EAAE,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;CACjD;AAED,wBAAgB,YAAY,IAAI,sBAAsB,CAMrD;AAED,wBAAsB,WAAW,CAAC,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EACpB,KAAK,EAAE,sBAAsB,EAC7B,GAAG,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,sBAAsB,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAYzE"}
package/esm/perf.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Stores performance data for each handler. Used to collect and display performance stats.
3
+ */
4
+ const handlerPerformanceData = new Map();
5
+ export function newPerfStats() {
6
+ return {
7
+ count: 0,
8
+ processed: 0,
9
+ data: new Map(),
10
+ };
11
+ }
12
+ export async function runWithPerf(name, action, stats, run) {
13
+ const actionMap = stats.data.get(action) ?? new Map();
14
+ let dur = actionMap.get(name) ?? 0;
15
+ const start = Date.now();
16
+ const result = await run();
17
+ dur += Date.now() - start;
18
+ actionMap.set(name, dur);
19
+ stats.data.set(action, actionMap);
20
+ return result;
21
+ }
22
+ export function logStats(stats, log) {
23
+ log.log(`Statistics: ${stats.processed} processed, ${stats.count - stats.processed} excluded, ${stats.count} total`);
24
+ for (const [action, handlerPerf] of handlerPerformanceData.entries()) {
25
+ log.log(`Performance for "${action}":`);
26
+ for (const [handler, dur] of handlerPerf.entries()) {
27
+ log.log(`\t${handler}: ${dur}ms`);
28
+ }
29
+ }
30
+ }
31
+ //# sourceMappingURL=perf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perf.js","sourceRoot":"","sources":["../src/perf.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,sBAAsB,GAAG,IAAI,GAAG,EAAyC,CAAC;AAQhF,MAAM,UAAU,YAAY;IAC3B,OAAO;QACN,KAAK,EAAE,CAAC;QACR,SAAS,EAAE,CAAC;QACZ,IAAI,EAAE,IAAI,GAAG,EAAyC;KACtD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,IAAY,EACZ,MAAoB,EACpB,KAA6B,EAC7B,GAAqB;IAErB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,GAAG,EAAkB,CAAC;IACtE,IAAI,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC;IAC3B,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;IAE1B,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AACf,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAA6B,EAAE,GAAW;IAClE,GAAG,CAAC,GAAG,CACN,eAAe,KAAK,CAAC,SAAS,eAC7B,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,SACrB,cAAc,KAAK,CAAC,KAAK,QAAQ,CACjC,CAAC;IACF,KAAK,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI,sBAAsB,CAAC,OAAO,EAAE,EAAE,CAAC;QACtE,GAAG,CAAC,GAAG,CAAC,oBAAoB,MAAM,IAAI,CAAC,CAAC;QACxC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;YACpD,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO,KAAK,GAAG,IAAI,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;AACF,CAAC","sourcesContent":["import type { Logger } from \"@tylerbu/cli-api\";\nimport type { PolicyName } from \"./policy.js\";\n\nexport type PolicyAction = \"handle\" | \"resolve\";\n\n/**\n * Stores performance data for each handler. Used to collect and display performance stats.\n */\nconst handlerPerformanceData = new Map<PolicyAction, Map<PolicyName, number>>();\n\nexport interface PolicyHandlerPerfStats {\n\tcount: number;\n\tprocessed: number;\n\tdata: Map<PolicyAction, Map<PolicyName, number>>;\n}\n\nexport function newPerfStats(): PolicyHandlerPerfStats {\n\treturn {\n\t\tcount: 0,\n\t\tprocessed: 0,\n\t\tdata: new Map<PolicyAction, Map<PolicyName, number>>(),\n\t};\n}\n\nexport async function runWithPerf<T>(\n\tname: string,\n\taction: PolicyAction,\n\tstats: PolicyHandlerPerfStats,\n\trun: () => Promise<T>,\n): Promise<T> {\n\tconst actionMap = stats.data.get(action) ?? new Map<string, number>();\n\tlet dur = actionMap.get(name) ?? 0;\n\n\tconst start = Date.now();\n\tconst result = await run();\n\tdur += Date.now() - start;\n\n\tactionMap.set(name, dur);\n\tstats.data.set(action, actionMap);\n\treturn result;\n}\n\nexport function logStats(stats: PolicyHandlerPerfStats, log: Logger): void {\n\tlog.log(\n\t\t`Statistics: ${stats.processed} processed, ${\n\t\t\tstats.count - stats.processed\n\t\t} excluded, ${stats.count} total`,\n\t);\n\tfor (const [action, handlerPerf] of handlerPerformanceData.entries()) {\n\t\tlog.log(`Performance for \"${action}\":`);\n\t\tfor (const [handler, dur] of handlerPerf.entries()) {\n\t\t\tlog.log(`\\t${handler}: ${dur}ms`);\n\t\t}\n\t}\n}\n"]}
package/esm/policy.d.ts CHANGED
@@ -83,15 +83,32 @@ export declare class RepoPolicyClass implements RepoPolicy {
83
83
  * @alpha
84
84
  */
85
85
  export interface PolicyFailure {
86
+ /**
87
+ * Name of the policy that failed.
88
+ */
86
89
  name: PolicyName;
90
+ /**
91
+ * Path to the file that failed the policy.
92
+ */
87
93
  file: string;
94
+ /**
95
+ * Set to `true` if the policy can be fixed automatically.
96
+ */
88
97
  autoFixable?: boolean | undefined;
98
+ /**
99
+ * An optional error message accompanying the failure.
100
+ */
89
101
  errorMessage?: string | undefined;
90
102
  }
91
103
  /**
104
+ * The result of an automatic fix for a failing policy.
105
+ *
92
106
  * @alpha
93
107
  */
94
108
  export interface PolicyFixResult extends PolicyFailure {
109
+ /**
110
+ * Set to true if the failure was resolved by the automated fixer.
111
+ */
95
112
  resolved: boolean;
96
113
  }
97
114
  export declare function isPolicyFixResult(toCheck: any): toCheck is PolicyFixResult;
@@ -1 +1 @@
1
- {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC;CACX;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS,IAAI,CACpD,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAC5B,OAAO,CAAC,IAAI,GAAG,aAAa,GAAG,eAAe,CAAC,CAAC;AAOrD;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS,IAAI,CAC/D,IAAI,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,KAC7C,eAAe,CAAC;AAIrB;;;;;;;;;;;;GAYG;AAGH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,GAAG,GAAG,SAAS;IAC9C;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAE1B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CACnD;AAED,qBAAa,eAAgB,YAAW,UAAU;aAWhC,IAAI,EAAE,MAAM;aACZ,KAAK,EAAE,MAAM;IACtB,OAAO,EAAE,aAAa;IACtB,QAAQ,CAAC,EAAE,wBAAwB;WAb7B,gBAAgB,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,wBAAwB,GACjC,eAAe;gBAKD,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACtB,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,wBAAwB,YAAA;CAI3C;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACrD,QAAQ,EAAE,OAAO,CAAC;CAClB;AAGD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,eAAe,CAK1E;AAiBD;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,UAAU,EAMvC,CAAC"}
1
+ {"version":3,"file":"policy.d.ts","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAMA;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC;AAEhC;;GAEG;AACH,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS;IAC/D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC;CACX;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS,IAAI,CACpD,IAAI,EAAE,uBAAuB,CAAC,CAAC,CAAC,KAC5B,OAAO,CAAC,IAAI,GAAG,aAAa,GAAG,eAAe,CAAC,CAAC;AAOrD;;;;GAIG;AACH,MAAM,MAAM,wBAAwB,CAAC,CAAC,GAAG,OAAO,GAAG,SAAS,IAAI,CAC/D,IAAI,EAAE,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,KAC7C,eAAe,CAAC;AAIrB;;;;;;;;;;;;GAYG;AAGH,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,GAAG,GAAG,SAAS;IAC9C;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC;IAEjB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAE1B;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CACnD;AAED,qBAAa,eAAgB,YAAW,UAAU;aAWhC,IAAI,EAAE,MAAM;aACZ,KAAK,EAAE,MAAM;IACtB,OAAO,EAAE,aAAa;IACtB,QAAQ,CAAC,EAAE,wBAAwB;WAb7B,gBAAgB,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,wBAAwB,GACjC,eAAe;gBAKD,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACtB,OAAO,EAAE,aAAa,EACtB,QAAQ,CAAC,EAAE,wBAAwB,YAAA;CAI3C;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC7B;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC;IAEjB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAElC;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAgB,SAAQ,aAAa;IACrD;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;CAClB;AAGD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,eAAe,CAK1E;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,UAAU,EAMvC,CAAC"}
package/esm/policy.js CHANGED
@@ -26,18 +26,6 @@ export function isPolicyFixResult(toCheck) {
26
26
  }
27
27
  return "resolved" in toCheck;
28
28
  }
29
- // export const commonMatchPatterns = {
30
- // "package.json": /(^|\/)package\.json/i,
31
- // } as const;
32
- // export function createPackageJsonPolicy(
33
- // props: Omit<RepoPolicy, "match">,
34
- // ): RepoPolicy {
35
- // const newPolicy: RepoPolicy = {
36
- // ...props,
37
- // match: commonMatchPatterns["package.json"],
38
- // };
39
- // return newPolicy;
40
- // }
41
29
  /**
42
30
  * Default policies included with repopo.
43
31
  *
package/esm/policy.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AA+F5D,MAAM,OAAO,eAAe;IAWV;IACA;IACT;IACA;IAbD,MAAM,CAAC,gBAAgB,CAC7B,IAAY,EACZ,KAAa,EACb,OAAsB,EACtB,QAAmC;QAEnC,OAAO,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED,YACiB,IAAY,EACZ,KAAa,EACtB,OAAsB,EACtB,QAAmC;QAH1B,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAQ;QACtB,YAAO,GAAP,OAAO,CAAe;QACtB,aAAQ,GAAR,QAAQ,CAA2B;QAE1C,QAAQ;IACT,CAAC;CACD;AAqBD,yDAAyD;AACzD,MAAM,UAAU,iBAAiB,CAAC,OAAY;IAC7C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,UAAU,IAAI,OAAO,CAAC;AAC9B,CAAC;AAED,uCAAuC;AACvC,2CAA2C;AAC3C,cAAc;AAEd,2CAA2C;AAC3C,qCAAqC;AACrC,kBAAkB;AAClB,mCAAmC;AACnC,cAAc;AACd,gDAAgD;AAChD,MAAM;AAEN,qBAAqB;AACrB,IAAI;AAEJ;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC5C,kBAAkB;IAClB,gCAAgC;IAChC,qBAAqB;IACrB,uBAAuB;IACvB,aAAa;CACb,CAAC","sourcesContent":["import { NoJsFileExtensions } from \"./policies/NoJsFileExtensions.js\";\nimport { PackageJsonProperties } from \"./policies/PackageJsonProperties.js\";\nimport { PackageJsonRepoDirectoryProperty } from \"./policies/PackageJsonRepoDirectoryProperty.js\";\nimport { PackageJsonSortedPolicy } from \"./policies/PackageJsonSortedPolicy.js\";\nimport { SortTsconfigs } from \"./policies/SortTsconfigs.js\";\n\n/**\n * A type representing a policy name.\n *\n * @alpha\n */\nexport type PolicyName = string;\n\n/**\n * @alpha\n */\nexport interface PolicyFunctionArguments<C = unknown | undefined> {\n\tfile: string;\n\troot: string;\n\tresolve: boolean;\n\tconfig?: C;\n}\n\n/**\n * A policy handler is a function that is called to check policy against a file.\n *\n * @alpha\n */\nexport type PolicyHandler<C = unknown | undefined> = (\n\targs: PolicyFunctionArguments<C>,\n) => Promise<true | PolicyFailure | PolicyFixResult>;\n\n// export type PolicyCheckOnly = (\n// \tfile: string,\n// \troot: string,\n// ) => Promise<true | PolicyFailure | PolicyFixResult>;\n\n/**\n * A standalone function that can be called to resolve a policy failure.\n *\n * @alpha\n */\nexport type PolicyStandaloneResolver<C = unknown | undefined> = (\n\targs: Omit<PolicyFunctionArguments<C>, \"resolve\">,\n) => PolicyFixResult;\n\n// function isPolicyHandler(input: PolicyHandler | PolicyCheckOnly): input is PolicyHandler\n\n/**\n * A RepoPolicy checks and applies policies to files in the repository.\n *\n * Each policy has a name and a match regex for matching which files it should apply to. Every file in th repo is\n * enumerated and if it matches the regex for a policy, that policy is applied.\n *\n * Each policy includes a handler function that checks a file against the policy and can optionally resolve any problems\n * (automated resolutions depend on the policy implementation).\n *\n * @typeParam C - type of configuration object used by the policy\n *\n * @alpha\n */\n\n// biome-ignore lint/suspicious/noExplicitAny: TODO - figure out if this can work with unknown or in another typesafe manner\nexport interface RepoPolicy<C = any | undefined> {\n\t/**\n\t * The name of the policy; displayed in UI and used in settings.\n\t */\n\tname: PolicyName;\n\n\t/**\n\t * A more detailed description of the policy and its intended function.\n\t */\n\tdescription?: string;\n\n\t/**\n\t * A regular expression that is used to match files in the repo.\n\t */\n\tmatch: RegExp;\n\n\t/**\n\t * A handler function that checks if a file is compliant with the policy.\n\t *\n\t * @param file - Repo-relative path to the file to check.\n\t * @param root - Absolute path to the root of the repo.\n\t * @param resolve - If true, automated policy fixes will be applied. Not all policies support automated fixes.\n\t * @returns True if the file passed the policy; otherwise a PolicyFailure object will be returned.\n\t */\n\thandler: PolicyHandler<C>;\n\n\t/**\n\t * A resolver function that can be used to automatically address the policy violation.\n\t *\n\t * @param file - Repo-relative path to the file to check.\n\t * @param root - Absolute path to the root of the repo.\n\t * @returns true if the file passed the policy; otherwise a PolicyFailure object will be returned.\n\t */\n\tresolver?: PolicyStandaloneResolver<C> | undefined;\n}\n\nexport class RepoPolicyClass implements RepoPolicy {\n\tpublic static createRepoPolicy(\n\t\tname: string,\n\t\tmatch: RegExp,\n\t\thandler: PolicyHandler,\n\t\tresolver?: PolicyStandaloneResolver,\n\t): RepoPolicyClass {\n\t\treturn new RepoPolicyClass(name, match, handler, resolver);\n\t}\n\n\tpublic constructor(\n\t\tpublic readonly name: string,\n\t\tpublic readonly match: RegExp,\n\t\tpublic handler: PolicyHandler,\n\t\tpublic resolver?: PolicyStandaloneResolver,\n\t) {\n\t\t// empty\n\t}\n}\n\n/**\n * A policy failure.\n *\n * @alpha\n */\nexport interface PolicyFailure {\n\tname: PolicyName;\n\tfile: string;\n\tautoFixable?: boolean | undefined;\n\terrorMessage?: string | undefined;\n}\n\n/**\n * @alpha\n */\nexport interface PolicyFixResult extends PolicyFailure {\n\tresolved: boolean;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: type guard\nexport function isPolicyFixResult(toCheck: any): toCheck is PolicyFixResult {\n\tif (typeof toCheck !== \"object\") {\n\t\treturn false;\n\t}\n\treturn \"resolved\" in toCheck;\n}\n\n// export const commonMatchPatterns = {\n// \t\"package.json\": /(^|\\/)package\\.json/i,\n// } as const;\n\n// export function createPackageJsonPolicy(\n// \tprops: Omit<RepoPolicy, \"match\">,\n// ): RepoPolicy {\n// \tconst newPolicy: RepoPolicy = {\n// \t\t...props,\n// \t\tmatch: commonMatchPatterns[\"package.json\"],\n// \t};\n\n// \treturn newPolicy;\n// }\n\n/**\n * Default policies included with repopo.\n *\n * @alpha\n */\nexport const DefaultPolicies: RepoPolicy[] = [\n\tNoJsFileExtensions,\n\tPackageJsonRepoDirectoryProperty,\n\tPackageJsonProperties,\n\tPackageJsonSortedPolicy,\n\tSortTsconfigs,\n];\n"]}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,gCAAgC,EAAE,MAAM,gDAAgD,CAAC;AAClG,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AA+F5D,MAAM,OAAO,eAAe;IAWV;IACA;IACT;IACA;IAbD,MAAM,CAAC,gBAAgB,CAC7B,IAAY,EACZ,KAAa,EACb,OAAsB,EACtB,QAAmC;QAEnC,OAAO,IAAI,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED,YACiB,IAAY,EACZ,KAAa,EACtB,OAAsB,EACtB,QAAmC;QAH1B,SAAI,GAAJ,IAAI,CAAQ;QACZ,UAAK,GAAL,KAAK,CAAQ;QACtB,YAAO,GAAP,OAAO,CAAe;QACtB,aAAQ,GAAR,QAAQ,CAA2B;QAE1C,QAAQ;IACT,CAAC;CACD;AAyCD,yDAAyD;AACzD,MAAM,UAAU,iBAAiB,CAAC,OAAY;IAC7C,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QACjC,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,UAAU,IAAI,OAAO,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB;IAC5C,kBAAkB;IAClB,gCAAgC;IAChC,qBAAqB;IACrB,uBAAuB;IACvB,aAAa;CACb,CAAC","sourcesContent":["import { NoJsFileExtensions } from \"./policies/NoJsFileExtensions.js\";\nimport { PackageJsonProperties } from \"./policies/PackageJsonProperties.js\";\nimport { PackageJsonRepoDirectoryProperty } from \"./policies/PackageJsonRepoDirectoryProperty.js\";\nimport { PackageJsonSortedPolicy } from \"./policies/PackageJsonSortedPolicy.js\";\nimport { SortTsconfigs } from \"./policies/SortTsconfigs.js\";\n\n/**\n * A type representing a policy name.\n *\n * @alpha\n */\nexport type PolicyName = string;\n\n/**\n * @alpha\n */\nexport interface PolicyFunctionArguments<C = unknown | undefined> {\n\tfile: string;\n\troot: string;\n\tresolve: boolean;\n\tconfig?: C;\n}\n\n/**\n * A policy handler is a function that is called to check policy against a file.\n *\n * @alpha\n */\nexport type PolicyHandler<C = unknown | undefined> = (\n\targs: PolicyFunctionArguments<C>,\n) => Promise<true | PolicyFailure | PolicyFixResult>;\n\n// export type PolicyCheckOnly = (\n// \tfile: string,\n// \troot: string,\n// ) => Promise<true | PolicyFailure | PolicyFixResult>;\n\n/**\n * A standalone function that can be called to resolve a policy failure.\n *\n * @alpha\n */\nexport type PolicyStandaloneResolver<C = unknown | undefined> = (\n\targs: Omit<PolicyFunctionArguments<C>, \"resolve\">,\n) => PolicyFixResult;\n\n// function isPolicyHandler(input: PolicyHandler | PolicyCheckOnly): input is PolicyHandler\n\n/**\n * A RepoPolicy checks and applies policies to files in the repository.\n *\n * Each policy has a name and a match regex for matching which files it should apply to. Every file in th repo is\n * enumerated and if it matches the regex for a policy, that policy is applied.\n *\n * Each policy includes a handler function that checks a file against the policy and can optionally resolve any problems\n * (automated resolutions depend on the policy implementation).\n *\n * @typeParam C - type of configuration object used by the policy\n *\n * @alpha\n */\n\n// biome-ignore lint/suspicious/noExplicitAny: TODO - figure out if this can work with unknown or in another typesafe manner\nexport interface RepoPolicy<C = any | undefined> {\n\t/**\n\t * The name of the policy; displayed in UI and used in settings.\n\t */\n\tname: PolicyName;\n\n\t/**\n\t * A more detailed description of the policy and its intended function.\n\t */\n\tdescription?: string;\n\n\t/**\n\t * A regular expression that is used to match files in the repo.\n\t */\n\tmatch: RegExp;\n\n\t/**\n\t * A handler function that checks if a file is compliant with the policy.\n\t *\n\t * @param file - Repo-relative path to the file to check.\n\t * @param root - Absolute path to the root of the repo.\n\t * @param resolve - If true, automated policy fixes will be applied. Not all policies support automated fixes.\n\t * @returns True if the file passed the policy; otherwise a PolicyFailure object will be returned.\n\t */\n\thandler: PolicyHandler<C>;\n\n\t/**\n\t * A resolver function that can be used to automatically address the policy violation.\n\t *\n\t * @param file - Repo-relative path to the file to check.\n\t * @param root - Absolute path to the root of the repo.\n\t * @returns true if the file passed the policy; otherwise a PolicyFailure object will be returned.\n\t */\n\tresolver?: PolicyStandaloneResolver<C> | undefined;\n}\n\nexport class RepoPolicyClass implements RepoPolicy {\n\tpublic static createRepoPolicy(\n\t\tname: string,\n\t\tmatch: RegExp,\n\t\thandler: PolicyHandler,\n\t\tresolver?: PolicyStandaloneResolver,\n\t): RepoPolicyClass {\n\t\treturn new RepoPolicyClass(name, match, handler, resolver);\n\t}\n\n\tpublic constructor(\n\t\tpublic readonly name: string,\n\t\tpublic readonly match: RegExp,\n\t\tpublic handler: PolicyHandler,\n\t\tpublic resolver?: PolicyStandaloneResolver,\n\t) {\n\t\t// empty\n\t}\n}\n\n/**\n * A policy failure.\n *\n * @alpha\n */\nexport interface PolicyFailure {\n\t/**\n\t * Name of the policy that failed.\n\t */\n\tname: PolicyName;\n\n\t/**\n\t * Path to the file that failed the policy.\n\t */\n\tfile: string;\n\n\t/**\n\t * Set to `true` if the policy can be fixed automatically.\n\t */\n\tautoFixable?: boolean | undefined;\n\n\t/**\n\t * An optional error message accompanying the failure.\n\t */\n\terrorMessage?: string | undefined;\n}\n\n/**\n * The result of an automatic fix for a failing policy.\n *\n * @alpha\n */\nexport interface PolicyFixResult extends PolicyFailure {\n\t/**\n\t * Set to true if the failure was resolved by the automated fixer.\n\t */\n\tresolved: boolean;\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: type guard\nexport function isPolicyFixResult(toCheck: any): toCheck is PolicyFixResult {\n\tif (typeof toCheck !== \"object\") {\n\t\treturn false;\n\t}\n\treturn \"resolved\" in toCheck;\n}\n\n/**\n * Default policies included with repopo.\n *\n * @alpha\n */\nexport const DefaultPolicies: RepoPolicy[] = [\n\tNoJsFileExtensions,\n\tPackageJsonRepoDirectoryProperty,\n\tPackageJsonProperties,\n\tPackageJsonSortedPolicy,\n\tSortTsconfigs,\n];\n"]}
@@ -4,29 +4,6 @@
4
4
  "aliases": [],
5
5
  "args": {},
6
6
  "flags": {
7
- "verbose": {
8
- "char": "v",
9
- "description": "Enable verbose logging.",
10
- "exclusive": [
11
- "quiet"
12
- ],
13
- "helpGroup": "LOGGING",
14
- "name": "verbose",
15
- "required": false,
16
- "allowNo": false,
17
- "type": "boolean"
18
- },
19
- "quiet": {
20
- "description": "Disable all logging.",
21
- "exclusive": [
22
- "verbose"
23
- ],
24
- "helpGroup": "LOGGING",
25
- "name": "quiet",
26
- "required": false,
27
- "allowNo": false,
28
- "type": "boolean"
29
- },
30
7
  "fix": {
31
8
  "aliases": [
32
9
  "resolve"
@@ -38,6 +15,13 @@
38
15
  "allowNo": false,
39
16
  "type": "boolean"
40
17
  },
18
+ "stdin": {
19
+ "description": "Read list of files from stdin.",
20
+ "name": "stdin",
21
+ "required": false,
22
+ "allowNo": false,
23
+ "type": "boolean"
24
+ },
41
25
  "policy": {
42
26
  "char": "d",
43
27
  "description": "Filter policies to apply by <regex>. Only policies with a name matching the regex will be applied.",
@@ -67,13 +51,6 @@
67
51
  "multiple": false,
68
52
  "type": "option"
69
53
  },
70
- "stdin": {
71
- "description": "Read list of files from stdin.",
72
- "name": "stdin",
73
- "required": false,
74
- "allowNo": false,
75
- "type": "boolean"
76
- },
77
54
  "config": {
78
55
  "description": "The path to a configuration file.",
79
56
  "helpGroup": "CONFIGURATION",
@@ -90,7 +67,6 @@
90
67
  "pluginAlias": "repopo",
91
68
  "pluginName": "repopo",
92
69
  "pluginType": "core",
93
- "strict": true,
94
70
  "summary": "Checks and applies policies to the files in the repository.",
95
71
  "isESM": true,
96
72
  "relativePath": [
@@ -98,7 +74,64 @@
98
74
  "commands",
99
75
  "check.js"
100
76
  ]
77
+ },
78
+ "list": {
79
+ "aliases": [],
80
+ "args": {},
81
+ "flags": {
82
+ "policy": {
83
+ "char": "d",
84
+ "description": "Filter policies to apply by <regex>. Only policies with a name matching the regex will be applied.",
85
+ "name": "policy",
86
+ "required": false,
87
+ "hasDynamicHelp": false,
88
+ "multiple": false,
89
+ "type": "option"
90
+ },
91
+ "excludePolicy": {
92
+ "char": "D",
93
+ "description": "Exclude policies by name. Can be specified multiple times to exclude multiple policies.",
94
+ "exclusive": [
95
+ "policy"
96
+ ],
97
+ "name": "excludePolicy",
98
+ "hasDynamicHelp": false,
99
+ "multiple": true,
100
+ "type": "option"
101
+ },
102
+ "path": {
103
+ "char": "p",
104
+ "description": "Filter file paths by <regex>.",
105
+ "name": "path",
106
+ "required": false,
107
+ "hasDynamicHelp": false,
108
+ "multiple": false,
109
+ "type": "option"
110
+ },
111
+ "config": {
112
+ "description": "The path to a configuration file.",
113
+ "helpGroup": "CONFIGURATION",
114
+ "hidden": true,
115
+ "name": "config",
116
+ "hasDynamicHelp": false,
117
+ "multiple": false,
118
+ "type": "option"
119
+ }
120
+ },
121
+ "hasDynamicHelp": false,
122
+ "hiddenAliases": [],
123
+ "id": "list",
124
+ "pluginAlias": "repopo",
125
+ "pluginName": "repopo",
126
+ "pluginType": "core",
127
+ "summary": "Lists the policies configured to run.",
128
+ "isESM": true,
129
+ "relativePath": [
130
+ "esm",
131
+ "commands",
132
+ "list.js"
133
+ ]
101
134
  }
102
135
  },
103
- "version": "0.2.2"
136
+ "version": "0.3.0"
104
137
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "repopo",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Enforce policies on all or some of the files in a git repository.",
5
5
  "keywords": [
6
6
  "policy",
@@ -45,7 +45,7 @@
45
45
  "repositoryPrefix": "<%- repo %>/blob/main/packages/repopo/<%- commandPath %>"
46
46
  },
47
47
  "dependencies": {
48
- "@fluidframework/build-tools": "^0.44.0",
48
+ "@fluidframework/build-tools": "^0.47.0",
49
49
  "@oclif/core": "^4.0.19",
50
50
  "@oclif/plugin-help": "^6.2.10",
51
51
  "@rushstack/node-core-library": "^5.7.0",
@@ -53,8 +53,8 @@
53
53
  "cosmiconfig": "^9.0.0",
54
54
  "fs-extra": "^11.2.0",
55
55
  "sort-package-json": "2.10.0",
56
- "@tylerbu/cli-api": "^0.4.0",
57
- "sort-tsconfig": "^0.1.1"
56
+ "@tylerbu/cli-api": "^0.5.0",
57
+ "sort-tsconfig": "^0.1.2"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@biomejs/biome": "1.8.3",