fimbullinter / wotan

Pluggable TypeScript and JavaScript linter
Apache License 2.0
281 stars 23 forks source link

Allow aliases for rules (with configuration) #5

Closed ajafff closed 6 years ago

ajafff commented 6 years ago

Add an optional field alias per rule. This allows you to use a rule with a specific configuration under another name. That name is then used for error reporting, disable comments and extending configs.

This enables extending rules like ESLint's no-resticted-syntax. Normally extending this rule overrides all config options defined in the base config. This is not really the desired behavior. Now you can create an alias for a specific rule configuration. By overriding the original rule, you don't alter the alias. By overriding the alias, you don't alter the original rule's config.

How it used to be:

# bad/base.yaml
rules:
  no-restricted-syntax:
    - error
    - WithStatement
# bad/extending.yaml
extends: ./bad/base.yaml
rules:
  no-restricted-syntax:
    - error
    - DeleteExpression
    - WithStatement # the base config is completely overridden, so we need to specify WithStatement here again

Adding to the existing config is very cumbersome. Even worse: if you extend a shareable config, you don't necessarily (want to) know the base config.

How it can be improved:

# good/base.yaml
rules:
  ban-with-statement: # same as above, but introduces an alias
    severity: error
    options: WithStatement
    alias: no-restricted-syntax
# good/extending.yaml
extends: ./good/base.yaml
rules:
  ban-delete-expression: # Introduces another name
    severity: error
    options: DeleteExpression
    alias: no-restricted-syntax

Using aliases configures no-restricted-syntax twice, indenpendently. You can even disable one of them without interfering with the other.

The good parts:

The bad parts:

TBD

ajafff commented 6 years ago

Regarding the open design decisions:

Updated example:

# base.yaml
aliases:
  my:
    ban-with-statement:
      options: WithStatement
      rule: no-restricted-syntax
rules:
  my/ban-with-statement: error
# extending.yaml
extends: ./base.yaml
aliases:
  my:
    ban-delete-expression:
      options: DeleteExpression
      rule: no-restricted-syntax
rules:
  my/ban-delete-expression: error
ajafff commented 6 years ago

aliases can shadow custom rules ~and custom rules can shadow aliases~

If there is an alias in scope, it is always preferred. You can explicitly reset aliases by setting it to a falsy value.

# child.yaml
extends: ./extending.yaml
rulesDirectories:
  my: ./rules
aliases:
  my:
    ban-with-statement: # clear alias
rules:
  my/ban-with-statement: # use rule from rulesDirectory

The example above clears the alias. It also needs to explicitly list the rule again. Otherwise it will still reference the alias as this was the valid reference where the rule was enabled in the base config. This allows the rule to be loaded from the corresponding rulesDirectory