Diviner Phabricator User Docs Arcanist User Guide: Customizing Existing Linters

Arcanist User Guide: Customizing Existing Linters
Phabricator User Documentation (Application User Guides)

Explains how to customize existing linters.

This is a configuration guide that helps you set up advanced features. If you're just getting started, you don't need to look at this yet. Instead, start with the Arcanist User Guide.

This guide explains how to refine lint behavior. To configure lint in the first place, see Arcanist User Guide: Configuring a New Project and Arcanist User Guide: Lint.

Overview

Arcanist ships with a number of linters which you may want to reuse in whole or in part in other projects. This document explains how to customize existing linters for use in new engines.

First, you should set up an engine by following the instructions in Arcanist User Guide: Lint and possibly Arcanist User Guide: Customizing Lint, Unit Tests and Workflows. Then, follow this guide to customize linters.

General Guidelines

You should customize linters by configuring or composing them, not by extending them -- their implementations are not necessarily stable. If a linter's configuration options aren't flexible enough to meet your needs, sending a patch which improves its configurability is better than one that makes it nonfinal.

Changing Rule Severities

By default, most linters raise lint messages as errors. You may want to reduce the severity of some messages (e.g., reduce errors to warnings). Do this by calling setCustomSeverityMap():

$linter = new ArcanistTextLinter();

// Change "missing newline at end of file" message from error to warning.
$linter->setCustomSeverityMap(
  array(
    ArcanistTextLinter::LINT_EOF_NEWLINE
      => ArcanistLintSeverity::SEVERITY_WARNING,
  ));

See ArcanistLintSeverity for a list of available severity constants.

Disabling Rules

To disable rules entirely, set their severities to SEVERITY_DISABLED:

$linter = new ArcanistTextLinter();

// Disable "Tab Literal" message.
$linter->setCustomSeverityMap(
  array(
    ArcanistTextLinter::LINT_TAB_LITERAL
      => ArcanistLintSeverity::SEVERITY_DISABLED,
  ));

Running Multiple Rulesets

If you want to run the same linter on different types of files but vary the configuration based on the file type, just instantiate it twice and configure each instance appropriately. For instance, this will enforce different column widths on different languages:

$linters = array();

// Warn on JS/CSS lines longer than 80 columns.
$linters['TextLinter80Col'] = id(new ArcanistTextLinter())
  ->setPaths(preg_grep('/\.(js|css)$/', $paths));

// Warn on Java lines longer than 120 columns.
$linters['TextLinter120Col'] = id(new ArcanistTextLinter())
  ->setMaxLineLength(120)
  ->setPaths(preg_grep('/\.(java)$/', $paths));

// ...

return $linters;

Customizing Specific Linters

Some linters are specifically customizable or configurable. Some common options are documented here, consult class documentation for complete information.

ArcanistTextLinter

  • Use setMaxLineLength() to change the 80-column warning to something else.

ArcanistXHPASTLinter

  • Use lint.xhpast.naminghook in .arcconfig to override naming convention rules. See ArcanistXHPASTLintNamingHook for details.
  • Use getXHPASTTreeForPath() to reuse the AAST in other linters.