archprint 0.8.3 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +88 -17
  3. package/dist/cli/adopted-rules.d.ts +49 -0
  4. package/dist/cli/adopted-rules.d.ts.map +1 -0
  5. package/dist/cli/adopted-rules.js +159 -0
  6. package/dist/cli/adopted-rules.js.map +1 -0
  7. package/dist/cli/check-diff.d.ts +19 -0
  8. package/dist/cli/check-diff.d.ts.map +1 -0
  9. package/dist/cli/check-diff.js +41 -0
  10. package/dist/cli/check-diff.js.map +1 -0
  11. package/dist/cli/check-evaluate.d.ts +10 -0
  12. package/dist/cli/check-evaluate.d.ts.map +1 -0
  13. package/dist/cli/check-evaluate.js +83 -0
  14. package/dist/cli/check-evaluate.js.map +1 -0
  15. package/dist/cli/check-git.d.ts +12 -0
  16. package/dist/cli/check-git.d.ts.map +1 -0
  17. package/dist/cli/check-git.js +83 -0
  18. package/dist/cli/check-git.js.map +1 -0
  19. package/dist/cli/check-locate.d.ts +3 -0
  20. package/dist/cli/check-locate.d.ts.map +1 -0
  21. package/dist/cli/check-locate.js +29 -0
  22. package/dist/cli/check-locate.js.map +1 -0
  23. package/dist/cli/check.d.ts +42 -0
  24. package/dist/cli/check.d.ts.map +1 -0
  25. package/dist/cli/check.js +233 -0
  26. package/dist/cli/check.js.map +1 -0
  27. package/dist/cli/generate.d.ts +5 -0
  28. package/dist/cli/generate.d.ts.map +1 -1
  29. package/dist/cli/generate.js +37 -11
  30. package/dist/cli/generate.js.map +1 -1
  31. package/dist/cli/git-env.d.ts +2 -0
  32. package/dist/cli/git-env.d.ts.map +1 -0
  33. package/dist/cli/git-env.js +14 -0
  34. package/dist/cli/git-env.js.map +1 -0
  35. package/dist/cli/layout.d.ts +2 -0
  36. package/dist/cli/layout.d.ts.map +1 -1
  37. package/dist/cli/layout.js +3 -1
  38. package/dist/cli/layout.js.map +1 -1
  39. package/dist/cli/migrate.d.ts.map +1 -1
  40. package/dist/cli/migrate.js +1 -0
  41. package/dist/cli/migrate.js.map +1 -1
  42. package/dist/cli/program.d.ts.map +1 -1
  43. package/dist/cli/program.js +53 -1
  44. package/dist/cli/program.js.map +1 -1
  45. package/dist/cli/recommend.js +1 -1
  46. package/dist/cli/recommend.js.map +1 -1
  47. package/dist/cli/report.d.ts.map +1 -1
  48. package/dist/cli/report.js +2 -1
  49. package/dist/cli/report.js.map +1 -1
  50. package/dist/cli/rule-guidance.js +3 -3
  51. package/dist/cli/rule-guidance.js.map +1 -1
  52. package/dist/cli/scan.d.ts.map +1 -1
  53. package/dist/cli/scan.js +6 -3
  54. package/dist/cli/scan.js.map +1 -1
  55. package/dist/data/adoption-catalog.js +1 -1
  56. package/dist/data/adoption-catalog.js.map +1 -1
  57. package/dist/detector/marker-inference.d.ts +3 -0
  58. package/dist/detector/marker-inference.d.ts.map +1 -1
  59. package/dist/detector/marker-inference.js +26 -18
  60. package/dist/detector/marker-inference.js.map +1 -1
  61. package/dist/detector/pattern-detector.d.ts +1 -0
  62. package/dist/detector/pattern-detector.d.ts.map +1 -1
  63. package/dist/detector/pattern-detector.js +7 -4
  64. package/dist/detector/pattern-detector.js.map +1 -1
  65. package/dist/generator/public-api-emitters.d.ts +1 -0
  66. package/dist/generator/public-api-emitters.d.ts.map +1 -1
  67. package/dist/generator/public-api-emitters.js +2 -1
  68. package/dist/generator/public-api-emitters.js.map +1 -1
  69. package/dist/generator/rule-generator.d.ts.map +1 -1
  70. package/dist/generator/rule-generator.js +51 -29
  71. package/dist/generator/rule-generator.js.map +1 -1
  72. package/dist/mcp/server.d.ts +27 -4
  73. package/dist/mcp/server.d.ts.map +1 -1
  74. package/dist/mcp/server.js +38 -5
  75. package/dist/mcp/server.js.map +1 -1
  76. package/dist/mcp/tools.d.ts +3 -0
  77. package/dist/mcp/tools.d.ts.map +1 -1
  78. package/dist/mcp/tools.js +23 -2
  79. package/dist/mcp/tools.js.map +1 -1
  80. package/dist/scanner/file-walker.d.ts +5 -0
  81. package/dist/scanner/file-walker.d.ts.map +1 -1
  82. package/dist/scanner/file-walker.js +8 -2
  83. package/dist/scanner/file-walker.js.map +1 -1
  84. package/dist/scanner/import-graph.d.ts +2 -0
  85. package/dist/scanner/import-graph.d.ts.map +1 -1
  86. package/dist/scanner/import-graph.js +1 -1
  87. package/dist/scanner/import-graph.js.map +1 -1
  88. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-git.d.ts","sourceRoot":"","sources":["../../src/cli/check-git.ts"],"names":[],"mappings":"AAMA,qBAAa,eAAgB,SAAQ,KAAK;CAAG;AAgB7C,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,KAAG,MAA2D,CAAC;AAEnG,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQhD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAW5D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAc9E;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAgBD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,QAAQ,CAcxF"}
@@ -0,0 +1,83 @@
1
+ import { execFileSync } from 'node:child_process';
2
+ import { existsSync, mkdtempSync, rmSync, symlinkSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import * as path from 'node:path';
5
+ import { gitEnv } from './git-env.js';
6
+ export class CheckSetupError extends Error {
7
+ }
8
+ const git = (cwd, args, env = gitEnv()) => {
9
+ try {
10
+ return execFileSync('git', args, {
11
+ cwd,
12
+ env,
13
+ encoding: 'utf8',
14
+ stdio: ['ignore', 'pipe', 'pipe'],
15
+ });
16
+ }
17
+ catch (error) {
18
+ const stderr = error.stderr?.trim();
19
+ throw new CheckSetupError(`git ${args.join(' ')} failed${stderr ? `: ${stderr}` : ''}`);
20
+ }
21
+ };
22
+ export const repoRoot = (cwd) => git(cwd, ['rev-parse', '--show-toplevel']).trim();
23
+ export function defaultBase(root) {
24
+ try {
25
+ return git(root, ['rev-parse', '--abbrev-ref', 'origin/HEAD']).trim();
26
+ }
27
+ catch {
28
+ throw new CheckSetupError('no --base given and origin/HEAD is not set; pass the branch or commit to compare against, for example --base origin/main');
29
+ }
30
+ }
31
+ export function mergeBase(root, base) {
32
+ if (base.startsWith('-')) {
33
+ throw new CheckSetupError(`"${base}" is not a branch or commit name.`);
34
+ }
35
+ try {
36
+ return git(root, ['merge-base', 'HEAD', base]).trim();
37
+ }
38
+ catch {
39
+ throw new CheckSetupError(`cannot find a common ancestor of HEAD and ${base}. In CI, fetch the full history (actions/checkout with fetch-depth: 0).`);
40
+ }
41
+ }
42
+ export function renamedPaths(root, commit) {
43
+ const renames = new Map();
44
+ const output = git(root, ['diff', '--name-status', '-M', '-z', commit]);
45
+ const fields = output.split('\u0000');
46
+ for (let index = 0; index < fields.length; index++) {
47
+ const status = fields[index];
48
+ if (status.startsWith('R')) {
49
+ renames.set(fields[index + 1], fields[index + 2]);
50
+ index += 2;
51
+ }
52
+ else if (status !== '') {
53
+ index += 1;
54
+ }
55
+ }
56
+ return renames;
57
+ }
58
+ function linkNodeModules(headRoot, baseRoot, relativeDirs) {
59
+ for (const relative of new Set(relativeDirs)) {
60
+ const source = path.join(headRoot, relative, 'node_modules');
61
+ const target = path.join(baseRoot, relative, 'node_modules');
62
+ if (existsSync(source) && !existsSync(target) && existsSync(path.dirname(target))) {
63
+ symlinkSync(source, target, 'dir');
64
+ }
65
+ }
66
+ }
67
+ export function checkoutBase(root, commit, appRelative) {
68
+ const parent = mkdtempSync(path.join(tmpdir(), 'archprint-check-'));
69
+ const snapshot = path.join(parent, 'base');
70
+ const dispose = () => rmSync(parent, { recursive: true, force: true });
71
+ const env = { ...gitEnv(), GIT_INDEX_FILE: path.join(parent, 'index') };
72
+ try {
73
+ git(root, ['read-tree', commit], env);
74
+ git(root, ['checkout-index', '--all', `--prefix=${snapshot}/`], env);
75
+ }
76
+ catch (error) {
77
+ dispose();
78
+ throw error;
79
+ }
80
+ linkNodeModules(root, snapshot, ['', appRelative]);
81
+ return { root: snapshot, dispose };
82
+ }
83
+ //# sourceMappingURL=check-git.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-git.js","sourceRoot":"","sources":["../../src/cli/check-git.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Finding } from './check-evaluate.js';
2
+ export declare function createLineLocator(appDir: string): (finding: Finding) => number | null;
3
+ //# sourceMappingURL=check-locate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-locate.d.ts","sourceRoot":"","sources":["../../src/cli/check-locate.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,GAAG,IAAI,CAmBrF"}
@@ -0,0 +1,29 @@
1
+ import * as path from 'node:path';
2
+ import { importLocations } from '../scanner/file-walker.js';
3
+ import { buildAliasEntries } from '../scanner/import-graph.js';
4
+ import { resolveFirstPartyImport } from '../scanner/resolve-import.js';
5
+ const toPosix = (value) => value.split(path.sep).join('/');
6
+ export function createLineLocator(appDir) {
7
+ const aliases = buildAliasEntries(appDir);
8
+ return (finding) => {
9
+ if (finding.kind === 'file')
10
+ return null;
11
+ const absolute = path.join(appDir, finding.file);
12
+ let locations;
13
+ try {
14
+ locations = importLocations(absolute);
15
+ }
16
+ catch {
17
+ return null;
18
+ }
19
+ const matches = locations.filter((location) => {
20
+ if (finding.kind === 'specifier')
21
+ return location.specifier === finding.subject;
22
+ const resolved = resolveFirstPartyImport(location.specifier, absolute, aliases);
23
+ return resolved !== null && toPosix(path.relative(appDir, resolved)) === finding.subject;
24
+ });
25
+ const lines = [...new Set(matches.map((location) => location.line))];
26
+ return lines.length === 1 ? lines[0] : null;
27
+ };
28
+ }
29
+ //# sourceMappingURL=check-locate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-locate.js","sourceRoot":"","sources":["../../src/cli/check-locate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,MAAM,OAAO,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE3E,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,OAAO,EAAE,EAAE;QACjB,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,IAAI,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QACjD,IAAI,SAAS,CAAC;QACd,IAAI,CAAC;YACH,SAAS,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC5C,IAAI,OAAO,CAAC,IAAI,KAAK,WAAW;gBAAE,OAAO,QAAQ,CAAC,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC;YAChF,MAAM,QAAQ,GAAG,uBAAuB,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;YAChF,OAAO,QAAQ,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC;QAC3F,CAAC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrE,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { type AdoptedRule } from './adopted-rules.js';
2
+ import { type RuleChange } from './check-diff.js';
3
+ import { type Finding } from './check-evaluate.js';
4
+ export type FailOn = 'none' | 'new';
5
+ export interface CheckOptions {
6
+ cwd: string;
7
+ out: string;
8
+ path?: string;
9
+ base?: string;
10
+ }
11
+ export interface ReportedFinding extends Finding {
12
+ line: number | null;
13
+ rule: AdoptedRule;
14
+ }
15
+ export interface AdoptedInChange {
16
+ rule: AdoptedRule;
17
+ change: RuleChange;
18
+ count: number;
19
+ }
20
+ export type CheckResult = {
21
+ status: 'skipped';
22
+ reason: string;
23
+ } | {
24
+ status: 'checked';
25
+ base: string;
26
+ commit: string;
27
+ appPath: string;
28
+ rules: AdoptedRule[];
29
+ introduced: ReportedFinding[];
30
+ fixed: ReportedFinding[];
31
+ adoptedInChange: AdoptedInChange[];
32
+ removedInChange: AdoptedRule[];
33
+ };
34
+ export declare function runCheck(options: CheckOptions): CheckResult;
35
+ export declare function checkExitCode(result: CheckResult, failOn: FailOn): number;
36
+ export declare function findingMessage(rule: AdoptedRule): string;
37
+ export declare function renderCheckText(result: CheckResult): string;
38
+ export declare function checkJson(result: CheckResult, version: string): unknown;
39
+ export declare function checkReport(result: CheckResult): Record<string, unknown>;
40
+ export declare function githubAnnotations(result: CheckResult, failOn: FailOn): string[];
41
+ export declare function githubSummary(result: CheckResult): string;
42
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/cli/check.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,WAAW,EAEjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAWlE,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEpC,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAgB,SAAQ,OAAO;IAC9C,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,WAAW,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACrC;IACE,MAAM,EAAE,SAAS,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,eAAe,EAAE,eAAe,EAAE,CAAC;IACnC,eAAe,EAAE,WAAW,EAAE,CAAC;CAChC,CAAC;AA+CN,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,CAoE3D;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEzE;AAOD,wBAAgB,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAGxD;AAKD,wBAAgB,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAqB3D;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAyBxE;AAUD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAc/E;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAsCzD"}
@@ -0,0 +1,233 @@
1
+ import { existsSync, realpathSync, statSync } from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { readConfig } from './archprint-config.js';
4
+ import { InvalidRulesError, readAdoptedRules, } from './adopted-rules.js';
5
+ import { diffFindings, partitionRules } from './check-diff.js';
6
+ import { evaluateRules } from './check-evaluate.js';
7
+ import { CheckSetupError, checkoutBase, defaultBase, mergeBase, renamedPaths, repoRoot, } from './check-git.js';
8
+ import { createLineLocator } from './check-locate.js';
9
+ const toPosix = (value) => value.split(path.sep).join('/');
10
+ function appRelativeRenames(renames, appPrefix) {
11
+ const prefix = appPrefix === '' ? '' : `${appPrefix}/`;
12
+ const mapped = new Map();
13
+ for (const [from, to] of renames) {
14
+ if (from.startsWith(prefix) && to.startsWith(prefix)) {
15
+ mapped.set(from.slice(prefix.length), to.slice(prefix.length));
16
+ }
17
+ }
18
+ return mapped;
19
+ }
20
+ function readBaseRules(baseOutDir) {
21
+ try {
22
+ return readAdoptedRules(baseOutDir);
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ function insideRepo(root, target, label) {
29
+ const real = (value) => {
30
+ try {
31
+ return realpathSync(value);
32
+ }
33
+ catch {
34
+ throw new CheckSetupError(`the ${label} (${target}) does not exist.`);
35
+ }
36
+ };
37
+ const relative = path.relative(real(root), real(target));
38
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
39
+ throw new CheckSetupError(`the ${label} (${target}) is outside the repository at ${root}.`);
40
+ }
41
+ return toPosix(relative);
42
+ }
43
+ function loadRules(outDir) {
44
+ try {
45
+ return readAdoptedRules(outDir);
46
+ }
47
+ catch (error) {
48
+ const reason = error instanceof InvalidRulesError ? error.message : error.message;
49
+ throw new CheckSetupError(`cannot read the adopted rules: ${reason}`);
50
+ }
51
+ }
52
+ export function runCheck(options) {
53
+ const outDir = path.resolve(options.cwd, options.out);
54
+ const shown = toPosix(path.relative(options.cwd, outDir) || '.');
55
+ const config = readConfig(outDir);
56
+ if (config === null && options.path === undefined) {
57
+ return {
58
+ status: 'skipped',
59
+ reason: `no ${shown}/config.json. Run archprint init (or generate) first.`,
60
+ };
61
+ }
62
+ const adopted = loadRules(outDir);
63
+ if (adopted === null) {
64
+ return {
65
+ status: 'skipped',
66
+ reason: `no ${shown}/rules.json. Re-run archprint generate once; setups made before 0.9.0 do not have it.`,
67
+ };
68
+ }
69
+ const appDir = path.resolve(options.cwd, options.path ?? config.app);
70
+ const root = repoRoot(options.cwd);
71
+ const outPrefix = insideRepo(root, outDir, 'rules directory');
72
+ const base = options.base ?? defaultBase(root);
73
+ const commit = mergeBase(root, base);
74
+ const appPrefix = insideRepo(root, appDir, 'app directory');
75
+ if (!statSync(appDir).isDirectory()) {
76
+ throw new CheckSetupError(`the app directory (${appDir}) is not a directory.`);
77
+ }
78
+ const renames = appRelativeRenames(renamedPaths(root, commit), appPrefix);
79
+ const ruleById = new Map(adopted.rules.map((rule) => [rule.id, rule]));
80
+ const baseTree = checkoutBase(root, commit, appPrefix);
81
+ try {
82
+ const baseRules = readBaseRules(path.join(baseTree.root, outPrefix));
83
+ const partition = partitionRules(adopted.rules, baseRules?.rules ?? null);
84
+ const baseApp = path.join(baseTree.root, appPrefix);
85
+ const baseFindings = existsSync(baseApp) ? evaluateRules(baseApp, partition.comparable) : [];
86
+ const headFindings = evaluateRules(appDir, partition.comparable);
87
+ const { introduced, fixed } = diffFindings(baseFindings, headFindings, renames);
88
+ const locate = createLineLocator(appDir);
89
+ const adoptedFindings = evaluateRules(appDir, partition.adoptedInChange.map((entry) => entry.rule));
90
+ return {
91
+ status: 'checked',
92
+ base,
93
+ commit,
94
+ appPath: appPrefix,
95
+ rules: adopted.rules,
96
+ introduced: introduced.map((finding) => ({
97
+ ...finding,
98
+ line: locate(finding),
99
+ rule: ruleById.get(finding.ruleId),
100
+ })),
101
+ fixed: fixed.map((finding) => ({
102
+ ...finding,
103
+ line: null,
104
+ rule: ruleById.get(finding.ruleId),
105
+ })),
106
+ adoptedInChange: partition.adoptedInChange.map(({ rule, change }) => ({
107
+ rule,
108
+ change,
109
+ count: adoptedFindings.filter((finding) => finding.ruleId === rule.id).length,
110
+ })),
111
+ removedInChange: partition.removedInChange,
112
+ };
113
+ }
114
+ finally {
115
+ baseTree.dispose();
116
+ }
117
+ }
118
+ export function checkExitCode(result, failOn) {
119
+ return result.status === 'checked' && failOn === 'new' && result.introduced.length > 0 ? 1 : 0;
120
+ }
121
+ const sentence = (text) => {
122
+ const trimmed = text.trim().replace(/\.$/, '');
123
+ return trimmed.charAt(0).toUpperCase() + trimmed.slice(1);
124
+ };
125
+ export function findingMessage(rule) {
126
+ const { conforming, total, floor } = rule.evidence;
127
+ return `${sentence(rule.statement)}. When this rule was adopted, ${conforming} of ${total} files it applies to followed it (confidence ${Math.round(floor * 100)}%).`;
128
+ }
129
+ const describeSubject = (finding) => finding.kind === 'file' ? '' : ` (${finding.subject})`;
130
+ export function renderCheckText(result) {
131
+ if (result.status === 'skipped')
132
+ return `archprint check did not run: ${result.reason}`;
133
+ const lines = [
134
+ `archprint check against ${result.base} (${result.commit.slice(0, 12)}): ${result.rules.length} adopted rule(s)`,
135
+ ];
136
+ if (result.introduced.length === 0)
137
+ lines.push('No new violations.');
138
+ for (const finding of result.introduced) {
139
+ const where = finding.line === null ? finding.file : `${finding.file}:${finding.line}`;
140
+ lines.push(` ${where} ${finding.rule.id}${describeSubject(finding)}`);
141
+ lines.push(` ${findingMessage(finding.rule)}`);
142
+ }
143
+ if (result.fixed.length > 0)
144
+ lines.push(`Fixed: ${result.fixed.length} violation(s) removed.`);
145
+ for (const entry of result.adoptedInChange) {
146
+ lines.push(`Rule ${entry.rule.id} was ${entry.change === 'new' ? 'adopted' : 'changed'} in this change (${entry.count} existing violation(s), not counted).`);
147
+ }
148
+ for (const rule of result.removedInChange) {
149
+ lines.push(`Rule ${rule.id} was removed in this change, so it is no longer checked.`);
150
+ }
151
+ return lines.join('\n');
152
+ }
153
+ export function checkJson(result, version) {
154
+ return { archprintVersion: version, ...checkReport(result) };
155
+ }
156
+ export function checkReport(result) {
157
+ if (result.status === 'skipped') {
158
+ return { status: 'skipped', reason: result.reason };
159
+ }
160
+ const shape = (finding) => ({
161
+ rule: finding.rule.id,
162
+ file: finding.file,
163
+ line: finding.line,
164
+ subject: finding.kind === 'file' ? null : finding.subject,
165
+ message: findingMessage(finding.rule),
166
+ });
167
+ return {
168
+ status: 'checked',
169
+ app: result.appPath || '.',
170
+ base: result.base,
171
+ commit: result.commit,
172
+ introduced: result.introduced.map(shape),
173
+ fixed: result.fixed.map(shape),
174
+ adoptedInChange: result.adoptedInChange.map((entry) => ({
175
+ rule: entry.rule.id,
176
+ change: entry.change,
177
+ existingViolations: entry.count,
178
+ })),
179
+ removedInChange: result.removedInChange.map((rule) => rule.id),
180
+ };
181
+ }
182
+ const tableCell = (value) => value.replace(/\|/g, '\\|').replace(/\r?\n/g, ' ');
183
+ const escapeData = (value) => value.replace(/%/g, '%25').replace(/\r/g, '%0D').replace(/\n/g, '%0A');
184
+ const escapeProperty = (value) => escapeData(value).replace(/:/g, '%3A').replace(/,/g, '%2C');
185
+ export function githubAnnotations(result, failOn) {
186
+ if (result.status === 'skipped') {
187
+ return [
188
+ `::notice title=${escapeProperty('archprint check did not run')}::${escapeData(result.reason)}`,
189
+ ];
190
+ }
191
+ const level = failOn === 'new' ? 'error' : 'warning';
192
+ return result.introduced.map((finding) => {
193
+ const file = toPosix(path.posix.join(result.appPath, finding.file));
194
+ const properties = [`file=${escapeProperty(file)}`];
195
+ if (finding.line !== null)
196
+ properties.push(`line=${finding.line}`);
197
+ properties.push(`title=${escapeProperty(`archprint: ${finding.rule.id}`)}`);
198
+ return `::${level} ${properties.join(',')}::${escapeData(findingMessage(finding.rule))}`;
199
+ });
200
+ }
201
+ export function githubSummary(result) {
202
+ if (result.status === 'skipped') {
203
+ return `### archprint check did not run\n\n${result.reason}\n`;
204
+ }
205
+ const lines = [
206
+ '### archprint check',
207
+ '',
208
+ `Compared with \`${result.base}\` (\`${result.commit.slice(0, 12)}\`) across ${result.rules.length} adopted rule(s).`,
209
+ '',
210
+ ];
211
+ if (result.introduced.length === 0) {
212
+ lines.push('No new violations.');
213
+ }
214
+ else {
215
+ lines.push(`**${result.introduced.length} new violation(s):**`, '');
216
+ lines.push('| File | Rule | Why |', '| --- | --- | --- |');
217
+ for (const finding of result.introduced) {
218
+ const where = finding.line === null ? finding.file : `${finding.file}:${finding.line}`;
219
+ lines.push(`| \`${tableCell(where)}\` | ${tableCell(finding.rule.id)} | ${tableCell(findingMessage(finding.rule))} |`);
220
+ }
221
+ lines.push('', 'Run `npx archprint explain <rule>` locally for the full evidence.');
222
+ }
223
+ if (result.fixed.length > 0)
224
+ lines.push('', `Fixed: ${result.fixed.length} violation(s) removed.`);
225
+ for (const entry of result.adoptedInChange) {
226
+ lines.push('', `Rule \`${entry.rule.id}\` was ${entry.change === 'new' ? 'adopted' : 'changed'} in this change; its ${entry.count} existing violation(s) are not counted.`);
227
+ }
228
+ for (const rule of result.removedInChange) {
229
+ lines.push('', `Rule \`${rule.id}\` was **removed** in this change, so it is no longer checked.`);
230
+ }
231
+ return `${lines.join('\n')}\n`;
232
+ }
233
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/cli/check.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import type { InstalledEnforcers } from '../scanner/enforcers.js';
2
2
  import { type BoundaryRule } from '../generator/tsarch-emitter.js';
3
3
  import { type ForbiddenImportSpec } from '../generator/eslint-plugin-emitter.js';
4
4
  import type { ScannedPattern, ScanResult } from './scan.js';
5
+ import { type AdoptedRule, type ResolutionMode } from './adopted-rules.js';
5
6
  export declare const ESLINT_FILE = "eslint.mjs";
6
7
  export declare const DEPCRUISE_FILE = "dependency-cruiser.json";
7
8
  export declare const ARCHPRINT_DIR = ".archprint";
@@ -24,12 +25,14 @@ export interface CollectedEnforcement {
24
25
  boundaries: unknown | null;
25
26
  tsArchRules: BoundaryRule[];
26
27
  hasGraph: boolean;
28
+ adopted: AdoptedRule[];
27
29
  }
28
30
  export interface CollectOptions {
29
31
  structural?: boolean;
30
32
  enforcers: InstalledEnforcers;
31
33
  only?: string;
32
34
  ruleIds?: readonly string[];
35
+ mode?: ResolutionMode;
33
36
  }
34
37
  export declare function collectEnforcement(scan: ScanResult, options: CollectOptions): CollectedEnforcement;
35
38
  export declare function writeArchprintEslint(collected: CollectedEnforcement, outDir: string): string | null;
@@ -37,11 +40,13 @@ export declare function writeArchprintDepcruise(collected: CollectedEnforcement,
37
40
  export interface EmitResult {
38
41
  eslint: string | null;
39
42
  depcruise: string | null;
43
+ rules: string;
40
44
  expanded: string[];
41
45
  }
42
46
  export declare function emitLayout(scan: ScanResult, outDir: string, options: CollectOptions & {
43
47
  expand?: boolean;
44
48
  graph?: boolean;
49
+ version: string;
45
50
  }): EmitResult;
46
51
  export declare function emitOne(pattern: ScannedPattern, appDir: string, outDir: string): string;
47
52
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AASlE,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEtF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAM/C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5D,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,cAAc,4BAA4B,CAAC;AACxD,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,YAAY,iSAkBf,CAAC;AAEX,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,qBAAqB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,SAAS,EAAE,uBAAuB,EAAE,CAAC;IACrC,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B;AAKD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,cAAc,GACtB,oBAAoB,CA0FtB;AAwCD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,oBAAoB,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAOf;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,oBAAoB,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAKf;AAwED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D,UAAU,CAQZ;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvF"}
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AASlE,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEtF,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,uCAAuC,CAAC;AAM/C,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,EAOL,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,WAAW,eAAe,CAAC;AACxC,eAAO,MAAM,cAAc,4BAA4B,CAAC;AACxD,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,YAAY,iSAkBf,CAAC;AAEX,UAAU,qBAAqB;IAC7B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,iBAAiB;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,qBAAqB,EAAE,CAAC;CACpC;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,mBAAmB,EAAE,CAAC;IACnC,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,SAAS,EAAE,uBAAuB,EAAE,CAAC;IACrC,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,YAAY,EAAE,CAAC;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,kBAAkB,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AAKD,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,cAAc,GACtB,oBAAoB,CA6GtB;AAwCD,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,oBAAoB,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAOf;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,oBAAoB,EAC/B,MAAM,EAAE,MAAM,GACb,MAAM,GAAG,IAAI,CAKf;AAwED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,UAAU,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,cAAc,GAAG;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/E,UAAU,CASZ;AAED,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAEvF"}
@@ -22,6 +22,7 @@ import { emitRuleArtifacts } from '../generator/rule-generator.js';
22
22
  import { buildForbiddenImportSpecs, renderEslintPluginSource, } from '../generator/eslint-plugin-emitter.js';
23
23
  import { renderEslintPreset } from '../generator/eslint-preset-emitter.js';
24
24
  import { mergeNoRestrictedImports, } from '../generator/eslint-scope.js';
25
+ import { consoleIsolationRule, forbiddenImportRule, importStyleRule, publicApiRules, testIsolationRule, writeAdoptedRules, } from './adopted-rules.js';
25
26
  export const ESLINT_FILE = 'eslint.mjs';
26
27
  export const DEPCRUISE_FILE = 'dependency-cruiser.json';
27
28
  export const ARCHPRINT_DIR = '.archprint';
@@ -53,20 +54,35 @@ export function collectEnforcement(scan, options) {
53
54
  const eslintSpecs = emitEslint && pick('forbidden-imports')
54
55
  ? filterSpecs(buildForbiddenImportSpecs(scan.patterns), scan, options.ruleIds)
55
56
  : [];
57
+ const adopted = scan.patterns
58
+ .filter((pattern) => eslintSpecs.some((spec) => spec.name === pattern.config.name))
59
+ .map((pattern) => forbiddenImportRule(pattern, options.mode ?? 'deep'));
56
60
  const eslintBlocks = [];
57
61
  const pushBlock = (family, block) => {
58
62
  if (block !== null)
59
63
  eslintBlocks.push({ family, block });
60
64
  };
61
- if (emitEslint && pick('console'))
62
- pushBlock('console', toEslintConsoleIsolation(scan.consoleIsolation));
65
+ if (emitEslint && pick('console')) {
66
+ const block = toEslintConsoleIsolation(scan.consoleIsolation);
67
+ pushBlock('console', block);
68
+ if (block !== null)
69
+ adopted.push(consoleIsolationRule(scan));
70
+ }
63
71
  if (structural && emitEslint && pick('env-access'))
64
72
  pushBlock('env-access', toEslintEnvAccess(scan.envAccess));
65
73
  const noRestricted = [];
66
- if (emitEslint && pick('import-style'))
67
- noRestricted.push(toEslintDeepRelative(scan.deepRelative));
68
- if (emitEslint && pick('test-isolation'))
69
- noRestricted.push(toEslintTestIsolation(scan.testIsolation));
74
+ if (emitEslint && pick('import-style')) {
75
+ const block = toEslintDeepRelative(scan.deepRelative);
76
+ noRestricted.push(block);
77
+ if (block !== null)
78
+ adopted.push(importStyleRule(scan));
79
+ }
80
+ if (emitEslint && pick('test-isolation')) {
81
+ const block = toEslintTestIsolation(scan.testIsolation);
82
+ noRestricted.push(block);
83
+ if (block !== null)
84
+ adopted.push(testIsolationRule(scan));
85
+ }
70
86
  if (structural && emitEslint && pick('workspace-package'))
71
87
  noRestricted.push(toEslintWorkspacePackageApi(scan.workspacePackageApi));
72
88
  pushBlock('no-restricted-imports', mergeNoRestrictedImports(noRestricted));
@@ -79,14 +95,22 @@ export function collectEnforcement(scan, options) {
79
95
  pushDc('layer', toDependencyCruiser(scan.layerBoundaries, ['AUTO']).forbidden);
80
96
  if (structural && emitDepcruise && pick('role-layering'))
81
97
  pushDc('role-layering', toDependencyCruiserRoleLayering(scan.roleLayering.boundaries, ['AUTO']).forbidden);
82
- if (emitDepcruise && pick('public-api'))
83
- pushDc('public-api', toDependencyCruiserPublicApi(scan.publicApi.groups, ['AUTO']).forbidden);
98
+ if (emitDepcruise && pick('public-api')) {
99
+ const forbidden = toDependencyCruiserPublicApi(scan.publicApi.groups, ['AUTO']).forbidden;
100
+ pushDc('public-api', forbidden);
101
+ if (forbidden.length > 0)
102
+ adopted.push(...publicApiRules(scan));
103
+ }
84
104
  if (structural && emitDepcruise && pick('feature-slice'))
85
105
  pushDc('feature-slice', toDependencyCruiserFeatureSlice(scan.featureSlices.groups, ['AUTO']).forbidden);
86
106
  if (structural && emitDepcruise && pick('app-isolation'))
87
107
  pushDc('app-isolation', toDependencyCruiserAppIsolation(scan.appIsolation.groups, ['AUTO']).forbidden);
88
- if (pick('test-isolation') && !emitEslint && emitDepcruise)
89
- pushDc('test-isolation', toDependencyCruiserTestIsolation(scan.testIsolation).forbidden);
108
+ if (pick('test-isolation') && !emitEslint && emitDepcruise) {
109
+ const forbidden = toDependencyCruiserTestIsolation(scan.testIsolation).forbidden;
110
+ pushDc('test-isolation', forbidden);
111
+ if (forbidden.length > 0)
112
+ adopted.push(testIsolationRule(scan));
113
+ }
90
114
  if (structural && emitDepcruise && pick('dependency-hygiene'))
91
115
  pushDc('dependency-internals', toDependencyCruiserDependencyInternals(scan.dependencyInternals).forbidden);
92
116
  if (structural && emitDepcruise && pick('entry-purity'))
@@ -111,6 +135,7 @@ export function collectEnforcement(scan, options) {
111
135
  boundaries,
112
136
  tsArchRules,
113
137
  hasGraph: bundles && scan.layerBoundaries.length > 0,
138
+ adopted,
114
139
  };
115
140
  }
116
141
  function filterSpecs(specs, scan, ruleIds) {
@@ -195,10 +220,11 @@ export function emitLayout(scan, outDir, options) {
195
220
  const collected = collectEnforcement(scan, options);
196
221
  const eslint = writeArchprintEslint(collected, outDir);
197
222
  const depcruise = writeArchprintDepcruise(collected, outDir);
223
+ const rules = writeAdoptedRules(outDir, collected.adopted, options.version);
198
224
  const expanded = options.expand
199
225
  ? writeExpanded(collected, scan, outDir, options.graph !== false)
200
226
  : [];
201
- return { eslint, depcruise, expanded };
227
+ return { eslint, depcruise, rules, expanded };
202
228
  }
203
229
  export function emitOne(pattern, appDir, outDir) {
204
230
  return emitRuleArtifacts(pattern.config, pattern.result, outDir, `archprint scan ${appDir}`);