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 2837 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 |
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] | |
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] | |
2913 | |
2914 return diff_cmd | |
2896 | 2915 |
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 |
2964 if opts.full: | 2968 if opts.full: |
2965 # diff_output is a list of files to send to clang-format. | 2969 # diff_output is a list of files to send to clang-format. |
2966 files = diff_output.splitlines() | 2970 files = diff_output.splitlines() |
2967 if not files: | 2971 if files: |
2968 print "Nothing to format." | 2972 cmd = [clang_format_tool] |
2969 return 0 | 2973 if not opts.dry_run and not opts.diff: |
2970 cmd = [clang_format_tool] | 2974 cmd.append('-i') |
2971 if not opts.dry_run and not opts.diff: | 2975 stdout = RunCommand(cmd + files, cwd=top_dir) |
2972 cmd.append('-i') | 2976 if opts.diff: |
2973 stdout = RunCommand(cmd + files, cwd=top_dir) | 2977 sys.stdout.write(stdout) |
2974 if opts.diff: | |
2975 sys.stdout.write(stdout) | |
2976 else: | 2978 else: |
2977 env = os.environ.copy() | 2979 env = os.environ.copy() |
2978 env['PATH'] = str(os.path.dirname(clang_format_tool)) | 2980 env['PATH'] = str(os.path.dirname(clang_format_tool)) |
2979 # diff_output is a patch to send to clang-format-diff.py | 2981 # diff_output is a patch to send to clang-format-diff.py |
2980 try: | 2982 try: |
2981 script = clang_format.FindClangFormatScriptInChromiumTree( | 2983 script = clang_format.FindClangFormatScriptInChromiumTree( |
2982 'clang-format-diff.py') | 2984 'clang-format-diff.py') |
2983 except clang_format.NotFoundError, e: | 2985 except clang_format.NotFoundError, e: |
2984 DieWithError(e) | 2986 DieWithError(e) |
2985 | 2987 |
2986 cmd = [sys.executable, script, '-p0'] | 2988 cmd = [sys.executable, script, '-p0'] |
2987 if not opts.dry_run and not opts.diff: | 2989 if not opts.dry_run and not opts.diff: |
2988 cmd.append('-i') | 2990 cmd.append('-i') |
2989 | 2991 |
2990 stdout = RunCommand(cmd, stdin=diff_output, cwd=top_dir, env=env) | 2992 stdout = RunCommand(cmd, stdin=diff_output, cwd=top_dir, env=env) |
2991 if opts.diff: | 2993 if opts.diff: |
2992 sys.stdout.write(stdout) | 2994 sys.stdout.write(stdout) |
2995 # TODO(erg): Deal with this. | |
2993 if opts.dry_run and len(stdout) > 0: | 2996 if opts.dry_run and len(stdout) > 0: |
2994 return 2 | 2997 return 2 |
Elliot Glaysher
2015/02/18 20:41:42
enne: you added the above two lines to return a va
enne (OOO)
2015/02/18 20:56:46
Yeah, the "return 2" is to indicate to CheckPatchF
Elliot Glaysher
2015/02/18 21:16:17
TYVM. I've modified this so that unformatted dart
| |
2995 | 2998 |
2999 # Build a diff command that only operates on dart files. dart's formatter | |
3000 # does not have the nice property of only operating on modified chunks, so | |
3001 # hard code full. | |
3002 dart_diff_cmd = BuildGitDiffCmd('--name-only', upstream_commit, | |
3003 args, ['.dart']) | |
3004 dart_diff_output = RunGit(dart_diff_cmd) | |
3005 if dart_diff_output: | |
3006 try: | |
3007 dartfmt = dart_format.FindDartFmtToolInChromiumTree() | |
3008 except dart_format.NotFoundError, e: | |
3009 DieWithError(e) | |
3010 | |
3011 command = [dartfmt] | |
3012 if not opts.dry_run and not opts.diff: | |
3013 command.append('-w') | |
3014 files = dart_diff_output.splitlines() | |
3015 command.extend(files) | |
3016 | |
3017 stdout = RunCommand(command, cwd=top_dir, env=env) | |
3018 if opts.dry_run: | |
3019 sys.stdout.write(stdout) | |
3020 | |
2996 return 0 | 3021 return 0 |
2997 | 3022 |
2998 | 3023 |
2999 def CMDlol(parser, args): | 3024 def CMDlol(parser, args): |
3000 # This command is intentionally undocumented. | 3025 # This command is intentionally undocumented. |
3001 print zlib.decompress(base64.b64decode( | 3026 print zlib.decompress(base64.b64decode( |
3002 'eNptkLEOwyAMRHe+wupCIqW57v0Vq84WqWtXyrcXnCBsmgMJ+/SSAxMZgRB6NzE' | 3027 'eNptkLEOwyAMRHe+wupCIqW57v0Vq84WqWtXyrcXnCBsmgMJ+/SSAxMZgRB6NzE' |
3003 'E2ObgCKJooYdu4uAQVffUEoE1sRQLxAcqzd7uK2gmStrll1ucV3uZyaY5sXyDd9' | 3028 'E2ObgCKJooYdu4uAQVffUEoE1sRQLxAcqzd7uK2gmStrll1ucV3uZyaY5sXyDd9' |
3004 'JAnN+lAXsOMJ90GANAi43mq5/VeeacylKVgi8o6F1SC63FxnagHfJUTfUYdCR/W' | 3029 'JAnN+lAXsOMJ90GANAi43mq5/VeeacylKVgi8o6F1SC63FxnagHfJUTfUYdCR/W' |
3005 'Ofe+0dHL7PicpytKP750Fh1q2qnLVof4w8OZWNY')) | 3030 'Ofe+0dHL7PicpytKP750Fh1q2qnLVof4w8OZWNY')) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3044 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' | 3069 ('AppEngine is misbehaving and returned HTTP %d, again. Keep faith ' |
3045 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 3070 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
3046 | 3071 |
3047 | 3072 |
3048 if __name__ == '__main__': | 3073 if __name__ == '__main__': |
3049 # These affect sys.stdout so do it outside of main() to simplify mocks in | 3074 # These affect sys.stdout so do it outside of main() to simplify mocks in |
3050 # unit testing. | 3075 # unit testing. |
3051 fix_encoding.fix_encoding() | 3076 fix_encoding.fix_encoding() |
3052 colorama.init() | 3077 colorama.init() |
3053 sys.exit(main(sys.argv[1:])) | 3078 sys.exit(main(sys.argv[1:])) |
OLD | NEW |