OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 # Copyright (C) 2008 Evan Martin <martine@danga.com> | 6 # Copyright (C) 2008 Evan Martin <martine@danga.com> |
7 | 7 |
8 """A git-command for integrating reviews on Rietveld.""" | 8 """A git-command for integrating reviews on Rietveld.""" |
9 | 9 |
10 from distutils.version import LooseVersion | 10 from distutils.version import LooseVersion |
(...skipping 3165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3176 else: | 3176 else: |
3177 DieWithError('Argument "%s" is not a file or a directory' % arg) | 3177 DieWithError('Argument "%s" is not a file or a directory' % arg) |
3178 else: | 3178 else: |
3179 diff_cmd.extend('*' + ext for ext in extensions) | 3179 diff_cmd.extend('*' + ext for ext in extensions) |
3180 | 3180 |
3181 return diff_cmd | 3181 return diff_cmd |
3182 | 3182 |
3183 | 3183 |
3184 @subcommand.usage('[files or directories to diff]') | 3184 @subcommand.usage('[files or directories to diff]') |
3185 def CMDformat(parser, args): | 3185 def CMDformat(parser, args): |
3186 """Runs clang-format on the diff.""" | 3186 """Runs auto-formatting tools (clang-format etc.) on the diff.""" |
3187 CLANG_EXTS = ['.cc', '.cpp', '.h', '.mm', '.proto', '.java'] | 3187 CLANG_EXTS = ['.cc', '.cpp', '.h', '.mm', '.proto', '.java'] |
3188 parser.add_option('--full', action='store_true', | 3188 parser.add_option('--full', action='store_true', |
3189 help='Reformat the full content of all touched files') | 3189 help='Reformat the full content of all touched files') |
3190 parser.add_option('--dry-run', action='store_true', | 3190 parser.add_option('--dry-run', action='store_true', |
3191 help='Don\'t modify any file on disk.') | 3191 help='Don\'t modify any file on disk.') |
| 3192 parser.add_option('--python', action='store_true', |
| 3193 help='Format python code with yapf (experimental).') |
3192 parser.add_option('--diff', action='store_true', | 3194 parser.add_option('--diff', action='store_true', |
3193 help='Print diff to stdout rather than modifying files.') | 3195 help='Print diff to stdout rather than modifying files.') |
3194 opts, args = parser.parse_args(args) | 3196 opts, args = parser.parse_args(args) |
3195 | 3197 |
3196 # git diff generates paths against the root of the repository. Change | 3198 # git diff generates paths against the root of the repository. Change |
3197 # to that directory so clang-format can find files even within subdirs. | 3199 # to that directory so clang-format can find files even within subdirs. |
3198 rel_base_path = settings.GetRelativeRoot() | 3200 rel_base_path = settings.GetRelativeRoot() |
3199 if rel_base_path: | 3201 if rel_base_path: |
3200 os.chdir(rel_base_path) | 3202 os.chdir(rel_base_path) |
3201 | 3203 |
3202 # Grab the merge-base commit, i.e. the upstream commit of the current | 3204 # Grab the merge-base commit, i.e. the upstream commit of the current |
3203 # branch when it was created or the last time it was rebased. This is | 3205 # branch when it was created or the last time it was rebased. This is |
3204 # to cover the case where the user may have called "git fetch origin", | 3206 # to cover the case where the user may have called "git fetch origin", |
3205 # moving the origin branch to a newer commit, but hasn't rebased yet. | 3207 # moving the origin branch to a newer commit, but hasn't rebased yet. |
3206 upstream_commit = None | 3208 upstream_commit = None |
3207 cl = Changelist() | 3209 cl = Changelist() |
3208 upstream_branch = cl.GetUpstreamBranch() | 3210 upstream_branch = cl.GetUpstreamBranch() |
3209 if upstream_branch: | 3211 if upstream_branch: |
3210 upstream_commit = RunGit(['merge-base', 'HEAD', upstream_branch]) | 3212 upstream_commit = RunGit(['merge-base', 'HEAD', upstream_branch]) |
3211 upstream_commit = upstream_commit.strip() | 3213 upstream_commit = upstream_commit.strip() |
3212 | 3214 |
3213 if not upstream_commit: | 3215 if not upstream_commit: |
3214 DieWithError('Could not find base commit for this branch. ' | 3216 DieWithError('Could not find base commit for this branch. ' |
3215 'Are you in detached state?') | 3217 'Are you in detached state?') |
3216 | 3218 |
3217 if opts.full: | 3219 if opts.full: |
3218 # Only list the names of modified files. | 3220 # Only list the names of modified files. |
3219 clang_diff_type = '--name-only' | 3221 diff_type = '--name-only' |
3220 else: | 3222 else: |
3221 # Only generate context-less patches. | 3223 # Only generate context-less patches. |
3222 clang_diff_type = '-U0' | 3224 diff_type = '-U0' |
3223 | 3225 |
3224 diff_cmd = BuildGitDiffCmd(clang_diff_type, upstream_commit, args, CLANG_EXTS) | 3226 diff_cmd = BuildGitDiffCmd(diff_type, upstream_commit, args, CLANG_EXTS) |
3225 diff_output = RunGit(diff_cmd) | 3227 diff_output = RunGit(diff_cmd) |
3226 | 3228 |
3227 top_dir = os.path.normpath( | 3229 top_dir = os.path.normpath( |
3228 RunGit(["rev-parse", "--show-toplevel"]).rstrip('\n')) | 3230 RunGit(["rev-parse", "--show-toplevel"]).rstrip('\n')) |
3229 | 3231 |
3230 # Locate the clang-format binary in the checkout | 3232 # Locate the clang-format binary in the checkout |
3231 try: | 3233 try: |
3232 clang_format_tool = clang_format.FindClangFormatToolInChromiumTree() | 3234 clang_format_tool = clang_format.FindClangFormatToolInChromiumTree() |
3233 except clang_format.NotFoundError, e: | 3235 except clang_format.NotFoundError, e: |
3234 DieWithError(e) | 3236 DieWithError(e) |
(...skipping 25 matching lines...) Expand all Loading... |
3260 cmd = [sys.executable, script, '-p0'] | 3262 cmd = [sys.executable, script, '-p0'] |
3261 if not opts.dry_run and not opts.diff: | 3263 if not opts.dry_run and not opts.diff: |
3262 cmd.append('-i') | 3264 cmd.append('-i') |
3263 | 3265 |
3264 stdout = RunCommand(cmd, stdin=diff_output, cwd=top_dir, env=env) | 3266 stdout = RunCommand(cmd, stdin=diff_output, cwd=top_dir, env=env) |
3265 if opts.diff: | 3267 if opts.diff: |
3266 sys.stdout.write(stdout) | 3268 sys.stdout.write(stdout) |
3267 if opts.dry_run and len(stdout) > 0: | 3269 if opts.dry_run and len(stdout) > 0: |
3268 return_value = 2 | 3270 return_value = 2 |
3269 | 3271 |
| 3272 # Similar code to above, but using yapf on .py files rather than clang-format |
| 3273 # on C/C++ files |
| 3274 if opts.python: |
| 3275 diff_cmd = BuildGitDiffCmd(diff_type, upstream_commit, args, ['.py']) |
| 3276 diff_output = RunGit(diff_cmd) |
| 3277 yapf_tool = gclient_utils.FindExecutable('yapf') |
| 3278 if yapf_tool is None: |
| 3279 DieWithError('yapf not found in PATH') |
| 3280 |
| 3281 if opts.full: |
| 3282 files = diff_output.splitlines() |
| 3283 if files: |
| 3284 cmd = [yapf_tool] |
| 3285 if not opts.dry_run and not opts.diff: |
| 3286 cmd.append('-i') |
| 3287 stdout = RunCommand(cmd + files, cwd=top_dir) |
| 3288 if opts.diff: |
| 3289 sys.stdout.write(stdout) |
| 3290 else: |
| 3291 # TODO(sbc): yapf --lines mode still has some issues. |
| 3292 # https://github.com/google/yapf/issues/154 |
| 3293 DieWithError('--python currently only works with --full') |
| 3294 |
3270 # Build a diff command that only operates on dart files. dart's formatter | 3295 # Build a diff command that only operates on dart files. dart's formatter |
3271 # does not have the nice property of only operating on modified chunks, so | 3296 # does not have the nice property of only operating on modified chunks, so |
3272 # hard code full. | 3297 # hard code full. |
3273 dart_diff_cmd = BuildGitDiffCmd('--name-only', upstream_commit, | 3298 dart_diff_cmd = BuildGitDiffCmd('--name-only', upstream_commit, |
3274 args, ['.dart']) | 3299 args, ['.dart']) |
3275 dart_diff_output = RunGit(dart_diff_cmd) | 3300 dart_diff_output = RunGit(dart_diff_cmd) |
3276 if dart_diff_output: | 3301 if dart_diff_output: |
3277 try: | 3302 try: |
3278 command = [dart_format.FindDartFmtToolInChromiumTree()] | 3303 command = [dart_format.FindDartFmtToolInChromiumTree()] |
3279 if not opts.dry_run and not opts.diff: | 3304 if not opts.dry_run and not opts.diff: |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3345 if __name__ == '__main__': | 3370 if __name__ == '__main__': |
3346 # These affect sys.stdout so do it outside of main() to simplify mocks in | 3371 # These affect sys.stdout so do it outside of main() to simplify mocks in |
3347 # unit testing. | 3372 # unit testing. |
3348 fix_encoding.fix_encoding() | 3373 fix_encoding.fix_encoding() |
3349 colorama.init() | 3374 colorama.init() |
3350 try: | 3375 try: |
3351 sys.exit(main(sys.argv[1:])) | 3376 sys.exit(main(sys.argv[1:])) |
3352 except KeyboardInterrupt: | 3377 except KeyboardInterrupt: |
3353 sys.stderr.write('interrupted\n') | 3378 sys.stderr.write('interrupted\n') |
3354 sys.exit(1) | 3379 sys.exit(1) |
OLD | NEW |