From 0a6b544e206b3adada64b01fb51d4a63c0faa580 Mon Sep 17 00:00:00 2001 From: Olivier Robin Date: Thu, 7 Apr 2022 07:25:04 +0000 Subject: [PATCH] Support git cl formatting for swift files swift format is only available on mac hosts. Swift formatting is disabled by default. It will be enabled by default on mac host in another CL. Change-Id: Id603be203edd44b6419d545027c249111abe1baf Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/3550197 Reviewed-by: Josip Sokcevic Commit-Queue: Olivier Robin --- git_cl.py | 51 +++++++++++++++++++++++++++++++++++ swift-format | 8 ++++++ swift_format.py | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+) create mode 100755 swift-format create mode 100644 swift_format.py diff --git a/git_cl.py b/git_cl.py index 57519296f..1e2f675cb 100755 --- a/git_cl.py +++ b/git_cl.py @@ -52,6 +52,7 @@ import setup_color import split_cl import subcommand import subprocess2 +import swift_format import watchlists from third_party import six @@ -5143,6 +5144,33 @@ def _RunRustFmt(opts, rust_diff_files, top_dir, upstream_commit): return 0 +def _RunSwiftFormat(opts, swift_diff_files, top_dir, upstream_commit): + """Runs swift-format. Just like _RunClangFormatDiff returns 2 to indicate + that presubmit checks have failed (and returns 0 otherwise).""" + + if not swift_diff_files: + return 0 + + # Locate the swift-format binary. + try: + swift_format_tool = swift_format.FindSwiftFormatToolInChromiumTree() + except swift_format.NotFoundError as e: + DieWithError(e) + + cmd = [swift_format_tool] + if opts.dry_run: + cmd.append('lint') + else: + cmd += ['format', '-i'] + cmd += swift_diff_files + swift_format_exitcode = subprocess2.call(cmd) + + if opts.presubmit and swift_format_exitcode != 0: + return 2 + + return 0 + + def MatchingFileType(file_name, extensions): """Returns True if the file name ends with one of the given extensions.""" return bool([ext for ext in extensions if file_name.lower().endswith(ext)]) @@ -5155,6 +5183,7 @@ def CMDformat(parser, args): CLANG_EXTS = ['.cc', '.cpp', '.h', '.m', '.mm', '.proto', '.java'] GN_EXTS = ['.gn', '.gni', '.typemap'] RUST_EXTS = ['.rs'] + SWIFT_EXTS = ['.swift'] parser.add_option('--full', action='store_true', help='Reformat the full content of all touched files') parser.add_option('--upstream', help='Branch to check against') @@ -5200,6 +5229,19 @@ def CMDformat(parser, args): action='store_false', help='Disables formatting of Rust file types using rustfmt.') + parser.add_option( + '--swift-format', + dest='use_swift_format', + action='store_true', + default=False, + help='Enables formatting of Swift file types using swift-format ' + '(macOS host only).') + parser.add_option( + '--no-swift-format', + dest='use_swift_format', + action='store_false', + help='Disables formatting of Swift file types using swift-format.') + opts, args = parser.parse_args(args) if opts.python is not None and opts.no_python: @@ -5250,6 +5292,7 @@ def CMDformat(parser, args): ] python_diff_files = [x for x in diff_files if MatchingFileType(x, ['.py'])] rust_diff_files = [x for x in diff_files if MatchingFileType(x, RUST_EXTS)] + swift_diff_files = [x for x in diff_files if MatchingFileType(x, SWIFT_EXTS)] gn_diff_files = [x for x in diff_files if MatchingFileType(x, GN_EXTS)] top_dir = settings.GetRoot() @@ -5263,6 +5306,14 @@ def CMDformat(parser, args): if rust_fmt_return_value == 2: return_value = 2 + if opts.use_swift_format: + if sys.platform != 'darwin': + DieWithError('swift-format is only supported on macOS.') + swift_format_return_value = _RunSwiftFormat(opts, swift_diff_files, top_dir, + upstream_commit) + if swift_format_return_value == 2: + return_value = 2 + # Similar code to above, but using yapf on .py files rather than clang-format # on C/C++ files py_explicitly_disabled = opts.python is not None and not opts.python diff --git a/swift-format b/swift-format new file mode 100755 index 000000000..b0162db17 --- /dev/null +++ b/swift-format @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +base_dir=$(dirname "$0") + +PYTHONDONTWRITEBYTECODE=1 exec python3 "$base_dir/swift_format.py" "$@" diff --git a/swift_format.py b/swift_format.py new file mode 100644 index 000000000..50536fe5e --- /dev/null +++ b/swift_format.py @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +# Copyright 2022 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""Redirects to the version of swift-format present in the Chrome tree. + +Swift format binaries are pulled down from CIPD whenever you sync Chrome. +This script knows how to locate those tools, assuming the script is +invoked from inside a Chromium checkout.""" + +import gclient_paths +import os +import subprocess +import sys + + +class NotFoundError(Exception): + """A file could not be found.""" + + def __init__(self, e): + Exception.__init__( + self, + 'Problem while looking for swift-format in Chromium source tree:\n' + '%s' % e) + + +def FindSwiftFormatToolInChromiumTree(): + """Return a path to the rustfmt executable, or die trying.""" + chromium_src_path = gclient_paths.GetPrimarySolutionPath() + if not chromium_src_path: + raise NotFoundError( + 'Could not find checkout in any parent of the current path.\n' + 'Set CHROMIUM_BUILDTOOLS_PATH to use outside of a chromium checkout.') + + tool_path = os.path.join(chromium_src_path, 'third_party', 'swift-format', + 'swift-format') + if not os.path.exists(tool_path): + raise NotFoundError('File does not exist: %s' % tool_path) + return tool_path + + +def IsSwiftFormatSupported(): + try: + FindSwiftFormatToolInChromiumTree() + return True + except NotFoundError: + return False + + +def main(args): + try: + tool = FindSwiftFormatToolInChromiumTree() + except NotFoundError as e: + sys.stderr.write("%s\n" % str(e)) + return 1 + + # Add some visibility to --help showing where the tool lives, since this + # redirection can be a little opaque. + help_syntax = ('-h', '--help', '-help', '-help-list', '--help-list') + if any(match in args for match in help_syntax): + print('\nDepot tools redirects you to the swift-format at:\n %s\n' % + tool) + + return subprocess.call([tool] + args) + + +if __name__ == '__main__': + try: + sys.exit(main(sys.argv[1:])) + except KeyboardInterrupt: + sys.stderr.write('interrupted\n') + sys.exit(1)