A collection of custom Arcanist linters

Overview

Arcanist Linters

This is a collection of custom Arcanist linters that we've written at Pinterest.

We also welcome additional contributions.

Linters

Apache Thrift

Lints for errors in Apache Thrift IDL (schema) files using the thrift compiler.

{
    "type": "thrift",
    "include": "(\\.thrift$)",
    "flags": [
        "--allow-64bit-consts"
    ],
    "version": ">= 0.9.0",
    "thrift.generators": [
        "py:dynamic,utf8strings,new_style,slots",
        "java",
        "go",
        "erl"
    ],
    "thrift.includes": [
        ".",
        "common"
    ]
}

Apache Thrift Generated

Lints files generated by the Apache Thrift compiler to ensure they were generated using a supported Thrift compiler.

{
    "type": "thrift-gen",
    "include": "(^schemas/.*\\.py$)",
    "thrift-gen.version": ">=0.9.3"
}

Note: Currently only generated Python files are supported.

Black

Uses the Black opinionated code formatter to normalize the format of Python code.

{
    "type": "black",
    "include": "(\\.py$)",
    "flags": ["-S", "--line-length=132"]
}

Checkstyle

Uses the Checkstyle tool to check Java code against a coding standard.

{
    "type": "checkstyle",
    "include": "(\\.java$)",
    "checkstyle.config": "google_check.xml"
}

ESLint

Lints JavaScript and JSX files using ESLint.

{
    "type": "eslint",
    "include": "(\\.js$)",
    "bin": "./node_modules/.bin/eslint",
    "eslint.config": "~/my-eslint.json",
    "eslint.env": "browser,node"
}

Flake8

Lints Python source files using Flake8. This is an extended version of the stock ArcanistFlake8Linter that adds support for checking required Python and extension versions.

{
    "type": "flake8ext",
    "include": "(\\.py$)",
    "flake8.python": "< 3.0",
    "flake8.extensions": {
        "assertive": "1.0.1",
        "naming": "0.7.0"
    }
}

Flawfinder

Lints C/C++ source files using flawfinder.

{
    "type": "flawfinder",
    "include": "(\\.(c|cc|cpp|h)$)"
}

GraphQL Schema Linter

Lint GraphQL Schema Definition Language (SDL) using graphql-schema-linter.

{
    "type": "graphql-schema",
    "include": "(\\.(graphql|gql)$)",
    "graphql-schema.rules": [
        "fields-have-descriptions",
        "types-have-descriptions"
    ],
    "graphql-schema.config": "config",
    "graphql-schema.custom-rules": [
        "config/custom-rules/*.js",
        "vendor/extra-graphql-rules/*.js"
    ],
    "graphql-schema.ignore": {
        "fields-have-descriptions": [
            "Obvious",
            "Query.obvious",
            "Query.something.obvious"
        ]
    },
    "graphql-schema.comment-descriptions": false,
    "graphql-schema.old-implements-syntax": false
}

Go Vet

Uses the Go vet command to lint for suspicious code constructs.

{
    "type": "govet",
    "include": "(^src/example.com/.*\\.go$)"
}

OpenAPI Validator

Lint OpenAPI specifications using openapi-validator.

(Supports openapi-validator version 0.36.0 and later.)

{
    "type": "openapi-spec",
    "version": ">=0.36.0",
    "openapi-spec.config": ".validaterc",
    "openapi-spec.debug": false,
    "openapi-spec.errors_only": true,
    "include": [
        "(\\.yaml$)"
    ]
}

Prettier

Formats JavaScript using Prettier.

{
    "type": "prettier",
    "include": "(\\.js$)",
    "bin": "./node_modules/.bin/prettier",
    "prettier.cwd": "./"
}

Prettier ESLint

Formats JavaScript using Prettier and then fixes with ESLint.

{
    "type": "prettier-eslint",
    "include": "(\\.js$)",
    "bin": "./node_modules/.bin/prettier-eslint",
    "prettier-eslint.cwd": "./"
}

Python Imports

Lints for illegal Python module imports.

{
    "type": "python-imports",
    "python-imports.pattern": "(mock)",
    "include": "(\\.py$)",
    "exclude": "(^tests/)"
}

Python isort

Lints Python imports using isort.

{
    "type": "isort",
    "include": "(\\.py$)"
}

Pylint

Lints Python using pylint. Unlike the module that ships with Arcanist, this implementation works with recent releases of Pylint and also supports virtual environments.

{
    "type": "pinterest-pylint",
    "include": "(\\.py$)"
}

Pyright

Type-checks Python code using Pyright.

{
    "type": "pyright",
    "include": "(\\.py$)"
}

Python Requirements

Ensures Python package requirements in requirements.txt files are sorted, unique, and pinned to exact versions.

{
    "type": "requirements-txt",
    "include": "(requirements.txt$)"
}

Individual requirement lines can be excluded by adding a # noqa comment:

six>=1.10.0  # noqa: allow any recent version of six

Spectral

Lints OpenAPI documents using Spectral.

{
    "type": "spectral",
    "include": "(openapi.yaml)",
    "spectral.ruleset": ".spectral.yml",
}

ThriftCheck

Lints Thrift IDL files using ThriftCheck.

{
    "type": "thriftcheck",
    "include": "(\\.thrift$)",
    "thriftcheck.config": ".thriftcheck.toml",
    "thriftcheck.includes": [
        ".",
        "common"
    ]
}

YamlLinter

Lints YAML files using YamlLinter.

{
    "type": "yamllint",
    "include": "(\\.(yml|yaml)$)",
    "exclude": []
}

Installation

In short, you'll need to add this repository to your local machine and tell Arcanist to load the extension. You either can do this globally or on a per-project basis.

Once installed, the individual linters can be enabled and configured via the project's .arclint file. See the Arcanist Lint User Guide for details.

Global Installation

Arcanist can load modules from an absolute path, but because it also searches for modules one level up from itself on the filesystem, it's convenient to clone this repository at the same level as arcanist and libphutil.

$ git clone https://github.com/pinterest/arcanist-linters.git pinterest-linters
$ ls
arcanist
pinterest-linters
libphutil

Then, tell Arcanist to load the module by editing ~/.arcconfig (or /etc/arcconfig):

{
  "load": ["pinterest-linters"]
}

Project Installation

You can also load arcanist-linters on a per-project basis. In that case, using a git submodule is probably the most convenient approach.

$ git submodule add https://github.com/pinterest/arcanist-linters.git .pinterest-linters
$ git submodule update --init

Then, enable the module in your project-level .arcconfig file:

{
  "load": [".pinterest-linters"]
}
Comments
  • Some small fixes

    Some small fixes

    1. Prettier linter now doesn't show a warning for files that don't require any formatting changes (are already formatted)
    2. ESLintLinter and PrettierLinter now don't throw an error because of return status code 1
    3. Fix ESLinter failing because of missing source parameter in some of messages in eslint output
    opened by kuba-orlik 6
  • Add detect-secrets (open source repo from Yelp) to pinterest linters

    Add detect-secrets (open source repo from Yelp) to pinterest linters

    Yelp released an open source repo (https://github.com/Yelp/detect-secrets) which is used to detect potential secrets in code base. Adding this open source repo as part of pinterest linters will allow us to prevent users from committing secrets in Phabricator.

    opened by uditgpt5 4
  • Arc crashes on ESLint parse errors

    Arc crashes on ESLint parse errors

    ruleId comes out to be None for babel-eslint. I fixed by changing to $offense['ruleId'] || 'unknown'

    https://github.com/pinterest/arcanist-linters/blob/24c6667187f941dbe39c38efd5961f0a09b17f1b/src/ESLintLinter.php#L166

    bug 
    opened by michaelmwu 3
  • Revise the OpenAPI validator / linter

    Revise the OpenAPI validator / linter

    • Tweak the reported names to match the existing conventions
    • Use --version to query the version string (and trim() it)
    • Request --verbose JSON output to also report the rule names
    • Use the rule name as the linter message's "code"
    • Document that we now support v0.34.1 and later
    opened by jparise 2
  • Handle too much output from graphql-schema-linter, other json errors

    Handle too much output from graphql-schema-linter, other json errors

    When there are a lot of lint errors raised by graphql-schema-linter, the output JSON it produces can easily exceed the 2^16 character limit on the $stdout contents provided by Arcanist. The resulting truncated string will fail to JSON parse and the script will raise an error.

    To correct for this, we check if there were any errors encountered in JSON decoding and raise these explicitly so the user can take action.

    For this specific case, we see if the stdout buffer is at its maximum length and, if so, advise the author to run the linter outside of Arcanist and correct issues before running again.

    opened by steverice 2
  • Add configuration props to prettier-eslint linter

    Add configuration props to prettier-eslint linter

    Adds config and eslintConfig options to prettier-eslint linter.

    This will allow us to set the path of the configuration files for prettier and eslint when using prettier-eslint linter.

    opened by nachofassini 2
  • Skip file ignored warning

    Skip file ignored warning

    First of all, thanks for publishing your linters!

    I've been into an issue with the eslint linter: My .arclint enables the linter for "include": ["(\\.(j|t)sx?$)"], while excludes are defined in .eslintignore (so that other tools also respect them).

    Some version of ESLint (IIRC last year) started emitting a warning so that if one invokes eslint some-ignored-file.js, it communicates to the user that it ignored it.

    The warning doesn't have most fields set, so PHP emits a bunch of warnings when building ArcanistLintMessage. This change makes the linter just ignore that warning.

    opened by mrcljx 2
  • Fix setName call in ESLintLinter

    Fix setName call in ESLintLinter

    Fixes a bug introduced in #22.

    $offense['ruleId'] || 'unknown' was returning a bool (true) which caused the following exception when arc tried to post the lint results via the harbormaster.sendmessage API:

    [2019-10-15 01:34:16] EXCEPTION: (ConduitClientException) ERR-CONDUIT-CORE: Parameter 'name' has invalid type. Expected type 'string', got type 'bool'. at [<phutil>/src/conduit/ConduitFuture.php:62]
    arcanist(head=master, ref.master=96fde137a1dc), linters(head=test, ref.master=81e8d886d5c8, ref.test=f20a8b42a357), phutil(head=master, ref.master=f434f57578dd)
      #0 <#2> ConduitFuture::didReceiveResult(array) called at [<phutil>/src/future/FutureProxy.php:58]
      #1 <#2> FutureProxy::getResult() called at [<phutil>/src/future/FutureProxy.php:35]
      #2 <#2> FutureProxy::resolve() called at [<arcanist>/src/workflow/ArcanistDiffWorkflow.php:2999]
      #3 phlog(ConduitClientException) called at [<arcanist>/src/workflow/ArcanistDiffWorkflow.php:3005]
      #4 ArcanistDiffWorkflow::updateAutotargets(string, NULL) called at [<arcanist>/src/workflow/ArcanistDiffWorkflow.php:537]
      #5 ArcanistDiffWorkflow::run() called at [<arcanist>/scripts/arcanist.php:394]
    

    In these cases, arc lint and arc diff would successfully run, but the diff created on Phabricator would not show any details about what the lint errors/warnings were, or what line numbers they were on.

    With this fix, you can once again see the details of the lint errors and warnings in the Differential UI on Phabricator.

    I also changed the default name (when $offense['ruleId'] is not defined) from unknown to ESLintLinter, and tested both cases: https://www.dropbox.com/s/0mb54bf5xfe34hi/Screenshot%202019-10-14%2019.20.51.png?dl=0

    opened by jhurwitz 2
  • Improvement & cleanup on PR #7

    Improvement & cleanup on PR #7

    1. PrettierLinter: Don't warn for already formatted files
    2. ESLintLinter: Don't throw on exit code 1
    3. ESLintLinter: Fix error on occasional missing source parameter
    4. ESLintLinter: Add --fix & --cwd config options
    5. ESLintLinter, PrettierLinter, PrettierESLintLinter: Cleanup & normalize getDefaultBinary & getInstallInstructions
    6. ESLintLinter, PrettierLinter, PrettierESLintLinter: Improve global fallback

    Thanks @kuba-orlik (https://github.com/pinterest/arcanist-linters/pull/7/)

    opened by CrabDude 2
  • eslint.fix flag does not commit changes

    eslint.fix flag does not commit changes

    When there are autofixable lint errors detected by eslint, the order of operations is:

    1. arc diff
    2. if there are uncommited changes, amend or commit
    3. arc lint, which autofixes and returns successful
    4. autofixed changes are not committed nor staged
    5. diff is pushed to phabricator without changes

    This means that arc diff fails to properly apply lint changes before creating a diff.

    See messages for a file provided by [email protected]

            "messages": [
                {
                    "ruleId": "prettier/prettier",
                    "severity": 2,
                    "message": "Replace `(flow.component·&&·flow.component.archived)` with `flow.component·&&·flow.component.archived`",
                    "line": 61,
                    "column": 10,
                    "nodeType": null,
                    "messageId": "replace",
                    "endLine": 61,
                    "endColumn": 53,
                    "fix": {
                        "range": [
                            1462,
                            1505
                        ],
                        "text": "flow.component && flow.component.archived"
                    }
                },
                {
                    "ruleId": "prettier/prettier",
                    "severity": 2,
                    "message": "Insert `(⏎··········`",
                    "line": 65,
                    "column": 13,
                    "nodeType": null,
                    "messageId": "insert",
                    "endLine": 65,
                    "endColumn": 13,
                    "fix": {
                        "range": [
                            1675,
                            1675
                        ],
                        "text": "(\n          "
                    }
                },
                {
                    "ruleId": "prettier/prettier",
                    "severity": 2,
                    "message": "Replace `⏎⏎⏎········` with `········)`",
                    "line": 66,
                    "column": 1,
                    "nodeType": null,
                    "messageId": "replace",
                    "endLine": 69,
                    "endColumn": 9,
                    "fix": {
                        "range": [
                            1685,
                            1696
                        ],
                        "text": "        )"
                    }
                }
            ],
    
    opened by RainNapper 1
  • Pass working directory so ESLint can find plugins

    Pass working directory so ESLint can find plugins

    Directory structure:

    /Users/mmark/code/my-repo
    |-- .arclint
    |-- client
        |-- node_modules
        |-- .eslintrc
    |-- server
        |-- node_modules
        |-- .eslintrc
    

    Before the change:

    $ './client/node_modules/.bin/eslint' '--format=json' '--no-color' '--config' './client/.eslintrc' '--fix ' '/Users/mmark/code/my-repo/client/src/index.js'
    
    Oops! Something went wrong! :(
    
    ESLint: 6.8.0.
    
    ESLint couldn't find the plugin "eslint-plugin-react".
    
    (The package "eslint-plugin-react" was not found when loaded as a Node module from the directory "/Users/mmark/code/my-repo".)
    

    After the change:

    $ './client/node_modules/.bin/eslint' '--format=json' '--no-color' '--config' './client/.eslintrc' '--fix ' '/Users/mmark/code/metro/client/src/index.js' '--resolve-plugins-relative-to' './client'
    
    [successful output]
    

    Using .arclint entry:

        "client-eslint": {
          "type": "eslint",
          "include": "(client/.*\\.js$)",
          "bin": "./client/node_modules/.bin/eslint",
          "eslint.config": "./client/.eslintrc",
          "eslint.fix": true,
          "eslint.cwd": "./client"
        }
    
    opened by RainNapper 1
  • ESLint autofix is wrong

    ESLint autofix is wrong

    This took me a while to figure out but the ESLintLinter uses the column from ESLint to tell Arc what to fix:

            $message->setChar(idx($offense, 'column'));
    

    However this is the position of the error. It can actually be different to the position of the suggestion. For example with this code:

    import { addTab, addIframeTab } from "./tabs.js";
    

    ESLint will output:

          {
            "ruleId": "sort-imports",
            "severity": 2,
            "message": "Member 'addIframeTab' of the import declaration should be sorted alphabetically.",
            "line": 1,
            "column": 18,
            "nodeType": "ImportSpecifier",
            "messageId": "sortMembersAlphabetically",
            "endLine": 1,
            "endColumn": 30,
            "fix": {
              "range": [
                9,
                29
              ],
              "text": "addIframeTab, addTab"
            }
          },
    

    It should use the 9 offset to calculate the column, but it actually uses 18, resulting in this silly patch:

      Auto-Fix  (ESLINT) sort-imports
        Member 'addIframeTab' of the import declaration should be sorted
        alphabetically.
    
        >>> -      1 import { addTab, addTab, addIframeom "./tabs.js";
            +        import { addTab, addIframeTab, addom "./tabs.js";
    

    Unfortunately it doesn't look trivial to fix. My suggestion would be to apply all the fixes from the JSON in ESLintLinter and then just give the whole file as a single fix in one message.

    I did want to just use the --fix flag but unfortunately it can add or remove lines and then the positions of the other errors are wrong (and Arc freaks out if they are beyond the end of the fixed file).

    opened by Timmmm 2
  • Future of this project since Phabricator no longer maintained

    Future of this project since Phabricator no longer maintained

    This is more of a question than a bug or feature request:

    Since Phacility is winding down operations since June 1st, and therefore Phabricator is no longer actively maintained, how will this impact further development of this project?

    Btw, there are early community discussions and efforts for setting up an Open Source fork project:

    Would arcanist-linters try to stay compatible with the fork?

    question 
    opened by tiguchi 1
  • Prettier linter throws exception on invalid yaml

    Prettier linter throws exception on invalid yaml

    If you use the prettier linter, it works fine with normal auto fixes, but if the yaml is invalid and prettier throws to stderr it causes the entire arc lint run to fail. I'll be looking into fixing this, but wanted to post here in case anyone comes looking.

    EDIT: I noticed we extend a different base class internally, will follow up on if that is the root cause or not

    opened by Aghassi 0
  • prettier-eslint linter doesn't work - missing binary

    prettier-eslint linter doesn't work - missing binary

    I'm running arc lint with this config:

    {
    	"linters": {
    		"prettier-eslint": {
    			"type": "prettier-eslint",
    			"bin": "./node_modules/.bin/prettier-eslint",
    			"include": ["(\\.ts$)", "(\\.css$)"]
    		}
    	}
    }
    

    arc lint shows this error:

     Exception 
    Error in parsing '.arclint' file, in key 'bin' for linter 'prettier-eslint'.
    None of the configured binaries can be located.
    (Run with `--trace` for a full exception trace.)
    

    I've already installed prettier-eslint inside the repo

    opened by kuba-orlik 6
  • eslint arc formatter

    eslint arc formatter

    Hi there,

    We (Dropbox) also use ESLint with arc and I happened to stumble upon this repo. We just open-sourced https://github.com/dropbox/eslint-formatter-arcanist as well that deals w/ autofix and arc byte char issue so if you guys are interested feel free to take a look.

    opened by longlho 13
Owner
Pinterest
Pinterest's Open Source Projects
Pinterest
Easily integrate custom-made NPS (Net Promoter Score) into your application

Laravel NPS Easily integrate custom-made NPS (Net Promoter Score) to your application. Installation You can install the package via composer: composer

H-FARM Innovation 48 Oct 27, 2022
🧙‍♀️ Arcanist takes the pain out of building multi-step form wizards in Laravel.

Installation Arcanist requires PHP 8 and Laravel 8. composer require laravel-arcanist/arcanist Documentation You can find the full documentation here

Arcanist 378 Jan 3, 2023
Silverstripe-searchable - Adds to the default Silverstripe search by adding a custom results controller and allowing properly adding custom data objects and custom fields for searching

SilverStripe Searchable Module UPDATE - Full Text Search This module now uses Full Text Support for MySQL/MariaDB databases in version 3.* Adds more c

ilateral 13 Apr 14, 2022
A collection of common algorithms implemented in PHP. The collection is based on "Cracking the Coding Interview" by Gayle Laakmann McDowell

PHPAlgorithms A collection of common algorithms implemented in PHP. The collection is based on "Cracking the Coding Interview" by Gayle Laakmann McDow

Doğan Can Uçar 921 Dec 18, 2022
Lightweight and feature-rich PHP validation and filtering library. Support scene grouping, pre-filtering, array checking, custom validators, custom messages. 轻量且功能丰富的PHP验证、过滤库。支持场景分组,前置过滤,数组检查,自定义验证器,自定义消息。

PHP Validate 一个简洁小巧且功能完善的php验证、过滤库。 简单方便,支持添加自定义验证器 支持前置验证检查, 自定义如何判断非空 支持将规则按场景进行分组设置。或者部分验证 支持在进行验证前对值使用过滤器进行净化过滤内置过滤器 支持在进行验证前置处理和后置处理独立验证处理 支持自定义每

Inhere 246 Jan 5, 2023
A custom WordPress nav walker class to fully implement the Twitter Bootstrap 4.0+ navigation style (v3-branch available for Bootstrap 3) in a custom theme using the WordPress built in menu manager.

WP Bootstrap Navwalker This code in the main repo branch is undergoing a big shakeup to bring it in line with recent standards and to merge and test t

WP Bootstrap 3.3k Jan 5, 2023
A WordPress package for updating custom plugins and themes based on an API response from a custom update server.

WordPress Update Handler A WordPress package for updating custom plugins and themes based on an JSON REST API response from a custom update server. Ch

WP Forge 7 Oct 5, 2022
Glz custom fields - Unlimited Custom Fields for Textpattern

Unlimited custom fields for Textpattern This plugin sits under the Extensions tab in the back-end and gives your custom fields new life. You can final

Gerhard Lazu 21 Dec 1, 2019
Magento 2 custom extension to add custom attributes(longitude, latitude) to customer address

Magento 2 custom extension to add custom attributes(longitude, latitude) to customer address. Then save them to quote model and copy them from quote address to order address on bakend, frontend, rest api

MageArab 2 Jul 14, 2022
Wordpress advance plugin with multi purposes features like live chat, custom post type, custom forms, word count etc

What is this? This is wordpress plugin which is created for the multi purpose uses. How to use? Simply install the plugin. Go to the plugin settigs pa

Amir Liaqat 2 Jun 23, 2022
[READ-ONLY] Collection library in CakePHP. This repo is a split of the main code that can be found in https://github.com/cakephp/cakephp

CakePHP Collection Library The collection classes provide a set of tools to manipulate arrays or Traversable objects. If you have ever used underscore

CakePHP 85 Nov 28, 2022
[DEPRECATED] Collection of PSR-7 middlewares

This package is deprecated in favor of the new PSR-15 standard. Check it out here psr7-middlewares Collection of PSR-7 middlewares. Requirements PHP >

Oscar Otero 669 Dec 27, 2022
Collection pipeline library for PHP

Knapsack Collection pipeline library for PHP Knapsack is a collection library for PHP >= 5.6 that implements most of the sequence operations proposed

Dušan Kasan 540 Dec 17, 2022
A set of useful Laravel collection macros

A set of useful Laravel collection macros This repository contains some useful collection macros. Spatie is a webdesign agency based in Antwerp, Belgi

Spatie 1.5k Dec 31, 2022
Library that provides collection, processing, and rendering functionality for PHP code coverage information.

phpunit/php-code-coverage Provides collection, processing, and rendering functionality for PHP code coverage information. Installation You can add thi

Sebastian Bergmann 8.5k Jan 5, 2023
A yii-log-target of collection(Bark、Chanify、DingTalk、FeiShu、ServerChan、WeWork、XiZhi).

A yii-log-target of collection(Bark、Chanify、DingTalk、FeiShu、ServerChan、WeWork、XiZhi). - 集合了多种 yii-log-target(Bark、Chanify、钉钉群机器人、飞书群机器人、Server 酱、企业微信群机器人、息知)。

guanguans 7 Jul 2, 2022
Collection of the Laravel/Eloquent Model classes that allows you to get data directly from a Magento 2 database.

Laragento LAravel MAgento Micro services Magento 2 has legacy code based on abandoned Zend Framework 1 with really ugly ORM on top of outdated Zend_DB

Egor Shitikov 87 Nov 26, 2022
A collection of helper functions that I use across my projects.

A collection of helper functions that I use across my projects. This package includes some of the helper functions that I tend to use in all of my pro

Ryan Chandler 33 Oct 18, 2022
A collection of generators for Lumen and Laravel 5.

Lumen generators A collection of generators for Lumen and Laravel 5. Contents Why ? Installation Quick Usage Detailed Usage Model Generator Migration

Amine Ben hammou 349 Mar 24, 2022