Commit 9d0644d7 authored by sbc@chromium.org's avatar sbc@chromium.org

Add experimental support for python in 'git cl format'

Based on yapf (https://github.com/google/yapf) this
formatter currently only works with --full.  It defaults
to pep8 style and projects that use a different style
can add .style.yapf to the top level.

Review URL: https://codereview.chromium.org/1156743008

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@295547 0039d316-1c4b-4281-b951-d872f2087c98
parent 015cdc34
[style]
based_on_style = chromium
......@@ -698,6 +698,8 @@ def GetBuildtoolsPath():
return override
primary_solution = GetPrimarySolutionPath()
if not primary_solution:
return None
buildtools_path = os.path.join(primary_solution, 'buildtools')
if not os.path.exists(buildtools_path):
# Buildtools may be in the gclient root.
......@@ -1171,6 +1173,7 @@ def NumLocalCpus():
logging.debug('Failed to get CPU count. Defaulting to 1.')
return 1
def DefaultDeltaBaseCacheLimit():
"""Return a reasonable default for the git config core.deltaBaseCacheLimit.
......@@ -1183,6 +1186,7 @@ def DefaultDeltaBaseCacheLimit():
else:
return '512m'
def DefaultIndexPackConfig(url=''):
"""Return reasonable default values for configuring git-index-pack.
......@@ -1193,3 +1197,21 @@ def DefaultIndexPackConfig(url=''):
if url in THREADED_INDEX_PACK_BLACKLIST:
result.extend(['-c', 'pack.threads=1'])
return result
def FindExecutable(executable):
"""This mimics the "which" utility."""
path_folders = os.environ.get('PATH').split(os.pathsep)
for path_folder in path_folders:
target = os.path.join(path_folder, executable)
# Just incase we have some ~/blah paths.
target = os.path.abspath(os.path.expanduser(target))
if os.path.isfile(target) and os.access(target, os.X_OK):
return target
if sys.platform.startswith('win'):
for suffix in ('.bat', '.cmd', '.exe'):
alt_target = target + suffix
if os.path.isfile(alt_target) and os.access(alt_target, os.X_OK):
return alt_target
return None
......@@ -185,24 +185,6 @@ class Mirror(object):
netpath = re.sub(r'\b-\b', '/', os.path.basename(path)).replace('--', '-')
return 'https://%s' % netpath
@staticmethod
def FindExecutable(executable):
"""This mimics the "which" utility."""
path_folders = os.environ.get('PATH').split(os.pathsep)
for path_folder in path_folders:
target = os.path.join(path_folder, executable)
# Just incase we have some ~/blah paths.
target = os.path.abspath(os.path.expanduser(target))
if os.path.isfile(target) and os.access(target, os.X_OK):
return target
if sys.platform.startswith('win'):
for suffix in ('.bat', '.cmd', '.exe'):
alt_target = target + suffix
if os.path.isfile(alt_target) and os.access(alt_target, os.X_OK):
return alt_target
return None
@classmethod
def SetCachePath(cls, cachepath):
with cls.cachepath_lock:
......@@ -273,12 +255,13 @@ class Mirror(object):
"""
python_fallback = False
if sys.platform.startswith('win') and not self.FindExecutable('7z'):
if (sys.platform.startswith('win') and
not gclient_utils.FindExecutable('7z')):
python_fallback = True
elif sys.platform.startswith('darwin'):
# The OSX version of unzip doesn't support zip64.
python_fallback = True
elif not self.FindExecutable('unzip'):
elif not gclient_utils.FindExecutable('unzip'):
python_fallback = True
gs_folder = 'gs://%s/%s' % (self.bootstrap_bucket, self.basedir)
......
......@@ -3183,12 +3183,14 @@ def BuildGitDiffCmd(diff_type, upstream_commit, args, extensions):
@subcommand.usage('[files or directories to diff]')
def CMDformat(parser, args):
"""Runs clang-format on the diff."""
"""Runs auto-formatting tools (clang-format etc.) on the diff."""
CLANG_EXTS = ['.cc', '.cpp', '.h', '.mm', '.proto', '.java']
parser.add_option('--full', action='store_true',
help='Reformat the full content of all touched files')
parser.add_option('--dry-run', action='store_true',
help='Don\'t modify any file on disk.')
parser.add_option('--python', action='store_true',
help='Format python code with yapf (experimental).')
parser.add_option('--diff', action='store_true',
help='Print diff to stdout rather than modifying files.')
opts, args = parser.parse_args(args)
......@@ -3216,12 +3218,12 @@ def CMDformat(parser, args):
if opts.full:
# Only list the names of modified files.
clang_diff_type = '--name-only'
diff_type = '--name-only'
else:
# Only generate context-less patches.
clang_diff_type = '-U0'
diff_type = '-U0'
diff_cmd = BuildGitDiffCmd(clang_diff_type, upstream_commit, args, CLANG_EXTS)
diff_cmd = BuildGitDiffCmd(diff_type, upstream_commit, args, CLANG_EXTS)
diff_output = RunGit(diff_cmd)
top_dir = os.path.normpath(
......@@ -3267,6 +3269,29 @@ def CMDformat(parser, args):
if opts.dry_run and len(stdout) > 0:
return_value = 2
# Similar code to above, but using yapf on .py files rather than clang-format
# on C/C++ files
if opts.python:
diff_cmd = BuildGitDiffCmd(diff_type, upstream_commit, args, ['.py'])
diff_output = RunGit(diff_cmd)
yapf_tool = gclient_utils.FindExecutable('yapf')
if yapf_tool is None:
DieWithError('yapf not found in PATH')
if opts.full:
files = diff_output.splitlines()
if files:
cmd = [yapf_tool]
if not opts.dry_run and not opts.diff:
cmd.append('-i')
stdout = RunCommand(cmd + files, cwd=top_dir)
if opts.diff:
sys.stdout.write(stdout)
else:
# TODO(sbc): yapf --lines mode still has some issues.
# https://github.com/google/yapf/issues/154
DieWithError('--python currently only works with --full')
# Build a diff command that only operates on dart files. dart's formatter
# does not have the nice property of only operating on modified chunks, so
# hard code full.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment