Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Recreate --cache flag #1327

Open
azu opened this issue Jan 17, 2024 · 5 comments
Open

Recreate --cache flag #1327

azu opened this issue Jan 17, 2024 · 5 comments
Labels
Status: Proposal Request for comments

Comments

@azu
Copy link
Member

azu commented Jan 17, 2024

The current cache implementation is incomplete.
For example, the current cache only sees the meta information of the file, so it cannot be used in CI. In the strategy of Cache, there are metadata and hash, but now I'm only looking at metadata.

TODO

Related

@azu azu added Status: Proposal Request for comments Status: PR Welcome Welcome to Pull Request labels Jan 17, 2024
@azu
Copy link
Member Author

azu commented Jan 17, 2024

If possible, I would like to solve #281 as well
However, it is necessary to obtain the rule/plugin version from package, and I think that processing requies I/O cost.

This imperfection is the reason why I did not defaulted to Content Hash.

@azu
Copy link
Member Author

azu commented Jan 17, 2024

Another approach is to add a command for CI like BIOME.

Biome v1.5 | Biome

@azu
Copy link
Member Author

azu commented Jan 20, 2024

I was thinking about this and had written an implementation that takes a version from package.json, but the restrictions of Node.js are too strong,
I'm starting to think it would be simpler to just receive the lock file and hash it.

impldiff --git a/packages/@textlint/config-loader/src/loader.ts b/packages/@textlint/config-loader/src/loader.ts index 275b9d5af..bc68386bc 100644 --- a/packages/@textlint/config-loader/src/loader.ts +++ b/packages/@textlint/config-loader/src/loader.ts @@ -8,14 +8,15 @@ import { isPresetCreator, isTextlintFilterRuleReporter, isTextlintRuleModule } f import { dynamicImport } from "./import"; import { normalizeTextlintPresetSubRuleKey } from "@textlint/utils"; +const TEXTLINT_DISABLE_META = process.env.TEXTLINT_DISABLE_META === "true" ? {} : undefined; const isPluginCreator = (mod: any): mod is TextlintPluginCreator => { return typeof mod === "object" && Object.prototype.hasOwnProperty.call(mod, "Processor"); }; export const loadPlugins = async ({ - pluginsObject, - moduleResolver, - testReplaceDefinitions -}: { + pluginsObject, + moduleResolver, + testReplaceDefinitions + }: { pluginsObject: NonNullable<TextlintRcConfig["plugins"]>; parentPresetName?: string; moduleResolver: TextLintModuleResolver; @@ -47,13 +48,15 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs `) ); } + const meta = TEXTLINT_DISABLE_META || moduleResolver.resolvePackageMeta(resolvedModule); plugins.push({ type: "Plugin", pluginId, plugin, filePath: resolvedModule.filePath, moduleName: resolvedModule.moduleName, - inputModuleName: resolvedModule.inputModuleName + inputModuleName: resolvedModule.inputModuleName, + meta }); }) ); @@ -87,7 +90,7 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs ); return; } - + const meta = TEXTLINT_DISABLE_META || moduleResolver.resolvePackageMeta(resolvedPlugin); plugins.push({ type: "Plugin", pluginId, @@ -95,7 +98,8 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs options: pluginOptions, filePath: resolvedPlugin.filePath, moduleName: resolvedPlugin.moduleName, - inputModuleName: resolvedPlugin.inputModuleName + inputModuleName: resolvedPlugin.inputModuleName, + meta }); } } catch (error) { @@ -110,16 +114,16 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs pluginErrors.length === 0 ? null : { - message: "Can not load plugin", - errors: pluginErrors - } + message: "Can not load plugin", + errors: pluginErrors + } }; }; export const loadFilterRules = async ({ - rulesObject, - moduleResolver, - testReplaceDefinitions -}: { + rulesObject, + moduleResolver, + testReplaceDefinitions + }: { rulesObject: NonNullable<TextlintRcConfig["filters"]>; moduleResolver: TextLintModuleResolver; testReplaceDefinitions?: TextlintConfigDescriptor["filterRules"]; @@ -155,6 +159,7 @@ export const loadFilterRules = async ({ ); return; } + const meta = TEXTLINT_DISABLE_META || moduleResolver.resolvePackageMeta(resolvePackage); // rule rules.push({ ruleId, @@ -162,7 +167,8 @@ export const loadFilterRules = async ({ options: ruleOptions, filePath: resolvePackage.filePath, moduleName: resolvePackage.moduleName, - inputModuleName: resolvePackage.inputModuleName + inputModuleName: resolvePackage.inputModuleName, + meta }); } } catch (error) { @@ -176,17 +182,17 @@ export const loadFilterRules = async ({ ruleErrors.length === 0 ? null : { - message: "Can not load filter rule", - errors: ruleErrors - } + message: "Can not load filter rule", + errors: ruleErrors + } }; }; export const loadRules = async ({ - rulesObject, - moduleResolver, - testReplaceDefinitions -}: { + rulesObject, + moduleResolver, + testReplaceDefinitions + }: { rulesObject: NonNullable<TextlintRcConfig["rules"]>; moduleResolver: TextLintModuleResolver; testReplaceDefinitions?: TextlintConfigDescriptor["rules"]; @@ -243,6 +249,7 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs ); return; } + const meta = TEXTLINT_DISABLE_META || moduleResolver.resolvePackageMeta(resolvePackage); // rule rules.push({ type: "Rule", @@ -251,7 +258,8 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs options: ruleOptions, filePath: resolvePackage.filePath, moduleName: resolvePackage.moduleName, - inputModuleName: resolvePackage.inputModuleName + inputModuleName: resolvePackage.inputModuleName, + meta }); } } @@ -266,27 +274,29 @@ For more details, See FAQ: https://github.com/textlint/textlint/blob/master/docs ruleErrors.length === 0 ? null : { - message: "Can not load rule", - errors: ruleErrors - } + message: "Can not load rule", + errors: ruleErrors + } }; }; export async function loadPreset({ - presetName, - presetRulesOptions, - moduleResolver -}: { + presetName, + presetRulesOptions, + moduleResolver + }: { presetName: string; presetRulesOptions: NonNullable<TextlintRcConfig["rules"]>; moduleResolver: TextLintModuleResolver; }): Promise<TextlintConfigDescriptor["rules"]> { - const presetPackageName = moduleResolver.resolvePresetPackageName(presetName); - const mod = await dynamicImport(presetPackageName.filePath); + const presetPackageResult = moduleResolver.resolvePresetPackageName(presetName); + const mod = await dynamicImport(presetPackageResult.filePath); const preset = moduleInterop(mod.default); if (!isPresetCreator(preset)) { throw new Error(`preset should have rules and rulesConfig: ${presetName}`); } + const meta = TEXTLINT_DISABLE_META || moduleResolver.resolvePackageMeta(presetPackageResult); + // we should use preset.rules → some preset use different name actual rule /* // "textlint-rule-preset-example/index.js" @@ -317,12 +327,13 @@ export async function loadPreset({ // prefer .textlintrc config than preset.rulesConfig rule: preset.rules[ruleKey], options: presetRulesOptions[ruleKey] ?? preset.rulesConfig[ruleKey], - filePath: presetPackageName.filePath, + filePath: presetPackageResult.filePath, // preset package name - moduleName: presetPackageName.moduleName, - inputModuleName: presetPackageName.inputModuleName, + moduleName: presetPackageResult.moduleName, + inputModuleName: presetPackageResult.inputModuleName, // rule key in preset - ruleKey + ruleKey, + meta }; }); } diff --git a/packages/@textlint/config-loader/src/textlint-module-resolver.ts b/packages/@textlint/config-loader/src/textlint-module-resolver.ts index e39c79708..849f8275c 100644 --- a/packages/@textlint/config-loader/src/textlint-module-resolver.ts +++ b/packages/@textlint/config-loader/src/textlint-module-resolver.ts @@ -1,8 +1,19 @@ import * as path from "path"; import { PackageNamePrefix } from "./package-prefix"; import { createFullPackageName } from "./textlint-package-name-util"; -// @ts-ignore -import tryResolve from "try-resolve"; +import fs from "node:fs"; + +const tryResolve = (moduleName: string) => { + try { + return require.resolve(moduleName); + } catch (error) { + return undefined; + } +}; + +export type PackageMeta = { + version?: string; +} export interface ConfigModulePrefix { CONFIG_PACKAGE_PREFIX: string; @@ -13,8 +24,15 @@ export interface ConfigModulePrefix { } export type TextLintModuleResolverResolveResult = { + // input module name + // In sometimes, input module name is different from resolved module name. + // inputModuleName: preset-foo + // moduleName: textlint-rule-preset-foo inputModuleName: string; + // resolved module name moduleName: string; + // resolved file path for module + // it is used for import() filePath: string; }; @@ -59,100 +77,100 @@ export class TextLintModuleResolver { /** * Take package name, and return path to module. - * @param {string} packageName + * @param {string} inputModuleName * @returns {string} return path to module */ - resolveRulePackageName(packageName: string): TextLintModuleResolverResolveResult { + resolveRulePackageName(inputModuleName: string): TextLintModuleResolverResolveResult { const baseDir = this.baseDirectory; - const fullPackageName = createFullPackageName(PackageNamePrefix.rule, packageName); + const fullPackageName = createFullPackageName(PackageNamePrefix.rule, inputModuleName); // <rule-name> or textlint-rule-<rule-name> const resultFullPackagePath = this.tryResolvePackagePath(path.join(baseDir, fullPackageName)); if (resultFullPackagePath) { return { - inputModuleName: packageName, + inputModuleName, moduleName: fullPackageName, filePath: resultFullPackagePath }; } - const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, packageName)); + const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, inputModuleName)); if (resultPackagePath) { return { - inputModuleName: packageName, - moduleName: packageName, + inputModuleName, + moduleName: inputModuleName, filePath: resultPackagePath }; } - throw new ReferenceError(`Failed to load textlint's rule module: "${packageName}" is not found. + throw new ReferenceError(`Failed to load textlint's rule module: "${inputModuleName}" is not found. See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md `); } /** * Take package name, and return path to module. - * @param {string} packageName + * @param {string} inputModuleName * @returns {string} return path to module */ - resolveFilterRulePackageName(packageName: string): TextLintModuleResolverResolveResult { + resolveFilterRulePackageName(inputModuleName: string): TextLintModuleResolverResolveResult { const baseDir = this.baseDirectory; - const fullPackageName = createFullPackageName(PackageNamePrefix.filterRule, packageName); + const fullPackageName = createFullPackageName(PackageNamePrefix.filterRule, inputModuleName); // <rule-name> or textlint-filter-rule-<rule-name> or @scope/<rule-name> const resultFullPackagePath = this.tryResolvePackagePath(path.join(baseDir, fullPackageName)); if (resultFullPackagePath) { return { - inputModuleName: packageName, + inputModuleName, moduleName: fullPackageName, filePath: resultFullPackagePath }; } - const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, packageName)); + const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, inputModuleName)); if (resultPackagePath) { return { - inputModuleName: packageName, - moduleName: packageName, + inputModuleName, + moduleName: inputModuleName, filePath: resultPackagePath }; } - throw new ReferenceError(`Failed to load textlint's filter rule module: "${packageName}" is not found. + throw new ReferenceError(`Failed to load textlint's filter rule module: "${inputModuleName}" is not found. See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md `); } /** * Take package name, and return path to module. - * @param {string} packageName + * @param {string} inputModuleName * @returns {string} return path to module */ - resolvePluginPackageName(packageName: string): TextLintModuleResolverResolveResult { + resolvePluginPackageName(inputModuleName: string): TextLintModuleResolverResolveResult { const baseDir = this.baseDirectory; - const fullPackageName = createFullPackageName(PackageNamePrefix.plugin, packageName); + const fullPackageName = createFullPackageName(PackageNamePrefix.plugin, inputModuleName); // <plugin-name> or textlint-plugin-<rule-name> const resultFullPackagePath = this.tryResolvePackagePath(path.join(baseDir, fullPackageName)); if (resultFullPackagePath) { return { - inputModuleName: packageName, + inputModuleName, moduleName: fullPackageName, filePath: resultFullPackagePath }; } - const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, packageName)); + const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, inputModuleName)); if (resultPackagePath) { return { - inputModuleName: packageName, - moduleName: packageName, + inputModuleName, + moduleName: inputModuleName, filePath: resultPackagePath }; } - throw new ReferenceError(`Failed to load textlint's plugin module: "${packageName}" is not found. + throw new ReferenceError(`Failed to load textlint's plugin module: "${inputModuleName}" is not found. See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md `); } /** * Take package name, and return path to module. - * @param {string} packageName + * @param {string} inputModuleName * The user must specify preset- prefix to these `packageName`. */ - resolvePresetPackageName(packageName: string): TextLintModuleResolverResolveResult { + resolvePresetPackageName(inputModuleName: string): TextLintModuleResolverResolveResult { const baseDir = this.baseDirectory; const PREFIX = PackageNamePrefix.rulePreset; /* Implementation Note @@ -170,7 +188,7 @@ See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-loa */ // preset-<name> or textlint-rule-preset-<name> // @scope/preset-<name> or @scope/textlint-rule-preset-<name> - const packageNameWithoutPreset = packageName + const packageNameWithoutPreset = inputModuleName .replace(/^preset-/, "") .replace(/^@([^/]+)\/preset-(.*)$/, `@$1/$2`); const fullPackageName = createFullPackageName(PREFIX, packageNameWithoutPreset); @@ -179,7 +197,7 @@ See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-loa const resultFullPresetPackagePath = this.tryResolvePackagePath(path.join(baseDir, fullFullPackageName)); if (resultFullPresetPackagePath) { return { - inputModuleName: packageName, + inputModuleName, moduleName: fullFullPackageName, filePath: resultFullPresetPackagePath }; @@ -188,7 +206,7 @@ See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-loa const resultPresetPackagePath = this.tryResolvePackagePath(path.join(baseDir, packageNameWithoutPreset)); if (resultPresetPackagePath) { return { - inputModuleName: packageName, + inputModuleName, moduleName: packageNameWithoutPreset, filePath: resultPresetPackagePath }; @@ -197,37 +215,59 @@ See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-loa const resultFullPackagePath = this.tryResolvePackagePath(path.join(baseDir, fullPackageName)); if (resultFullPackagePath) { return { - inputModuleName: packageName, + inputModuleName, moduleName: fullPackageName, filePath: resultFullPackagePath }; } // <package-name> - const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, packageName)); + const resultPackagePath = this.tryResolvePackagePath(path.join(baseDir, inputModuleName)); if (resultPackagePath) { return { - inputModuleName: packageName, - moduleName: packageName, + inputModuleName, + moduleName: inputModuleName, filePath: resultPackagePath }; } - throw new ReferenceError(`Failed to load textlint's preset module: "${packageName}" is not found. + throw new ReferenceError(`Failed to load textlint's preset module: "${inputModuleName}" is not found. See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md `); } + /** + * + * @param resolved is result of `resolve*` method + * You need to get resolved moduleName by `resolve*` method. + */ + resolvePackageMeta(resolved: TextLintModuleResolverResolveResult): PackageMeta { + // Node.js does not have resolve method for package dir or package.json + // So, we need to read package.json directly. + // https://github.com/nodejs/node/issues/49445 + // https://www.npmjs.com/package/package-resolver + const packageJsonPath = path.join(this.baseDirectory, resolved.moduleName, "package.json"); + try { + const packageContent = fs.readFileSync(packageJsonPath, "utf-8"); + const pkg = JSON.parse(packageContent); + return { + version: pkg.version + }; + } catch { + return {}; + } + } + /** * Take Config package name, and return path to module. - * @param {string} packageName + * @param {string} inputModuleName * @returns {string} return path to module */ - resolveConfigPackageName(packageName: string): string { + resolveConfigPackageName(inputModuleName: string): string { const baseDir = this.baseDirectory; - const fullPackageName = createFullPackageName(PackageNamePrefix.config, packageName); + const fullPackageName = createFullPackageName(PackageNamePrefix.config, inputModuleName); // <plugin-name> or textlint-config-<rule-name> - const pkgPath = tryResolve(path.join(baseDir, fullPackageName)) || tryResolve(path.join(baseDir, packageName)); + const pkgPath = tryResolve(path.join(baseDir, fullPackageName)) || tryResolve(path.join(baseDir, inputModuleName)); if (!pkgPath) { - throw new ReferenceError(`Failed to load textlint's config module: "${packageName}" is not found. + throw new ReferenceError(`Failed to load textlint's config module: "${inputModuleName}" is not found. See FAQ: https://github.com/textlint/textlint/blob/master/docs/faq/failed-to-load-textlints-module.md `); } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-a/package.json b/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-a/package.json index dc09ca028..c7ead0dd1 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-a/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-a/package.json @@ -1,4 +1,5 @@ { "name": "@scope/textlint-rule-a", - "main": "index.js" + "main": "index.js", + "version": "1.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-b/package.json b/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-b/package.json index 5c44b061f..c6da2323e 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-b/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-b/package.json @@ -1,4 +1,5 @@ { "name": "@scope/textlint-rule-b", - "main": "index.js" + "main": "index.js", + "version": "2.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-c/package.json b/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-c/package.json index 5056e5e45..9cca4fbdc 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-c/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/@scope/textlint-rule-c/package.json @@ -1,4 +1,5 @@ { "name": "@scope/textlint-rule-c-sub1", - "main": "index.js" + "main": "index.js", + "version": "3.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-plugin-esm/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-plugin-esm/package.json index bcccf701d..c0a9a9eba 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-plugin-esm/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-plugin-esm/package.json @@ -1,5 +1,6 @@ { "name": "textlint-plugin-esm", "main": "index.mjs", - "type": "module" + "type": "module", + "version": "1.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-a/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-a/package.json index 4f2bc4243..747bac280 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-a/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-a/package.json @@ -1,4 +1,5 @@ { "name": "textlint-rule-a", - "main": "index.js" + "main": "index.js", + "version": "1.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-b/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-b/package.json index d2a722c5b..2aae70adf 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-b/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-b/package.json @@ -1,4 +1,5 @@ { "name": "textlint-rule-b", - "main": "index.js" + "main": "index.js", + "version": "2.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-c/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-c/package.json index 6cf603147..cc360a34e 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-c/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-c/package.json @@ -1,4 +1,5 @@ { - "name": "textlint-rule-c-sub1", - "main": "index.js" + "name": "textlint-rule-c", + "main": "index.js", + "version": "3.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-a/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-a/package.json index 007db6c66..ccf1eb378 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-a/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-a/package.json @@ -1,5 +1,6 @@ { "name": "textlint-rule-esm-a", "main": "index.mjs", - "type": "module" + "type": "module", + "version": "1.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-b/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-b/package.json index 633e50d37..c359b7063 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-b/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-esm-b/package.json @@ -1,5 +1,6 @@ { "name": "textlint-rule-esm-b", "main": "index.js", - "type": "module" + "type": "module", + "version": "1.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc-but-unique-rule-key/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc-but-unique-rule-key/package.json index e56857ae8..254b3ae2a 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc-but-unique-rule-key/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc-but-unique-rule-key/package.json @@ -1,4 +1,5 @@ { "name": "textlint-rule-preset-abc", - "main": "index.js" + "main": "index.js", + "version": "1.1.1" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc/package.json index e56857ae8..211ac1131 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-abc/package.json @@ -1,4 +1,5 @@ { "name": "textlint-rule-preset-abc", - "main": "index.js" + "main": "index.js", + "version": "1.0.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-c/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-c/package.json index 418187df3..b0a6741bc 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-c/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-c/package.json @@ -1,4 +1,5 @@ { "name": "textlint-rule-preset-c", - "main": "index.js" + "main": "index.js", + "version": "3.1.0" } diff --git a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-esm/package.json b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-esm/package.json index 712185b91..883eb26de 100644 --- a/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-esm/package.json +++ b/packages/@textlint/config-loader/test/modules_fixtures/textlint-rule-preset-esm/package.json @@ -1,5 +1,6 @@ { "name": "textlint-rule-preset-esm", "main": "index.js", - "type": "module" + "type": "module", + "version": "2.1.0" } diff --git a/packages/@textlint/config-loader/test/snapshots/disable-child-rule-of-preset/output.json b/packages/@textlint/config-loader/test/snapshots/disable-child-rule-of-preset/output.json index 2b804cd01..a09b2766a 100644 --- a/packages/@textlint/config-loader/test/snapshots/disable-child-rule-of-preset/output.json +++ b/packages/@textlint/config-loader/test/snapshots/disable-child-rule-of-preset/output.json @@ -9,7 +9,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc/index.js", "moduleName": "textlint-rule-preset-abc", "inputModuleName": "preset-abc", - "ruleKey": "a" + "ruleKey": "a", + "meta": { + "version": "1.0.0" + } }, { "type": "RuleInPreset", @@ -18,7 +21,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc/index.js", "moduleName": "textlint-rule-preset-abc", "inputModuleName": "preset-abc", - "ruleKey": "b" + "ruleKey": "b", + "meta": { + "version": "1.0.0" + } }, { "type": "RuleInPreset", @@ -27,7 +33,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc/index.js", "moduleName": "textlint-rule-preset-abc", "inputModuleName": "preset-abc", - "ruleKey": "c" + "ruleKey": "c", + "meta": { + "version": "1.0.0" + } } ], "plugins": [], diff --git a/packages/@textlint/config-loader/test/snapshots/esm/output.json b/packages/@textlint/config-loader/test/snapshots/esm/output.json index 891aab720..a23868bc9 100644 --- a/packages/@textlint/config-loader/test/snapshots/esm/output.json +++ b/packages/@textlint/config-loader/test/snapshots/esm/output.json @@ -10,7 +10,10 @@ "options": true, "filePath": "<MODULES_DIR>/textlint-plugin-esm/index.mjs", "moduleName": "textlint-plugin-esm", - "inputModuleName": "esm" + "inputModuleName": "esm", + "meta": { + "version": "1.0.0" + } } ], "filterRules": [] diff --git a/packages/@textlint/config-loader/test/snapshots/no-used-rule-will-be-skip-to-load/output.json b/packages/@textlint/config-loader/test/snapshots/no-used-rule-will-be-skip-to-load/output.json index 726c7f577..067a2d549 100644 --- a/packages/@textlint/config-loader/test/snapshots/no-used-rule-will-be-skip-to-load/output.json +++ b/packages/@textlint/config-loader/test/snapshots/no-used-rule-will-be-skip-to-load/output.json @@ -8,7 +8,10 @@ "options": true, "filePath": "<MODULES_DIR>/textlint-rule-a/index.js", "moduleName": "textlint-rule-a", - "inputModuleName": "a" + "inputModuleName": "a", + "meta": { + "version": "1.0.0" + } }, { "type": "Rule", @@ -18,7 +21,10 @@ }, "filePath": "<MODULES_DIR>/textlint-rule-b/index.js", "moduleName": "textlint-rule-b", - "inputModuleName": "b" + "inputModuleName": "b", + "meta": { + "version": "2.0.0" + } }, { "type": "RuleInPreset", @@ -27,7 +33,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-c/index.js", "moduleName": "textlint-rule-preset-c", "inputModuleName": "preset-c", - "ruleKey": "c-sub1" + "ruleKey": "c-sub1", + "meta": { + "version": "3.1.0" + } }, { "type": "RuleInPreset", @@ -36,7 +45,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-c/index.js", "moduleName": "textlint-rule-preset-c", "inputModuleName": "preset-c", - "ruleKey": "c-sub2" + "ruleKey": "c-sub2", + "meta": { + "version": "3.1.0" + } } ], "plugins": [], diff --git a/packages/@textlint/config-loader/test/snapshots/plguin/output.json b/packages/@textlint/config-loader/test/snapshots/plguin/output.json index 7c6eb8705..d96aed73a 100644 --- a/packages/@textlint/config-loader/test/snapshots/plguin/output.json +++ b/packages/@textlint/config-loader/test/snapshots/plguin/output.json @@ -8,7 +8,10 @@ "options": true, "filePath": "<MODULES_DIR>/textlint-rule-a/index.js", "moduleName": "textlint-rule-a", - "inputModuleName": "a" + "inputModuleName": "a", + "meta": { + "version": "1.0.0" + } } ], "plugins": [ @@ -18,7 +21,8 @@ "plugin": {}, "filePath": "<MODULES_DIR>/textlint-plugin-custom/index.js", "moduleName": "textlint-plugin-custom", - "inputModuleName": "custom" + "inputModuleName": "custom", + "meta": {} } ], "filterRules": [] diff --git a/packages/@textlint/config-loader/test/snapshots/preset/output.json b/packages/@textlint/config-loader/test/snapshots/preset/output.json index 318530bd8..e8c22fdb1 100644 --- a/packages/@textlint/config-loader/test/snapshots/preset/output.json +++ b/packages/@textlint/config-loader/test/snapshots/preset/output.json @@ -9,7 +9,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc/index.js", "moduleName": "textlint-rule-preset-abc", "inputModuleName": "preset-abc", - "ruleKey": "a" + "ruleKey": "a", + "meta": { + "version": "1.0.0" + } }, { "type": "RuleInPreset", @@ -18,7 +21,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc/index.js", "moduleName": "textlint-rule-preset-abc", "inputModuleName": "preset-abc", - "ruleKey": "b" + "ruleKey": "b", + "meta": { + "version": "1.0.0" + } }, { "type": "RuleInPreset", @@ -27,7 +33,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc/index.js", "moduleName": "textlint-rule-preset-abc", "inputModuleName": "preset-abc", - "ruleKey": "c" + "ruleKey": "c", + "meta": { + "version": "1.0.0" + } } ], "plugins": [], diff --git a/packages/@textlint/config-loader/test/snapshots/ruke-key-should-refer-property-name/output.json b/packages/@textlint/config-loader/test/snapshots/ruke-key-should-refer-property-name/output.json index 1822a6c6d..c00668a8c 100644 --- a/packages/@textlint/config-loader/test/snapshots/ruke-key-should-refer-property-name/output.json +++ b/packages/@textlint/config-loader/test/snapshots/ruke-key-should-refer-property-name/output.json @@ -9,7 +9,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc-but-unique-rule-key/index.js", "moduleName": "textlint-rule-preset-abc-but-unique-rule-key", "inputModuleName": "preset-abc-but-unique-rule-key", - "ruleKey": "uniqueA" + "ruleKey": "uniqueA", + "meta": { + "version": "1.1.1" + } }, { "type": "RuleInPreset", @@ -18,7 +21,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc-but-unique-rule-key/index.js", "moduleName": "textlint-rule-preset-abc-but-unique-rule-key", "inputModuleName": "preset-abc-but-unique-rule-key", - "ruleKey": "uniqueB" + "ruleKey": "uniqueB", + "meta": { + "version": "1.1.1" + } }, { "type": "RuleInPreset", @@ -27,7 +33,10 @@ "filePath": "<MODULES_DIR>/textlint-rule-preset-abc-but-unique-rule-key/index.js", "moduleName": "textlint-rule-preset-abc-but-unique-rule-key", "inputModuleName": "preset-abc-but-unique-rule-key", - "ruleKey": "uniqueC" + "ruleKey": "uniqueC", + "meta": { + "version": "1.1.1" + } } ], "plugins": [], diff --git a/packages/@textlint/config-loader/test/snapshots/scoped-rule/output.json b/packages/@textlint/config-loader/test/snapshots/scoped-rule/output.json index 821d838bf..4450922ca 100644 --- a/packages/@textlint/config-loader/test/snapshots/scoped-rule/output.json +++ b/packages/@textlint/config-loader/test/snapshots/scoped-rule/output.json @@ -9,7 +9,8 @@ "filePath": "<MODULES_DIR>/@scope/textlint-rule-preset-abc/index.js", "moduleName": "@scope/textlint-rule-preset-abc", "inputModuleName": "@scope/preset-abc", - "ruleKey": "a" + "ruleKey": "a", + "meta": {} }, { "type": "RuleInPreset", @@ -18,7 +19,8 @@ "filePath": "<MODULES_DIR>/@scope/textlint-rule-preset-abc/index.js", "moduleName": "@scope/textlint-rule-preset-abc", "inputModuleName": "@scope/preset-abc", - "ruleKey": "b" + "ruleKey": "b", + "meta": {} }, { "type": "RuleInPreset", @@ -27,7 +29,8 @@ "filePath": "<MODULES_DIR>/@scope/textlint-rule-preset-abc/index.js", "moduleName": "@scope/textlint-rule-preset-abc", "inputModuleName": "@scope/preset-abc", - "ruleKey": "c" + "ruleKey": "c", + "meta": {} } ], "plugins": [], diff --git a/packages/@textlint/kernel/src/textlint-kernel-interface.ts b/packages/@textlint/kernel/src/textlint-kernel-interface.ts index e10b989ee..36a6b1873 100644 --- a/packages/@textlint/kernel/src/textlint-kernel-interface.ts +++ b/packages/@textlint/kernel/src/textlint-kernel-interface.ts @@ -24,6 +24,15 @@ export interface TextlintKernelPlugin { plugin: TextlintPluginCreator; // plugin options options?: TextlintPluginOptions | boolean; + /** + * meta + */ + meta?: { + /** + * This version is used in cache key + */ + version?: string; + }; } export interface TextlintKernelRule { @@ -38,6 +47,16 @@ export interface TextlintKernelRule { // rule options // Often rule option is written in .textlintrc options?: TextlintRuleOptions | boolean; + + /** + * meta + */ + meta?: { + /** + * This version is used in cache key + */ + version?: string; + }; } export interface TextlintKernelFilterRule { @@ -49,6 +68,16 @@ export interface TextlintKernelFilterRule { // filter rule options // Often rule option is written in .textlintrc options?: TextlintFilterRuleOptions | boolean; + /** + * meta + */ + meta?: { + /** + * version of rule module + * This version is used in cache key + */ + version?: string; + }; } export interface TextlintKernelOptions {

Node.js does not have following methods:

This makes it difficult to get a package version of a specific package.

In this cache use case, we can use lock file like package-lock.json instead of the package version to see if there is any change in the dependency.
So, We can add hash-for-lock to https://github.com/azu/file-cache and use it.

@azu
Copy link
Member Author

azu commented Jan 20, 2024

@file-cache/package-lock
https://github.com/azu/file-cache/releases/tag/v2.0.0

@azu
Copy link
Member Author

azu commented Jan 30, 2024

💡 Idea

I've come up with a way to use caches to greatly improve the execution speed. Right now, it's a cache for a file unit, but in the way of writing a sentence, it's basically written from top to bottom, so the sentence until halfway through doesn't change much. Also, many of the rules of text print are handled by paragraphs, so there's a lot of possibility that there's no dependency between paragraphs. Considering this situation, by having a cache for each paragraph, you might be able to print only the part that's been added. As a condition, you need to have the ability to isolate each paragraph by the rules definitions.

export default function(context) {
  const { Syntax } = context;
  return {
    [Syntax.ParagraphIsolated](node){
      // this result is cacheable
    }
  };
}

@azu azu removed the Status: PR Welcome Welcome to Pull Request label Feb 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Proposal Request for comments
Projects
None yet
Development

No branches or pull requests

1 participant