CoffeeLint is a style checker that helps keep CoffeeScript code clean and consistent. CoffeeScript does a great job at insulating programmers from many of JavaScript's bad parts, but it won't help enforce a consistent style across a code base. CoffeeLint can help with that.
If you have an idea, a bug report or anything else to say, reach out on the issues page.
To install, make sure you have a working version of the latest stable version of Node and NPM (the Node Package Manager) and then run:
npm install -g @coffeelint/cli
Remove the
-gif you do not want to install globally.
Once you have Coffeelint installed, to lint your scripts, run:
coffeelint application.coffee
To specify your own configuration file, do the following:
coffeelint -f coffeelint.json application.coffee
If any errors were found, a non-zero code will be returned.
To generate a configuration file, do
coffeelint --makeconfig > coffeelint.json
You can then configure the rules to your liking.
New in 1.0: CoffeeLint will automatically pick up config files. When linting a file (as opposed to stdin) it will walk up the directory tree looking for a coffeelint.json or a package.json that has a "coffeelintConfig" object. If neither of those are found or you're linting from stdin it will check your home for a coffeelint.json file.
By default, CoffeeLint will help ensure you are writing idiomatic CoffeeScript, but every rule is optional and configurable so it can be tuned to fit your preferred coding style. To override any of CoffeeLint's default options, generate a configuration file and tweak it as needed. To enable an option, set its level to
error, and to disable an option, set its level to
ignore. If you set the level to
warn, violations will be reported, but won't cause a non-zero exit code.
To disable a rule inline use the following:
# coffeelint: disable=max_line_length
foo = "some/huge/line/string/with/embed/#{values}.that/surpasses/the/max/column/width"
# coffeelint: enable=max_line_length
You can also disable all checks for a single line by appending
# noqaat the end of the line:
throw "I should be an Error not a string but YOLO" # noqa
Here's a rundown of CoffeeLint's rules:
| Name | Description |
|---|---|
| arrow_spacing |
This rule checks to see that there is spacing before and after the arrow operator that declares a function. This rule is disabled by default. Note that if arrow_spacing is enabled, and you pass an empty function as a parameter, arrow_spacing will accept either a space or no space in-between the arrow operator and the parenthesis
default level: ignore |
| braces_spacing |
This rule checks to see that there is the proper spacing inside
curly braces. The spacing amount is specified by "spaces".
The spacing amount for empty objects is specified by
"empty_object_spaces".
The spacing amount for objects containing a single item is
specified by "mono_object_spaces".
This rule is disabled by default.
default level: ignore |
| bracket_spacing |
This rule checks to see that there is the proper spacing inside
square brackets. The spacing amount is specified by "spaces".
The spacing amount for empty arrays is specified by
"empty_array_spaces".
The spacing amount for arrays containing a single item is
specified by "mono_array_spaces".
Specified characters will be ignored if listed in "exceptions".
This rule is disabled by default.
default level: ignore |
| camel_case_classes |
This rule mandates that all class names are UpperCamelCased.
Camel casing class names is a generally accepted way of
distinguishing constructor functions - which require the 'new'
prefix to behave properly - from plain old functions.
This rule is enabled by default.
default level: error |
| coffeescript_error |
[no description provided]
default level: error |
| colon_assignment_spacing |
This rule checks to see that there is spacing before and after the colon in a colon assignment (i.e., classes, objects). The spacing amount is specified by spacing.left and spacing.right, respectively. A zero value means no spacing required.
default level: ignore |
| cyclomatic_complexity |
Examine the complexity of your function.
default level: ignore |
| duplicate_key |
Prevents defining duplicate keys in object literals and classes
default level: error |
| empty_constructor_needs_parens |
Requires constructors with no parameters to include the parens
default level: ignore |
| ensure_comprehensions |
This rule makes sure that parentheses are around comprehensions.
default level: warn |
| eol_last |
Checks that the file ends with a single newline
default level: ignore |
| indentation |
This rule imposes a standard number of spaces(tabs) to be used for
indentation. Since whitespace is significant in CoffeeScript, it's
critical that a project chooses a standard indentation format and
stays consistent. Other roads lead to darkness.
Two space indentation is enabled by default.
default level: error |
| line_endings |
This rule ensures your project uses only windows or
unix line endings. This rule is disabled by default.
default level: ignore |
| max_line_length |
This rule imposes a maximum line length on your code. Python's style
guide does a good job explaining why you might want to limit the
length of your lines, though this is a matter of taste.
Lines can be no longer than eighty characters by default.
default level: error |
| missing_fat_arrows |
Warns when you use `this` inside a function that wasn't defined
with a fat arrow. This rule does not apply to methods defined in a
class, since they have `this` bound to the class instance (or the
class itself, for class methods). The option `is_strict` is
available for checking bindings of class methods.
It is impossible to statically determine whether a function using
`this` will be bound with the correct `this` value due to language
features like `Function.prototype.call` and
`Function.prototype.bind`, so this rule may produce false positives.
default level: ignore |
| missing_parseint_radix |
This rule warns about using parseInt without a radix. From the MDN
developers reference: Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.
default level: warn |
| newlines_after_classes |
Checks the number of blank lines between classes and other code. Options: - - The number of required blank lines
after class definitions. Defaults to 3.
default level: ignore |
| no_backticks |
Backticks allow snippets of JavaScript to be embedded in
CoffeeScript. While some folks consider backticks useful in a few
niche circumstances, they should be avoided because so none of
JavaScript's "bad parts", like with and eval,
sneak into CoffeeScript.
This rule is enabled by default.
default level: error |
| no_debugger |
This rule detects `debugger` and optionally `console` calls
This rule is `warn` by default.
default level: warn |
| no_empty_functions |
Disallows declaring empty functions. The goal of this rule is that
unintentional empty callbacks can be detected:
The problem is that the call to
doSomethingSignificant will be made regardless
of someFunctionWithCallback's execution. It can
be because you did not indent the call to
doSomethingSignificant properly.
If you really meant that someFunctionWithCallback
should call a callback that does nothing, you can write your code
this way:
default level: ignore |
| no_empty_param_list |
This rule prohibits empty parameter lists in function definitions.
Empty parameter lists are permitted by default.
default level: ignore |
| no_implicit_braces |
This rule prohibits implicit braces when declaring object literals.
Implicit braces can make code more difficult to understand,
especially when used in combination with optional parenthesis.
Implicit braces are permitted by default, since their use is
idiomatic CoffeeScript.
default level: ignore |
| no_implicit_parens |
This rule prohibits implicit parens on function calls.
Implicit parens are permitted by default, since their use is
idiomatic CoffeeScript.
default level: ignore |
| no_interpolation_in_single_quotes |
This rule prohibits string interpolation in a single quoted string.
String interpolation in single quoted strings is permitted by
default.
default level: ignore |
| no_nested_string_interpolation |
This rule warns about nested string interpolation,
as it tends to make code harder to read and understand.
default level: warn |
| no_plusplus |
This rule forbids the increment and decrement arithmetic operators.
Some people believe the ++ and -- to be cryptic
and the cause of bugs due to misunderstandings of their precedence
rules.
This rule is disabled by default.
default level: ignore |
| no_private_function_fat_arrows |
Warns when you use the fat arrow for a private function
inside a class definition scope. It is not necessary and
it does not do anything.
default level: warn |
| no_spaces |
This rule forbids spaces in indentation. It is disabled by default.
default level: ignore |
| no_stand_alone_at |
This rule checks that no stand alone @ are in use, they are
discouraged. Further information in CoffeeScript issue
#1601
default level: ignore |
| no_tabs |
This rule forbids tabs in indentation. Enough said. It is enabled by
default.
default level: error |
| no_this |
This rule prohibits 'this'.
Use '@' instead.
default level: ignore |
| no_throwing_strings |
This rule forbids throwing string literals or interpolations. While
JavaScript (and CoffeeScript by extension) allow any expression to
be thrown, it is best to only throw Error objects,
because they contain valuable debugging information like the stack
trace. Because of JavaScript's dynamic nature, CoffeeLint cannot
ensure you are always throwing instances of Error. It will
only catch the simple but real case of throwing literal strings.
This rule is enabled by default.
default level: error |
| no_trailing_semicolons |
This rule prohibits trailing semicolons, since they are needless
cruft in CoffeeScript.
Trailing semicolons are forbidden by default.
default level: error |
| no_trailing_whitespace |
This rule forbids trailing whitespace in your code, since it is
needless cruft. It is enabled by default.
default level: error |
| no_unnecessary_double_quotes |
This rule prohibits double quotes unless string interpolation is
used or the string contains single quotes.
Double quotes are permitted by default.
default level: ignore |
| no_unnecessary_fat_arrows |
Disallows defining functions with fat arrows when `this`
is not used within the function.
default level: warn |
| non_empty_constructor_needs_parens |
Requires constructors with parameters to include the parens
default level: ignore |
| object_shorthand |
Use property value shorthand in objects, when explicit braces are used.
default level: ignore |
| prefer_english_operator |
This rule prohibits &&, ||, ==, != and !.
Use and, or, is, isnt, and not instead.
!! for converting to a boolean is ignored.
default level: ignore |
| prefer_fat_arrows_in_methods |
Warns when you do not use a fat arrow for functions defined inside
method bodies. This assures that `this` is always bound to the
method's object inside the code block of a method.
default level: ignore |
| prefer_logical_operator |
This rule prohibits is, isnt, not, and, or, yes, on, no, off.
Use ==, !=, !, &&, ||, true, false instead.
default level: ignore |
| space_operators |
This rule enforces that operators have space around them.
Optionally, you can set `default_parameters` to `false` to
require no space around `=` when used to define default paramaters.
default level: ignore |
| spacing_after_comma |
This rule checks to make sure you have a space after commas.
Consecutive commas are allowed when skipping array elements
if "ignore_elision" is true.
default level: ignore |
| transform_messes_up_line_numbers |
This rule detects when changes are made by transform function,
and warns that line numbers are probably incorrect.
default level: warn |
If you'd like to run CoffeeScript in the browser or any other Javascript runtime, include coffee-script.js and coffeelint.js and you're off to the races. Then you can call CoffeeLint directly with the following API:
Lints the CoffeeScript source with the given configuration and returns an array of lint errors and warnings. If the array is empty, all is well. Compile time errors will be thrown. An error is a Javascript object with the following properties:
{
rule : 'Name of the violated rule',
lineNumber: 'Number of the line that caused the violation',
level: 'The severity level of the violated rule',
message: 'Information about the violated rule',
context: 'Optional details about why the rule was violated'
}
Registers a custom rule that may be run by CoffeeLint. If the rule is ignored by default it will still require overriding it's level just like the default rules. They have actually all be re-implemented as pluggable rules that come bundled in CoffeeLint.
Not every possible rule will be included in the CoffeeLint project. Maybe it's very specific to your project, or it's not specific to CoffeeScript.
By convention rule authors add the keyword
coffeelintruleto their npm package.json so custom rules can be found easily. Click here to list all currently available custom rules on npm.
For example, maybe you want to get a warning if you don't have a newline at the end of your files. We'll imagine you globally installed the package "coffeelint-newline-eof".
{
// This name MUST match the default configuration of the rule being loaded.
"newline_at_eof": {
// NodeJS module to load. It can also be a path to the rule (useful for devleopment)
"module": "coffeelint-newline-at-eof",
// Maybe the rule author set it to error by default and you only want a warning.
"level": "warn"
}
}
Now every time you run CoffeeLint it will load that rule and override it's default level to "warn".
CoffeeLint has three types of linters that run. In no particular order they are.
Rules may be loaded using
--rules /path/to/rules/
or
coffeelint.registerRule(RuleConstructor)
when outside of the CLI.
Rules do not have to be written in CoffeeScript. A new instance of each rule is constructed for each file, so the RuleConstructor must be a constructor function that generates a new clean instance of your rule when the new operator is used.
Your rule instance must have a .rule attribute with it's default configuration. "name", "level" "message", and "description" are all required. "level" must be one of 'ignore', 'warn', or 'error'. Once you have a valid rule configuration CoffeeLint requires you to implement one function depending on which type of linter your rule needs.
lintLine(line, lineApi)
lintToken(token, tokenApi)
lintAST(ast, astApi)
The second parameter of each is an object with helper functions. It's best to just check the source or look at how other plugins are using those.
If your function returns true it will generate an error. If you need to override how the error is generated, maybe providing a context attribute, you can return an object that will get mixed into the generated error. The No_PlusPlus rule is a simple example of this.
The core rules have been rewritten as stand alone rules both to prove the system and provide examples of how to write rules. To get started no_plusplus is a Token rule, no_tabs is a Line rule, and cyclomatic_complexity is an AST rule.
The
--rulesoption will load every .js or .coffee file it finds and assume they export the RuleConstructor. Since the browser doesn't have a standard export system it's up to you to determine how you'll load your plugin and register it with
coffeelint.registerRuleSome nice folks have coded up some cool CoffeeLint plugins for editors and build systems. Check them out:
CoffeeLint is open sourced under the MIT License. If you want to hack on the code, report a bug or suggest a new feature, head on over to the repo.
Thanks to CoffeeScript's developers for a great language (and a re-usable Lexer). Thanks to the creators of JSLint, JSHint, Pylint, lint and my mother for inspiration.
Add prefer_fat_arrows_in_methods rule.
Fix newlines_after_classes when there are blank lines before last line in class.
Update coffeescript dependency to v2.5.1.
Update commandline dependency to maintained dependency.
First 1.x release under new npm package; to use: npm install -g @coffeelint/cli@old
Added a few rules and rules options. More bug fixes and internal updates to make developing easier. We got through the backlog of pull requests. Now on to the issues...
prefer_logical_operator rule. #13missing_parseint_radix rule. #17bracket_spacing rule. #26space_operators: add default_parameters option. #16colon_assignment_spacing: add min_left and min_right option. #22spacing_after_comma: add ignore_elision option. #34braces_spacing: add mono_object_spaces option. #17csv reporter. #14checkstyle reporter. #12no_tabs rejects tabs at the end of the line. #20resolve to v1.15.1small fixes
resolve to v1.15.0CoffeeLint has a new webpage at https://coffeelint.github.io
CoffeeLint has a new home at https://github.com/coffeelint/coffeelint and a new npm package @coffeelint/cli.
duplicate_key when keys are wrapped in quotes. #6no_spaces rule to disallow spaces for indentation. #7This version updates the enable/disable directives. In addition to
the existing # coffeelint: disable=rule_name you can also
use # coffeelint: disable-line=rule_name. The rule name is
still optional in both cases, and you can enable the rules using
the same syntax.
You can also use # noqa as a shortcut for # coffeelint: disable-line
Most of the changes are more for linting the development files of coffeelint. The minor version increase is due to the change in cyclomatic_complexity, which now ignores nested functions. I foresee this change affecting very few people but probably still needs a minor version increase.
cyclomatic_complexity rule has been changed to ignore nested functionsThe v1.12.x versions are considered buggy and you should upgrade to v1.13.x if you experience problems
These releases were largely for bugfixes!
no_implicit_braces causing errors in classes and other edge casesensure_comprehensions where it failed if a nested loop had an equal signbraces_spacing failing over generated curly bracesindentation See bffa25 for the full list of changes. However between the release of v1.12.0 and v1.13.0, a regression was caused by fixing one of the indentation requests and as a result the change was reverted. The revert will most likely not affect too many usersnewlines_after_classes, also fixed regressions caused between v1.12.0 and v1.13.0. If you have v1.12.x and are experiencing problems, please upgrade. Also note nested classes are now ignored completelyno_this is now compatible with no_stand_alone_at and will make checks against singular thismissing_fat_arrows, declaring a class prototype (via '::' operator) no longer fail if they don't use a fat arroweol_last, it now fails if there are multiple newlines at the end of a file (thanks charlierudolph)-arrow_spacing, now ignores arrow spacing in empty functions (thanks sgentle){ "extends": "coffeelint-config-myconfig" } based on eslint's shareable configsno_nested_string_interpolationno_private_function_fat_arrows--ext to specify alternate file extensions to checkNew option --trimconfig. shows the minimal config to implement your customizations.
New rule eol_last
New rule no_this (prefer @ instead)
New option in no_debugger to flag console calls
Many small bug fixes
arrow_spacingno_implicit_braces error in class declarationsbraces_paddingensure_comprehensions (warn by default)transform_messes_up_line_numbers. This simply tells you if a transform you're using changes the total number of lines in the file.spacing_after_comma so that newlines count as space after commasspacing_after_commano_unnecessary_double_quotesprefer_english_operator.coffeelintignore works just like a .gitignoreErrorReporter to 3rd parties so reporters can be used outside our CLI implementation. See #330 for details-f option can specify a package.json that contains coffeelintConfig--no-color in favor of new --color=<always/never/auto> optionspace_operatorsno_implicit_parensno_unnecessary_fat_arrows doesn't trigger if the function contains super.no_empty_functionsno_debuggerno_interpolation_in_single_quotesno_unnecessary_double_quotesno_implicit_parens. Turning it off allows implicit parens when they span multiple lines.colon_assignment_spacingno_unnecessary_fat_arrowsmissing_fat_arrowsno_trailing_whitespace to forbid trailing space on empty linesno_implicit_braces to allow unambiguous implicit bracesnon_empty_constructor_needs_parens for namespaced constructorsspace_operators(https://github.com/clutchski/coffeelint/issues/137)no_empty_param_list rule.--makeconfig option.no_stand_alone_at (https://github.com/jashkenas/coffee-script/issues/1601)arrow_spacing rule (require spaces around arrows)empty_constructor_needs_parensnon_empty_constructor_needs_parensduplicate_key (https://jslinterrors.com/duplicate-key-a/)no_trailing_whitespace.allowed_in_comments rule option (Allow trailing space in comments. Created to allow markdown)newlines_after_classes ruleCOFFEELINT_CONFIG.no_stand_alone_at rule.--nocolor option.-q option was suppressing information even when it was off.jslint option.no_trailing_semicolons rule now works on Windows files.-q command line option, which only prints errors.--stdin option, thanks to sjz.no_implicit_parens rule.--jslint reporter, to allow CoffeeLint to integrate with the Jenkin's violations plugin.line endings rule.no_backticks rule.