-
-
Notifications
You must be signed in to change notification settings - Fork 714
Description
I think this was covered slightly by #6050, but may have been missed as being within scope of the problem.
no-unused-vars, for example, has various options available. But the page for the rule makes no mention of them.
The same is true with max-classes-per-file, which has options for ignoreExpressions and max, but no mention of that in the documentation.
It might be good to enforce this somehow via a check, but I'm not really familiar enough with rust to say how.
Here's a script to get all rules without the autogenerated config set up, but that do have configuration options:
Script for finding lint rules with options but no autogen config
#!/usr/bin/env node
// Find eslint rule files that have from_configuration
// but no "config =" in declare_oxc_lint!
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const RULES_DIR = path.join(__dirname, 'crates/oxc_linter/src/rules');
function scanDirectory(dir) {
const files = fs.readdirSync(dir, { withFileTypes: true });
const results = [];
for (const file of files) {
const fullPath = path.join(dir, file.name);
if (file.isDirectory()) {
// Recursively scan subdirectories
results.push(...scanDirectory(fullPath));
} else if (file.isFile() && file.name.endsWith('.rs')) {
const content = fs.readFileSync(fullPath, 'utf8');
const hasDeclareLint = content.includes('declare_oxc_lint!(');
const hasFromConfig = content.includes('fn from_configuration(');
const hasConfigParam = (/^\s*config\s*=\s/m).test(content);
if (hasDeclareLint && hasFromConfig && !hasConfigParam) {
results.push(path.relative(__dirname, fullPath));
}
}
}
return results;
}
const missingFiles = scanDirectory(RULES_DIR);
if (missingFiles.length === 0) {
console.log('No files found missing config parameter.');
} else {
// Group by plugin (first directory under crates/oxc_linter/src/rules)
const groups = new Map();
// Normalize, compute path relative to RULES_DIR, and bucket by plugin
missingFiles.sort().forEach(file => {
const absPath = path.join(__dirname, file);
const relToRules = path.relative(RULES_DIR, absPath);
const parts = relToRules.split(path.sep);
const plugin = parts[0] || 'unknown';
if (!groups.has(plugin)) groups.set(plugin, []);
groups.get(plugin).push(relToRules);
});
console.log('Files with declare_oxc_lint! and from_configuration but missing "config =" (grouped by plugin):');
console.log('');
// Print per-plugin breakdown (alphabetical), with sorted file lists
const pluginNames = Array.from(groups.keys()).sort();
for (const plugin of pluginNames) {
const files = groups.get(plugin).sort();
console.log(`${plugin} (${files.length})`);
for (const f of files) {
console.log(`- [ ] ${f}`);
}
console.log('');
}
const pluginCount = pluginNames.length;
console.log(`Total: ${missingFiles.length} files across ${pluginCount} plugin${pluginCount === 1 ? '' : 's'}`);
}This is not going to be perfect, but it works pretty well. It is absolutely possible that a rule would have config = but no doc comments for each option, and so wouldn't really be complete. That case would be missed entirely by this script.
Current list of rules that need to be updated (155 files):
-
eslint/class_methods_use_this.rs -
eslint/curly.rs -
eslint/getter_return.rs -
eslint/grouped_accessor_pairs.rs -
eslint/id_length.rs -
eslint/init_declarations.rs -
eslint/max_lines.rs -
eslint/max_lines_per_function.rs -
eslint/max_nested_callbacks.rs -
eslint/max_params.rs -
eslint/no_bitwise.rs -
eslint/no_console.rs -
eslint/no_constant_condition.rs -
eslint/no_duplicate_imports.rs -
eslint/no_empty.rs -
eslint/no_eval.rs -
eslint/no_extend_native.rs -
eslint/no_extra_boolean_cast.rs -
eslint/no_global_assign.rs -
eslint/no_inner_declarations.rs -
eslint/no_labels.rs -
eslint/no_magic_numbers.rs -
eslint/no_misleading_character_class.rs -
eslint/no_multi_assign.rs -
eslint/no_redeclare.rs -
eslint/no_return_assign.rs -
eslint/no_self_assign.rs -
eslint/no_undef.rs -
eslint/no_unneeded_ternary.rs -
eslint/no_unsafe_negation.rs -
eslint/no_unsafe_optional_chaining.rs -
eslint/no_useless_computed_key.rs -
eslint/no_useless_rename.rs -
eslint/operator_assignment.rs -
eslint/prefer_destructuring.rs -
eslint/prefer_promise_reject_errors.rs -
eslint/radix.rs -
eslint/sort_imports.rs -
eslint/sort_keys.rs -
eslint/sort_vars.rs -
eslint/unicode_bom.rs -
import/consistent_type_specifier_style.rs -
import/extensions.rs -
import/first.rs -
import/max_dependencies.rs -
import/no_absolute_path.rs -
import/no_commonjs.rs -
import/no_cycle.rs -
import/no_duplicates.rs -
import/no_dynamic_require.rs -
import/no_namespace.rs -
import/prefer_default_export.rs -
jest/expect_expect.rs -
jest/no_large_snapshots.rs -
jest/no_restricted_jest_methods.rs -
jest/no_restricted_matchers.rs -
jest/no_standalone_expect/mod.rs -
jest/prefer_lowercase_title/mod.rs -
jest/valid_expect.rs -
jsdoc/check_tag_names.rs -
jsdoc/empty_tags.rs -
jsdoc/no_defaults.rs -
jsdoc/require_yields.rs -
jsx_a11y/alt_text.rs -
jsx_a11y/anchor_ambiguous_text.rs -
jsx_a11y/anchor_is_valid.rs -
jsx_a11y/aria_role.rs -
jsx_a11y/autocomplete_valid.rs -
jsx_a11y/heading_has_content.rs -
jsx_a11y/img_redundant_alt.rs -
jsx_a11y/label_has_associated_control.rs -
jsx_a11y/media_has_caption.rs -
jsx_a11y/mouse_events_have_key_events.rs -
jsx_a11y/no_autofocus.rs -
jsx_a11y/no_noninteractive_tabindex.rs -
oxc/no_optional_chaining.rs -
oxc/no_rest_spread_properties.rs -
promise/always_return.rs -
promise/catch_or_return.rs -
promise/no_callback_in_promise.rs -
promise/no_return_wrap.rs -
promise/prefer_await_to_then.rs -
promise/spec_only.rs -
react/button_has_type.rs -
react/checked_requires_onchange_or_readonly.rs -
react/exhaustive_deps.rs -
react/jsx_boolean_value.rs -
react/jsx_curly_brace_presence.rs -
react/jsx_filename_extension.rs -
react/jsx_fragments.rs -
react/jsx_no_script_url.rs -
react/jsx_no_target_blank.rs -
react/jsx_no_useless_fragment.rs -
react/jsx_pascal_case.rs -
react/no_string_refs.rs -
react/no_unknown_property.rs -
react/only_export_components.rs -
react/self_closing_comp.rs -
react/style_prop_object.rs -
typescript/array_type.rs -
typescript/consistent_generic_constructors.rs -
typescript/consistent_indexed_object_style.rs -
typescript/consistent_type_definitions.rs -
typescript/explicit_function_return_type.rs -
typescript/explicit_module_boundary_types.rs -
typescript/no_empty_interface.rs -
typescript/no_empty_object_type.rs -
typescript/no_explicit_any.rs -
typescript/no_extraneous_class.rs -
typescript/no_inferrable_types.rs -
typescript/no_namespace.rs -
typescript/no_require_imports.rs -
typescript/no_this_alias.rs -
typescript/prefer_literal_enum_member.rs -
typescript/triple_slash_reference.rs -
unicorn/explicit_length_check.rs -
unicorn/no_array_reduce.rs -
unicorn/no_array_reverse.rs -
unicorn/no_instanceof_builtins.rs -
unicorn/no_null.rs -
unicorn/no_typeof_undefined.rs -
unicorn/no_useless_promise_resolve_reject.rs -
unicorn/no_useless_undefined.rs -
unicorn/numeric_separators_style.rs -
unicorn/prefer_at.rs -
unicorn/prefer_number_properties.rs -
unicorn/prefer_object_from_entries.rs -
unicorn/prefer_structured_clone.rs -
eslint/arrow_body_style.rs -
eslint/default_case.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
eslint/func_names.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078) -
eslint/new_cap.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
eslint/no_cond_assign.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078) -
eslint/no_else_return.rs -
eslint/no_empty_function.rs -
eslint/no_fallthrough.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
eslint/no_restricted_globals.rs -
eslint/no_restricted_imports.rs -
eslint/no_warning_comments.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
eslint/yoda.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078) -
jest/consistent_test_it.rs -
jest/valid_title.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
jsdoc/require_param.rs -
jsdoc/require_returns.rs -
promise/param_names.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
react/forbid_dom_props.rs -
react/forbid_elements.rs -
react/jsx_handler_names.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
react/prefer_es6_class.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078) -
typescript/ban_ts_comment.rs -
typescript/consistent_type_imports.rs -
unicorn/catch_error_name.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
unicorn/filename_case.rs(not doable yet, due to lazy_regex Linter: Regex serialization for JsonSchema #15203) -
unicorn/switch_case_braces.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078) -
vue/define_emits_declaration.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078) -
vue/define_props_declaration.rs(not doable yet, due to using a string-only argument linter: Improve config generation for website to support string-based configs #15078)
If you use Copilot or a similar tool, you can also use this prompt file that I have put together. It works fairly well with VS Code + GitHub Copilot, if you have access to it. You can use "Run Prompt" in the command palette to create a prompt file and then run it.