| #!/usr/bin/env python |
| # |
| # Copyright 2008 The Closure Linter Authors. All Rights Reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS-IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| """Determines the list of files to be checked from command line arguments.""" |
| |
| __author__ = ('robbyw@google.com (Robert Walker)', |
| 'ajp@google.com (Andy Perelson)') |
| |
| import glob |
| import os |
| import re |
| |
| import gflags as flags |
| |
| |
| FLAGS = flags.FLAGS |
| |
| flags.DEFINE_multistring( |
| 'recurse', |
| None, |
| 'Recurse in to the subdirectories of the given path', |
| short_name='r') |
| flags.DEFINE_list( |
| 'exclude_directories', |
| ('_demos'), |
| 'Exclude the specified directories (only applicable along with -r or ' |
| '--presubmit)', |
| short_name='e') |
| flags.DEFINE_list( |
| 'exclude_files', |
| ('deps.js'), |
| 'Exclude the specified files', |
| short_name='x') |
| |
| |
| def MatchesSuffixes(filename, suffixes): |
| """Returns whether the given filename matches one of the given suffixes. |
| |
| Args: |
| filename: Filename to check. |
| suffixes: Sequence of suffixes to check. |
| |
| Returns: |
| Whether the given filename matches one of the given suffixes. |
| """ |
| suffix = filename[filename.rfind('.'):] |
| return suffix in suffixes |
| |
| |
| def _GetUserSpecifiedFiles(argv, suffixes): |
| """Returns files to be linted, specified directly on the command line. |
| |
| Can handle the '*' wildcard in filenames, but no other wildcards. |
| |
| Args: |
| argv: Sequence of command line arguments. The second and following arguments |
| are assumed to be files that should be linted. |
| suffixes: Expected suffixes for the file type being checked. |
| |
| Returns: |
| A sequence of files to be linted. |
| """ |
| files = argv[1:] or [] |
| all_files = [] |
| lint_files = [] |
| |
| # Perform any necessary globs. |
| for f in files: |
| if f.find('*') != -1: |
| for result in glob.glob(f): |
| all_files.append(result) |
| else: |
| all_files.append(f) |
| |
| for f in all_files: |
| if MatchesSuffixes(f, suffixes): |
| lint_files.append(f) |
| return lint_files |
| |
| |
| def _GetRecursiveFiles(suffixes): |
| """Returns files to be checked specified by the --recurse flag. |
| |
| Args: |
| suffixes: Expected suffixes for the file type being checked. |
| |
| Returns: |
| A list of files to be checked. |
| """ |
| lint_files = [] |
| # Perform any request recursion |
| if FLAGS.recurse: |
| for start in FLAGS.recurse: |
| for root, subdirs, files in os.walk(start): |
| for f in files: |
| if MatchesSuffixes(f, suffixes): |
| lint_files.append(os.path.join(root, f)) |
| return lint_files |
| |
| |
| def GetAllSpecifiedFiles(argv, suffixes): |
| """Returns all files specified by the user on the commandline. |
| |
| Args: |
| argv: Sequence of command line arguments. The second and following arguments |
| are assumed to be files that should be linted. |
| suffixes: Expected suffixes for the file type |
| |
| Returns: |
| A list of all files specified directly or indirectly (via flags) on the |
| command line by the user. |
| """ |
| files = _GetUserSpecifiedFiles(argv, suffixes) |
| |
| if FLAGS.recurse: |
| files += _GetRecursiveFiles(suffixes) |
| |
| return FilterFiles(files) |
| |
| |
| def FilterFiles(files): |
| """Filters the list of files to be linted be removing any excluded files. |
| |
| Filters out files excluded using --exclude_files and --exclude_directories. |
| |
| Args: |
| files: Sequence of files that needs filtering. |
| |
| Returns: |
| Filtered list of files to be linted. |
| """ |
| num_files = len(files) |
| |
| ignore_dirs_regexs = [] |
| for ignore in FLAGS.exclude_directories: |
| ignore_dirs_regexs.append(re.compile(r'(^|[\\/])%s[\\/]' % ignore)) |
| |
| result_files = [] |
| for f in files: |
| add_file = True |
| for exclude in FLAGS.exclude_files: |
| if f.endswith('/' + exclude) or f == exclude: |
| add_file = False |
| break |
| for ignore in ignore_dirs_regexs: |
| if ignore.search(f): |
| # Break out of ignore loop so we don't add to |
| # filtered files. |
| add_file = False |
| break |
| if add_file: |
| # Convert everything to absolute paths so we can easily remove duplicates |
| # using a set. |
| result_files.append(os.path.abspath(f)) |
| |
| skipped = num_files - len(result_files) |
| if skipped: |
| print 'Skipping %d file(s).' % skipped |
| |
| return set(result_files) |
| |
| |
| def GetFileList(argv, file_type, suffixes): |
| """Parse the flags and return the list of files to check. |
| |
| Args: |
| argv: Sequence of command line arguments. |
| suffixes: Sequence of acceptable suffixes for the file type. |
| |
| Returns: |
| The list of files to check. |
| """ |
| return sorted(GetAllSpecifiedFiles(argv, suffixes)) |
| |
| |
| def IsEmptyArgumentList(argv): |
| return not (len(argv[1:]) or FLAGS.recurse) |