Skip to content

Commit

Permalink
Add PrettierESLintLinter (MobileNativeFoundation#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
CrabDude authored and jparise committed Apr 12, 2018
1 parent 7e482b8 commit c642a97
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 7 deletions.
24 changes: 19 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Pinterest.
- [ESLint](#eslint)
- [Go Vet](#go-vet)
- [Prettier](#prettier)
- [Prettier ESLint](#prettier-eslint)
- [Python Imports](#python-imports)
- [Python isort](#python-isort)
- [Python Requirements](#python-requirements)
Expand Down Expand Up @@ -85,6 +86,17 @@ Lints JavaScript and JSX files using [ESLint](https://eslint.org/).
}
```

### Go Vet

Uses the [Go vet command](https://golang.org/cmd/vet/) to lint for suspicious
code constructs.

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

### Prettier

Expand All @@ -99,15 +111,17 @@ Formats JavaScript using [Prettier](https://prettier.io/).
}
```

### Go Vet

Uses the [Go vet command](https://golang.org/cmd/vet/) to lint for suspicious
code constructs.
### Prettier ESLint

Formats JavaScript using [Prettier](https://prettier.io/) and then fixes with [ESLint](https://eslint.org/).

```json
{
"type": "govet",
"include": "(^src/example.com/.*\\.go$)"
"type": "prettier-eslint",
"include": "(\\.js$)",
"bin": "./node_modules/.bin/prettier-eslint",
"prettier-eslint.cwd": "./"
}
```

Expand Down
6 changes: 4 additions & 2 deletions __phutil_library_map__.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
'class' => array(
'ApacheThriftGeneratedLinter' => 'src/ApacheThriftGeneratedLinter.php',
'ApacheThriftLinter' => 'src/ApacheThriftLinter.php',
'PrettierLinter' => 'src/PrettierLinter.php',
'CheckstyleLinter' => 'src/CheckstyleLinter.php',
'ESLintLinter' => 'src/ESLintLinter.php',
'GoVetLinter' => 'src/GoVetLinter.php',
'PrettierESLintLinter' => 'src/PrettierESLintLinter.php',
'PrettierLinter' => 'src/PrettierLinter.php',
'PythonImportsLinter' => 'src/PythonImportsLinter.php',
'PythonIsortLinter' => 'src/PythonIsortLinter.php',
'PythonRequirementsLinter' => 'src/PythonRequirementsLinter.php',
Expand All @@ -23,10 +24,11 @@
'xmap' => array(
'ApacheThriftGeneratedLinter' => 'ArcanistLinter',
'ApacheThriftLinter' => 'ArcanistExternalLinter',
'PrettierLinter' => 'ArcanistExternalLinter',
'CheckstyleLinter' => 'ArcanistExternalLinter',
'ESLintLinter' => 'ArcanistExternalLinter',
'GoVetLinter' => 'ArcanistExternalLinter',
'PrettierESLintLinter' => 'ArcanistExternalLinter',
'PrettierLinter' => 'ArcanistExternalLinter',
'PythonImportsLinter' => 'ArcanistLinter',
'PythonIsortLinter' => 'ArcanistExternalLinter',
'PythonRequirementsLinter' => 'ArcanistLinter',
Expand Down
151 changes: 151 additions & 0 deletions src/PrettierESLintLinter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
<?php
/**
* Copyright 2018 Pinterest, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Lints JavaScript and JSX files using Prettier & Eslint auto-fix
*/
final class PrettierESLintLinter extends ArcanistExternalLinter {
private $cwd = '';
private $flags = array();

public function getInfoName() {
return 'PrettierESLint';
}

public function getInfoURI() {
return 'https://github.com/prettier/prettier-eslint-cli';
}

public function getInfoDescription() {
return pht('A combo Prettier formatter & Eslint auto-fix linter');
}

public function getLinterName() {
return 'PRETTIERESLINT';
}

public function getLinterConfigurationName() {
return 'prettier-eslint';
}

public function shouldUseInterpreter() {
return true;
}

public function getDefaultInterpreter() {
list($err, $stdout, $stderr) = exec_manual('node -v');
preg_match('/^v([^\.]+)\..*$/', $stdout, $m);
if (empty($m)) {
// Copied from arcanist/master/src/lint/linter/ArcanistExternalLinter.php
throw new ArcanistMissingLinterException(
pht(
'Unable to locate interpreter "%s" to run linter %s. You may need '.
'to install the interpreter, or adjust your linter configuration.',
'node',
get_class($this)));
}
if ((int)$m[1] < 6) {
// Only used for node < 6
return __DIR__ . '/node4_proxy';
}
return 'node';
}

public function getDefaultBinary() {
list($err, $stdout, $stderr) = exec_manual('yarn -s --cwd %s which prettier-eslint', $this->getProjectRoot() . '/' . $this->cwd);
$binaryPath = strtok($stdout, "\n");
if (!empty($stderr)) {
// Copied from arcanist/master/src/lint/linter/ArcanistExternalLinter.php
throw new ArcanistMissingLinterException(
sprintf(
"%s\n%s",
pht(
'Unable to locate script "%s" to run linter %s. You may need '.
'to install the script, or adjust your linter configuration.',
'yarn@1',
get_class($this)),
pht(
'TO INSTALL: %s',
$this->getInstallInstructions())));
}
return $binaryPath;
}

public function getVersion() {
list($err, $stdout, $stderr) = exec_manual('%C -v', $this->getExecutableCommand());
return $stdout;
}

protected function getMandatoryFlags() {
return array(
'--log-level=silent',
);
}

public function getLinterConfigurationOptions() {
$options = array(
'prettier-eslint.cwd' => array(
'type' => 'optional string',
'help' => pht('Specify a project sub-directory for both the local prettier-eslint-cli install and the sub-directory to lint within.'),
),
);
return $options + parent::getLinterConfigurationOptions();
}

public function setLinterConfigurationValue($key, $value) {
switch ($key) {
case 'prettier-eslint.cwd':
$this->cwd = $value;
return;
}
return parent::setLinterConfigurationValue($key, $value);
}

public function getInstallInstructions() {
return pht(
'run `%s` to install yarn@1 globally (needed for specifying --cwd & `yarn which`), and `%s` to add prettier-eslint-cli to your project (configurable at prettier-eslint.cwd).',
'npm install --global yarn@1',
'yarn add --dev prettier-eslint-cli'
);
}

protected function parseLinterOutput($path, $err, $stdout, $stderr) {
if ($err) {
return false;
}

$originalText = $this->getData($path);
$messages = array();

// Note: $stdout is empty for ignored files
if ($stdout && $stdout != $originalText) {
$message = new ArcanistLintMessage();
$message->setPath($path);
$message->setSeverity(ArcanistLintSeverity::SEVERITY_AUTOFIX);
$message->setName('Prettier-Eslint Format');
$message->setLine(1);
$message->setCode($this->getLinterName());
$message->setChar(1);
$message->setDescription('Your file has not been prettier-eslint-ified');
$message->setOriginalText($originalText);
$message->setReplacementText($stdout);
$messages[] = $message;
}

return $messages;
}
}
2 changes: 2 additions & 0 deletions src/node4_proxy
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
node --harmony_array_includes "$@"

0 comments on commit c642a97

Please sign in to comment.