CoffeeLint's rule management system allows developers to extend the linter with custom rules and access the complete set of built-in rules. The system provides both programmatic rule registration and dynamic rule loading capabilities.
Register custom linting rules that integrate seamlessly with the CoffeeLint engine.
/**
* Register a new linting rule
* @param RuleConstructor - Constructor function for the rule
* @param ruleName - Optional override name for the rule (uses rule.name if not provided)
*/
function registerRule(RuleConstructor, ruleName);Usage Example:
const coffeelint = require('coffeelint');
// Define a custom rule
function NoConsoleRule() {
return {
rule: {
name: 'no_console',
level: 'warn',
message: 'Console statements should not be used in production',
description: 'Prohibits the use of console.log and related methods'
},
lintToken: function(token, tokenApi) {
if (token[0] === 'IDENTIFIER' && token[1] === 'console') {
return {
level: this.rule.level,
message: this.rule.message
};
}
}
};
}
// Register the rule
coffeelint.registerRule(NoConsoleRule);
// Use the rule in configuration
const config = {
'no_console': {
'level': 'error'
}
};
const source = `
console.log "This will trigger our custom rule"
`;
const errors = coffeelint.lint(source, config);
console.log(errors); // Will include our custom rule violationAccess the complete collection of built-in linting rules and their definitions.
/**
* Object containing all rule definitions keyed by rule name
*/
const RULES: { [ruleName: string]: RuleDefinition };Usage Example:
const coffeelint = require('coffeelint');
// Access all built-in rules
console.log('Built-in rules:');
Object.keys(coffeelint.RULES).forEach(ruleName => {
const rule = coffeelint.RULES[ruleName];
console.log(`${ruleName}: ${rule.description}`);
});
// Check if a specific rule exists
if (coffeelint.RULES['max_line_length']) {
const rule = coffeelint.RULES['max_line_length'];
console.log(`Max line length default: ${rule.value} characters`);
console.log(`Current level: ${rule.level}`);
}
// Get rule configuration for custom config generation
const customConfig = {};
Object.keys(coffeelint.RULES).forEach(ruleName => {
const rule = coffeelint.RULES[ruleName];
if (rule.level === 'ignore') {
customConfig[ruleName] = { level: 'warn' };
}
});The rule system also supports loading external rules from npm modules or local files through the configuration system.
Configuration-based Rule Loading:
// In your coffeelint configuration
const config = {
// Standard rule configuration
'max_line_length': {
'level': 'error',
'value': 80
},
// Global configuration for external rule loading
'coffeelint': {
'transforms': ['coffeelint-no-semicolons', './custom-rules/my-rule.js']
}
};
const errors = coffeelint.lint(source, config);Custom rules must follow a specific structure to integrate with the CoffeeLint engine:
/**
* Rule constructor function structure
*/
interface RuleConstructor {
(): {
/** Rule metadata and configuration */
rule: RuleDefinition;
/** Optional: Lint individual tokens */
lintToken?: (token: any, tokenApi: any) => LintViolation | null;
/** Optional: Lint individual lines */
lintLine?: (line: string, lineApi: any) => LintViolation | null;
/** Optional: Lint AST nodes */
lintAST?: (node: any, astApi: any) => LintViolation | null;
/** Optional: Specify token types to examine */
tokens?: string[];
};
}
/**
* Lint violation returned by rule methods
*/
interface LintViolation {
/** Error level for this specific violation */
level: 'error' | 'warn' | 'ignore';
/** Custom message for this violation */
message: string;
/** Optional context information */
context?: string;
/** Optional line number override */
lineNumber?: number;
}
/**
* Extended rule definition with configuration options
*/
interface RuleDefinition {
/** Unique rule name */
name: string;
/** Default severity level */
level: 'error' | 'warn' | 'ignore';
/** Default error message */
message: string;
/** Human-readable rule description */
description: string;
/** Rule-specific options (varies by rule) */
[option: string]: any;
}The built-in rules cover several categories of style and code quality checks:
Style Rules:
arrow_spacing - Spacing around arrow functionsbraces_spacing - Spacing inside object bracescolon_assignment_spacing - Spacing around colon assignmentsspace_operators - Spacing around operatorsspacing_after_comma - Spacing after commasIndentation and Whitespace:
indentation - Consistent indentationno_tabs - Forbid tab charactersno_trailing_whitespace - No trailing whitespaceline_endings - Consistent line endingseol_last - File must end with newlineCode Quality:
cyclomatic_complexity - Limit function complexitymax_line_length - Maximum line lengthno_debugger - No debugger statementsno_empty_functions - No empty function definitionsduplicate_key - No duplicate object keysLanguage Features:
no_backticks - No JavaScript backticksno_implicit_braces - Explicit object bracesno_implicit_parens - Explicit function parenthesesno_plusplus - No ++ or -- operatorsprefer_english_operator - Use 'and', 'or', 'not' instead of &&, ||, !Each rule can be individually configured with custom levels, messages, and rule-specific options.