3 # Copyright 2008 The Closure Linter Authors. All Rights Reserved.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS-IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 """Determines the list of files to be checked from command line arguments."""
19 __author__ = ('robbyw@google.com (Robert Walker)',
20 'ajp@google.com (Andy Perelson)')
26 import gflags as flags
31 flags.DEFINE_multistring(
34 'Recurse in to the subdirectories of the given path',
37 'exclude_directories',
39 'Exclude the specified directories (only applicable along with -r or '
45 'Exclude the specified files',
49 def MatchesSuffixes(filename, suffixes):
50 """Returns whether the given filename matches one of the given suffixes.
53 filename: Filename to check.
54 suffixes: Sequence of suffixes to check.
57 Whether the given filename matches one of the given suffixes.
59 suffix = filename[filename.rfind('.'):]
60 return suffix in suffixes
63 def _GetUserSpecifiedFiles(argv, suffixes):
64 """Returns files to be linted, specified directly on the command line.
66 Can handle the '*' wildcard in filenames, but no other wildcards.
69 argv: Sequence of command line arguments. The second and following arguments
70 are assumed to be files that should be linted.
71 suffixes: Expected suffixes for the file type being checked.
74 A sequence of files to be linted.
76 files = argv[1:] or []
80 # Perform any necessary globs.
83 for result in glob.glob(f):
84 all_files.append(result)
89 if MatchesSuffixes(f, suffixes):
94 def _GetRecursiveFiles(suffixes):
95 """Returns files to be checked specified by the --recurse flag.
98 suffixes: Expected suffixes for the file type being checked.
101 A list of files to be checked.
104 # Perform any request recursion
106 for start in FLAGS.recurse:
107 for root, subdirs, files in os.walk(start):
109 if MatchesSuffixes(f, suffixes):
110 lint_files.append(os.path.join(root, f))
114 def GetAllSpecifiedFiles(argv, suffixes):
115 """Returns all files specified by the user on the commandline.
118 argv: Sequence of command line arguments. The second and following arguments
119 are assumed to be files that should be linted.
120 suffixes: Expected suffixes for the file type
123 A list of all files specified directly or indirectly (via flags) on the
124 command line by the user.
126 files = _GetUserSpecifiedFiles(argv, suffixes)
129 files += _GetRecursiveFiles(suffixes)
131 return FilterFiles(files)
134 def FilterFiles(files):
135 """Filters the list of files to be linted be removing any excluded files.
137 Filters out files excluded using --exclude_files and --exclude_directories.
140 files: Sequence of files that needs filtering.
143 Filtered list of files to be linted.
145 num_files = len(files)
147 ignore_dirs_regexs = []
148 for ignore in FLAGS.exclude_directories:
149 ignore_dirs_regexs.append(re.compile(r'(^|[\\/])%s[\\/]' % ignore))
154 for exclude in FLAGS.exclude_files:
155 if f.endswith('/' + exclude) or f == exclude:
158 for ignore in ignore_dirs_regexs:
160 # Break out of ignore loop so we don't add to
165 # Convert everything to absolute paths so we can easily remove duplicates
167 result_files.append(os.path.abspath(f))
169 skipped = num_files - len(result_files)
171 print 'Skipping %d file(s).' % skipped
173 return set(result_files)
176 def GetFileList(argv, file_type, suffixes):
177 """Parse the flags and return the list of files to check.
180 argv: Sequence of command line arguments.
181 suffixes: Sequence of acceptable suffixes for the file type.
184 The list of files to check.
186 return sorted(GetAllSpecifiedFiles(argv, suffixes))
189 def IsEmptyArgumentList(argv):
190 return not (len(argv[1:]) or FLAGS.recurse)