62def list_files(files, recursive=False, extensions=None, exclude=None):
63 if extensions
is None:
70 if recursive
and os.path.isdir(file):
71 for dirpath, dnames, fnames
in os.walk(file):
72 fpaths = [os.path.join(dirpath, fname)
for fname
in fnames]
73 for pattern
in exclude:
80 not fnmatch.fnmatch(os.path.join(dirpath, x), pattern)
83 x
for x
in fpaths
if not fnmatch.fnmatch(x, pattern)
86 ext = os.path.splitext(f)[1][1:]
130 with io.open(file,
'r', encoding=
'utf-8')
as f:
131 original = f.readlines()
132 except IOError
as exc:
136 invocation = [args.clang_format_executable,
'-i', file]
138 invocation = [args.clang_format_executable, file]
141 invocation.extend([
'--style', args.style])
144 print(
" ".join(invocation))
166 if sys.version_info[0] >= 3:
167 encoding_py3[
'encoding'] =
'utf-8'
170 proc = subprocess.Popen(
172 stdout=subprocess.PIPE,
173 stderr=subprocess.PIPE,
174 universal_newlines=
True,
176 except OSError
as exc:
178 "Command '{}' failed to start: {}".format(
179 subprocess.list2cmdline(invocation), exc
182 proc_stdout = proc.stdout
183 proc_stderr = proc.stderr
184 if sys.version_info[0] < 3:
188 proc_stdout = codecs.getreader(encoding)(proc_stdout)
189 proc_stderr = codecs.getreader(encoding)(proc_stderr)
191 outs = list(proc_stdout.readlines())
192 errs = list(proc_stderr.readlines())
196 "Command '{}' returned non-zero exit status {}".format(
197 subprocess.list2cmdline(invocation), proc.returncode
203 return make_diff(file, original, outs), errs
253 parser = argparse.ArgumentParser(description=__doc__)
255 '--clang-format-executable',
256 metavar=
'EXECUTABLE',
257 help=
'path to the clang-format executable',
258 default=
'clang-format')
261 help=
'comma separated list of file extensions (default: {})'.format(
263 default=DEFAULT_EXTENSIONS)
268 help=
'run recursively over directories')
273 help=
'just print the list of files')
278 help=
'format file instead of printing differences')
279 parser.add_argument(
'files', metavar=
'file', nargs=
'+')
284 help=
"disable output, useful for the exit code")
290 help=
'run N clang-format jobs in parallel'
291 ' (default number of cpus + 1)')
295 choices=[
'auto',
'always',
'never'],
296 help=
'show colored diff (default: auto)')
303 help=
'exclude paths matching the given glob-like pattern(s)'
304 ' from recursive search')
307 help=
'formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)')
309 args = parser.parse_args()
313 signal.signal(signal.SIGINT, signal.SIG_DFL)
316 except AttributeError:
320 signal.signal(signal.SIGPIPE, signal.SIG_DFL)
322 colored_stdout =
False
323 colored_stderr =
False
324 if args.color ==
'always':
325 colored_stdout =
True
326 colored_stderr =
True
327 elif args.color ==
'auto':
328 colored_stdout = sys.stdout.isatty()
329 colored_stderr = sys.stderr.isatty()
331 version_invocation = [args.clang_format_executable, str(
"--version")]
333 subprocess.check_call(version_invocation, stdout=DEVNULL)
334 except subprocess.CalledProcessError
as e:
335 print_trouble(parser.prog, str(e), use_colors=colored_stderr)
336 return ExitStatus.TROUBLE
340 "Command '{}' failed to start: {}".format(
341 subprocess.list2cmdline(version_invocation), e
343 use_colors=colored_stderr,
345 return ExitStatus.TROUBLE
347 retcode = ExitStatus.SUCCESS
350 excludes.extend(args.exclude)
354 recursive=args.recursive,
356 extensions=args.extensions.split(
','))
363 njobs = multiprocessing.cpu_count() + 1
364 njobs =
min(len(files), njobs)
372 pool = multiprocessing.Pool(njobs)
373 it = pool.imap_unordered(
374 partial(run_clang_format_diff_wrapper, args), files)
378 outs, errs = next(it)
379 except StopIteration:
381 except DiffError
as e:
382 print_trouble(parser.prog, str(e), use_colors=colored_stderr)
383 retcode = ExitStatus.TROUBLE
384 sys.stderr.writelines(e.errs)
385 except UnexpectedError
as e:
386 print_trouble(parser.prog, str(e), use_colors=colored_stderr)
387 sys.stderr.write(e.formatted_traceback)
388 retcode = ExitStatus.TROUBLE
396 sys.stderr.writelines(errs)
401 if retcode == ExitStatus.SUCCESS:
402 retcode = ExitStatus.DIFF