diff options
Diffstat (limited to 'buildscripts/eslint.py')
-rwxr-xr-x | buildscripts/eslint.py | 93 |
1 files changed, 40 insertions, 53 deletions
diff --git a/buildscripts/eslint.py b/buildscripts/eslint.py index 8a68220d5cd..bb365311640 100755 --- a/buildscripts/eslint.py +++ b/buildscripts/eslint.py @@ -1,15 +1,17 @@ #!/usr/bin/env python +"""ESLint module. + +Will download a prebuilt ESLint binary if necessary (i.e. it isn't installed, isn't in the current +path, or is the wrong version). It works in much the same way as clang_format.py. In lint mode, it +will lint the files or directory paths passed. In lint-patch mode, for upload.py, it will see if +there are any candidate files in the supplied patch. Fix mode will run ESLint with the --fix +option, and that will update the files with missing semicolons and similar repairable issues. +There is also a -d mode that assumes you only want to run one copy of ESLint per file / directory +parameter supplied. This lets ESLint search for candidate files to lint. """ -eslint.py - Will download a prebuilt ESLint binary if necessary (i.e. it isn't installed, isn't in the current - path, or is the wrong version). It works in much the same way as clang_format.py. In lint mode, it - will lint the files or directory paths passed. In lint-patch mode, for upload.py, it will see if - there are any candidate files in the supplied patch. Fix mode will run ESLint with the --fix - option, and that will update the files with missing semicolons and similar repairable issues. - There is also a -d mode that assumes you only want to run one copy of ESLint per file / directory - parameter supplied. This lets ESLint search for candidate files to lint. -""" -import itertools + +from __future__ import print_function + import os import shutil import string @@ -19,17 +21,17 @@ import tarfile import tempfile import threading import urllib -from distutils import spawn +from distutils import spawn # pylint: disable=no-name-in-module from optparse import OptionParser # Get relative imports to work when the package is not installed on the PYTHONPATH. if __name__ == "__main__" and __package__ is None: sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(os.path.realpath(__file__))))) -from buildscripts.resmokelib.utils import globstar +from buildscripts.resmokelib.utils import globstar # pylint: disable=wrong-import-position -from buildscripts.linter import git -from buildscripts.linter import parallel +from buildscripts.linter import git # pylint: disable=wrong-import-position +from buildscripts.linter import parallel # pylint: disable=wrong-import-position ############################################################################## # @@ -54,12 +56,12 @@ ESLINT_SOURCE_TAR_BASE = string.Template(ESLINT_PROGNAME + "-$platform-$arch") def callo(args): - """Call a program, and capture its output - """ + """Call a program, and capture its output.""" return subprocess.check_output(args) def extract_eslint(tar_path, target_file): + """Extract ESLint tar file.""" tarfp = tarfile.open(tar_path) for name in tarfp.getnames(): if name == target_file: @@ -68,8 +70,7 @@ def extract_eslint(tar_path, target_file): def get_eslint_from_cache(dest_file, platform, arch): - """Get ESLint binary from mongodb's cache - """ + """Get ESLint binary from mongodb's cache.""" # Get URL if platform == "Linux": url = ESLINT_HTTP_LINUX_CACHE @@ -91,10 +92,10 @@ def get_eslint_from_cache(dest_file, platform, arch): class ESLint(object): - """Class encapsulates finding a suitable copy of ESLint, and linting an individual file - """ + """Class encapsulates finding a suitable copy of ESLint, and linting an individual file.""" - def __init__(self, path, cache_dir): + def __init__(self, path, cache_dir): # pylint: disable=too-many-branches + """Initialize ESLint.""" eslint_progname = ESLINT_PROGNAME # Initialize ESLint configuration information @@ -150,8 +151,7 @@ class ESLint(object): self.print_lock = threading.Lock() def _validate_version(self, warn=False): - """Validate ESLint is the expected version - """ + """Validate ESLint is the expected version.""" esl_version = callo([self.path, "--version"]).rstrip() # Ignore the leading v in the version string. if ESLINT_VERSION == esl_version[1:]: @@ -163,52 +163,43 @@ class ESLint(object): return False def _lint(self, file_name, print_diff): - """Check the specified file for linting errors - """ + """Check the specified file for linting errors.""" # ESLint returns non-zero on a linting error. That's all we care about # so only enter the printing logic if we have an error. try: - eslint_output = callo([self.path, "-f", "unix", file_name]) - except subprocess.CalledProcessError as e: + callo([self.path, "-f", "unix", file_name]) + except subprocess.CalledProcessError as err: if print_diff: # Take a lock to ensure error messages do not get mixed when printed to the screen with self.print_lock: print("ERROR: ESLint found errors in " + file_name) - print(e.output) - return False - except: - print("ERROR: ESLint process threw unexpected error", sys.exc_info()[0]) + print(err.output) return False return True def lint(self, file_name): - """Check the specified file has no linting errors - """ + """Check the specified file has no linting errors.""" return self._lint(file_name, print_diff=True) def autofix(self, file_name): - """ Run ESLint in fix mode. - """ + """Run ESLint in fix mode.""" return not subprocess.call([self.path, "--fix", file_name]) def is_interesting_file(file_name): - """"Return true if this file should be checked - """ + """Return true if this file should be checked.""" return ((file_name.startswith("src/mongo") or file_name.startswith("jstests")) and file_name.endswith(".js")) def _get_build_dir(): - """Get the location of the scons build directory in case we need to download ESLint - """ + """Get the location of the scons build directory in case we need to download ESLint.""" return os.path.join(git.get_base_dir(), "build") def _lint_files(eslint, files): - """Lint a list of files with ESLint - """ + """Lint a list of files with ESLint.""" eslint = ESLint(eslint, _get_build_dir()) lint_clean = parallel.parallel_process([os.path.abspath(f) for f in files], eslint.lint) @@ -222,8 +213,7 @@ def _lint_files(eslint, files): def lint_patch(eslint, infile): - """Lint patch command entry point - """ + """Lint patch command entry point.""" files = git.get_files_to_check_from_patch(infile, is_interesting_file) # Patch may have files that we do not want to check which is fine @@ -233,12 +223,11 @@ def lint_patch(eslint, infile): def lint(eslint, dirmode, glob): - """Lint files command entry point - """ + """Lint files command entry point.""" if dirmode and glob: files = glob else: - files = get_files_to_check(glob, is_interesting_file) + files = git.get_files_to_check(glob, is_interesting_file) _lint_files(eslint, files) @@ -246,8 +235,7 @@ def lint(eslint, dirmode, glob): def _autofix_files(eslint, files): - """Auto-fix the specified files with ESLint. - """ + """Auto-fix the specified files with ESLint.""" eslint = ESLint(eslint, _get_build_dir()) autofix_clean = parallel.parallel_process([os.path.abspath(f) for f in files], eslint.autofix) @@ -255,22 +243,21 @@ def _autofix_files(eslint, files): if not autofix_clean: print("ERROR: failed to auto-fix files") return False + return True def autofix_func(eslint, dirmode, glob): - """Auto-fix files command entry point - """ + """Auto-fix files command entry point.""" if dirmode: files = glob else: - files = get_files_to_check(glob, is_interesting_file) + files = git.get_files_to_check(glob, is_interesting_file) return _autofix_files(eslint, files) def main(): - """Main entry point - """ + """Execute Main entry point.""" success = False usage = "%prog [-e <eslint>] [-d] lint|lint-patch|fix [glob patterns] " description = "lint runs ESLint on provided patterns or all .js files under jstests/ "\ |