@goodbones/oxlint 0.1.0-beta.8 → 0.1.0-beta.9

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.
@@ -1 +1 @@
1
- {"version":3,"file":"campaigns-rule.d.ts","sourceRoot":"","sources":["../../src/campaigns-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,YAAY,EAElB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,KAAK,UAAU,EAIhB,MAAM,iBAAiB,CAAC;AA2BzB,eAAO,MAAM,iBAAiB,WAAY,YAAY,KAAG,UAoDvD,CAAC"}
1
+ {"version":3,"file":"campaigns-rule.d.ts","sourceRoot":"","sources":["../../src/campaigns-rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,YAAY,EAGlB,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAEL,KAAK,UAAU,EAIhB,MAAM,iBAAiB,CAAC;AAsCzB,eAAO,MAAM,iBAAiB,WAAY,YAAY,KAAG,UAuExD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,YAAY,EAKlB,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAmBpD,eAAO,MAAM,kBAAkB,aACnB,MAAM,mBACC,MAAM,KACtB,OAAO,CAAC,YAAY,CA4BtB,CAAC"}
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,YAAY,EAOlB,MAAM,iBAAiB,CAAC;AAIzB,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAmBpD,eAAO,MAAM,kBAAkB,aACnB,MAAM,mBACC,MAAM,KACtB,OAAO,CAAC,YAAY,CA4CtB,CAAC"}
@@ -1,4 +1,4 @@
1
- import { campaignsSelecting, evaluateCampaigns, formatMessage, leafTermsOf, reconcile, } from "@goodbones/core";
1
+ import { campaignsSelecting, evaluateCampaigns, formatMessage, leafTermsOf, reconcile, ReportUnavailable, } from "@goodbones/core";
2
2
  import { sourceFactsOf } from "@goodbones/typescript";
3
3
  import { factsOfProgram, toRepoRelative, } from "./oxlint-api.js";
4
4
  // The campaigns family, one file at a time: every hit of a campaign selecting
@@ -22,49 +22,81 @@ const unledgered = (policy, selected, hits) => {
22
22
  }
23
23
  return hits.filter((hit) => !carried.has(hit.violation));
24
24
  };
25
- export const makeCampaignsRule = (policy) => ({
26
- meta: {
27
- type: "problem",
28
- docs: {
29
- description: "the campaigns: every place a pattern the repository is migrating away from still occurs, that its ledger does not carry",
30
- },
31
- schema: [],
32
- },
33
- createOnce(context) {
34
- let file = "";
35
- let selected = [];
36
- return {
37
- before() {
38
- file = toRepoRelative(policy.repoRoot, context.filename);
39
- if (file.startsWith(".."))
40
- return false;
41
- selected = campaignsSelecting(policy.campaignRules, file);
42
- return selected.length > 0;
43
- },
44
- Program(node) {
45
- const text = context.sourceCode.text;
46
- const needsSyntax = selected.some((rule) => leafTermsOf(rule.detect).some((leaf) => leaf === "syntax" || leaf === "report" || leaf === "fn"));
47
- const hits = evaluateCampaigns(selected, {
48
- file,
49
- text,
50
- facts: sourceFactsOf(factsOfProgram(file, node)),
51
- resolver: policy.resolver,
52
- fileSystem: policy.fileSystem,
53
- syntax: needsSyntax ? policy.syntax.parse(file, text) : null,
54
- functions: policy.functions,
55
- reports: policy.reports,
56
- });
57
- for (const hit of unledgered(policy, selected, hits)) {
58
- // A match lands where it was found; a file-unit hit, on line 1, as
59
- // the structure rule places a finding about the file itself.
60
- const at = hit.range ?? { start: { line: 0, column: 0 } };
61
- context.report({
62
- message: formatMessage(hit.violation),
63
- loc: { line: at.start.line + 1, column: at.start.column },
64
- });
65
- }
25
+ // A `report` a campaign names that cannot be read — a command the kernel
26
+ // refused to spawn, a file no step wrote — is one fact about the run, not
27
+ // one about each file the campaign selects. The live source keeps the
28
+ // failure per spec; this keeps which failures have been said, so the first
29
+ // selected file carries the notice and the rest stay quiet. Without it, a
30
+ // lint of eight hundred files is eight hundred copies of oxlint's generic
31
+ // "error running JS plugin", with the cause dropped by the terser formats.
32
+ const aside = (cause) => `A report a campaign names could not be read, so no campaign naming it is judged in this ` +
33
+ `run: ${cause.message}`;
34
+ export const makeCampaignsRule = (policy) => {
35
+ // Per rule instance, which is per plugin load — one process — rather than
36
+ // per `createOnce`, which a host may call more often than that.
37
+ const said = new Set();
38
+ return {
39
+ meta: {
40
+ type: "problem",
41
+ docs: {
42
+ description: "the campaigns: every place a pattern the repository is migrating away from still occurs, that its ledger does not carry",
66
43
  },
67
- };
68
- },
69
- });
44
+ schema: [],
45
+ },
46
+ createOnce(context) {
47
+ let file = "";
48
+ let selected = [];
49
+ return {
50
+ before() {
51
+ file = toRepoRelative(policy.repoRoot, context.filename);
52
+ if (file.startsWith(".."))
53
+ return false;
54
+ selected = campaignsSelecting(policy.campaignRules, file);
55
+ return selected.length > 0;
56
+ },
57
+ Program(node) {
58
+ const text = context.sourceCode.text;
59
+ const needsSyntax = selected.some((rule) => leafTermsOf(rule.detect).some((leaf) => leaf === "syntax" || leaf === "report" || leaf === "fn"));
60
+ const input = {
61
+ file,
62
+ text,
63
+ facts: sourceFactsOf(factsOfProgram(file, node)),
64
+ resolver: policy.resolver,
65
+ fileSystem: policy.fileSystem,
66
+ syntax: needsSyntax ? policy.syntax.parse(file, text) : null,
67
+ functions: policy.functions,
68
+ reports: policy.reports,
69
+ };
70
+ // One campaign at a time, so a report one of them cannot read costs
71
+ // that campaign's answer for this file and not its neighbours'.
72
+ const hits = [];
73
+ for (const rule of selected) {
74
+ try {
75
+ for (const hit of evaluateCampaigns([rule], input))
76
+ hits.push(hit);
77
+ }
78
+ catch (cause) {
79
+ if (!(cause instanceof ReportUnavailable))
80
+ throw cause;
81
+ const message = aside(cause);
82
+ if (said.has(message))
83
+ continue;
84
+ said.add(message);
85
+ context.report({ message, loc: { line: 1, column: 0 } });
86
+ }
87
+ }
88
+ for (const hit of unledgered(policy, selected, hits)) {
89
+ // A match lands where it was found; a file-unit hit, on line 1, as
90
+ // the structure rule places a finding about the file itself.
91
+ const at = hit.range ?? { start: { line: 0, column: 0 } };
92
+ context.report({
93
+ message: formatMessage(hit.violation),
94
+ loc: { line: at.start.line + 1, column: at.start.column },
95
+ });
96
+ }
97
+ },
98
+ };
99
+ },
100
+ };
101
+ };
70
102
  //# sourceMappingURL=campaigns-rule.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"campaigns-rule.js","sourceRoot":"","sources":["../../src/campaigns-rule.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"campaigns-rule.js","sourceRoot":"","sources":["../../src/campaigns-rule.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import * as path from "node:path";
2
2
  import { astGrepMatcher } from "@goodbones/ast-grep";
3
- import { findManifestFile, loadCampaignFunctions, loadPolicy, makeFileSystemLive, makeReportSourceLive, readManifestFile, } from "@goodbones/core";
3
+ import { findManifestFile, loadCampaignFunctions, loadPolicy, makeFileSystemLive, makeReportSourceLive, readManifestFile, reportSpecsOf, ReportUnavailable, } from "@goodbones/core";
4
4
  import { typescriptLanguage } from "@goodbones/typescript";
5
5
  import * as Result from "effect/Result";
6
6
  // The clock the campaigns are judged by; `ARCHITECTURE_NOW` pins it, as it
@@ -47,6 +47,24 @@ export const loadPolicyFromFile = async (repoRoot, configFilename) => {
47
47
  });
48
48
  if (Result.isFailure(loaded))
49
49
  throw loaded.failure;
50
- return loaded.success;
50
+ const policy = loaded.success;
51
+ // Every `report` a campaign names is read now, while oxlint has linted
52
+ // nothing. A `command` forks this process, and once the linter is running
53
+ // Linux can refuse the fork: the linter's per-thread AST buffers merge
54
+ // into one mapping larger than RAM and swap together, which the default
55
+ // overcommit heuristic refuses to duplicate. The source caches the answer,
56
+ // and a failure, so the rules read what was read here. A report that
57
+ // cannot be read is not a load failure — the campaigns rule reports it
58
+ // once, on the first file a campaign naming it selects.
59
+ for (const spec of reportSpecsOf(policy.campaignRules)) {
60
+ try {
61
+ policy.reports.diagnosticsOf(spec, "");
62
+ }
63
+ catch (cause) {
64
+ if (!(cause instanceof ReportUnavailable))
65
+ throw cause;
66
+ }
67
+ }
68
+ return policy;
51
69
  };
52
70
  //# 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,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EAErB,UAAU,EACV,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAIxC,2EAA2E;AAC3E,oBAAoB;AACpB,MAAM,OAAO,GAAG,GAAW,EAAE;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;IAC5C,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC1E,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,wBAAwB,CAAC,CAAC;IACzF,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,uEAAuE;AACvE,+EAA+E;AAC/E,0EAA0E;AAC1E,iEAAiE;AACjE,2CAA2C;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,QAAgB,EAChB,cAAuB,EACA,EAAE;IACzB,wEAAwE;IACxE,uCAAuC;IACvC,MAAM,UAAU,GACd,cAAc,KAAK,SAAS;QAC1B,CAAC,CAAC,gBAAgB,CAAC,QAAQ,CAAC;QAC5B,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAChD,wEAAwE;IACxE,sEAAsE;IACtE,qEAAqE;IACrE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,MAAM,qBAAqB,CAAC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvF,MAAM,MAAM,GAAG,UAAU,CAAC;QACxB,QAAQ;QACR,UAAU;QACV,QAAQ;QACR,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,SAAS,EAAE,CAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;QAC7D,UAAU,EAAE,kBAAkB,CAAC,QAAQ,CAAC;QACxC,SAAS;QACT,qEAAqE;QACrE,qEAAqE;QACrE,yEAAyE;QACzE,OAAO,EAAE,oBAAoB,CAAC,QAAQ,CAAC;QACvC,GAAG,EAAE,OAAO,EAAE;KACf,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;QAAE,MAAM,MAAM,CAAC,OAAO,CAAC;IACnD,OAAO,MAAM,CAAC,OAAO,CAAC;AACxB,CAAC,CAAC"}
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../../src/config-loader.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodbones/oxlint",
3
- "version": "0.1.0-beta.8",
3
+ "version": "0.1.0-beta.9",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "The oxlint plugin for @goodbones/core: the imports, exports, members, structure and surface families as five oxlint rules, evaluated in the editor and in CI from the same manifest the CLI reads.",
@@ -44,9 +44,9 @@
44
44
  ],
45
45
  "dependencies": {
46
46
  "effect": "4.0.0-beta.94",
47
- "@goodbones/ast-grep": "0.1.0",
48
- "@goodbones/typescript": "0.1.0-beta.8",
49
- "@goodbones/core": "0.1.0-beta.8"
47
+ "@goodbones/ast-grep": "0.1.1",
48
+ "@goodbones/core": "0.1.0-beta.9",
49
+ "@goodbones/typescript": "0.1.0-beta.9"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "oxlint": ">=1.77.0"
@@ -7,6 +7,7 @@ import {
7
7
  leafTermsOf,
8
8
  type LoadedPolicy,
9
9
  reconcile,
10
+ ReportUnavailable,
10
11
  } from "@goodbones/core";
11
12
  import { sourceFactsOf } from "@goodbones/typescript";
12
13
 
@@ -43,56 +44,86 @@ const unledgered = (
43
44
  return hits.filter((hit) => !carried.has(hit.violation));
44
45
  };
45
46
 
46
- export const makeCampaignsRule = (policy: LoadedPolicy): OxlintRule => ({
47
- meta: {
48
- type: "problem" as const,
49
- docs: {
50
- description:
51
- "the campaigns: every place a pattern the repository is migrating away from still occurs, that its ledger does not carry",
47
+ // A `report` a campaign names that cannot be read — a command the kernel
48
+ // refused to spawn, a file no step wrote — is one fact about the run, not
49
+ // one about each file the campaign selects. The live source keeps the
50
+ // failure per spec; this keeps which failures have been said, so the first
51
+ // selected file carries the notice and the rest stay quiet. Without it, a
52
+ // lint of eight hundred files is eight hundred copies of oxlint's generic
53
+ // "error running JS plugin", with the cause dropped by the terser formats.
54
+ const aside = (cause: ReportUnavailable): string =>
55
+ `A report a campaign names could not be read, so no campaign naming it is judged in this ` +
56
+ `run: ${cause.message}`;
57
+
58
+ export const makeCampaignsRule = (policy: LoadedPolicy): OxlintRule => {
59
+ // Per rule instance, which is per plugin load — one process — rather than
60
+ // per `createOnce`, which a host may call more often than that.
61
+ const said = new Set<string>();
62
+ return {
63
+ meta: {
64
+ type: "problem" as const,
65
+ docs: {
66
+ description:
67
+ "the campaigns: every place a pattern the repository is migrating away from still occurs, that its ledger does not carry",
68
+ },
69
+ schema: [],
52
70
  },
53
- schema: [],
54
- },
55
71
 
56
- createOnce(context: RuleContext) {
57
- let file = "";
58
- let selected: ReadonlyArray<CompiledCampaign> = [];
72
+ createOnce(context: RuleContext) {
73
+ let file = "";
74
+ let selected: ReadonlyArray<CompiledCampaign> = [];
59
75
 
60
- return {
61
- before() {
62
- file = toRepoRelative(policy.repoRoot, context.filename);
63
- if (file.startsWith("..")) return false;
64
- selected = campaignsSelecting(policy.campaignRules, file);
65
- return selected.length > 0;
66
- },
76
+ return {
77
+ before() {
78
+ file = toRepoRelative(policy.repoRoot, context.filename);
79
+ if (file.startsWith("..")) return false;
80
+ selected = campaignsSelecting(policy.campaignRules, file);
81
+ return selected.length > 0;
82
+ },
67
83
 
68
- Program(node: Program) {
69
- const text = context.sourceCode.text;
70
- const needsSyntax = selected.some((rule) =>
71
- leafTermsOf(rule.detect).some(
72
- (leaf) => leaf === "syntax" || leaf === "report" || leaf === "fn",
73
- ),
74
- );
75
- const hits = evaluateCampaigns(selected, {
76
- file,
77
- text,
78
- facts: sourceFactsOf(factsOfProgram(file, node)),
79
- resolver: policy.resolver,
80
- fileSystem: policy.fileSystem,
81
- syntax: needsSyntax ? policy.syntax.parse(file, text) : null,
82
- functions: policy.functions,
83
- reports: policy.reports,
84
- });
84
+ Program(node: Program) {
85
+ const text = context.sourceCode.text;
86
+ const needsSyntax = selected.some((rule) =>
87
+ leafTermsOf(rule.detect).some(
88
+ (leaf) => leaf === "syntax" || leaf === "report" || leaf === "fn",
89
+ ),
90
+ );
91
+ const input = {
92
+ file,
93
+ text,
94
+ facts: sourceFactsOf(factsOfProgram(file, node)),
95
+ resolver: policy.resolver,
96
+ fileSystem: policy.fileSystem,
97
+ syntax: needsSyntax ? policy.syntax.parse(file, text) : null,
98
+ functions: policy.functions,
99
+ reports: policy.reports,
100
+ };
101
+ // One campaign at a time, so a report one of them cannot read costs
102
+ // that campaign's answer for this file and not its neighbours'.
103
+ const hits: Array<CampaignHit> = [];
104
+ for (const rule of selected) {
105
+ try {
106
+ for (const hit of evaluateCampaigns([rule], input)) hits.push(hit);
107
+ } catch (cause) {
108
+ if (!(cause instanceof ReportUnavailable)) throw cause;
109
+ const message = aside(cause);
110
+ if (said.has(message)) continue;
111
+ said.add(message);
112
+ context.report({ message, loc: { line: 1, column: 0 } });
113
+ }
114
+ }
85
115
 
86
- for (const hit of unledgered(policy, selected, hits)) {
87
- // A match lands where it was found; a file-unit hit, on line 1, as
88
- // the structure rule places a finding about the file itself.
89
- const at = hit.range ?? { start: { line: 0, column: 0 } };
90
- context.report({
91
- message: formatMessage(hit.violation),
92
- loc: { line: at.start.line + 1, column: at.start.column },
93
- });
94
- }
95
- },
96
- };
97
- },
98
- });
116
+ for (const hit of unledgered(policy, selected, hits)) {
117
+ // A match lands where it was found; a file-unit hit, on line 1, as
118
+ // the structure rule places a finding about the file itself.
119
+ const at = hit.range ?? { start: { line: 0, column: 0 } };
120
+ context.report({
121
+ message: formatMessage(hit.violation),
122
+ loc: { line: at.start.line + 1, column: at.start.column },
123
+ });
124
+ }
125
+ },
126
+ };
127
+ },
128
+ };
129
+ };
@@ -9,6 +9,8 @@ import {
9
9
  makeFileSystemLive,
10
10
  makeReportSourceLive,
11
11
  readManifestFile,
12
+ reportSpecsOf,
13
+ ReportUnavailable,
12
14
  } from "@goodbones/core";
13
15
  import { typescriptLanguage } from "@goodbones/typescript";
14
16
  import * as Result from "effect/Result";
@@ -62,5 +64,21 @@ export const loadPolicyFromFile = async (
62
64
  now: hostNow(),
63
65
  });
64
66
  if (Result.isFailure(loaded)) throw loaded.failure;
65
- return loaded.success;
67
+ const policy = loaded.success;
68
+ // Every `report` a campaign names is read now, while oxlint has linted
69
+ // nothing. A `command` forks this process, and once the linter is running
70
+ // Linux can refuse the fork: the linter's per-thread AST buffers merge
71
+ // into one mapping larger than RAM and swap together, which the default
72
+ // overcommit heuristic refuses to duplicate. The source caches the answer,
73
+ // and a failure, so the rules read what was read here. A report that
74
+ // cannot be read is not a load failure — the campaigns rule reports it
75
+ // once, on the first file a campaign naming it selects.
76
+ for (const spec of reportSpecsOf(policy.campaignRules)) {
77
+ try {
78
+ policy.reports.diagnosticsOf(spec, "");
79
+ } catch (cause) {
80
+ if (!(cause instanceof ReportUnavailable)) throw cause;
81
+ }
82
+ }
83
+ return policy;
66
84
  };