@alint-js/core 0.7.1 → 0.7.3
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/dist/index.d.mts +9 -0
- package/dist/index.mjs +43 -9
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -203,6 +203,15 @@ interface RunOptions {
|
|
|
203
203
|
* Defaults to `true`. Pass `false` for runs that target partial subsets of a project.
|
|
204
204
|
*/
|
|
205
205
|
projectTargets?: boolean;
|
|
206
|
+
/**
|
|
207
|
+
* Only run rules whose configured id (`plugin/rule`) or own name (`rule`) matches one of these
|
|
208
|
+
* glob patterns. Everything else stays unplanned, so a filtered run neither calls its model nor
|
|
209
|
+
* reports its diagnostics.
|
|
210
|
+
*
|
|
211
|
+
* A filter that matches no enabled rule fails the run, because a silent empty run is
|
|
212
|
+
* indistinguishable from a clean one. Pass the patterns you typed on the command line.
|
|
213
|
+
*/
|
|
214
|
+
ruleFilter?: readonly string[];
|
|
206
215
|
runner?: RunnerOptions;
|
|
207
216
|
setupConfig?: SetupConfig;
|
|
208
217
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -271,7 +271,7 @@ function mergeStopGateConfig(resolved, item) {
|
|
|
271
271
|
}
|
|
272
272
|
//#endregion
|
|
273
273
|
//#region package.json
|
|
274
|
-
var version = "0.7.
|
|
274
|
+
var version = "0.7.3";
|
|
275
275
|
//#endregion
|
|
276
276
|
//#region src/core/cache/types.ts
|
|
277
277
|
const CACHE_MAGIC = "ALINT_CACHE";
|
|
@@ -1165,6 +1165,19 @@ function resolveRuleLanguages(languages) {
|
|
|
1165
1165
|
};
|
|
1166
1166
|
}
|
|
1167
1167
|
//#endregion
|
|
1168
|
+
//#region src/core/rule-filter.ts
|
|
1169
|
+
const minimatchOptions = { dot: true };
|
|
1170
|
+
/**
|
|
1171
|
+
* Whether one enabled rule survives a `--rule` filter.
|
|
1172
|
+
*
|
|
1173
|
+
* A pattern matches the configured rule id (`plugin/rule`) or the rule's own name
|
|
1174
|
+
* (`rule`), so `--rule docs/review-copy` narrows a run to a single rule while
|
|
1175
|
+
* `--rule 'docs/*'` keeps a plugin's rules. Patterns are matched with glob syntax.
|
|
1176
|
+
*/
|
|
1177
|
+
function matchesRuleFilter(rule, patterns) {
|
|
1178
|
+
return patterns.some((pattern) => minimatch(rule.id, pattern, minimatchOptions) || minimatch(rule.localId, pattern, minimatchOptions));
|
|
1179
|
+
}
|
|
1180
|
+
//#endregion
|
|
1168
1181
|
//#region src/core/preparation.ts
|
|
1169
1182
|
/**
|
|
1170
1183
|
* The `ctx.src.extract` a run hands to rules, for parsing files it was never asked to lint, which
|
|
@@ -1197,10 +1210,17 @@ function createSourceExtractor(cwd, config, getSrc) {
|
|
|
1197
1210
|
function prepareRun(options = {}) {
|
|
1198
1211
|
const cwd$2 = options.cwd ?? cwd();
|
|
1199
1212
|
const config = options.config ?? [];
|
|
1213
|
+
const ruleFilter = options.ruleFilter ?? [];
|
|
1200
1214
|
const files = [];
|
|
1201
1215
|
const directories = [];
|
|
1216
|
+
const knownRuleIds = /* @__PURE__ */ new Set();
|
|
1202
1217
|
const missingLanguages = /* @__PURE__ */ new Map();
|
|
1203
1218
|
const unregisteredLanguages = /* @__PURE__ */ new Map();
|
|
1219
|
+
const prepareRulesFor = (effectiveConfig) => {
|
|
1220
|
+
const enabledRules = buildRuleRegistry(effectiveConfig).enabledRules;
|
|
1221
|
+
for (const enabledRule of enabledRules) knownRuleIds.add(enabledRule.id);
|
|
1222
|
+
return prepareRules(enabledRules, ruleFilter);
|
|
1223
|
+
};
|
|
1204
1224
|
for (const filePath of options.files ?? []) {
|
|
1205
1225
|
const path = resolve(cwd$2, filePath);
|
|
1206
1226
|
const resolvedConfig = resolveConfigForFile(path, config, { cwd: cwd$2 });
|
|
@@ -1208,7 +1228,7 @@ function prepareRun(options = {}) {
|
|
|
1208
1228
|
const effectiveConfig = resolvedConfig.config;
|
|
1209
1229
|
const languageRegistry = createLanguageRegistry(effectiveConfig);
|
|
1210
1230
|
const language = resolveLanguageForPath(path, languageRegistry, { language: effectiveConfig.language });
|
|
1211
|
-
const rules =
|
|
1231
|
+
const rules = prepareRulesFor(effectiveConfig);
|
|
1212
1232
|
recordMissingLanguages(missingLanguages, rules, languageRegistry, path);
|
|
1213
1233
|
if (effectiveConfig.language === void 0 && language.name === "plaintext" && rules.some(({ enabledRule }) => !isTargetLanguageAccepted(resolveRuleLanguages(enabledRule.rule.languages), "file", "plaintext"))) recordUnregistered(unregisteredLanguages, path, unregisteredLanguageSeverity(effectiveConfig.linterOptions));
|
|
1214
1234
|
files.push({
|
|
@@ -1237,7 +1257,7 @@ function prepareRun(options = {}) {
|
|
|
1237
1257
|
agent: effectiveConfig.agent,
|
|
1238
1258
|
configHash: stableHash({ settings: effectiveConfig.settings }),
|
|
1239
1259
|
directoryIndex: directories.length,
|
|
1240
|
-
rules:
|
|
1260
|
+
rules: prepareRulesFor(effectiveConfig),
|
|
1241
1261
|
settings: effectiveConfig.settings,
|
|
1242
1262
|
target: {
|
|
1243
1263
|
kind: "directory",
|
|
@@ -1245,11 +1265,13 @@ function prepareRun(options = {}) {
|
|
|
1245
1265
|
}
|
|
1246
1266
|
});
|
|
1247
1267
|
}
|
|
1268
|
+
const project = options.projectTargets === false ? void 0 : prepareProject(cwd$2, config, prepareRulesFor);
|
|
1269
|
+
if (ruleFilter.length > 0 && !hasPreparedRule(files, directories, project)) throw new Error(formatUnmatchedRuleFilter(ruleFilter, knownRuleIds));
|
|
1248
1270
|
return {
|
|
1249
1271
|
directories,
|
|
1250
1272
|
files,
|
|
1251
1273
|
missingLanguages,
|
|
1252
|
-
project
|
|
1274
|
+
project,
|
|
1253
1275
|
unregisteredLanguages
|
|
1254
1276
|
};
|
|
1255
1277
|
}
|
|
@@ -1258,7 +1280,15 @@ function createLanguageRegistry(config) {
|
|
|
1258
1280
|
for (const plugin of Object.values(config.plugins)) for (const language of Object.values(plugin.languages ?? {})) registerLanguage(registry, language);
|
|
1259
1281
|
return registry;
|
|
1260
1282
|
}
|
|
1261
|
-
function
|
|
1283
|
+
function formatUnmatchedRuleFilter(ruleFilter, knownRuleIds) {
|
|
1284
|
+
const patterns = ruleFilter.map((pattern) => `"${pattern}"`).join(", ");
|
|
1285
|
+
const knownIds = [...knownRuleIds].sort();
|
|
1286
|
+
return `No enabled rule matched --rule ${patterns}. ${knownIds.length === 0 ? "This run enabled no rule at all. Run `alint config inspect <file>` to see which rules apply to a file." : `Enabled rules: ${knownIds.slice(0, 20).join(", ")}${knownIds.length > 20 ? ", ..." : ""}.`}`;
|
|
1287
|
+
}
|
|
1288
|
+
function hasPreparedRule(files, directories, project) {
|
|
1289
|
+
return files.some((input) => input.rules.length > 0) || directories.some((input) => input.rules.length > 0) || (project?.rules.length ?? 0) > 0;
|
|
1290
|
+
}
|
|
1291
|
+
function prepareProject(root, config, prepareRulesFor) {
|
|
1262
1292
|
const resolvedConfig = resolveConfigForProject(root, config, { cwd: root });
|
|
1263
1293
|
if (resolvedConfig.ignored) return void 0;
|
|
1264
1294
|
const effectiveConfig = resolvedConfig.config;
|
|
@@ -1266,15 +1296,19 @@ function prepareProject(root, config) {
|
|
|
1266
1296
|
agent: effectiveConfig.agent,
|
|
1267
1297
|
configHash: stableHash({ settings: effectiveConfig.settings }),
|
|
1268
1298
|
root,
|
|
1269
|
-
rules:
|
|
1299
|
+
rules: prepareRulesFor(effectiveConfig),
|
|
1270
1300
|
settings: effectiveConfig.settings
|
|
1271
1301
|
};
|
|
1272
1302
|
}
|
|
1273
|
-
|
|
1274
|
-
|
|
1303
|
+
/**
|
|
1304
|
+
* Keeps the registry position of every surviving rule: `ruleIndex` is an enabled-registry
|
|
1305
|
+
* position that jobs and progress refs share, so filtering must not renumber the rules that stay.
|
|
1306
|
+
*/
|
|
1307
|
+
function prepareRules(enabledRules, ruleFilter) {
|
|
1308
|
+
return enabledRules.map((enabledRule, ruleIndex) => ({
|
|
1275
1309
|
enabledRule,
|
|
1276
1310
|
ruleIndex
|
|
1277
|
-
}));
|
|
1311
|
+
})).filter((rule) => ruleFilter.length === 0 || matchesRuleFilter(rule.enabledRule, ruleFilter));
|
|
1278
1312
|
}
|
|
1279
1313
|
function recordMissingLanguages(into, rules, registry, path) {
|
|
1280
1314
|
for (const { enabledRule } of rules) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alint-js/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.7.
|
|
4
|
+
"version": "0.7.3",
|
|
5
5
|
"description": "Public rule and plugin SDK and run engine for alint",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"pathe": "^2.0.3",
|
|
57
57
|
"proper-lockfile": "4.1.2",
|
|
58
58
|
"valibot": "^1.4.2",
|
|
59
|
-
"@alint-js/utils": "0.7.
|
|
59
|
+
"@alint-js/utils": "0.7.3"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@types/proper-lockfile": "4.1.4",
|