| #!/usr/bin/env python |
| # Copyright 2016 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Runs source formatters on modified files. |
| |
| In order to find the files to be formatted, this uses `git diff-index` against |
| the newest parent commit in the upstream branch (or against HEAD if there is no |
| upstream branch). In result, files that are locally modified, staged or touched |
| by any commits introduced on the local branch are formatted. |
| """ |
| |
| import argparse |
| import os |
| import platform |
| import subprocess |
| import sys |
| import git_utils |
| import paths |
| |
| clang_platform = "%s-%s" % ( |
| platform.system().lower().replace("darwin", "mac"), |
| { |
| "x86_64": "x64", |
| "aarch64": "arm64", |
| }[platform.machine()], |
| ) |
| CLANG_TOOL = os.path.join(paths.BUILDTOOLS_ROOT, clang_platform, "clang", "bin", |
| "clang-format") |
| DART_TOOL = os.path.join(paths.DART_ROOT, "bin", "dartfmt") |
| GN_TOOL = os.path.join(paths.BUILDTOOLS_ROOT, "gn") |
| gotoolos = "linux64" |
| if platform.platform().startswith("Darwin"): |
| gotoolos = "mac" |
| GO_TOOL = os.path.join(paths.BUILDTOOLS_ROOT, gotoolos, "go", "bin", "gofmt") |
| CHECK_HEADER_GUARDS_TOOL = os.path.join(paths.FUCHSIA_ROOT, "scripts", "style", |
| "check-header-guards.py") |
| |
| C_CMD = [ |
| CLANG_TOOL, "-style=file", "-fallback-style=Chromium", "-sort-includes", |
| "-i" |
| ] |
| DART_CMD = [DART_TOOL, "-w"] |
| GN_CMD = [GN_TOOL, "format"] |
| GO_CMD = [GO_TOOL, "-w"] |
| FIX_HEADER_GUARDS_COMMAND = [CHECK_HEADER_GUARDS_TOOL, "--fix"] |
| |
| EXT_TO_COMMANDS = { |
| ".cc": [C_CMD], |
| ".cpp": [C_CMD], |
| ".dart": [DART_CMD], |
| ".gn": [GN_CMD], |
| ".gni": [GN_CMD], |
| ".go": [GO_CMD], |
| ".h": [FIX_HEADER_GUARDS_COMMAND, C_CMD], |
| ".hh": [C_CMD], |
| ".hpp": [C_CMD], |
| } |
| |
| |
| def main(): |
| parser = argparse.ArgumentParser(description="Format modified files.") |
| parser.add_argument( |
| "--dry-run", |
| dest="dry_run", |
| action="store_true", |
| default=False, |
| help="just pretend to run stuff") |
| parser.add_argument( |
| "--verbose", |
| dest="verbose", |
| action="store_true", |
| default=False, |
| help="tell me what you're doing") |
| parser.add_argument( |
| "--all", |
| dest="all", |
| action="store_true", |
| default=False, |
| help="format all files in the repo, not just the modified ones") |
| args = parser.parse_args() |
| |
| # Find the files to be formatted. |
| if args.all: |
| files = git_utils.get_all_files() |
| else: |
| files = git_utils.get_diff_files() |
| |
| if args.verbose: |
| print |
| print "Files to be formatted:" |
| if not files: |
| print " (no files)" |
| return |
| |
| for file in files: |
| print " - " + file |
| |
| # Run the formatters. |
| if args.dry_run: |
| print |
| print "Would run the following formatters (dry run):" |
| elif args.verbose: |
| print "Running the following formatters:" |
| |
| count = 0 |
| |
| for file in files: |
| # Skip deleted files. |
| if not os.path.isfile(file): |
| continue |
| |
| _, extension = os.path.splitext(file) |
| if extension not in EXT_TO_COMMANDS: |
| continue |
| |
| count += 1 |
| cmds = EXT_TO_COMMANDS[extension] |
| for cmd in cmds: |
| cmd = cmd + [file] |
| if args.dry_run or args.verbose: |
| print cmd |
| |
| if args.dry_run: |
| continue |
| |
| try: |
| subprocess.check_call(cmd) |
| except Exception as e: |
| print " ".join(cmd) + " failed" |
| raise e |
| |
| if (args.dry_run or args.verbose) and not count: |
| print " (none)" |
| return 0 |
| |
| |
| if __name__ == "__main__": |
| sys.exit(main()) |