From ac47c067376937f65292458cfc781bbff1d66c09 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Mon, 31 Jul 2017 10:33:07 -0700 Subject: [PATCH 01/15] Add javascriptstyle lint goal --- build-support/javascriptstyle/.eslintrc | 289 ++++++++++++++++++ .../src/python/pants/contrib/node/register.py | 3 + .../pants/contrib/node/targets/node_module.py | 5 +- .../contrib/node/tasks/javascript_style.py | 113 +++++++ pants.ini | 12 + 5 files changed, 421 insertions(+), 1 deletion(-) create mode 100644 build-support/javascriptstyle/.eslintrc create mode 100644 contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py diff --git a/build-support/javascriptstyle/.eslintrc b/build-support/javascriptstyle/.eslintrc new file mode 100644 index 00000000000..49e31735986 --- /dev/null +++ b/build-support/javascriptstyle/.eslintrc @@ -0,0 +1,289 @@ +{ + // babel parser to support ES6/7 features + "parser": "babel-eslint", + "parserOptions": { + "ecmaVersion": 7, + "ecmaFeatures": { + "experimentalObjectRestSpread": true, + "jsx": true + }, + "sourceType": "module" + }, + "plugins": [ + "flowtype", + "jsx-a11y", + "promise", + "react" + ], + "env": { + "es6": true, + "node": true + }, + "globals": { + "document": false, + "navigator": false, + "window": false + }, + "rules": { + "accessor-pairs": 2, + "array-bracket-spacing": ["error", "always"], + "arrow-parens": [2, "always"], + "arrow-spacing": [2, { "before": true, "after": true }], + "block-spacing": [2, "always"], + "brace-style": [2, "1tbs", { "allowSingleLine": true }], + "camelcase": 0, + "comma-dangle": [2, "never"], + "comma-spacing": [2, { "before": false, "after": true }], + "comma-style": [2, "last"], + "computed-property-spacing": ["error", "never"], + "constructor-super": 2, + "curly": [2, "all"], + "default-case": [2, { commentPattern: '^no default$' }], + "dot-location": [2, "property"], + "eol-last": 2, + "eqeqeq": [2, "allow-null"], + "generator-star-spacing": [2, { "before": true, "after": true }], + "handle-callback-err": [2, "^(err|error)$" ], + "indent": 0, + "indent-legacy": [2, 2, { "SwitchCase": 1 }], + "key-spacing": [2, { "beforeColon": false, "afterColon": true }], + "keyword-spacing": [2, { "before": true, "after": true }], + "max-len": [2, 120, 4], + "new-cap": [2, { "newIsCap": true, "capIsNew": false }], + "new-parens": 2, + "no-alert": 1, + "no-array-constructor": 2, + "no-caller": 2, + "no-case-declarations": 2, + "no-class-assign": 2, + "no-compare-neg-zero": 2, + "no-cond-assign": 2, + "no-const-assign": 2, + "no-control-regex": 2, + "no-debugger": 2, + "no-delete-var": 2, + "no-dupe-args": 2, + "no-dupe-class-members": 2, + "no-dupe-keys": 2, + "no-duplicate-case": 2, + "no-duplicate-imports": 2, + "no-empty-character-class": 2, + "no-empty-pattern": 2, + "no-eval": 2, + "no-ex-assign": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-extra-boolean-cast": 2, + "no-extra-parens": [2, "functions"], + "no-extra-semi": 2, + "no-fallthrough": 2, + "no-floating-decimal": 2, + "no-func-assign": 2, + "no-implied-eval": 2, + "no-inner-declarations": [2, "functions"], + "no-invalid-regexp": 2, + "no-irregular-whitespace": 2, + "no-iterator": 2, + "no-label-var": 2, + "no-labels": [2, { "allowLoop": false, "allowSwitch": false }], + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-mixed-spaces-and-tabs": 2, + "no-multi-spaces": ["error", { "ignoreEOLComments": true }], + "no-multi-str": 2, + "no-multiple-empty-lines": [2, { "max": 1 }], + "no-native-reassign": 2, + "no-negated-in-lhs": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-object": 2, + "no-new-require": 2, + "no-new-symbol": 2, + "no-new-wrappers": 2, + "no-obj-calls": 2, + "no-octal": 2, + "no-octal-escape": 2, + "no-path-concat": 2, + "no-proto": 2, + "no-redeclare": 2, + "no-regex-spaces": 2, + "no-return-assign": [2, "except-parens"], + "no-script-url": 2, + "no-self-assign": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-shadow-restricted-names": 2, + "no-spaced-func": 2, + "no-sparse-arrays": 2, + "no-this-before-super": 2, + "no-throw-literal": 2, + "no-trailing-spaces": 2, + "no-undef": 2, + "no-undef-init": 2, + "no-unexpected-multiline": 2, + "no-unmodified-loop-condition": 2, + "no-unneeded-ternary": [2, { "defaultAssignment": false }], + "no-unreachable": 2, + "no-unsafe-finally": 2, + "no-unused-vars": [2, { "vars": "all", "args": "none" }], + "no-useless-call": 2, + "no-useless-computed-key": 2, + "no-useless-concat": 2, + "no-useless-constructor": 2, + "no-useless-escape": 2, + "no-var": 2, + "no-whitespace-before-property": 2, + "no-with": 2, + "object-curly-spacing": ["error", "always"], + "operator-linebreak": [2, "after"], + "padded-blocks": [2, "never"], + "prefer-const": 2, + "prefer-rest-params": 2, + "prefer-template": 2, + "quotes": [2, "single", "avoid-escape"], + "radix": 2, + "require-yield": 2, + "rest-spread-spacing": ["error"], + "semi": [2, "always"], + "semi-spacing": [2, { "before": false, "after": true }], + "sort-imports": ["error", { "memberSyntaxSortOrder": ["none", "all", "single", "multiple"], "ignoreCase": true }], + "space-before-blocks": [2, "always"], + "space-before-function-paren": [2, { "anonymous": "always", "named": "never" }], + "space-in-parens": [2, "never"], + "space-infix-ops": 2, + "space-unary-ops": [2, { "words": true, "nonwords": false }], + "spaced-comment": [2, "always", { "markers": ["global", "globals", "eslint", "eslint-disable", "*package", "!", ","] }], + "template-curly-spacing": [2, "never"], + "use-isnan": 2, + "valid-typeof": 2, + "wrap-iife": [2, "outside"], + "yield-star-spacing": [2, "both"], + "yoda": [2, "never"], + + // promise + "promise/param-names": 2, + + // jsx accessibility + "jsx-a11y/accessible-emoji": 2, + "jsx-a11y/alt-text": 2, + "jsx-a11y/anchor-has-content": 2, + "jsx-a11y/anchor-is-valid": 2, + "jsx-a11y/aria-activedescendant-has-tabindex": 2, + "jsx-a11y/aria-props": 2, + "jsx-a11y/aria-proptypes": 2, + "jsx-a11y/aria-role": 2, + "jsx-a11y/aria-unsupported-elements": 2, + "jsx-a11y/click-events-have-key-events": 2, + "jsx-a11y/heading-has-content": 2, + "jsx-a11y/html-has-lang": 2, + "jsx-a11y/iframe-has-title": 2, + "jsx-a11y/img-redundant-alt": 2, + "jsx-a11y/interactive-supports-focus": 2, + "jsx-a11y/label-has-for": 2, + "jsx-a11y/media-has-caption": 0, + "jsx-a11y/mouse-events-have-key-events": 2, + "jsx-a11y/no-access-key": 2, + // Re-visit if we move config to an `eslint-config-twitter` + "jsx-a11y/no-autofocus": 0, + "jsx-a11y/no-distracting-elements": 2, + "jsx-a11y/no-interactive-element-to-noninteractive-role": ["error", { "tr": ["none", "presentation"] }], + "jsx-a11y/no-noninteractive-element-interactions": 0, + "jsx-a11y/no-noninteractive-element-to-interactive-role": ["error", { + "li": ["menuitem", "option", "row", "tab", "treeitem"], + "ol": ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"], + "ul": ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"], + "table": ["grid"], + "td": ["gridcell"] + }], + "jsx-a11y/no-noninteractive-tabindex": ["error", { "tags": [], "roles": ["tabpanel"] }], + "jsx-a11y/no-onchange": 0, + "jsx-a11y/no-redundant-roles": 2, + "jsx-a11y/no-static-element-interactions": 0, + "jsx-a11y/role-has-required-aria-props": 2, + "jsx-a11y/role-supports-aria-props": 2, + "jsx-a11y/scope": 2, + "jsx-a11y/tabindex-no-positive": 2, + + // react + "jsx-quotes": [2, "prefer-single"], + "react/display-name": 0, + "react/jsx-boolean-value": 2, + "react/jsx-handler-names": [2, { + "eventHandlerPrefix": "_handle" + }], + "react/jsx-indent": [2, 2], + "react/jsx-indent-props": [2, 2], + "react/jsx-no-bind": 2, + "react/jsx-no-duplicate-props": 2, + "react/jsx-no-undef": 2, + "react/jsx-pascal-case": 2, + "react/jsx-sort-props": 2, + "react/jsx-uses-react": 2, + "react/jsx-uses-vars": 2, + "react/jsx-wrap-multilines": 0, + "react/no-did-mount-set-state": 0, + "react/no-did-update-set-state": 2, + "react/no-direct-mutation-state": 2, + "react/no-multi-comp": 0, + "react/no-string-refs": 2, + "react/no-unknown-property": 2, + "react/prefer-es6-class": 2, + "react/prop-types": 2, + "react/react-in-jsx-scope": 0, + "react/self-closing-comp": 2, + "react/sort-comp": 0, + "react/sort-prop-types": 2, + + // flow types + "flowtype/boolean-style": [ + 2, + "boolean" + ], + "flowtype/define-flow-type": 1, + "flowtype/delimiter-dangle": [ + 2, + "never" + ], + "flowtype/generic-spacing": [ + 2, + "never" + ], + "flowtype/no-primitive-constructor-types": 2, + "flowtype/no-weak-types": 0, + "flowtype/object-type-delimiter": [ + 2, + "comma" + ], + "flowtype/require-parameter-type": 0, + "flowtype/require-return-type": 0, + "flowtype/require-valid-file-annotation": 2, + "flowtype/semi": [ + 2, + "always" + ], + "flowtype/space-after-type-colon": [ + 2, + "always" + ], + "flowtype/space-before-generic-bracket": [ + 2, + "never" + ], + "flowtype/space-before-type-colon": [ + 2, + "never" + ], + "flowtype/type-id-match": 0, + "flowtype/union-intersection-spacing": [ + 2, + "always" + ], + "flowtype/use-flow-type": 1, + "flowtype/valid-syntax": 1 + }, + "settings": { + "flowtype": { + "onlyFilesWithFlowAnnotation": true + } + } +} \ No newline at end of file diff --git a/contrib/node/src/python/pants/contrib/node/register.py b/contrib/node/src/python/pants/contrib/node/register.py index 090c189d239..3db672cf558 100644 --- a/contrib/node/src/python/pants/contrib/node/register.py +++ b/contrib/node/src/python/pants/contrib/node/register.py @@ -16,6 +16,7 @@ from pants.contrib.node.targets.node_preinstalled_module import NodePreinstalledModule from pants.contrib.node.targets.node_remote_module import NodeRemoteModule from pants.contrib.node.targets.node_test import NodeTest as NodeTestTarget +from pants.contrib.node.tasks.javascript_style import JavascriptStyle from pants.contrib.node.tasks.node_build import NodeBuild from pants.contrib.node.tasks.node_bundle import NodeBundle as NodeBundleTask from pants.contrib.node.tasks.node_repl import NodeRepl @@ -43,6 +44,8 @@ def register_goals(): task(name='node', action=NodeBuild).install('compile', first=True) task(name='node', action=NodeTestTask).install('test') task(name='node', action=NodeBundleTask).install('bundle') + # Linting + task(name='javascriptstyle', action=JavascriptStyle).install('lint') def global_subsystems(): diff --git a/contrib/node/src/python/pants/contrib/node/targets/node_module.py b/contrib/node/src/python/pants/contrib/node/targets/node_module.py index 5f67c5bc6ad..a686f56a529 100644 --- a/contrib/node/src/python/pants/contrib/node/targets/node_module.py +++ b/contrib/node/src/python/pants/contrib/node/targets/node_module.py @@ -21,7 +21,7 @@ class NodeModule(NodePackage): def __init__( self, package_manager=None, sources=None, build_script=None, output_dir='dist', - dev_dependency=False, address=None, payload=None, **kwargs): + dev_dependency=False, address=None, payload=None, lint_config=None, **kwargs): """ :param sources: Javascript and other source code files that make up this module; paths are relative to the BUILD file's directory. @@ -38,6 +38,8 @@ def __init__( :param dev_dependency: boolean value. Default is False. If a node_module is used as parts of devDependencies and thus should not be included in the final bundle or JVM binaries, set this value to True. + :param lint_config: Override the default lint configuration. Any lint rules requiring a plugin + will need to be included in the node_modules/package.json. """ # TODO(John Sirois): Support devDependencies, etc. The devDependencies case is not # clear-cut since pants controlled builds would provide devDependencies as needed to perform @@ -52,6 +54,7 @@ def __init__( 'package_manager': PrimitiveField(package_manager), 'output_dir': PrimitiveField(output_dir), 'dev_dependency': PrimitiveField(dev_dependency), + 'lint_config': PrimitiveField(lint_config), }) logger.debug('NodeModule payload: %s', payload.fields) super(NodeModule, self).__init__(address=address, payload=payload, **kwargs) diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py new file mode 100644 index 00000000000..9d312f28eeb --- /dev/null +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -0,0 +1,113 @@ +# coding=utf-8 +# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import (absolute_import, division, generators, nested_scopes, print_function, + unicode_literals, with_statement) + +import os + +from pants.base.exceptions import TaskError +from pants.base.workunit import WorkUnit, WorkUnitLabel +from pants.option.custom_types import file_option +from pants.util.contextutil import pushd +from pants.base.build_environment import get_buildroot + +from pants.contrib.node.targets.node_package import NodePackage +from pants.contrib.node.tasks.node_task import NodeTask +from pants.contrib.node.tasks.node_paths import NodePaths + + +class JavascriptStyle(NodeTask): + """ Check javascript source files to ensure they follow the style guidelines. + + :API: public + """ + + _JS_SOURCE_EXTENSION = '.js' + _JSX_SOURCE_EXTENSION = '.jsx' + + def __init__(self, *args, **kwargs): + super(JavascriptStyle, self).__init__(*args, **kwargs) + + @classmethod + def register_options(cls, register): + super(JavascriptStyle, cls).register_options(register) + register('--cmd', advanced=True, default='eslint', fingerprint=True, + help='Run this command to start style checker.') + register('--cmd-args', advanced=True, type=list, default=[], fingerprint=True, + help='Passthrough command line args.') + register('--package', advanced=True, default='eslint', fingerprint=True, help='Linter tool') + register('--skip', type=bool, fingerprint=True, help='Skip javascriptstyle.') + register('--config', type=file_option, advanced=True, fingerprint=True, + help='Path to javascriptstyle config file.') + register('--linter-plugins', advanced=True, type=list, default=[], fingerprint=True, + help='Add these plugins to extend linter.') + + def get_lintable_node_targets(self, targets): + return filter( + lambda target: isinstance(target, NodePackage) + and (target.has_sources(self._JS_SOURCE_EXTENSION) + or target.has_sources(self._JSX_SOURCE_EXTENSION)) + and (not target.is_synthetic), + targets) + + def get_javascript_sources(self, target): + sources = set() + sources.update(os.path.join(get_buildroot(), source) for source in target.sources_relative_to_buildroot() + if (source.endswith(self._JS_SOURCE_EXTENSION) or + source.endswith(self._JSX_SOURCE_EXTENSION))) + return sources + + def _install_packages(self, target, packages): + """Install packages related to javascript style checker.""" + for package in packages: + self.context.log.debug('Installing package %s.'% package) + result, yarn_add_command = self.execute_yarnpkg( + args=['add', package], + workunit_name=target.address.reference(), + workunit_labels=[WorkUnitLabel.PREP]) + if result != 0: + raise TaskError('Failed to install package: {}\n' + '\t{} failed with exit code {}'.format(package, yarn_add_command, result)) + + def _run_lint_tool(self, target, files): + command = self.get_options().cmd + command_args = self.get_options().cmd_args + global_config = self.get_options().config + config = target.payload.get_field('lint_config').value + # If no config file is specified use default config. + if not config: + config = global_config + self.context.log.info('Config: %s' % config) + args = ['run', command, '--', '--config', config, files] + args.extend(command_args) + result, yarn_run_command = self.execute_yarnpkg( + args=args, + workunit_name=target.address.reference(), + workunit_labels=[WorkUnitLabel.PREP]) + if result != 0: + raise TaskError('Linting failed: \n' + '{} failed with exit code {}'.format(yarn_run_command, result)) + + def execute(self): + if self.get_options().skip: + self.context.log.info('Skipping javascript style check.') + return + + targets = self.get_lintable_node_targets(self.context.targets()) + if not targets: + return + + for target in targets: + packages = [self.get_options().package] + sources = self.get_javascript_sources(target) + if sources: + files = ' '.join(sources) + node_paths = self.context.products.get_data(NodePaths) + node_path = node_paths.node_path(target) + with pushd(node_path): + packages.extend(self.get_options().linter_plugins) + self._install_packages(target, packages) + self._run_lint_tool(target, files) + return \ No newline at end of file diff --git a/pants.ini b/pants.ini index b719358f952..0f468aa10b2 100644 --- a/pants.ini +++ b/pants.ini @@ -165,6 +165,18 @@ no_warning_args: [ [lint.checkstyle] configuration: %(pants_supportdir)s/checkstyle/coding_style.xml +[lint.javascriptstyle] +cmd: eslint +package: eslint +config: %(buildroot)s/build-support/javascriptstyle/.eslintrc +linter_plugins: [ + 'babel-eslint', + 'eslint-plugin-flowtype', + 'eslint-plugin-jsx-a11y', + 'eslint-plugin-promise', + 'eslint-plugin-react', + ] + [lint.python-eval] # After we fix the cycles from the engine refactor we should re-enable this. # https://github.com/pantsbuild/pants/issues/4601 From cd91b3025e50e18fd0a013ff40cc205c7cafca37 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 12:13:15 -0700 Subject: [PATCH 02/15] Use a built node package for javascript linting and formatting --- build-support/javascriptstyle/.eslintrc | 132 +- build-support/javascriptstyle/.gitignore | 3 + build-support/javascriptstyle/.npmrc | 1 + build-support/javascriptstyle/README.md | 3 + build-support/javascriptstyle/bin/cli.js | 4 + build-support/javascriptstyle/index.js | 6 + build-support/javascriptstyle/options.js | 18 + build-support/javascriptstyle/package.json | 28 + build-support/javascriptstyle/test/api.js | 20 + build-support/javascriptstyle/yarn.lock | 1113 +++++++++++++++++ contrib/node/examples/src/node/hello/index.js | 8 +- .../src/python/pants/contrib/node/register.py | 2 + .../pants/contrib/node/targets/node_module.py | 7 +- .../contrib/node/tasks/javascript_style.py | 94 +- .../pants_test/contrib/node/tasks/BUILD | 10 + .../node/tasks/test_node_lint_integration.py | 25 + pants.ini | 14 +- 17 files changed, 1290 insertions(+), 198 deletions(-) create mode 100644 build-support/javascriptstyle/.gitignore create mode 100644 build-support/javascriptstyle/.npmrc create mode 100644 build-support/javascriptstyle/README.md create mode 100755 build-support/javascriptstyle/bin/cli.js create mode 100644 build-support/javascriptstyle/index.js create mode 100644 build-support/javascriptstyle/options.js create mode 100644 build-support/javascriptstyle/package.json create mode 100644 build-support/javascriptstyle/test/api.js create mode 100644 build-support/javascriptstyle/yarn.lock create mode 100644 contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py diff --git a/build-support/javascriptstyle/.eslintrc b/build-support/javascriptstyle/.eslintrc index 49e31735986..c43edcc6b96 100644 --- a/build-support/javascriptstyle/.eslintrc +++ b/build-support/javascriptstyle/.eslintrc @@ -10,10 +10,6 @@ "sourceType": "module" }, "plugins": [ - "flowtype", - "jsx-a11y", - "promise", - "react" ], "env": { "es6": true, @@ -158,132 +154,6 @@ "valid-typeof": 2, "wrap-iife": [2, "outside"], "yield-star-spacing": [2, "both"], - "yoda": [2, "never"], - - // promise - "promise/param-names": 2, - - // jsx accessibility - "jsx-a11y/accessible-emoji": 2, - "jsx-a11y/alt-text": 2, - "jsx-a11y/anchor-has-content": 2, - "jsx-a11y/anchor-is-valid": 2, - "jsx-a11y/aria-activedescendant-has-tabindex": 2, - "jsx-a11y/aria-props": 2, - "jsx-a11y/aria-proptypes": 2, - "jsx-a11y/aria-role": 2, - "jsx-a11y/aria-unsupported-elements": 2, - "jsx-a11y/click-events-have-key-events": 2, - "jsx-a11y/heading-has-content": 2, - "jsx-a11y/html-has-lang": 2, - "jsx-a11y/iframe-has-title": 2, - "jsx-a11y/img-redundant-alt": 2, - "jsx-a11y/interactive-supports-focus": 2, - "jsx-a11y/label-has-for": 2, - "jsx-a11y/media-has-caption": 0, - "jsx-a11y/mouse-events-have-key-events": 2, - "jsx-a11y/no-access-key": 2, - // Re-visit if we move config to an `eslint-config-twitter` - "jsx-a11y/no-autofocus": 0, - "jsx-a11y/no-distracting-elements": 2, - "jsx-a11y/no-interactive-element-to-noninteractive-role": ["error", { "tr": ["none", "presentation"] }], - "jsx-a11y/no-noninteractive-element-interactions": 0, - "jsx-a11y/no-noninteractive-element-to-interactive-role": ["error", { - "li": ["menuitem", "option", "row", "tab", "treeitem"], - "ol": ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"], - "ul": ["listbox", "menu", "menubar", "radiogroup", "tablist", "tree", "treegrid"], - "table": ["grid"], - "td": ["gridcell"] - }], - "jsx-a11y/no-noninteractive-tabindex": ["error", { "tags": [], "roles": ["tabpanel"] }], - "jsx-a11y/no-onchange": 0, - "jsx-a11y/no-redundant-roles": 2, - "jsx-a11y/no-static-element-interactions": 0, - "jsx-a11y/role-has-required-aria-props": 2, - "jsx-a11y/role-supports-aria-props": 2, - "jsx-a11y/scope": 2, - "jsx-a11y/tabindex-no-positive": 2, - - // react - "jsx-quotes": [2, "prefer-single"], - "react/display-name": 0, - "react/jsx-boolean-value": 2, - "react/jsx-handler-names": [2, { - "eventHandlerPrefix": "_handle" - }], - "react/jsx-indent": [2, 2], - "react/jsx-indent-props": [2, 2], - "react/jsx-no-bind": 2, - "react/jsx-no-duplicate-props": 2, - "react/jsx-no-undef": 2, - "react/jsx-pascal-case": 2, - "react/jsx-sort-props": 2, - "react/jsx-uses-react": 2, - "react/jsx-uses-vars": 2, - "react/jsx-wrap-multilines": 0, - "react/no-did-mount-set-state": 0, - "react/no-did-update-set-state": 2, - "react/no-direct-mutation-state": 2, - "react/no-multi-comp": 0, - "react/no-string-refs": 2, - "react/no-unknown-property": 2, - "react/prefer-es6-class": 2, - "react/prop-types": 2, - "react/react-in-jsx-scope": 0, - "react/self-closing-comp": 2, - "react/sort-comp": 0, - "react/sort-prop-types": 2, - - // flow types - "flowtype/boolean-style": [ - 2, - "boolean" - ], - "flowtype/define-flow-type": 1, - "flowtype/delimiter-dangle": [ - 2, - "never" - ], - "flowtype/generic-spacing": [ - 2, - "never" - ], - "flowtype/no-primitive-constructor-types": 2, - "flowtype/no-weak-types": 0, - "flowtype/object-type-delimiter": [ - 2, - "comma" - ], - "flowtype/require-parameter-type": 0, - "flowtype/require-return-type": 0, - "flowtype/require-valid-file-annotation": 2, - "flowtype/semi": [ - 2, - "always" - ], - "flowtype/space-after-type-colon": [ - 2, - "always" - ], - "flowtype/space-before-generic-bracket": [ - 2, - "never" - ], - "flowtype/space-before-type-colon": [ - 2, - "never" - ], - "flowtype/type-id-match": 0, - "flowtype/union-intersection-spacing": [ - 2, - "always" - ], - "flowtype/use-flow-type": 1, - "flowtype/valid-syntax": 1 - }, - "settings": { - "flowtype": { - "onlyFilesWithFlowAnnotation": true - } + "yoda": [2, "never"] } } \ No newline at end of file diff --git a/build-support/javascriptstyle/.gitignore b/build-support/javascriptstyle/.gitignore new file mode 100644 index 00000000000..dd7174780cc --- /dev/null +++ b/build-support/javascriptstyle/.gitignore @@ -0,0 +1,3 @@ +.yarnclean +node_modules +yarn-error.log \ No newline at end of file diff --git a/build-support/javascriptstyle/.npmrc b/build-support/javascriptstyle/.npmrc new file mode 100644 index 00000000000..83a555c139a --- /dev/null +++ b/build-support/javascriptstyle/.npmrc @@ -0,0 +1 @@ +registry='https://registry.yarnpkg.com' diff --git a/build-support/javascriptstyle/README.md b/build-support/javascriptstyle/README.md new file mode 100644 index 00000000000..0846ee16562 --- /dev/null +++ b/build-support/javascriptstyle/README.md @@ -0,0 +1,3 @@ +The paths node_modules/**, *.min.js, bundle.js, coverage/**, +hidden files/folders (beginning with .), and all patterns in a +project's root .gitignore file are automatically ignored. \ No newline at end of file diff --git a/build-support/javascriptstyle/bin/cli.js b/build-support/javascriptstyle/bin/cli.js new file mode 100755 index 00000000000..c66c6b6eb11 --- /dev/null +++ b/build-support/javascriptstyle/bin/cli.js @@ -0,0 +1,4 @@ +#!/usr/bin/env node + +const opts = require('../options.js'); +require('standard-engine').cli(opts); diff --git a/build-support/javascriptstyle/index.js b/build-support/javascriptstyle/index.js new file mode 100644 index 00000000000..018897a0a41 --- /dev/null +++ b/build-support/javascriptstyle/index.js @@ -0,0 +1,6 @@ +// programmatic usage +const Linter = require('standard-engine').linter; + +const opts = require('./options.js'); + +module.exports = new Linter(opts); diff --git a/build-support/javascriptstyle/options.js b/build-support/javascriptstyle/options.js new file mode 100644 index 00000000000..418e6a82aa4 --- /dev/null +++ b/build-support/javascriptstyle/options.js @@ -0,0 +1,18 @@ +const eslint = require('eslint'); +const path = require('path'); +const pkg = require('./package.json'); + +// Option configuration for standard-engine +// See https://github.com/standard/standard-engine for more details. +module.exports = { + cmd: 'javascriptstyle', // should match the "bin" key in your package.json + version: pkg.version, + homepage: pkg.homepage, + bugs: pkg.bugs.url, + tagline: 'Pants JavaScript Standard Style', + eslint: eslint, + eslintConfig: { + configFile: path.join(__dirname, '.eslintrc') + }, + cwd: '' // current working directory, passed to eslint +}; diff --git a/build-support/javascriptstyle/package.json b/build-support/javascriptstyle/package.json new file mode 100644 index 00000000000..1ad9e44c483 --- /dev/null +++ b/build-support/javascriptstyle/package.json @@ -0,0 +1,28 @@ +{ + "name": "javascriptstyle", + "version": "1.0.0", + "description": "Pants JavaScript Standard Style", + "main": "index.js", + "homepage": "https://github.com/pantsbuild/pants", + "license": "MIT", + "bin": { + "javascriptstyle": "./bin/cli.js" + }, + "scripts": { + "test": "node ./bin/cli.js && tape test/*.js", + "test-quick": "node ./bin/cli.js" + }, + "dependencies": { + "babel-eslint": "^7.2.3", + "eslint": "^4.3.0", + "standard-engine": "^7.1.0", + "tape": "^4.8.0" + }, + "bugs": { + "url": "https://github.com/pantsbuild/pants/issues" + }, + + "javascriptstyle": { + "ignore": [] + } +} diff --git a/build-support/javascriptstyle/test/api.js b/build-support/javascriptstyle/test/api.js new file mode 100644 index 00000000000..78c17c0d0fc --- /dev/null +++ b/build-support/javascriptstyle/test/api.js @@ -0,0 +1,20 @@ +const javascriptstyle = require('../'); +const test = require('tape'); + +test('api: lintFiles', function (t) { + t.plan(3); + javascriptstyle.lintFiles([], { cwd: 'bin' }, function (err, result) { + t.error(err, 'no error while linting'); + t.equal(typeof result, 'object', 'result is an object'); + t.equal(result.errorCount, 0); + }); +}); + +test('api: lintText', function (t) { + t.plan(3); + javascriptstyle.lintText('console.log("hi there");\n', function (err, result) { + t.error(err, 'no error while linting'); + t.equal(typeof result, 'object', 'result is an object'); + t.equal(result.errorCount, 1, 'should have used single quotes'); + }); +}); diff --git a/build-support/javascriptstyle/yarn.lock b/build-support/javascriptstyle/yarn.lock new file mode 100644 index 00000000000..333dbcb24ff --- /dev/null +++ b/build-support/javascriptstyle/yarn.lock @@ -0,0 +1,1113 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-eslint@^7.2.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-7.2.3.tgz#b2fe2d80126470f5c19442dc757253a897710827" + dependencies: + babel-code-frame "^6.22.0" + babel-traverse "^6.23.1" + babel-types "^6.23.0" + babylon "^6.17.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-runtime@^6.22.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.25.0.tgz#33b98eaa5d482bb01a8d1aa6b437ad2b01aec41c" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-traverse@^6.23.1: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.25.0" + babylon "^6.17.2" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.23.0, babel-types@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.17.0, babylon@^6.17.2: + version "6.17.4" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.0.1.tgz#dbec49436d2ae15f536114e76d14656cdbc0f44d" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +color-convert@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +debug-log@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debug-log/-/debug-log-1.0.1.tgz#2307632d4c04382b8df8a32f70b895046d52745f" + +debug@^2.2.0, debug@^2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + +deglob@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/deglob/-/deglob-2.1.0.tgz#4d44abe16ef32c779b4972bd141a80325029a14a" + dependencies: + find-root "^1.0.0" + glob "^7.0.5" + ignore "^3.0.9" + pkg-config "^1.1.0" + run-parallel "^1.1.2" + uniq "^1.0.1" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.5.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.7.0.tgz#dfade774e01bfcd97f96180298c449c8623fb94c" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.0" + is-callable "^1.1.3" + is-regex "^1.0.3" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.3.0.tgz#fcd7c96376bbf34c85ee67ed0012a299642b108f" + dependencies: + ajv "^5.2.0" + babel-code-frame "^6.22.0" + chalk "^1.1.3" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^2.6.8" + doctrine "^2.0.0" + eslint-scope "^3.7.1" + espree "^3.4.3" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^9.17.0" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.8.4" + json-stable-stringify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^4.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-json-comments "~2.0.1" + table "^4.0.1" + text-table "~0.2.0" + +espree@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374" + dependencies: + acorn "^5.0.1" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" + tmp "^0.0.31" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +find-root@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +for-each@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.2.tgz#2c40450b9348e97f281322593ba96704b9abd4d4" + dependencies: + is-function "~1.0.0" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +function-bind@^1.0.2, function-bind@^1.1.0, function-bind@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.2, glob@~7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.0.0, globals@^9.17.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +has@^1.0.1, has@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +iconv-lite@^0.4.17: + version "0.4.18" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" + +ignore@^3.0.9, ignore@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inquirer@^3.0.6: + version "3.2.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.1.tgz#06ceb0f540f45ca548c17d6840959878265fa175" + dependencies: + ansi-escapes "^2.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +invariant@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-function@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.1.tgz#12cfb98b65b57dd3d193a3121f5f6e2f437602b5" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-regex@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +js-tokens@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.8.4: + version "3.9.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jschardet@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.0.tgz#a61f310306a5a71188e1b1acd08add3cfbb08b1e" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash@^4.0.0, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +loose-envify@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.0, minimist@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-inspect@~1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.3.0.tgz#5b1eb8e6742e2ee83342a637034d844928ba2f6d" + +object-keys@^1.0.8: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-tmpdir@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +p-limit@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-conf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-2.0.0.tgz#071c87650403bccfb9c627f58751bfe47c067279" + dependencies: + find-up "^2.0.0" + load-json-file "^2.0.0" + +pkg-config@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pkg-config/-/pkg-config-1.1.1.tgz#557ef22d73da3c8837107766c52eadabde298fe4" + dependencies: + debug-log "^1.0.0" + find-root "^1.0.0" + xtend "^4.0.1" + +pluralize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +readable-stream@^2.2.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +regenerator-runtime@^0.10.0: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +resolve@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.4.0.tgz#a75be01c53da25d934a98ebd0e4c4a7312f92a86" + dependencies: + path-parse "^1.0.5" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + dependencies: + through "~2.3.4" + +rimraf@^2.2.8: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +run-parallel@^1.1.2: + version "1.1.6" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.6.tgz#29003c9a2163e01e2d2dfc90575f2c6c1d61a039" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +standard-engine@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/standard-engine/-/standard-engine-7.1.0.tgz#9ef48ac8e70de42dad8246c6f48f923a47469ea9" + dependencies: + deglob "^2.1.0" + get-stdin "^5.0.1" + minimist "^1.1.0" + pkg-conf "^2.0.0" + +string-width@^2.0.0, string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string.prototype.trim@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.0" + function-bind "^1.0.2" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.1.tgz#65a4bb2631e90e02420dba5554c375a4754bb836" + dependencies: + has-flag "^2.0.0" + +table@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +tape@^4.8.0: + version "4.8.0" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.8.0.tgz#f6a9fec41cc50a1de50fa33603ab580991f6068e" + dependencies: + deep-equal "~1.0.1" + defined "~1.0.0" + for-each "~0.3.2" + function-bind "~1.1.0" + glob "~7.1.2" + has "~1.0.1" + inherits "~2.0.3" + minimist "~1.2.0" + object-inspect "~1.3.0" + resolve "~1.4.0" + resumer "~0.0.0" + string.prototype.trim "~1.1.2" + through "~2.3.8" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through@^2.3.6, through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmp@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + dependencies: + os-tmpdir "~1.0.1" + +to-fast-properties@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +xtend@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" diff --git a/contrib/node/examples/src/node/hello/index.js b/contrib/node/examples/src/node/hello/index.js index 41cfe411238..7ee62919c5c 100644 --- a/contrib/node/examples/src/node/hello/index.js +++ b/contrib/node/examples/src/node/hello/index.js @@ -1,4 +1,4 @@ -if(!process.argv[2]){ +if (!process.argv[2]) { console.log(` Hello! @@ -7,7 +7,7 @@ You can also run one of the following command to greet with name: npm run start -- name yarn run start -- name ./pants run contrib/node/examples/src/node/hello:pantsbuild-hello-node -- name - `) - process.exit(0) + `); + process.exit(0); } -console.log(`Hello, ${process.argv[2]}!`) +console.log(`Hello, ${process.argv[2]}!`); diff --git a/contrib/node/src/python/pants/contrib/node/register.py b/contrib/node/src/python/pants/contrib/node/register.py index 3db672cf558..6e74ee12ff7 100644 --- a/contrib/node/src/python/pants/contrib/node/register.py +++ b/contrib/node/src/python/pants/contrib/node/register.py @@ -17,6 +17,7 @@ from pants.contrib.node.targets.node_remote_module import NodeRemoteModule from pants.contrib.node.targets.node_test import NodeTest as NodeTestTarget from pants.contrib.node.tasks.javascript_style import JavascriptStyle +from pants.contrib.node.tasks.javascript_style import JavascriptStyleFmt from pants.contrib.node.tasks.node_build import NodeBuild from pants.contrib.node.tasks.node_bundle import NodeBundle as NodeBundleTask from pants.contrib.node.tasks.node_repl import NodeRepl @@ -46,6 +47,7 @@ def register_goals(): task(name='node', action=NodeBundleTask).install('bundle') # Linting task(name='javascriptstyle', action=JavascriptStyle).install('lint') + task(name='javascriptstyle', action=JavascriptStyleFmt).install('fmt') def global_subsystems(): diff --git a/contrib/node/src/python/pants/contrib/node/targets/node_module.py b/contrib/node/src/python/pants/contrib/node/targets/node_module.py index a686f56a529..35541e89679 100644 --- a/contrib/node/src/python/pants/contrib/node/targets/node_module.py +++ b/contrib/node/src/python/pants/contrib/node/targets/node_module.py @@ -21,7 +21,7 @@ class NodeModule(NodePackage): def __init__( self, package_manager=None, sources=None, build_script=None, output_dir='dist', - dev_dependency=False, address=None, payload=None, lint_config=None, **kwargs): + dev_dependency=False, address=None, payload=None, **kwargs): """ :param sources: Javascript and other source code files that make up this module; paths are relative to the BUILD file's directory. @@ -38,8 +38,6 @@ def __init__( :param dev_dependency: boolean value. Default is False. If a node_module is used as parts of devDependencies and thus should not be included in the final bundle or JVM binaries, set this value to True. - :param lint_config: Override the default lint configuration. Any lint rules requiring a plugin - will need to be included in the node_modules/package.json. """ # TODO(John Sirois): Support devDependencies, etc. The devDependencies case is not # clear-cut since pants controlled builds would provide devDependencies as needed to perform @@ -53,8 +51,7 @@ def __init__( 'build_script': PrimitiveField(build_script), 'package_manager': PrimitiveField(package_manager), 'output_dir': PrimitiveField(output_dir), - 'dev_dependency': PrimitiveField(dev_dependency), - 'lint_config': PrimitiveField(lint_config), + 'dev_dependency': PrimitiveField(dev_dependency) }) logger.debug('NodeModule payload: %s', payload.fields) super(NodeModule, self).__init__(address=address, payload=payload, **kwargs) diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index 9d312f28eeb..1c753a06b7d 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -7,15 +7,15 @@ import os +from pants.base.build_environment import get_buildroot from pants.base.exceptions import TaskError from pants.base.workunit import WorkUnit, WorkUnitLabel -from pants.option.custom_types import file_option -from pants.util.contextutil import pushd -from pants.base.build_environment import get_buildroot - from pants.contrib.node.targets.node_package import NodePackage from pants.contrib.node.tasks.node_task import NodeTask from pants.contrib.node.tasks.node_paths import NodePaths +from pants.option.custom_types import file_option +from pants.util.contextutil import pushd +from pants.util.memo import memoized_method class JavascriptStyle(NodeTask): @@ -26,6 +26,7 @@ class JavascriptStyle(NodeTask): _JS_SOURCE_EXTENSION = '.js' _JSX_SOURCE_EXTENSION = '.jsx' + INSTALL_JAVASCRIPTSTYLE_TARGET_NAME = 'synthetic-install-javascriptstyle-module' def __init__(self, *args, **kwargs): super(JavascriptStyle, self).__init__(*args, **kwargs) @@ -33,16 +34,9 @@ def __init__(self, *args, **kwargs): @classmethod def register_options(cls, register): super(JavascriptStyle, cls).register_options(register) - register('--cmd', advanced=True, default='eslint', fingerprint=True, - help='Run this command to start style checker.') - register('--cmd-args', advanced=True, type=list, default=[], fingerprint=True, - help='Passthrough command line args.') - register('--package', advanced=True, default='eslint', fingerprint=True, help='Linter tool') register('--skip', type=bool, fingerprint=True, help='Skip javascriptstyle.') - register('--config', type=file_option, advanced=True, fingerprint=True, - help='Path to javascriptstyle config file.') - register('--linter-plugins', advanced=True, type=list, default=[], fingerprint=True, - help='Add these plugins to extend linter.') + register('--javascriptstyle-dir', advanced=True, fingerprint=True, + help='Package directory for lint tool.') def get_lintable_node_targets(self, targets): return filter( @@ -59,36 +53,32 @@ def get_javascript_sources(self, target): source.endswith(self._JSX_SOURCE_EXTENSION))) return sources - def _install_packages(self, target, packages): - """Install packages related to javascript style checker.""" - for package in packages: - self.context.log.debug('Installing package %s.'% package) + @memoized_method + def _install_javascriptstyle(self, javascriptstyle_dir): + with pushd(javascriptstyle_dir): result, yarn_add_command = self.execute_yarnpkg( - args=['add', package], - workunit_name=target.address.reference(), + args=['install'], + workunit_name=self.INSTALL_JAVASCRIPTSTYLE_TARGET_NAME, workunit_labels=[WorkUnitLabel.PREP]) if result != 0: - raise TaskError('Failed to install package: {}\n' - '\t{} failed with exit code {}'.format(package, yarn_add_command, result)) - - def _run_lint_tool(self, target, files): - command = self.get_options().cmd - command_args = self.get_options().cmd_args - global_config = self.get_options().config - config = target.payload.get_field('lint_config').value - # If no config file is specified use default config. - if not config: - config = global_config - self.context.log.info('Config: %s' % config) - args = ['run', command, '--', '--config', config, files] - args.extend(command_args) - result, yarn_run_command = self.execute_yarnpkg( + raise TaskError('Failed to install javascriptstyle\n' + '\t{} failed with exit code {}'.format(yarn_add_command, result)) + javascriptstyle_bin_path = os.path.join(javascriptstyle_dir, 'bin', 'cli.js') + return javascriptstyle_bin_path + + def _run_javascriptstyle(self, target, javascriptstyle_bin_path, files, fix=False): + args = [javascriptstyle_bin_path] + if fix: + self.context.log.info('Autoformatting is enabled for javascriptstyle.') + args.extend(['--fix']) + args.extend(files) + result, node_run_command = self.execute_node( args=args, workunit_name=target.address.reference(), workunit_labels=[WorkUnitLabel.PREP]) if result != 0: - raise TaskError('Linting failed: \n' - '{} failed with exit code {}'.format(yarn_run_command, result)) + raise TaskError('Javascript linting failed: \n' + '{} failed with exit code {}'.format(node_run_command, result)) def execute(self): if self.get_options().skip: @@ -98,16 +88,24 @@ def execute(self): targets = self.get_lintable_node_targets(self.context.targets()) if not targets: return - + javascriptstyle_dir = self.get_options().javascriptstyle_dir + self.context.log.info('{}'.format(javascriptstyle_dir)) + javascriptstyle_bin_path = self._install_javascriptstyle(javascriptstyle_dir) for target in targets: - packages = [self.get_options().package] - sources = self.get_javascript_sources(target) - if sources: - files = ' '.join(sources) - node_paths = self.context.products.get_data(NodePaths) - node_path = node_paths.node_path(target) - with pushd(node_path): - packages.extend(self.get_options().linter_plugins) - self._install_packages(target, packages) - self._run_lint_tool(target, files) - return \ No newline at end of file + files = self.get_javascript_sources(target) + if files: + self._run_javascriptstyle(target, javascriptstyle_bin_path, files) + return + + +class JavascriptStyleFmt(JavascriptStyle): + """Check and fix source files to ensure they follow the style guidelines. + + :API: public + """ + + def _run_javascriptstyle(self, target, javascriptstyle_bin_path, files, fix=True): + super(JavascriptStyleFmt, self)._run_javascriptstyle(target, + javascriptstyle_bin_path, + files, + fix=fix) \ No newline at end of file diff --git a/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD b/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD index 3ba2075f515..1061bab7555 100644 --- a/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD +++ b/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD @@ -127,3 +127,13 @@ python_tests( 'tests/python/pants_test/tasks:task_test_base', ] ) + +python_tests( + name='node_lint_integration', + sources=['test_node_lint_integration.py'], + dependencies=[ + 'tests/python/pants_test:int-test', + ], + timeout=180, + tags={'integration'}, +) diff --git a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py new file mode 100644 index 00000000000..b6a118ae900 --- /dev/null +++ b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py @@ -0,0 +1,25 @@ +# coding=utf-8 +# Copyright 2015 Pants project contributors (see CONTRIBUTORS.md). +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import (absolute_import, division, generators, nested_scopes, print_function, + unicode_literals, with_statement) + +from pants_test.pants_run_integration_test import PantsRunIntegrationTest + + +class NodeRunIntegrationTest(PantsRunIntegrationTest): + + def test_lint_success(self): + command = ['lint', + 'contrib/node/examples/src/node/hello::'] + pants_run = self.run_pants(command=command) + + self.assert_success(pants_run) + + def test_lint_failure(self): + command = ['lint', + 'contrib/node/exaamples/src/node/hello-test::'] + pants_run = self.run_pants(command=command) + + self.assert_failure(pants_run) \ No newline at end of file diff --git a/pants.ini b/pants.ini index 0f468aa10b2..a0a25430bbd 100644 --- a/pants.ini +++ b/pants.ini @@ -166,16 +166,10 @@ no_warning_args: [ configuration: %(pants_supportdir)s/checkstyle/coding_style.xml [lint.javascriptstyle] -cmd: eslint -package: eslint -config: %(buildroot)s/build-support/javascriptstyle/.eslintrc -linter_plugins: [ - 'babel-eslint', - 'eslint-plugin-flowtype', - 'eslint-plugin-jsx-a11y', - 'eslint-plugin-promise', - 'eslint-plugin-react', - ] +javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle + +[fmt.javascriptstyle] +javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle [lint.python-eval] # After we fix the cycles from the engine refactor we should re-enable this. From 76fbb7346f6ad34db84646b7714788e89f74bf26 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 14:28:35 -0700 Subject: [PATCH 03/15] undo changes for node_module.py --- .../node/src/python/pants/contrib/node/targets/node_module.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/node/src/python/pants/contrib/node/targets/node_module.py b/contrib/node/src/python/pants/contrib/node/targets/node_module.py index 35541e89679..5f67c5bc6ad 100644 --- a/contrib/node/src/python/pants/contrib/node/targets/node_module.py +++ b/contrib/node/src/python/pants/contrib/node/targets/node_module.py @@ -51,7 +51,7 @@ def __init__( 'build_script': PrimitiveField(build_script), 'package_manager': PrimitiveField(package_manager), 'output_dir': PrimitiveField(output_dir), - 'dev_dependency': PrimitiveField(dev_dependency) + 'dev_dependency': PrimitiveField(dev_dependency), }) logger.debug('NodeModule payload: %s', payload.fields) super(NodeModule, self).__init__(address=address, payload=payload, **kwargs) From b462ea22edebd966c5d7a14a63f5f588102714db Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 14:31:36 -0700 Subject: [PATCH 04/15] Add new line at end of file --- build-support/javascriptstyle/.eslintrc | 2 +- build-support/javascriptstyle/.gitignore | 2 +- .../src/python/pants/contrib/node/tasks/javascript_style.py | 2 +- .../pants_test/contrib/node/tasks/test_node_lint_integration.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build-support/javascriptstyle/.eslintrc b/build-support/javascriptstyle/.eslintrc index c43edcc6b96..68e225159d8 100644 --- a/build-support/javascriptstyle/.eslintrc +++ b/build-support/javascriptstyle/.eslintrc @@ -156,4 +156,4 @@ "yield-star-spacing": [2, "both"], "yoda": [2, "never"] } -} \ No newline at end of file +} diff --git a/build-support/javascriptstyle/.gitignore b/build-support/javascriptstyle/.gitignore index dd7174780cc..c2525e2f8fb 100644 --- a/build-support/javascriptstyle/.gitignore +++ b/build-support/javascriptstyle/.gitignore @@ -1,3 +1,3 @@ .yarnclean node_modules -yarn-error.log \ No newline at end of file +yarn-error.log diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index 1c753a06b7d..ead1cc6dfd3 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -108,4 +108,4 @@ def _run_javascriptstyle(self, target, javascriptstyle_bin_path, files, fix=True super(JavascriptStyleFmt, self)._run_javascriptstyle(target, javascriptstyle_bin_path, files, - fix=fix) \ No newline at end of file + fix=fix) diff --git a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py index b6a118ae900..f2bf59bd777 100644 --- a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py +++ b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py @@ -22,4 +22,4 @@ def test_lint_failure(self): 'contrib/node/exaamples/src/node/hello-test::'] pants_run = self.run_pants(command=command) - self.assert_failure(pants_run) \ No newline at end of file + self.assert_failure(pants_run) From 3888611547340d4197d9e6f54c11f6a98860878f Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 15:07:12 -0700 Subject: [PATCH 05/15] Add --fail-slow flag for linting all targets before failing --- .../contrib/node/tasks/javascript_style.py | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index ead1cc6dfd3..6bc4679dfc6 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -35,6 +35,8 @@ def __init__(self, *args, **kwargs): def register_options(cls, register): super(JavascriptStyle, cls).register_options(register) register('--skip', type=bool, fingerprint=True, help='Skip javascriptstyle.') + register('--fail-slow', type=bool, + help='Check all targets and present the full list of errors.') register('--javascriptstyle-dir', advanced=True, fingerprint=True, help='Package directory for lint tool.') @@ -54,7 +56,8 @@ def get_javascript_sources(self, target): return sources @memoized_method - def _install_javascriptstyle(self, javascriptstyle_dir): + def _install_javascriptstyle(self): + javascriptstyle_dir = self.get_options().javascriptstyle_dir with pushd(javascriptstyle_dir): result, yarn_add_command = self.execute_yarnpkg( args=['install'], @@ -76,9 +79,10 @@ def _run_javascriptstyle(self, target, javascriptstyle_bin_path, files, fix=Fals args=args, workunit_name=target.address.reference(), workunit_labels=[WorkUnitLabel.PREP]) - if result != 0: + if result != 0 and not self.get_options().fail_slow: raise TaskError('Javascript linting failed: \n' '{} failed with exit code {}'.format(node_run_command, result)) + return result def execute(self): if self.get_options().skip: @@ -88,13 +92,21 @@ def execute(self): targets = self.get_lintable_node_targets(self.context.targets()) if not targets: return - javascriptstyle_dir = self.get_options().javascriptstyle_dir - self.context.log.info('{}'.format(javascriptstyle_dir)) - javascriptstyle_bin_path = self._install_javascriptstyle(javascriptstyle_dir) + failed_targets = [] + + javascriptstyle_bin_path = self._install_javascriptstyle() for target in targets: files = self.get_javascript_sources(target) if files: - self._run_javascriptstyle(target, javascriptstyle_bin_path, files) + result_code = self._run_javascriptstyle(target, javascriptstyle_bin_path, files) + if result_code != 0: + failed_targets.append(target) + + if failed_targets: + msg = 'Failed when evaluating {} targets:\n {}'.format( + len(failed_targets), + '\n '.join(t.address.spec for t in failed_targets)) + raise TaskError(msg) return @@ -105,7 +117,7 @@ class JavascriptStyleFmt(JavascriptStyle): """ def _run_javascriptstyle(self, target, javascriptstyle_bin_path, files, fix=True): - super(JavascriptStyleFmt, self)._run_javascriptstyle(target, - javascriptstyle_bin_path, - files, - fix=fix) + return super(JavascriptStyleFmt, self)._run_javascriptstyle(target, + javascriptstyle_bin_path, + files, + fix=fix) From 5784d1a5a2387b9898d83987f2318c63c67354d9 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 17:05:41 -0700 Subject: [PATCH 06/15] Add blacklist for javascript style checking --- build-support/javascriptstyle/.eslintrc | 3 ++- build-support/javascriptstyle/options.js | 6 ++++++ build-support/javascriptstyle/package.json | 4 ---- contrib/node/examples/src/node/hello-test/index.js | 2 +- .../node/examples/src/node/hello-test/test/test.js | 12 ++++++------ .../contrib/node/tasks/test_node_lint_integration.py | 7 ------- 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/build-support/javascriptstyle/.eslintrc b/build-support/javascriptstyle/.eslintrc index 68e225159d8..39a05ee17ba 100644 --- a/build-support/javascriptstyle/.eslintrc +++ b/build-support/javascriptstyle/.eslintrc @@ -13,7 +13,8 @@ ], "env": { "es6": true, - "node": true + "node": true, + "mocha": true, }, "globals": { "document": false, diff --git a/build-support/javascriptstyle/options.js b/build-support/javascriptstyle/options.js index 418e6a82aa4..bf598b06f35 100644 --- a/build-support/javascriptstyle/options.js +++ b/build-support/javascriptstyle/options.js @@ -1,6 +1,7 @@ const eslint = require('eslint'); const path = require('path'); const pkg = require('./package.json'); +const exclude = require('./exclude.js'); // Option configuration for standard-engine // See https://github.com/standard/standard-engine for more details. @@ -14,5 +15,10 @@ module.exports = { eslintConfig: { configFile: path.join(__dirname, '.eslintrc') }, + parseOpts: function (opts, packageOpts, rootDir) { + // Ignore the excluded files + opts.ignore.push.apply(opts.ignore, exclude.files) + return opts + }, cwd: '' // current working directory, passed to eslint }; diff --git a/build-support/javascriptstyle/package.json b/build-support/javascriptstyle/package.json index 1ad9e44c483..c06958df251 100644 --- a/build-support/javascriptstyle/package.json +++ b/build-support/javascriptstyle/package.json @@ -20,9 +20,5 @@ }, "bugs": { "url": "https://github.com/pantsbuild/pants/issues" - }, - - "javascriptstyle": { - "ignore": [] } } diff --git a/contrib/node/examples/src/node/hello-test/index.js b/contrib/node/examples/src/node/hello-test/index.js index 381a425ab26..0086c857a71 100644 --- a/contrib/node/examples/src/node/hello-test/index.js +++ b/contrib/node/examples/src/node/hello-test/index.js @@ -6,4 +6,4 @@ You can run mocha test with one of the following command: npm run test yarn run test ./pants test contrib/node/examples/src/node/hello-test:: -`) +`); diff --git a/contrib/node/examples/src/node/hello-test/test/test.js b/contrib/node/examples/src/node/hello-test/test/test.js index 44944efe03c..a95a070b80d 100644 --- a/contrib/node/examples/src/node/hello-test/test/test.js +++ b/contrib/node/examples/src/node/hello-test/test/test.js @@ -1,11 +1,11 @@ import assert from 'assert'; -describe('GETTING STARTED', function() { +describe('GETTING STARTED', function () { describe('Array', () => { describe('#indexOf()', () => { it('should return -1 when the value is not present', () => { - assert.equal(-1, [1,2,3].indexOf(4)) - }) - }) - }) -}) + assert.equal(-1, [ 1, 2, 3 ].indexOf(4)); + }); + }); + }); +}); diff --git a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py index f2bf59bd777..538b01f5dcf 100644 --- a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py +++ b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py @@ -16,10 +16,3 @@ def test_lint_success(self): pants_run = self.run_pants(command=command) self.assert_success(pants_run) - - def test_lint_failure(self): - command = ['lint', - 'contrib/node/exaamples/src/node/hello-test::'] - pants_run = self.run_pants(command=command) - - self.assert_failure(pants_run) From 6159fca742a412c44d96feed798ab93fb5364fc4 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 17:09:31 -0700 Subject: [PATCH 07/15] Add missing exclude.js file for blacklisting js file when running lint/fmt --- build-support/javascriptstyle/exclude.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 build-support/javascriptstyle/exclude.js diff --git a/build-support/javascriptstyle/exclude.js b/build-support/javascriptstyle/exclude.js new file mode 100644 index 00000000000..075c4864898 --- /dev/null +++ b/build-support/javascriptstyle/exclude.js @@ -0,0 +1,12 @@ +module.exports = { + files: [ + "contrib/node/examples/3rdparty", + "contrib/node/examples/src/node/preinstalled-project", + "contrib/node/examples/src/node/server-project", + "contrib/node/examples/src/node/web-build-tool", + "contrib/node/examples/src/node/web-component-button", + "contrib/node/examples/src/node/web-dependency-test", + "contrib/node/examples/src/node/web-project", + "contrib/node/tests" + ] +}; From f10ae8c910fa5efb767bb6fa4ee12d546f420baf Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 2 Aug 2017 18:44:49 -0700 Subject: [PATCH 08/15] Add python_library for javascript_style so it is discoverable --- .../node/src/python/pants/contrib/node/tasks/BUILD | 14 ++++++++++++++ .../pants/contrib/node/tasks/javascript_style.py | 7 ++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/contrib/node/src/python/pants/contrib/node/tasks/BUILD b/contrib/node/src/python/pants/contrib/node/tasks/BUILD index d05a754a04c..f6f0c095930 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/BUILD +++ b/contrib/node/src/python/pants/contrib/node/tasks/BUILD @@ -9,6 +9,7 @@ target( ':node_resolve', ':node_run', ':node_test', + ':javascript_style', ] ) @@ -104,3 +105,16 @@ python_library( 'src/python/pants/util:process_handler', ] ) + +python_library( + name='javascript_style', + sources=['javascript_style.py'], + dependencies=[ + ':node_paths', + ':node_task', + 'src/python/pants/base:exceptions', + 'src/python/pants/base:workunit', + 'src/python/pants/util:contextutil', + 'src/python/pants/util:process_handler', + ] +) \ No newline at end of file diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index 6bc4679dfc6..08d4225caab 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -10,13 +10,14 @@ from pants.base.build_environment import get_buildroot from pants.base.exceptions import TaskError from pants.base.workunit import WorkUnit, WorkUnitLabel -from pants.contrib.node.targets.node_package import NodePackage -from pants.contrib.node.tasks.node_task import NodeTask -from pants.contrib.node.tasks.node_paths import NodePaths from pants.option.custom_types import file_option from pants.util.contextutil import pushd from pants.util.memo import memoized_method +from pants.contrib.node.targets.node_package import NodePackage +from pants.contrib.node.tasks.node_paths import NodePaths +from pants.contrib.node.tasks.node_task import NodeTask + class JavascriptStyle(NodeTask): """ Check javascript source files to ensure they follow the style guidelines. From 00fd49d5ff553d184228361af59deade1a106465 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Thu, 3 Aug 2017 11:01:00 -0700 Subject: [PATCH 09/15] Fix python code to match pants style guideline for python --- contrib/node/src/python/pants/contrib/node/register.py | 3 +-- .../src/python/pants/contrib/node/tasks/javascript_style.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/contrib/node/src/python/pants/contrib/node/register.py b/contrib/node/src/python/pants/contrib/node/register.py index 6e74ee12ff7..cadcbd805b7 100644 --- a/contrib/node/src/python/pants/contrib/node/register.py +++ b/contrib/node/src/python/pants/contrib/node/register.py @@ -16,8 +16,7 @@ from pants.contrib.node.targets.node_preinstalled_module import NodePreinstalledModule from pants.contrib.node.targets.node_remote_module import NodeRemoteModule from pants.contrib.node.targets.node_test import NodeTest as NodeTestTarget -from pants.contrib.node.tasks.javascript_style import JavascriptStyle -from pants.contrib.node.tasks.javascript_style import JavascriptStyleFmt +from pants.contrib.node.tasks.javascript_style import JavascriptStyle, JavascriptStyleFmt from pants.contrib.node.tasks.node_build import NodeBuild from pants.contrib.node.tasks.node_bundle import NodeBundle as NodeBundleTask from pants.contrib.node.tasks.node_repl import NodeRepl diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index 08d4225caab..175dd276a2d 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -9,13 +9,11 @@ from pants.base.build_environment import get_buildroot from pants.base.exceptions import TaskError -from pants.base.workunit import WorkUnit, WorkUnitLabel -from pants.option.custom_types import file_option +from pants.base.workunit import WorkUnitLabel from pants.util.contextutil import pushd from pants.util.memo import memoized_method from pants.contrib.node.targets.node_package import NodePackage -from pants.contrib.node.tasks.node_paths import NodePaths from pants.contrib.node.tasks.node_task import NodeTask From d6a8e1b3ba746518c4a73daa511dc21184702d19 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Tue, 8 Aug 2017 11:49:09 -0700 Subject: [PATCH 10/15] Rename NodeLineIntegrationTest to match file name --- .../pants_test/contrib/node/tasks/test_node_lint_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py index 538b01f5dcf..9132c561ff2 100644 --- a/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py +++ b/contrib/node/tests/python/pants_test/contrib/node/tasks/test_node_lint_integration.py @@ -8,7 +8,7 @@ from pants_test.pants_run_integration_test import PantsRunIntegrationTest -class NodeRunIntegrationTest(PantsRunIntegrationTest): +class NodeLintIntegrationTest(PantsRunIntegrationTest): def test_lint_success(self): command = ['lint', From 779306e681dff220d27b4dee8b874fe2e0156245 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Fri, 11 Aug 2017 12:20:12 -0700 Subject: [PATCH 11/15] Skip javascriptstyle if it is not configured. Add documentation on how to set up javascriptstyle --- build-support/javascriptstyle/README.md | 57 ++++++++++++++++++- .../contrib/node/tasks/javascript_style.py | 29 +++++++++- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/build-support/javascriptstyle/README.md b/build-support/javascriptstyle/README.md index 0846ee16562..fe269f6e9d6 100644 --- a/build-support/javascriptstyle/README.md +++ b/build-support/javascriptstyle/README.md @@ -1,3 +1,56 @@ -The paths node_modules/**, *.min.js, bundle.js, coverage/**, +# Setting up JavaScript Style Checker + +1. Download the JavaScriptStyle package from https://github.com/pantsbuild/binaries/build-support/scripts/javascriptstyle +2. Unpack the javascriptstyle.tgz into your pants support directory +3. Configure pants.ini +4. Add new rules +5. Add plugins to extend beyond the default ruleset +6. Blacklisting + +## Configuring pants.ini + +[lint.javascriptstyle] +javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle +skip: False +fail_slow: False + +[fmt.javascriptstyle] +javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle +skip: False +fail_slow: Falsertdir)s/javascriptstyle + + +## Adding new rules + +Add new rules to the .eslintrc file under the "rules" section. +A full list of eslint rules can be found at http://eslint.org/docs/rules + +For plugins, you will need to append the plugin name followed by a '/'. + + "react/jsx-indent": [2, 2] + + +## Adding new plugins + +New plugins will need to be installed in the package.json and added to the .eslintrc + +To add react plugin to package.json: + + yarn add eslint-plugin-react + +To add react plugin to .eslintrc: + + "plugins": [ + "react" + ], + + +## Blacklisting + +You can blacklist files to be excluded from the style checker by listing them in exclude.js. + +The blacklist supports glob/rglob through the use of */** syntax. See default. + +By default the paths node_modules/**, *.min.js, bundle.js, coverage/**, hidden files/folders (beginning with .), and all patterns in a -project's root .gitignore file are automatically ignored. \ No newline at end of file +project's root .gitignore file are automatically ignored. diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index 175dd276a2d..9add2ed7c82 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -54,9 +54,25 @@ def get_javascript_sources(self, target): source.endswith(self._JSX_SOURCE_EXTENSION))) return sources + def _is_javascriptstyle_dir_valid(self, javascriptstyle_dir): + dir_exists = os.path.isdir(javascriptstyle_dir) + if not dir_exists: + raise TaskError( + 'javascriptstyle package does not exist: {}.'.format(javascriptstyle_dir)) + return False + else: + lock_file = os.path.join(javascriptstyle_dir, 'yarn.lock') + package_json = os.path.join(javascriptstyle_dir, 'package.json') + files_exist = os.path.isfile(lock_file) and os.path.isfile(package_json) + if not files_exist: + raise TaskError( + 'javascriptstyle cannot be installed because yarn.lock ' + 'or package.json does not exist.') + return False + return True + @memoized_method - def _install_javascriptstyle(self): - javascriptstyle_dir = self.get_options().javascriptstyle_dir + def _install_javascriptstyle(self, javascriptstyle_dir): with pushd(javascriptstyle_dir): result, yarn_add_command = self.execute_yarnpkg( args=['install'], @@ -93,7 +109,14 @@ def execute(self): return failed_targets = [] - javascriptstyle_bin_path = self._install_javascriptstyle() + # TODO: If javascriptstyle is not configured, pants should use a default installtion. + javascriptstyle_dir = self.get_options().javascriptstyle_dir + if not (javascriptstyle_dir and self._is_javascriptstyle_dir_valid(javascriptstyle_dir)): + self.context.log.warn('javascriptstyle is not configured, skipping javascript style check.') + self.context.log.warn('See https://github.com/pantsbuild/pants/tree/master/build-support/javascriptstyle/README.md') + return + + javascriptstyle_bin_path = self._install_javascriptstyle(javascriptstyle_dir) for target in targets: files = self.get_javascript_sources(target) if files: From e49dd91bf2255038cc1d13c7221807b911cc1ccc Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Tue, 15 Aug 2017 15:31:23 -0700 Subject: [PATCH 12/15] Fix ** characters due to .md styling --- build-support/javascriptstyle/README.md | 30 +++++++++++++++---------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/build-support/javascriptstyle/README.md b/build-support/javascriptstyle/README.md index fe269f6e9d6..8357b60168a 100644 --- a/build-support/javascriptstyle/README.md +++ b/build-support/javascriptstyle/README.md @@ -9,15 +9,15 @@ ## Configuring pants.ini -[lint.javascriptstyle] -javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle -skip: False -fail_slow: False + [lint.javascriptstyle] + javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle + skip: False + fail_slow: False -[fmt.javascriptstyle] -javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle -skip: False -fail_slow: Falsertdir)s/javascriptstyle + [fmt.javascriptstyle] + javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle + skip: False + fail_slow: Falsertdir)s/javascriptstyle ## Adding new rules @@ -49,8 +49,14 @@ To add react plugin to .eslintrc: You can blacklist files to be excluded from the style checker by listing them in exclude.js. -The blacklist supports glob/rglob through the use of */** syntax. See default. +The blacklist supports glob/rglob through the use of \*/\*\* syntax. See default. -By default the paths node_modules/**, *.min.js, bundle.js, coverage/**, -hidden files/folders (beginning with .), and all patterns in a -project's root .gitignore file are automatically ignored. +By default the paths: + +- node_modules/\*\* +- *\.min.js +- bundle.js +- coverage/\*\* +- hidden files/folders (beginning with .) + +and all patterns in a project's root .gitignore file are automatically ignored. From 5cad29408b3a5607fa0c310f86c2fc0f983dae58 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Tue, 26 Sep 2017 19:16:18 -0700 Subject: [PATCH 13/15] Fix typos and add comment about why javascriptstyle uses a mutable package --- build-support/javascriptstyle/README.md | 2 +- .../pants/contrib/node/tasks/javascript_style.py | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/build-support/javascriptstyle/README.md b/build-support/javascriptstyle/README.md index 8357b60168a..70b78e702d2 100644 --- a/build-support/javascriptstyle/README.md +++ b/build-support/javascriptstyle/README.md @@ -17,7 +17,7 @@ [fmt.javascriptstyle] javascriptstyle_dir: %(pants_supportdir)s/javascriptstyle skip: False - fail_slow: Falsertdir)s/javascriptstyle + fail_slow: False ## Adding new rules diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index 9add2ed7c82..aa504c26eca 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -109,7 +109,17 @@ def execute(self): return failed_targets = [] - # TODO: If javascriptstyle is not configured, pants should use a default installtion. + # TODO: If javascriptstyle is not configured, pants should use a default installation. + # Some concerns and thoughts regarding the current javascriptstyle implementation: + # 1.) The javascriptstyle package itself is designed to be mutable. That is problematic + # as there can be many changes in the same package version across multiple installations. + # Pushing updates to the original package will feel more like a major revision. + # 2.) The decision was made to ensure deterministic installation using yarn.lock file. The lock + # file is produced after an installation. And all eslint plugins need to be final and + # explicit during installation time. + # 3.) We can potentially solve this using a caching solution for yarn.lock/package.json files. + # That is, javascriptstyle package should only include base eslint + rules and all plugins + # and additional rules should be configured through pants.ini. javascriptstyle_dir = self.get_options().javascriptstyle_dir if not (javascriptstyle_dir and self._is_javascriptstyle_dir_valid(javascriptstyle_dir)): self.context.log.warn('javascriptstyle is not configured, skipping javascript style check.') From 5e85c208997ec487588def3eac641210bcd83e72 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 27 Sep 2017 12:13:01 -0700 Subject: [PATCH 14/15] Remove irrelevant python test due to merge bug --- .../python/pants_test/contrib/node/tasks/BUILD | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD b/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD index 1061bab7555..d62eb6a6a37 100644 --- a/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD +++ b/contrib/node/tests/python/pants_test/contrib/node/tasks/BUILD @@ -111,23 +111,6 @@ python_tests( ] ) -python_tests( - name='node_test', - sources=['test_node_test.py'], - dependencies=[ - '3rdparty/python:mock', - 'contrib/node/src/python/pants/contrib/node/targets:node_module', - 'contrib/node/src/python/pants/contrib/node/targets:node_test', - 'contrib/node/src/python/pants/contrib/node/tasks:node_paths', - 'contrib/node/src/python/pants/contrib/node/tasks:node_resolve', - 'contrib/node/src/python/pants/contrib/node/tasks:node_test', - 'contrib/node/src/python/pants/contrib/node/subsystems/resolvers:npm_resolver', - 'src/python/pants/base:exceptions', - 'src/python/pants/util:timeout', - 'tests/python/pants_test/tasks:task_test_base', - ] -) - python_tests( name='node_lint_integration', sources=['test_node_lint_integration.py'], From 3fcbf33158f1ef98ef251c349e30c0a6412fc141 Mon Sep 17 00:00:00 2001 From: Ny Saechao Date: Wed, 27 Sep 2017 14:26:25 -0700 Subject: [PATCH 15/15] Add transitive as an option for javascript linting --- .../src/python/pants/contrib/node/tasks/javascript_style.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py index aa504c26eca..c6d29f621b2 100644 --- a/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py +++ b/contrib/node/src/python/pants/contrib/node/tasks/javascript_style.py @@ -38,6 +38,9 @@ def register_options(cls, register): help='Check all targets and present the full list of errors.') register('--javascriptstyle-dir', advanced=True, fingerprint=True, help='Package directory for lint tool.') + register('--transitive', type=bool, default=True, + help='True to run the tool transitively on targets in the context, false to run ' + 'for only roots specified on the commandline.') def get_lintable_node_targets(self, targets): return filter( @@ -104,7 +107,8 @@ def execute(self): self.context.log.info('Skipping javascript style check.') return - targets = self.get_lintable_node_targets(self.context.targets()) + all_targets = self.context.targets() if self.get_options().transitive else self.context.target_roots + targets = self.get_lintable_node_targets(all_targets) if not targets: return failed_targets = []