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 18 matching lines...) Expand all Loading... | |
29 try: | 29 try: |
30 import readline # pylint: disable=F0401,W0611 | 30 import readline # pylint: disable=F0401,W0611 |
31 except ImportError: | 31 except ImportError: |
32 pass | 32 pass |
33 | 33 |
34 | 34 |
35 from third_party import colorama | 35 from third_party import colorama |
36 from third_party import upload | 36 from third_party import upload |
37 import breakpad # pylint: disable=W0611 | 37 import breakpad # pylint: disable=W0611 |
38 import clang_format | 38 import clang_format |
39 import dart_format | |
39 import fix_encoding | 40 import fix_encoding |
40 import gclient_utils | 41 import gclient_utils |
41 import git_common | 42 import git_common |
42 import owners | 43 import owners |
43 import owners_finder | 44 import owners_finder |
44 import presubmit_support | 45 import presubmit_support |
45 import rietveld | 46 import rietveld |
46 import scm | 47 import scm |
47 import subcommand | 48 import subcommand |
48 import subprocess2 | 49 import subprocess2 |
(...skipping 2836 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2885 # Default to diffing against the common ancestor of the upstream branch. | 2886 # Default to diffing against the common ancestor of the upstream branch. |
2886 base_branch = cl.GetCommonAncestorWithUpstream() | 2887 base_branch = cl.GetCommonAncestorWithUpstream() |
2887 | 2888 |
2888 change = cl.GetChange(base_branch, None) | 2889 change = cl.GetChange(base_branch, None) |
2889 return owners_finder.OwnersFinder( | 2890 return owners_finder.OwnersFinder( |
2890 [f.LocalPath() for f in | 2891 [f.LocalPath() for f in |
2891 cl.GetChange(base_branch, None).AffectedFiles()], | 2892 cl.GetChange(base_branch, None).AffectedFiles()], |
2892 change.RepositoryRoot(), author, | 2893 change.RepositoryRoot(), author, |
2893 fopen=file, os_path=os.path, glob=glob.glob, | 2894 fopen=file, os_path=os.path, glob=glob.glob, |
2894 disable_color=options.no_color).run() | 2895 disable_color=options.no_color).run() |
2895 | 2896 |
M-A Ruel
2015/02/23 18:47:26
2 empty lines between file level symbols.
| |
2897 def BuildGitDiffCmd(diff_type, upstream_commit, args, extensions): | |
2898 """Generates a diff command.""" | |
2899 # Generate diff for the current branch's changes. | |
2900 diff_cmd = ['diff', '--no-ext-diff', '--no-prefix', diff_type, | |
2901 upstream_commit, '--' ] | |
2902 | |
2903 if args: | |
2904 for arg in args: | |
2905 if os.path.isdir(arg): | |
2906 diff_cmd += [os.path.join(arg, '*' + ext) for ext in extensions] | |
M-A Ruel
2015/02/23 18:47:26
diff_cmd.extend(os.path.join(arg, '*' + ext) for e
| |
2907 elif os.path.isfile(arg): | |
2908 diff_cmd.append(arg) | |
2909 else: | |
2910 DieWithError('Argument "%s" is not a file or a directory' % arg) | |
2911 else: | |
2912 diff_cmd += ['*' + ext for ext in extensions] | |
M-A Ruel
2015/02/23 18:47:25
diff_cmd.extend('*' + ext for ext in extensions)
| |
2913 | |
2914 return diff_cmd | |
2896 | 2915 |
M-A Ruel
2015/02/23 18:47:25
2 empty lines
| |
2897 @subcommand.usage('[files or directories to diff]') | 2916 @subcommand.usage('[files or directories to diff]') |
2898 def CMDformat(parser, args): | 2917 def CMDformat(parser, args): |
2899 """Runs clang-format on the diff.""" | 2918 """Runs clang-format on the diff.""" |
2900 CLANG_EXTS = ['.cc', '.cpp', '.h', '.mm', '.proto', '.java'] | 2919 CLANG_EXTS = ['.cc', '.cpp', '.h', '.mm', '.proto', '.java'] |
2901 parser.add_option('--full', action='store_true', | 2920 parser.add_option('--full', action='store_true', |
2902 help='Reformat the full content of all touched files') | 2921 help='Reformat the full content of all touched files') |
2903 parser.add_option('--dry-run', action='store_true', | 2922 parser.add_option('--dry-run', action='store_true', |
2904 help='Don\'t modify any file on disk.') | 2923 help='Don\'t modify any file on disk.') |
2905 parser.add_option('--diff', action='store_true', | 2924 parser.add_option('--diff', action='store_true', |
2906 help='Print diff to stdout rather than modifying files.') | 2925 help='Print diff to stdout rather than modifying files.') |
2907 opts, args = parser.parse_args(args) | 2926 opts, args = parser.parse_args(args) |
2908 | 2927 |
2909 # git diff generates paths against the root of the repository. Change | 2928 # git diff generates paths against the root of the repository. Change |
2910 # to that directory so clang-format can find files even within subdirs. | 2929 # to that directory so clang-format can find files even within subdirs. |
2911 rel_base_path = settings.GetRelativeRoot() | 2930 rel_base_path = settings.GetRelativeRoot() |
2912 if rel_base_path: | 2931 if rel_base_path: |
2913 os.chdir(rel_base_path) | 2932 os.chdir(rel_base_path) |
2914 | 2933 |
2915 # Generate diff for the current branch's changes. | |
2916 diff_cmd = ['diff', '--no-ext-diff', '--no-prefix'] | |
2917 if opts.full: | |
2918 # Only list the names of modified files. | |
2919 diff_cmd.append('--name-only') | |
2920 else: | |
2921 # Only generate context-less patches. | |
2922 diff_cmd.append('-U0') | |
2923 | |
2924 # Grab the merge-base commit, i.e. the upstream commit of the current | 2934 # Grab the merge-base commit, i.e. the upstream commit of the current |
2925 # branch when it was created or the last time it was rebased. This is | 2935 # branch when it was created or the last time it was rebased. This is |
2926 # to cover the case where the user may have called "git fetch origin", | 2936 # to cover the case where the user may have called "git fetch origin", |
2927 # moving the origin branch to a newer commit, but hasn't rebased yet. | 2937 # moving the origin branch to a newer commit, but hasn't rebased yet. |
2928 upstream_commit = None | 2938 upstream_commit = None |
2929 cl = Changelist() | 2939 cl = Changelist() |
2930 upstream_branch = cl.GetUpstreamBranch() | 2940 upstream_branch = cl.GetUpstreamBranch() |
2931 if upstream_branch: | 2941 if upstream_branch: |
2932 upstream_commit = RunGit(['merge-base', 'HEAD', upstream_branch]) | 2942 upstream_commit = RunGit(['merge-base', 'HEAD', upstream_branch]) |
2933 upstream_commit = upstream_commit.strip() | 2943 upstream_commit = upstream_commit.strip() |
2934 | 2944 |
2935 if not upstream_commit: | 2945 if not upstream_commit: |
2936 DieWithError('Could not find base commit for this branch. ' | 2946 DieWithError('Could not find base commit for this branch. ' |
2937 'Are you in detached state?') | 2947 'Are you in detached state?') |
2938 | 2948 |
2939 diff_cmd.append(upstream_commit) | 2949 if opts.full: |
2950 # Only list the names of modified files. | |
2951 clang_diff_type = '--name-only' | |
2952 else: | |
2953 # Only generate context-less patches. | |
2954 clang_diff_type = '-U0' | |
2940 | 2955 |
2941 # Handle source file filtering. | 2956 diff_cmd = BuildGitDiffCmd(clang_diff_type, upstream_commit, args, CLANG_EXTS) |
2942 diff_cmd.append('--') | |
2943 if args: | |
2944 for arg in args: | |
2945 if os.path.isdir(arg): | |
2946 diff_cmd += [os.path.join(arg, '*' + ext) for ext in CLANG_EXTS] | |
2947 elif os.path.isfile(arg): | |
2948 diff_cmd.append(arg) | |
2949 else: | |
2950 DieWithError('Argument "%s" is not a file or a directory' % arg) | |
2951 else: | |
2952 diff_cmd += ['*' + ext for ext in CLANG_EXTS] | |
2953 diff_output = RunGit(diff_cmd) | 2957 diff_output = RunGit(diff_cmd) |
2954 | 2958 |
2955 top_dir = os.path.normpath( | 2959 top_dir = os.path.normpath( |
2956 RunGit(["rev-parse", "--show-toplevel"]).rstrip('\n')) | 2960 RunGit(["rev-parse", "--show-toplevel"]).rstrip('\n')) |
2957 | 2961 |
2958 # Locate the clang-format binary in the checkout | 2962 # Locate the clang-format binary in the checkout |
2959 try: | 2963 try: |
2960 clang_format_tool = clang_format.FindClangFormatToolInChromiumTree() | 2964 clang_format_tool = clang_format.FindClangFormatToolInChromiumTree() |
2961 except clang_format.NotFoundError, e: | 2965 except clang_format.NotFoundError, e: |
2962 DieWithError(e) | 2966 DieWithError(e) |
2963 | 2967 |
2968 # Set to 2 to signal to CheckPatchFormatted() that this patch isn't | |
2969 # formatted. This is used to block during the presubmit. | |
2970 return_value = 0 | |
2971 | |
2964 if opts.full: | 2972 if opts.full: |
2965 # diff_output is a list of files to send to clang-format. | 2973 # diff_output is a list of files to send to clang-format. |
2966 files = diff_output.splitlines() | 2974 files = diff_output.splitlines() |
2967 if not files: | 2975 if files: |
2968 print "Nothing to format." | 2976 cmd = [clang_format_tool] |
2969 return 0 | 2977 if not opts.dry_run and not opts.diff: |
2970 cmd = [clang_format_tool] | 2978 cmd.append('-i') |
2971 if not opts.dry_run and not opts.diff: | 2979 stdout = RunCommand(cmd + files, cwd=top_dir) |
2972 cmd.append('-i') | 2980 if opts.diff: |
2973 stdout = RunCommand(cmd + files, cwd=top_dir) | 2981 sys.stdout.write(stdout) |
2974 if opts.diff: | |
2975 sys.stdout.write(stdout) | |
2976 else: | 2982 else: |
2977 env = os.environ.copy() | 2983 env = os.environ.copy() |
2978 env['PATH'] = str(os.path.dirname(clang_format_tool)) | 2984 env['PATH'] = str(os.path.dirname(clang_format_tool)) |
2979 # diff_output is a patch to send to clang-format-diff.py | 2985 # diff_output is a patch to send to clang-format-diff.py |
2980 try: | 2986 try: |
2981 script = clang_format.FindClangFormatScriptInChromiumTree( | 2987 script = clang_format.FindClangFormatScriptInChromiumTree( |
2982 'clang-format-diff.py') | 2988 'clang-format-diff.py') |
2983 except clang_format.NotFoundError, e: | 2989 except clang_format.NotFoundError, e: |
2984 DieWithError(e) | 2990 DieWithError(e) |
2985 | 2991 |
2986 cmd = [sys.executable, script, '-p0'] | 2992 cmd = [sys.executable, script, '-p0'] |
2987 if not opts.dry_run and not opts.diff: | 2993 if not opts.dry_run and not opts.diff: |
2988 cmd.append('-i') | 2994 cmd.append('-i') |
2989 | 2995 |
2990 stdout = RunCommand(cmd, stdin=diff_output, cwd=top_dir, env=env) | 2996 stdout = RunCommand(cmd, stdin=diff_output, cwd=top_dir, env=env) |
2991 if opts.diff: | 2997 if opts.diff: |
2992 sys.stdout.write(stdout) | 2998 sys.stdout.write(stdout) |
2993 if opts.dry_run and len(stdout) > 0: | 2999 if opts.dry_run and len(stdout) > 0: |
2994 return 2 | 3000 return_value = 2 |
2995 | 3001 |
2996 return 0 | 3002 # Build a diff command that only operates on dart files. dart's formatter |
3003 # does not have the nice property of only operating on modified chunks, so | |
3004 # hard code full. | |
3005 dart_diff_cmd = BuildGitDiffCmd('--name-only', upstream_commit, | |
3006 args, ['.dart']) | |
3007 dart_diff_output = RunGit(dart_diff_cmd) | |
3008 if dart_diff_output: | |
3009 try: | |
3010 dartfmt = dart_format.FindDartFmtToolInChromiumTree() | |
3011 | |
3012 command = [dartfmt] | |
M-A Ruel
2015/02/23 18:47:25
command = [dart_format.FindDartFmtToolInChromiumTr
| |
3013 if not opts.dry_run and not opts.diff: | |
3014 command.append('-w') | |
3015 files = dart_diff_output.splitlines() | |
3016 command.extend(files) | |
M-A Ruel
2015/02/23 18:47:26
command.extend(dart_diff_output.splitlines())
| |
3017 | |
3018 stdout = RunCommand(command, cwd=top_dir, env=env) | |
3019 if opts.dry_run and len(stdout) > 0: | |
M-A Ruel
2015/02/23 18:47:26
if opts.dry_run and stdout:
| |
3020 return_value = 2 | |
3021 except dart_format.NotFoundError, e: | |
M-A Ruel
2015/02/23 18:47:26
except dart_format.NotFoundError as e:
| |
3022 print ("Unable to check dart code formatting. Dart SDK is not in " + | |
M-A Ruel
2015/02/23 18:47:26
single quotes
| |
3023 "this checkout.") | |
3024 | |
3025 return return_value | |
2997 | 3026 |
2998 | 3027 |
2999 def CMDlol(parser, args): | 3028 def CMDlol(parser, args): |
3000 # This command is intentionally undocumented. | 3029 # This command is intentionally undocumented. |
3001 print zlib.decompress(base64.b64decode( | 3030 print zlib.decompress(base64.b64decode( |
3002 'eNptkLEOwyAMRHe+wupCIqW57v0Vq84WqWtXyrcXnCBsmgMJ+/SSAxMZgRB6NzE' | 3031 'eNptkLEOwyAMRHe+wupCIqW57v0Vq84WqWtXyrcXnCBsmgMJ+/SSAxMZgRB6NzE' |
3003 'E2ObgCKJooYdu4uAQVffUEoE1sRQLxAcqzd7uK2gmStrll1ucV3uZyaY5sXyDd9' | 3032 'E2ObgCKJooYdu4uAQVffUEoE1sRQLxAcqzd7uK2gmStrll1ucV3uZyaY5sXyDd9' |
3004 'JAnN+lAXsOMJ90GANAi43mq5/VeeacylKVgi8o6F1SC63FxnagHfJUTfUYdCR/W' | 3033 'JAnN+lAXsOMJ90GANAi43mq5/VeeacylKVgi8o6F1SC63FxnagHfJUTfUYdCR/W' |
3005 'Ofe+0dHL7PicpytKP750Fh1q2qnLVof4w8OZWNY')) | 3034 'Ofe+0dHL7PicpytKP750Fh1q2qnLVof4w8OZWNY')) |
3006 return 0 | 3035 return 0 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3044 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 3073 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
3045 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 3074 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
3046 | 3075 |
3047 | 3076 |
3048 if __name__ == '__main__': | 3077 if __name__ == '__main__': |
3049 # These affect sys.stdout so do it outside of main() to simplify mocks in | 3078 # These affect sys.stdout so do it outside of main() to simplify mocks in |
3050 # unit testing. | 3079 # unit testing. |
3051 fix_encoding.fix_encoding() | 3080 fix_encoding.fix_encoding() |
3052 colorama.init() | 3081 colorama.init() |
3053 sys.exit(main(sys.argv[1:])) | 3082 sys.exit(main(sys.argv[1:])) |
OLD | NEW |