@goodbones/oxlint 0.1.0-beta.17 → 0.1.0-beta.18
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/build/dts/campaigns/host.d.ts +19 -0
- package/build/dts/campaigns/host.d.ts.map +1 -0
- package/build/dts/campaigns/live.d.ts +3 -0
- package/build/dts/campaigns/live.d.ts.map +1 -0
- package/build/dts/campaigns/none.d.ts +6 -0
- package/build/dts/campaigns/none.d.ts.map +1 -0
- package/build/dts/{campaigns-rule.d.ts → campaigns/rule.d.ts} +2 -2
- package/build/dts/campaigns/rule.d.ts.map +1 -0
- package/build/dts/config-loader.d.ts +3 -5
- package/build/dts/config-loader.d.ts.map +1 -1
- package/build/dts/plugin.d.ts.map +1 -1
- package/build/esm/campaigns/host.js +2 -0
- package/build/esm/campaigns/host.js.map +1 -0
- package/build/esm/campaigns/live.js +81 -0
- package/build/esm/campaigns/live.js.map +1 -0
- package/build/esm/campaigns/none.js +46 -0
- package/build/esm/campaigns/none.js.map +1 -0
- package/build/esm/{campaigns-rule.js → campaigns/rule.js} +2 -2
- package/build/esm/campaigns/rule.js.map +1 -0
- package/build/esm/config-loader.js +24 -65
- package/build/esm/config-loader.js.map +1 -1
- package/build/esm/plugin.js +5 -5
- package/build/esm/plugin.js.map +1 -1
- package/package.json +17 -7
- package/src/campaigns/host.ts +45 -0
- package/src/campaigns/live.ts +106 -0
- package/src/campaigns/none.ts +54 -0
- package/src/{campaigns-rule.ts → campaigns/rule.ts} +1 -1
- package/src/config-loader.ts +28 -83
- package/src/plugin.ts +5 -5
- package/build/dts/campaigns-rule.d.ts.map +0 -1
- package/build/esm/campaigns-rule.js.map +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { LoadedPolicy as CorePolicy, PolicyExtension, UninstalledExtension } from "@goodbones/core";
|
|
2
|
+
import type { OxlintRule } from "../oxlint-api.js";
|
|
3
|
+
export type CampaignsHost = {
|
|
4
|
+
readonly rule: (policy: CorePolicy) => OxlintRule;
|
|
5
|
+
};
|
|
6
|
+
export type LoadedPolicy = CorePolicy & {
|
|
7
|
+
readonly campaigns: CampaignsHost;
|
|
8
|
+
};
|
|
9
|
+
export type Composition = {
|
|
10
|
+
readonly manifest: unknown;
|
|
11
|
+
readonly extensions: ReadonlyArray<PolicyExtension>;
|
|
12
|
+
readonly uninstalled: ReadonlyArray<UninstalledExtension>;
|
|
13
|
+
};
|
|
14
|
+
export type CampaignsFamily = {
|
|
15
|
+
readonly host: CampaignsHost;
|
|
16
|
+
readonly compose: (repoRoot: string, configPath: string, manifest: unknown) => Promise<Composition>;
|
|
17
|
+
readonly prepare: (policy: CorePolicy) => Promise<void>;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../../src/campaigns/host.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,YAAY,IAAI,UAAU,EAC1B,eAAe,EACf,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,MAAM,aAAa,GAAG;IAE1B,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,UAAU,CAAC;CACnD,CAAC;AAIF,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG;IAAE,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAA;CAAE,CAAC;AAM9E,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IACpD,QAAQ,CAAC,WAAW,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;CAC3D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,CAChB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,KACd,OAAO,CAAC,WAAW,CAAC,CAAC;IAE1B,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../../src/campaigns/live.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA2CjD,eAAO,MAAM,aAAa,EAAE,eA2C3B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { OxlintRule } from "../oxlint-api.js";
|
|
2
|
+
import type { CampaignsFamily } from "./host.js";
|
|
3
|
+
export declare const CAMPAIGNS_PACKAGE = "@goodbones/campaigns";
|
|
4
|
+
export declare const notInstalledRule: () => OxlintRule;
|
|
5
|
+
export declare const campaignsNotInstalled: CampaignsFamily;
|
|
6
|
+
//# sourceMappingURL=none.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"none.d.ts","sourceRoot":"","sources":["../../../src/campaigns/none.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAwB,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAKjD,eAAO,MAAM,iBAAiB,yBAAyB,CAAC;AAWxD,eAAO,MAAM,gBAAgB,QAAO,UA0BnC,CAAC;AAGF,eAAO,MAAM,qBAAqB,EAAE,eAKnC,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type SectorIndex } from "@goodbones/campaigns";
|
|
2
2
|
import { type LoadedPolicy } from "@goodbones/core";
|
|
3
|
-
import { type OxlintRule } from "
|
|
3
|
+
import { type OxlintRule } from "../oxlint-api.js";
|
|
4
4
|
export type SectorIndexes = ReadonlyMap<string, SectorIndex>;
|
|
5
5
|
export declare const makeCampaignsRule: (policy: LoadedPolicy, indexes?: SectorIndexes) => OxlintRule;
|
|
6
|
-
//# sourceMappingURL=
|
|
6
|
+
//# sourceMappingURL=rule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../../src/campaigns/rule.ts"],"names":[],"mappings":"AAEA,OAAO,EAmBL,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAiB,KAAK,YAAY,EAAqB,MAAM,iBAAiB,CAAC;AAGtF,OAAO,EAEL,KAAK,UAAU,EAIhB,MAAM,kBAAkB,CAAC;AAsB1B,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AA2D7D,eAAO,MAAM,iBAAiB,WACpB,YAAY,YACX,aAAa,KACrB,UA6HF,CAAC"}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export declare const discoverSectorIndexes: (policy: LoadedPolicy) => ReadonlyMap<string, SectorIndex>;
|
|
5
|
-
export declare const loadPolicyFromFile: (repoRoot: string, configFilename?: string) => Promise<LoadedPolicy>;
|
|
1
|
+
import type { CampaignsFamily, LoadedPolicy } from "./campaigns/host.js";
|
|
2
|
+
export type { LoadedPolicy } from "./campaigns/host.js";
|
|
3
|
+
export declare const loadPolicyFromFile: (repoRoot: string, configFilename?: string, given?: CampaignsFamily) => Promise<LoadedPolicy>;
|
|
6
4
|
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGzE,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA6BxD,eAAO,MAAM,kBAAkB,aACnB,MAAM,mBACC,MAAM,UACf,eAAe,KACtB,OAAO,CAAC,YAAY,CA6BtB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAoBlD,eAAO,MAAM,KAAK,EAAE;IAClB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;CAWhC,CAAC;AAEF,QAAA,MAAM,MAAM,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,CAAA;CAGrF,CAAC;eAEa,MAAM"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"host.js","sourceRoot":"","sources":["../../../src/campaigns/host.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { campaignsExtension, campaignsOf, discoverSectors, loadCampaignFunctions, makeReportSourceLive, reportSpecsOf, } from "@goodbones/campaigns";
|
|
3
|
+
import { globToRegExp, listSourceFiles, listWorkspaceProjects, ReportUnavailable, } from "@goodbones/core";
|
|
4
|
+
import { makeCampaignsRule } from "./rule.js";
|
|
5
|
+
// The campaigns family as the plugin runs it, over `@goodbones/campaigns`.
|
|
6
|
+
// The one module that loads the package: the composition root imports it
|
|
7
|
+
// through `importOptional`, so its absence is `none`, not a failure to load.
|
|
8
|
+
// A `marker` or `nx` perimeter needs the other files to say which sector a
|
|
9
|
+
// file is in — the markers, or the workspace's projects — so the plugin
|
|
10
|
+
// reads them once at load, from a walk of the repository that reads no
|
|
11
|
+
// source text but the markers'. The other perimeters answer from the path
|
|
12
|
+
// or the file itself, and need nothing here.
|
|
13
|
+
const discoverSectorIndexes = (policy) => {
|
|
14
|
+
const indexes = new Map();
|
|
15
|
+
const needing = campaignsOf(policy).campaignRules.filter((rule) => rule.perimeter?.kind === "marker" || rule.perimeter?.kind === "nx");
|
|
16
|
+
if (needing.length === 0)
|
|
17
|
+
return indexes;
|
|
18
|
+
const widened = [...new Set(needing.flatMap((rule) => rule.extensions))];
|
|
19
|
+
const files = listSourceFiles(policy.repoRoot, ["."], policy.languages, widened);
|
|
20
|
+
const known = new Set(policy.languages.flatMap((one) => one.extensions));
|
|
21
|
+
const projects = needing.some((rule) => rule.perimeter?.kind === "nx")
|
|
22
|
+
? listWorkspaceProjects(policy.repoRoot, ["."])
|
|
23
|
+
: [];
|
|
24
|
+
for (const rule of needing) {
|
|
25
|
+
const scoped = files.filter((file) => rule.scope.some((pattern) => pattern.test(file)) &&
|
|
26
|
+
(known.has(path.extname(file)) || rule.extensions.includes(path.extname(file))));
|
|
27
|
+
indexes.set(rule.id, discoverSectors(rule, {
|
|
28
|
+
files: scoped,
|
|
29
|
+
readText: (file) => policy.fileSystem.readText(file),
|
|
30
|
+
globToRegExp,
|
|
31
|
+
projects,
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
return indexes;
|
|
35
|
+
};
|
|
36
|
+
export const liveCampaigns = {
|
|
37
|
+
// The sectors a `marker` or `nx` perimeter births are read once here,
|
|
38
|
+
// from the markers and the workspace, before any file is linted.
|
|
39
|
+
host: { rule: (policy) => makeCampaignsRule(policy, discoverSectorIndexes(policy)) },
|
|
40
|
+
// The `fn` terms are imported here, before the policy loads, as the CLI
|
|
41
|
+
// does. A `report` command runs once per process — once per editor session
|
|
42
|
+
// for oxlint's language server, which then sees that report until it
|
|
43
|
+
// restarts. A report the build writes to a file is the predictable form.
|
|
44
|
+
compose: async (repoRoot, configPath, manifest) => {
|
|
45
|
+
const loaded = await loadCampaignFunctions(configPath, manifest);
|
|
46
|
+
return {
|
|
47
|
+
manifest: loaded.manifest,
|
|
48
|
+
extensions: [
|
|
49
|
+
campaignsExtension({
|
|
50
|
+
functions: loaded.functions,
|
|
51
|
+
reports: makeReportSourceLive(repoRoot),
|
|
52
|
+
}),
|
|
53
|
+
],
|
|
54
|
+
uninstalled: [],
|
|
55
|
+
};
|
|
56
|
+
},
|
|
57
|
+
// Every `report` a campaign names is read now, while oxlint has linted
|
|
58
|
+
// nothing. A `command` forks this process, and once the linter is running
|
|
59
|
+
// Linux can refuse the fork: the linter's per-thread AST buffers merge
|
|
60
|
+
// into one mapping larger than RAM and swap together, which the default
|
|
61
|
+
// overcommit heuristic refuses to duplicate. The source keeps the answer,
|
|
62
|
+
// and a failure, so the rules read what was read here — a term's several
|
|
63
|
+
// commands run at once. A report that cannot be read is not a load
|
|
64
|
+
// failure — the campaigns rule reports it once, on the first file a
|
|
65
|
+
// campaign naming it selects; one that does not parse is.
|
|
66
|
+
prepare: async (policy) => {
|
|
67
|
+
const campaigns = campaignsOf(policy);
|
|
68
|
+
await Promise.all(reportSpecsOf(campaigns.campaignRules).map(async (spec) => {
|
|
69
|
+
if (campaigns.reports.read !== undefined)
|
|
70
|
+
return campaigns.reports.read(spec);
|
|
71
|
+
try {
|
|
72
|
+
campaigns.reports.diagnosticsOf(spec, "");
|
|
73
|
+
}
|
|
74
|
+
catch (cause) {
|
|
75
|
+
if (!(cause instanceof ReportUnavailable))
|
|
76
|
+
throw cause;
|
|
77
|
+
}
|
|
78
|
+
}));
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=live.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"live.js","sourceRoot":"","sources":["../../../src/campaigns/live.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// The package the family comes in, and the manifest keys it would claim: a
|
|
2
|
+
// manifest that uses one without it is refused naming the package, rather
|
|
3
|
+
// than as a misspelling.
|
|
4
|
+
export const CAMPAIGNS_PACKAGE = "@goodbones/campaigns";
|
|
5
|
+
const UNINSTALLED = {
|
|
6
|
+
manifestKeys: ["campaigns", "ledger"],
|
|
7
|
+
install: CAMPAIGNS_PACKAGE,
|
|
8
|
+
};
|
|
9
|
+
// The `campaigns` rule without the family. oxlint refuses a configuration
|
|
10
|
+
// naming a rule the plugin does not register, with no word of why, so the
|
|
11
|
+
// rule is registered anyway and says what to install — once per process, on
|
|
12
|
+
// the first file, rather than on every file of the run.
|
|
13
|
+
export const notInstalledRule = () => {
|
|
14
|
+
let said = false;
|
|
15
|
+
return {
|
|
16
|
+
meta: {
|
|
17
|
+
type: "problem",
|
|
18
|
+
docs: { description: `the campaigns, which need ${CAMPAIGNS_PACKAGE} installed` },
|
|
19
|
+
schema: [],
|
|
20
|
+
},
|
|
21
|
+
createOnce(context) {
|
|
22
|
+
return {
|
|
23
|
+
before() {
|
|
24
|
+
return !said;
|
|
25
|
+
},
|
|
26
|
+
Program(_node) {
|
|
27
|
+
if (said)
|
|
28
|
+
return;
|
|
29
|
+
said = true;
|
|
30
|
+
context.report({
|
|
31
|
+
message: `architecture/campaigns needs \`${CAMPAIGNS_PACKAGE}\`, which is not installed. ` +
|
|
32
|
+
`Install it beside @goodbones/oxlint, or turn the rule off.`,
|
|
33
|
+
loc: { line: 1, column: 0 },
|
|
34
|
+
});
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
// The family, when it is not installed.
|
|
41
|
+
export const campaignsNotInstalled = {
|
|
42
|
+
host: { rule: notInstalledRule },
|
|
43
|
+
compose: (_repoRoot, _configPath, manifest) => Promise.resolve({ manifest, extensions: [], uninstalled: [UNINSTALLED] }),
|
|
44
|
+
prepare: () => Promise.resolve(),
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=none.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"none.js","sourceRoot":"","sources":["../../../src/campaigns/none.ts"],"names":[],"mappings":"AAKA,2EAA2E;AAC3E,0EAA0E;AAC1E,yBAAyB;AACzB,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AAExD,MAAM,WAAW,GAAyB;IACxC,YAAY,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC;IACrC,OAAO,EAAE,iBAAiB;CAC3B,CAAC;AAEF,0EAA0E;AAC1E,0EAA0E;AAC1E,4EAA4E;AAC5E,wDAAwD;AACxD,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAe,EAAE;IAC/C,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,OAAO;QACL,IAAI,EAAE;YACJ,IAAI,EAAE,SAAkB;YACxB,IAAI,EAAE,EAAE,WAAW,EAAE,6BAA6B,iBAAiB,YAAY,EAAE;YACjF,MAAM,EAAE,EAAE;SACX;QACD,UAAU,CAAC,OAAoB;YAC7B,OAAO;gBACL,MAAM;oBACJ,OAAO,CAAC,IAAI,CAAC;gBACf,CAAC;gBACD,OAAO,CAAC,KAAc;oBACpB,IAAI,IAAI;wBAAE,OAAO;oBACjB,IAAI,GAAG,IAAI,CAAC;oBACZ,OAAO,CAAC,MAAM,CAAC;wBACb,OAAO,EACL,kCAAkC,iBAAiB,8BAA8B;4BACjF,4DAA4D;wBAC9D,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;qBAC5B,CAAC,CAAC;gBACL,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,wCAAwC;AACxC,MAAM,CAAC,MAAM,qBAAqB,GAAoB;IACpD,IAAI,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;IAChC,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,CAC5C,OAAO,CAAC,OAAO,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;IAC3E,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE;CACjC,CAAC"}
|
|
@@ -2,7 +2,7 @@ import * as path from "node:path";
|
|
|
2
2
|
import { campaignsOf, campaignsSelecting, detectorCandidatesOf, detectorOf, evaluateObjectives, isShared, ledgerKeyOf, ledgerPhaseOf, membershipOf, needsSyntax, objectivesInWindow, positionOf, reconcileSector, sectorEntryOf, sharedWindow, } from "@goodbones/campaigns";
|
|
3
3
|
import { formatMessage, ReportUnavailable } from "@goodbones/core";
|
|
4
4
|
import { sourceFactsOf } from "@goodbones/typescript";
|
|
5
|
-
import { factsOfProgram, toRepoRelative, } from "
|
|
5
|
+
import { factsOfProgram, toRepoRelative, } from "../oxlint-api.js";
|
|
6
6
|
const unledgered = (policy, rule, sector, root, hits) => {
|
|
7
7
|
const carried = new Set();
|
|
8
8
|
const byObjective = new Map();
|
|
@@ -160,4 +160,4 @@ export const makeCampaignsRule = (policy, indexes = new Map()) => {
|
|
|
160
160
|
},
|
|
161
161
|
};
|
|
162
162
|
};
|
|
163
|
-
//# sourceMappingURL=
|
|
163
|
+
//# sourceMappingURL=rule.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule.js","sourceRoot":"","sources":["../../../src/campaigns/rule.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,37 +1,13 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
|
-
import {
|
|
3
|
-
import { campaignsExtension, campaignsOf, discoverSectors, loadCampaignFunctions, makeReportSourceLive, reportSpecsOf, } from "@goodbones/campaigns";
|
|
4
|
-
import { findManifestFile, globToRegExp, listSourceFiles, listWorkspaceProjects, loadPolicy, makeFileSystemLive, readManifestFile, ReportUnavailable, } from "@goodbones/core";
|
|
2
|
+
import { findManifestFile, importOptional, loadPolicy, makeFileSystemLive, readManifestFile, } from "@goodbones/core";
|
|
5
3
|
import { typescriptLanguage } from "@goodbones/typescript";
|
|
6
4
|
import * as Result from "effect/Result";
|
|
7
|
-
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const indexes = new Map();
|
|
14
|
-
const needing = campaignsOf(policy).campaignRules.filter((rule) => rule.perimeter?.kind === "marker" || rule.perimeter?.kind === "nx");
|
|
15
|
-
if (needing.length === 0)
|
|
16
|
-
return indexes;
|
|
17
|
-
const widened = [...new Set(needing.flatMap((rule) => rule.extensions))];
|
|
18
|
-
const files = listSourceFiles(policy.repoRoot, ["."], policy.languages, widened);
|
|
19
|
-
const known = new Set(policy.languages.flatMap((one) => one.extensions));
|
|
20
|
-
const projects = needing.some((rule) => rule.perimeter?.kind === "nx")
|
|
21
|
-
? listWorkspaceProjects(policy.repoRoot, ["."])
|
|
22
|
-
: [];
|
|
23
|
-
for (const rule of needing) {
|
|
24
|
-
const scoped = files.filter((file) => rule.scope.some((pattern) => pattern.test(file)) &&
|
|
25
|
-
(known.has(path.extname(file)) || rule.extensions.includes(path.extname(file))));
|
|
26
|
-
indexes.set(rule.id, discoverSectors(rule, {
|
|
27
|
-
files: scoped,
|
|
28
|
-
readText: (file) => policy.fileSystem.readText(file),
|
|
29
|
-
globToRegExp,
|
|
30
|
-
projects,
|
|
31
|
-
}));
|
|
32
|
-
}
|
|
33
|
-
return indexes;
|
|
34
|
-
};
|
|
5
|
+
import { campaignsNotInstalled } from "./campaigns/none.js";
|
|
6
|
+
// The campaigns family, when `@goodbones/campaigns` is installed beside the
|
|
7
|
+
// plugin, and `none` when it is not. Everything that names the package is
|
|
8
|
+
// under `campaigns/`, reached through this one import.
|
|
9
|
+
const hostCampaigns = async () => (await importOptional(() => import("./campaigns/live.js"), "@goodbones/campaigns"))
|
|
10
|
+
?.liveCampaigns ?? campaignsNotInstalled;
|
|
35
11
|
// The clock the campaigns are judged by; `ARCHITECTURE_NOW` pins it, as it
|
|
36
12
|
// does for the CLI.
|
|
37
13
|
const hostNow = () => {
|
|
@@ -49,54 +25,37 @@ const hostNow = () => {
|
|
|
49
25
|
// failure throws out of here and out of oxlint's import of the plugin — a
|
|
50
26
|
// plugin that came up with no policy would report nothing and be
|
|
51
27
|
// indistinguishable from a clean codebase.
|
|
52
|
-
|
|
28
|
+
//
|
|
29
|
+
// `given` is the family to compose: found by `hostCampaigns` unless a test
|
|
30
|
+
// names one, which is how the plugin is run as if the package were absent.
|
|
31
|
+
export const loadPolicyFromFile = async (repoRoot, configFilename, given) => {
|
|
53
32
|
// Named, or discovered: architecture.yaml, .yml, .json, or .config.mjs,
|
|
54
33
|
// exactly one of which may be present.
|
|
55
34
|
const configPath = configFilename === undefined
|
|
56
35
|
? findManifestFile(repoRoot)
|
|
57
36
|
: path.resolve(repoRoot, configFilename);
|
|
58
37
|
const read = await readManifestFile(configPath);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
38
|
+
const campaigns = given ?? (await hostCampaigns());
|
|
39
|
+
const composed = await campaigns.compose(repoRoot, configPath, read.manifest);
|
|
40
|
+
// The syntax matcher, for the campaigns family's `syntax` term, is an
|
|
41
|
+
// optional peer with a native binary: composed into the pack when it is
|
|
42
|
+
// installed, and the plugin parses with it for that family only. A
|
|
43
|
+
// campaign that needs it without it is refused at load, naming it.
|
|
44
|
+
const astGrep = await importOptional(() => import("@goodbones/ast-grep"), "@goodbones/ast-grep");
|
|
63
45
|
const loaded = loadPolicy({
|
|
64
46
|
repoRoot,
|
|
65
47
|
configPath,
|
|
66
|
-
manifest,
|
|
48
|
+
manifest: composed.manifest,
|
|
67
49
|
locate: read.locate,
|
|
68
|
-
languages: [typescriptLanguage({ syntax: astGrepMatcher() })],
|
|
50
|
+
languages: [typescriptLanguage(astGrep === null ? {} : { syntax: astGrep.astGrepMatcher() })],
|
|
69
51
|
fileSystem: makeFileSystemLive(repoRoot),
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// restarts. A report the build writes to a file is the predictable form.
|
|
73
|
-
extensions: [campaignsExtension({ functions, reports: makeReportSourceLive(repoRoot) })],
|
|
52
|
+
extensions: composed.extensions,
|
|
53
|
+
uninstalled: composed.uninstalled,
|
|
74
54
|
now: hostNow(),
|
|
75
55
|
});
|
|
76
56
|
if (Result.isFailure(loaded))
|
|
77
57
|
throw loaded.failure;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// nothing. A `command` forks this process, and once the linter is running
|
|
81
|
-
// Linux can refuse the fork: the linter's per-thread AST buffers merge
|
|
82
|
-
// into one mapping larger than RAM and swap together, which the default
|
|
83
|
-
// overcommit heuristic refuses to duplicate. The source keeps the answer,
|
|
84
|
-
// and a failure, so the rules read what was read here — a term's several
|
|
85
|
-
// commands run at once. A report that cannot be read is not a load
|
|
86
|
-
// failure — the campaigns rule reports it once, on the first file a
|
|
87
|
-
// campaign naming it selects; one that does not parse is.
|
|
88
|
-
const campaigns = campaignsOf(policy);
|
|
89
|
-
await Promise.all(reportSpecsOf(campaigns.campaignRules).map(async (spec) => {
|
|
90
|
-
if (campaigns.reports.read !== undefined)
|
|
91
|
-
return campaigns.reports.read(spec);
|
|
92
|
-
try {
|
|
93
|
-
campaigns.reports.diagnosticsOf(spec, "");
|
|
94
|
-
}
|
|
95
|
-
catch (cause) {
|
|
96
|
-
if (!(cause instanceof ReportUnavailable))
|
|
97
|
-
throw cause;
|
|
98
|
-
}
|
|
99
|
-
}));
|
|
100
|
-
return policy;
|
|
58
|
+
await campaigns.prepare(loaded.success);
|
|
59
|
+
return { ...loaded.success, campaigns: campaigns.host };
|
|
101
60
|
};
|
|
102
61
|
//# sourceMappingURL=config-loader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,
|
|
1
|
+
{"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"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"}
|
package/build/esm/plugin.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { discoverSectorIndexes, loadPolicyFromFile } from "./config-loader.js";
|
|
1
|
+
import { loadPolicyFromFile } from "./config-loader.js";
|
|
3
2
|
import { makeExportsRule } from "./exports-rule.js";
|
|
4
3
|
import { makeImportsRule } from "./imports-rule.js";
|
|
5
4
|
import { makeMembersRule } from "./members-rule.js";
|
|
@@ -22,9 +21,10 @@ export const rules = {
|
|
|
22
21
|
members: makeMembersRule(policy),
|
|
23
22
|
structure: makeStructureRule(policy),
|
|
24
23
|
surface: makeSurfaceRule(policy),
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
|
|
24
|
+
// From the campaigns family the plugin was composed with: the rule over
|
|
25
|
+
// the ledgers when `@goodbones/campaigns` is installed, and one that says
|
|
26
|
+
// to install it when it is not.
|
|
27
|
+
campaigns: policy.campaigns.rule(policy),
|
|
28
28
|
};
|
|
29
29
|
const plugin = {
|
|
30
30
|
meta: { name: "architecture" },
|
package/build/esm/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,+EAA+E;AAC/E,YAAY;AACZ,MAAM,MAAM,GAAG,MAAM,kBAAkB,CACrC,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,EAAE,EAC9C,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAChC,CAAC;AAEF,6EAA6E;AAC7E,mCAAmC;AACnC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,MAAM,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAOd;IACF,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;IAChC,SAAS,EAAE,iBAAiB,CAAC,MAAM,CAAC;IACpC,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC;IAChC,wEAAwE;IACxE,0EAA0E;IAC1E,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,GAA+E;IACzF,IAAI,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE;IAC9B,KAAK;CACN,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodbones/oxlint",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.18",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "The oxlint plugin for @goodbones/core: the imports, exports, members, structure, surface and campaigns families as six oxlint rules, evaluated in the editor and in CI from the same manifest the CLI reads.",
|
|
@@ -44,17 +44,27 @@
|
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"effect": "4.0.0-beta.94",
|
|
47
|
-
"@goodbones/
|
|
48
|
-
"@goodbones/
|
|
49
|
-
"@goodbones/core": "0.1.0-beta.15",
|
|
50
|
-
"@goodbones/typescript": "0.1.0-beta.15"
|
|
47
|
+
"@goodbones/core": "0.1.0-beta.16",
|
|
48
|
+
"@goodbones/typescript": "0.1.0-beta.16"
|
|
51
49
|
},
|
|
52
50
|
"peerDependencies": {
|
|
53
|
-
"oxlint": ">=1.77.0"
|
|
51
|
+
"oxlint": ">=1.77.0",
|
|
52
|
+
"@goodbones/ast-grep": "^0.1.3-beta.5",
|
|
53
|
+
"@goodbones/campaigns": "^0.1.1-beta.7"
|
|
54
|
+
},
|
|
55
|
+
"peerDependenciesMeta": {
|
|
56
|
+
"@goodbones/ast-grep": {
|
|
57
|
+
"optional": true
|
|
58
|
+
},
|
|
59
|
+
"@goodbones/campaigns": {
|
|
60
|
+
"optional": true
|
|
61
|
+
}
|
|
54
62
|
},
|
|
55
63
|
"devDependencies": {
|
|
56
64
|
"@types/node": "^25.9.4",
|
|
57
|
-
"oxlint": "1.81.0"
|
|
65
|
+
"oxlint": "1.81.0",
|
|
66
|
+
"@goodbones/ast-grep": "0.1.3-beta.5",
|
|
67
|
+
"@goodbones/campaigns": "0.1.1-beta.7"
|
|
58
68
|
},
|
|
59
69
|
"nx": {
|
|
60
70
|
"includedScripts": []
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// What the plugin asks of the campaigns family, as one value.
|
|
2
|
+
//
|
|
3
|
+
// `@goodbones/campaigns` is an optional peer: a user who never runs a
|
|
4
|
+
// campaign does not install it. So nothing outside this folder names it, and
|
|
5
|
+
// nothing here reaches it at run time — this module and `none.ts` import its
|
|
6
|
+
// types only, which compile away. `live.ts` is the one module that loads it,
|
|
7
|
+
// and the composition root reaches `live.ts` through `importOptional`, so a
|
|
8
|
+
// repository without the package lints with every other rule.
|
|
9
|
+
import type {
|
|
10
|
+
LoadedPolicy as CorePolicy,
|
|
11
|
+
PolicyExtension,
|
|
12
|
+
UninstalledExtension,
|
|
13
|
+
} from "@goodbones/core";
|
|
14
|
+
|
|
15
|
+
import type { OxlintRule } from "../oxlint-api.js";
|
|
16
|
+
|
|
17
|
+
export type CampaignsHost = {
|
|
18
|
+
// The `campaigns` rule over the loaded policy.
|
|
19
|
+
readonly rule: (policy: CorePolicy) => OxlintRule;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// The policy as this host carries it: the core's, with the campaigns family
|
|
23
|
+
// it was composed with — the live one, or `none`.
|
|
24
|
+
export type LoadedPolicy = CorePolicy & { readonly campaigns: CampaignsHost };
|
|
25
|
+
|
|
26
|
+
// What the composition root hands the loader for the family: the manifest
|
|
27
|
+
// with each `fn` term's function imported and replaced by its name, the
|
|
28
|
+
// extension that claims the family's keys — or, with the family not
|
|
29
|
+
// installed, those keys named as uninstalled.
|
|
30
|
+
export type Composition = {
|
|
31
|
+
readonly manifest: unknown;
|
|
32
|
+
readonly extensions: ReadonlyArray<PolicyExtension>;
|
|
33
|
+
readonly uninstalled: ReadonlyArray<UninstalledExtension>;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type CampaignsFamily = {
|
|
37
|
+
readonly host: CampaignsHost;
|
|
38
|
+
readonly compose: (
|
|
39
|
+
repoRoot: string,
|
|
40
|
+
configPath: string,
|
|
41
|
+
manifest: unknown,
|
|
42
|
+
) => Promise<Composition>;
|
|
43
|
+
// Run once the policy has loaded and before oxlint lints a file.
|
|
44
|
+
readonly prepare: (policy: CorePolicy) => Promise<void>;
|
|
45
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
campaignsExtension,
|
|
5
|
+
campaignsOf,
|
|
6
|
+
discoverSectors,
|
|
7
|
+
loadCampaignFunctions,
|
|
8
|
+
makeReportSourceLive,
|
|
9
|
+
reportSpecsOf,
|
|
10
|
+
type SectorIndex,
|
|
11
|
+
} from "@goodbones/campaigns";
|
|
12
|
+
import {
|
|
13
|
+
globToRegExp,
|
|
14
|
+
listSourceFiles,
|
|
15
|
+
listWorkspaceProjects,
|
|
16
|
+
type LoadedPolicy,
|
|
17
|
+
ReportUnavailable,
|
|
18
|
+
} from "@goodbones/core";
|
|
19
|
+
|
|
20
|
+
import type { CampaignsFamily } from "./host.js";
|
|
21
|
+
import { makeCampaignsRule } from "./rule.js";
|
|
22
|
+
|
|
23
|
+
// The campaigns family as the plugin runs it, over `@goodbones/campaigns`.
|
|
24
|
+
// The one module that loads the package: the composition root imports it
|
|
25
|
+
// through `importOptional`, so its absence is `none`, not a failure to load.
|
|
26
|
+
|
|
27
|
+
// A `marker` or `nx` perimeter needs the other files to say which sector a
|
|
28
|
+
// file is in — the markers, or the workspace's projects — so the plugin
|
|
29
|
+
// reads them once at load, from a walk of the repository that reads no
|
|
30
|
+
// source text but the markers'. The other perimeters answer from the path
|
|
31
|
+
// or the file itself, and need nothing here.
|
|
32
|
+
const discoverSectorIndexes = (policy: LoadedPolicy): ReadonlyMap<string, SectorIndex> => {
|
|
33
|
+
const indexes = new Map<string, SectorIndex>();
|
|
34
|
+
const needing = campaignsOf(policy).campaignRules.filter(
|
|
35
|
+
(rule) => rule.perimeter?.kind === "marker" || rule.perimeter?.kind === "nx",
|
|
36
|
+
);
|
|
37
|
+
if (needing.length === 0) return indexes;
|
|
38
|
+
const widened = [...new Set(needing.flatMap((rule) => rule.extensions))];
|
|
39
|
+
const files = listSourceFiles(policy.repoRoot, ["."], policy.languages, widened);
|
|
40
|
+
const known = new Set(policy.languages.flatMap((one) => one.extensions));
|
|
41
|
+
const projects = needing.some((rule) => rule.perimeter?.kind === "nx")
|
|
42
|
+
? listWorkspaceProjects(policy.repoRoot, ["."])
|
|
43
|
+
: [];
|
|
44
|
+
for (const rule of needing) {
|
|
45
|
+
const scoped = files.filter(
|
|
46
|
+
(file) =>
|
|
47
|
+
rule.scope.some((pattern) => pattern.test(file)) &&
|
|
48
|
+
(known.has(path.extname(file)) || rule.extensions.includes(path.extname(file))),
|
|
49
|
+
);
|
|
50
|
+
indexes.set(
|
|
51
|
+
rule.id,
|
|
52
|
+
discoverSectors(rule, {
|
|
53
|
+
files: scoped,
|
|
54
|
+
readText: (file) => policy.fileSystem.readText(file),
|
|
55
|
+
globToRegExp,
|
|
56
|
+
projects,
|
|
57
|
+
}),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
return indexes;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export const liveCampaigns: CampaignsFamily = {
|
|
64
|
+
// The sectors a `marker` or `nx` perimeter births are read once here,
|
|
65
|
+
// from the markers and the workspace, before any file is linted.
|
|
66
|
+
host: { rule: (policy) => makeCampaignsRule(policy, discoverSectorIndexes(policy)) },
|
|
67
|
+
// The `fn` terms are imported here, before the policy loads, as the CLI
|
|
68
|
+
// does. A `report` command runs once per process — once per editor session
|
|
69
|
+
// for oxlint's language server, which then sees that report until it
|
|
70
|
+
// restarts. A report the build writes to a file is the predictable form.
|
|
71
|
+
compose: async (repoRoot, configPath, manifest) => {
|
|
72
|
+
const loaded = await loadCampaignFunctions(configPath, manifest);
|
|
73
|
+
return {
|
|
74
|
+
manifest: loaded.manifest,
|
|
75
|
+
extensions: [
|
|
76
|
+
campaignsExtension({
|
|
77
|
+
functions: loaded.functions,
|
|
78
|
+
reports: makeReportSourceLive(repoRoot),
|
|
79
|
+
}),
|
|
80
|
+
],
|
|
81
|
+
uninstalled: [],
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
// Every `report` a campaign names is read now, while oxlint has linted
|
|
85
|
+
// nothing. A `command` forks this process, and once the linter is running
|
|
86
|
+
// Linux can refuse the fork: the linter's per-thread AST buffers merge
|
|
87
|
+
// into one mapping larger than RAM and swap together, which the default
|
|
88
|
+
// overcommit heuristic refuses to duplicate. The source keeps the answer,
|
|
89
|
+
// and a failure, so the rules read what was read here — a term's several
|
|
90
|
+
// commands run at once. A report that cannot be read is not a load
|
|
91
|
+
// failure — the campaigns rule reports it once, on the first file a
|
|
92
|
+
// campaign naming it selects; one that does not parse is.
|
|
93
|
+
prepare: async (policy) => {
|
|
94
|
+
const campaigns = campaignsOf(policy);
|
|
95
|
+
await Promise.all(
|
|
96
|
+
reportSpecsOf(campaigns.campaignRules).map(async (spec) => {
|
|
97
|
+
if (campaigns.reports.read !== undefined) return campaigns.reports.read(spec);
|
|
98
|
+
try {
|
|
99
|
+
campaigns.reports.diagnosticsOf(spec, "");
|
|
100
|
+
} catch (cause) {
|
|
101
|
+
if (!(cause instanceof ReportUnavailable)) throw cause;
|
|
102
|
+
}
|
|
103
|
+
}),
|
|
104
|
+
);
|
|
105
|
+
},
|
|
106
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { UninstalledExtension } from "@goodbones/core";
|
|
2
|
+
|
|
3
|
+
import type { OxlintRule, Program, RuleContext } from "../oxlint-api.js";
|
|
4
|
+
import type { CampaignsFamily } from "./host.js";
|
|
5
|
+
|
|
6
|
+
// The package the family comes in, and the manifest keys it would claim: a
|
|
7
|
+
// manifest that uses one without it is refused naming the package, rather
|
|
8
|
+
// than as a misspelling.
|
|
9
|
+
export const CAMPAIGNS_PACKAGE = "@goodbones/campaigns";
|
|
10
|
+
|
|
11
|
+
const UNINSTALLED: UninstalledExtension = {
|
|
12
|
+
manifestKeys: ["campaigns", "ledger"],
|
|
13
|
+
install: CAMPAIGNS_PACKAGE,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// The `campaigns` rule without the family. oxlint refuses a configuration
|
|
17
|
+
// naming a rule the plugin does not register, with no word of why, so the
|
|
18
|
+
// rule is registered anyway and says what to install — once per process, on
|
|
19
|
+
// the first file, rather than on every file of the run.
|
|
20
|
+
export const notInstalledRule = (): OxlintRule => {
|
|
21
|
+
let said = false;
|
|
22
|
+
return {
|
|
23
|
+
meta: {
|
|
24
|
+
type: "problem" as const,
|
|
25
|
+
docs: { description: `the campaigns, which need ${CAMPAIGNS_PACKAGE} installed` },
|
|
26
|
+
schema: [],
|
|
27
|
+
},
|
|
28
|
+
createOnce(context: RuleContext) {
|
|
29
|
+
return {
|
|
30
|
+
before() {
|
|
31
|
+
return !said;
|
|
32
|
+
},
|
|
33
|
+
Program(_node: Program) {
|
|
34
|
+
if (said) return;
|
|
35
|
+
said = true;
|
|
36
|
+
context.report({
|
|
37
|
+
message:
|
|
38
|
+
`architecture/campaigns needs \`${CAMPAIGNS_PACKAGE}\`, which is not installed. ` +
|
|
39
|
+
`Install it beside @goodbones/oxlint, or turn the rule off.`,
|
|
40
|
+
loc: { line: 1, column: 0 },
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// The family, when it is not installed.
|
|
49
|
+
export const campaignsNotInstalled: CampaignsFamily = {
|
|
50
|
+
host: { rule: notInstalledRule },
|
|
51
|
+
compose: (_repoRoot, _configPath, manifest) =>
|
|
52
|
+
Promise.resolve({ manifest, extensions: [], uninstalled: [UNINSTALLED] }),
|
|
53
|
+
prepare: () => Promise.resolve(),
|
|
54
|
+
};
|
|
@@ -31,7 +31,7 @@ import {
|
|
|
31
31
|
type Program,
|
|
32
32
|
type RuleContext,
|
|
33
33
|
toRepoRelative,
|
|
34
|
-
} from "
|
|
34
|
+
} from "../oxlint-api.js";
|
|
35
35
|
|
|
36
36
|
// The campaigns family, one file at a time: every hit of an objective in
|
|
37
37
|
// window for the file's sector that its ledger does not carry, reported at
|
package/src/config-loader.ts
CHANGED
|
@@ -1,66 +1,26 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
|
|
3
|
-
import { astGrepMatcher } from "@goodbones/ast-grep";
|
|
4
|
-
import {
|
|
5
|
-
campaignsExtension,
|
|
6
|
-
campaignsOf,
|
|
7
|
-
discoverSectors,
|
|
8
|
-
loadCampaignFunctions,
|
|
9
|
-
makeReportSourceLive,
|
|
10
|
-
reportSpecsOf,
|
|
11
|
-
type SectorIndex,
|
|
12
|
-
} from "@goodbones/campaigns";
|
|
13
3
|
import {
|
|
14
4
|
findManifestFile,
|
|
15
|
-
|
|
16
|
-
listSourceFiles,
|
|
17
|
-
listWorkspaceProjects,
|
|
18
|
-
type LoadedPolicy,
|
|
5
|
+
importOptional,
|
|
19
6
|
loadPolicy,
|
|
20
7
|
makeFileSystemLive,
|
|
21
8
|
readManifestFile,
|
|
22
|
-
ReportUnavailable,
|
|
23
9
|
} from "@goodbones/core";
|
|
24
10
|
import { typescriptLanguage } from "@goodbones/typescript";
|
|
25
11
|
import * as Result from "effect/Result";
|
|
26
12
|
|
|
27
|
-
|
|
13
|
+
import type { CampaignsFamily, LoadedPolicy } from "./campaigns/host.js";
|
|
14
|
+
import { campaignsNotInstalled } from "./campaigns/none.js";
|
|
28
15
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
(rule) => rule.perimeter?.kind === "marker" || rule.perimeter?.kind === "nx",
|
|
38
|
-
);
|
|
39
|
-
if (needing.length === 0) return indexes;
|
|
40
|
-
const widened = [...new Set(needing.flatMap((rule) => rule.extensions))];
|
|
41
|
-
const files = listSourceFiles(policy.repoRoot, ["."], policy.languages, widened);
|
|
42
|
-
const known = new Set(policy.languages.flatMap((one) => one.extensions));
|
|
43
|
-
const projects = needing.some((rule) => rule.perimeter?.kind === "nx")
|
|
44
|
-
? listWorkspaceProjects(policy.repoRoot, ["."])
|
|
45
|
-
: [];
|
|
46
|
-
for (const rule of needing) {
|
|
47
|
-
const scoped = files.filter(
|
|
48
|
-
(file) =>
|
|
49
|
-
rule.scope.some((pattern) => pattern.test(file)) &&
|
|
50
|
-
(known.has(path.extname(file)) || rule.extensions.includes(path.extname(file))),
|
|
51
|
-
);
|
|
52
|
-
indexes.set(
|
|
53
|
-
rule.id,
|
|
54
|
-
discoverSectors(rule, {
|
|
55
|
-
files: scoped,
|
|
56
|
-
readText: (file) => policy.fileSystem.readText(file),
|
|
57
|
-
globToRegExp,
|
|
58
|
-
projects,
|
|
59
|
-
}),
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
return indexes;
|
|
63
|
-
};
|
|
16
|
+
export type { LoadedPolicy } from "./campaigns/host.js";
|
|
17
|
+
|
|
18
|
+
// The campaigns family, when `@goodbones/campaigns` is installed beside the
|
|
19
|
+
// plugin, and `none` when it is not. Everything that names the package is
|
|
20
|
+
// under `campaigns/`, reached through this one import.
|
|
21
|
+
const hostCampaigns = async (): Promise<CampaignsFamily> =>
|
|
22
|
+
(await importOptional(() => import("./campaigns/live.js"), "@goodbones/campaigns"))
|
|
23
|
+
?.liveCampaigns ?? campaignsNotInstalled;
|
|
64
24
|
|
|
65
25
|
// The clock the campaigns are judged by; `ARCHITECTURE_NOW` pins it, as it
|
|
66
26
|
// does for the CLI.
|
|
@@ -79,9 +39,13 @@ const hostNow = (): number => {
|
|
|
79
39
|
// failure throws out of here and out of oxlint's import of the plugin — a
|
|
80
40
|
// plugin that came up with no policy would report nothing and be
|
|
81
41
|
// indistinguishable from a clean codebase.
|
|
42
|
+
//
|
|
43
|
+
// `given` is the family to compose: found by `hostCampaigns` unless a test
|
|
44
|
+
// names one, which is how the plugin is run as if the package were absent.
|
|
82
45
|
export const loadPolicyFromFile = async (
|
|
83
46
|
repoRoot: string,
|
|
84
47
|
configFilename?: string,
|
|
48
|
+
given?: CampaignsFamily,
|
|
85
49
|
): Promise<LoadedPolicy> => {
|
|
86
50
|
// Named, or discovered: architecture.yaml, .yml, .json, or .config.mjs,
|
|
87
51
|
// exactly one of which may be present.
|
|
@@ -90,44 +54,25 @@ export const loadPolicyFromFile = async (
|
|
|
90
54
|
? findManifestFile(repoRoot)
|
|
91
55
|
: path.resolve(repoRoot, configFilename);
|
|
92
56
|
const read = await readManifestFile(configPath);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
//
|
|
96
|
-
|
|
57
|
+
const campaigns = given ?? (await hostCampaigns());
|
|
58
|
+
const composed = await campaigns.compose(repoRoot, configPath, read.manifest);
|
|
59
|
+
// The syntax matcher, for the campaigns family's `syntax` term, is an
|
|
60
|
+
// optional peer with a native binary: composed into the pack when it is
|
|
61
|
+
// installed, and the plugin parses with it for that family only. A
|
|
62
|
+
// campaign that needs it without it is refused at load, naming it.
|
|
63
|
+
const astGrep = await importOptional(() => import("@goodbones/ast-grep"), "@goodbones/ast-grep");
|
|
97
64
|
const loaded = loadPolicy({
|
|
98
65
|
repoRoot,
|
|
99
66
|
configPath,
|
|
100
|
-
manifest,
|
|
67
|
+
manifest: composed.manifest,
|
|
101
68
|
locate: read.locate,
|
|
102
|
-
languages: [typescriptLanguage({ syntax: astGrepMatcher() })],
|
|
69
|
+
languages: [typescriptLanguage(astGrep === null ? {} : { syntax: astGrep.astGrepMatcher() })],
|
|
103
70
|
fileSystem: makeFileSystemLive(repoRoot),
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// restarts. A report the build writes to a file is the predictable form.
|
|
107
|
-
extensions: [campaignsExtension({ functions, reports: makeReportSourceLive(repoRoot) })],
|
|
71
|
+
extensions: composed.extensions,
|
|
72
|
+
uninstalled: composed.uninstalled,
|
|
108
73
|
now: hostNow(),
|
|
109
74
|
});
|
|
110
75
|
if (Result.isFailure(loaded)) throw loaded.failure;
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// nothing. A `command` forks this process, and once the linter is running
|
|
114
|
-
// Linux can refuse the fork: the linter's per-thread AST buffers merge
|
|
115
|
-
// into one mapping larger than RAM and swap together, which the default
|
|
116
|
-
// overcommit heuristic refuses to duplicate. The source keeps the answer,
|
|
117
|
-
// and a failure, so the rules read what was read here — a term's several
|
|
118
|
-
// commands run at once. A report that cannot be read is not a load
|
|
119
|
-
// failure — the campaigns rule reports it once, on the first file a
|
|
120
|
-
// campaign naming it selects; one that does not parse is.
|
|
121
|
-
const campaigns = campaignsOf(policy);
|
|
122
|
-
await Promise.all(
|
|
123
|
-
reportSpecsOf(campaigns.campaignRules).map(async (spec) => {
|
|
124
|
-
if (campaigns.reports.read !== undefined) return campaigns.reports.read(spec);
|
|
125
|
-
try {
|
|
126
|
-
campaigns.reports.diagnosticsOf(spec, "");
|
|
127
|
-
} catch (cause) {
|
|
128
|
-
if (!(cause instanceof ReportUnavailable)) throw cause;
|
|
129
|
-
}
|
|
130
|
-
}),
|
|
131
|
-
);
|
|
132
|
-
return policy;
|
|
76
|
+
await campaigns.prepare(loaded.success);
|
|
77
|
+
return { ...loaded.success, campaigns: campaigns.host };
|
|
133
78
|
};
|
package/src/plugin.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { discoverSectorIndexes, loadPolicyFromFile } from "./config-loader.js";
|
|
1
|
+
import { loadPolicyFromFile } from "./config-loader.js";
|
|
3
2
|
import { makeExportsRule } from "./exports-rule.js";
|
|
4
3
|
import { makeImportsRule } from "./imports-rule.js";
|
|
5
4
|
import { makeMembersRule } from "./members-rule.js";
|
|
@@ -36,9 +35,10 @@ export const rules: {
|
|
|
36
35
|
members: makeMembersRule(policy),
|
|
37
36
|
structure: makeStructureRule(policy),
|
|
38
37
|
surface: makeSurfaceRule(policy),
|
|
39
|
-
//
|
|
40
|
-
//
|
|
41
|
-
|
|
38
|
+
// From the campaigns family the plugin was composed with: the rule over
|
|
39
|
+
// the ledgers when `@goodbones/campaigns` is installed, and one that says
|
|
40
|
+
// to install it when it is not.
|
|
41
|
+
campaigns: policy.campaigns.rule(policy),
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
const plugin: { readonly meta: { readonly name: string }; readonly rules: typeof rules } = {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"campaigns-rule.d.ts","sourceRoot":"","sources":["../../src/campaigns-rule.ts"],"names":[],"mappings":"AAEA,OAAO,EAmBL,KAAK,WAAW,EAEjB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAiB,KAAK,YAAY,EAAqB,MAAM,iBAAiB,CAAC;AAGtF,OAAO,EAEL,KAAK,UAAU,EAIhB,MAAM,iBAAiB,CAAC;AAsBzB,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AA2D7D,eAAO,MAAM,iBAAiB,WACpB,YAAY,YACX,aAAa,KACrB,UA6HF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"campaigns-rule.js","sourceRoot":"","sources":["../../src/campaigns-rule.ts"],"names":[],"mappings":"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"}
|