| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2009 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 import getpass | 6 import getpass |
| 7 import optparse | 7 import optparse |
| 8 import os | 8 import os |
| 9 import subprocess | 9 import subprocess |
| 10 import tempfile | 10 import tempfile |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 def GetSubRepWorkingDir(sub_rep_path): | 66 def GetSubRepWorkingDir(sub_rep_path): |
| 67 """Computes the path to the sub repository""" | 67 """Computes the path to the sub repository""" |
| 68 if sub_rep_path: | 68 if sub_rep_path: |
| 69 root_dir = os.path.abspath(Backquote(['git', 'rev-parse', '--show-cdup'])) | 69 root_dir = os.path.abspath(Backquote(['git', 'rev-parse', '--show-cdup'])) |
| 70 return os.path.join(root_dir, sub_rep_path) | 70 return os.path.join(root_dir, sub_rep_path) |
| 71 return None | 71 return None |
| 72 | 72 |
| 73 def GetMungedDiff(branch, prefix, sub_rep_path): | 73 def GetMungedDiff(branch, prefix, sub_rep_path): |
| 74 """Get the diff we'll send to the try server. We munge paths to match svn. | 74 """Get the diff we'll send to the try server. We munge paths to match svn. |
| 75 We add the prefix that the try bot is expecting. If sub_rep_path is | 75 We add the prefix that the try bot is expecting. If sub_rep_path is |
| 76 provided, diff will be calculated in the sub repository.""" | 76 provided, diff will be calculated in the sub repository. |
| 77 We also return the list of files in this diff, without munged paths.""" |
| 77 # Make the following changes: | 78 # Make the following changes: |
| 78 # - Prepend "src/" (or some other prefix) to paths as svn is expecting | 79 # - Prepend "src/" (or some other prefix) to paths as svn is expecting |
| 79 # - In the case of added files, replace /dev/null with the path to the file | 80 # - In the case of added files, replace /dev/null with the path to the file |
| 80 # being added. | 81 # being added. |
| 81 | 82 |
| 82 cwd = GetSubRepWorkingDir(sub_rep_path) | 83 cwd = GetSubRepWorkingDir(sub_rep_path) |
| 83 | 84 |
| 84 output = [] | 85 output = [] |
| 85 if not branch: | 86 if not branch: |
| 86 # Try to guess the upstream branch. | 87 # Try to guess the upstream branch. |
| 87 branch = Backquote(['git', 'cl', 'upstream'], cwd) | 88 branch = Backquote(['git', 'cl', 'upstream'], cwd) |
| 88 command = ['git', 'diff-tree', '-p'] | 89 command = ['git', 'diff-tree', '-p'] |
| 89 | 90 |
| 90 new_cwd = None | 91 new_cwd = None |
| 91 if not sub_rep_path: | 92 if not sub_rep_path: |
| 92 command.extend(['--no-prefix']) | 93 command.extend(['--no-prefix']) |
| 93 else: | 94 else: |
| 94 # Append / | 95 # Append / |
| 95 sub_rep_path = os.path.join(sub_rep_path, '') | 96 sub_rep_path = os.path.join(sub_rep_path, '') |
| 96 # Add the right prefix | 97 # Add the right prefix |
| 97 command.extend(['--src-prefix=' + sub_rep_path]) | 98 command.extend(['--src-prefix=' + sub_rep_path]) |
| 98 command.extend(['--dst-prefix=' + sub_rep_path]) | 99 command.extend(['--dst-prefix=' + sub_rep_path]) |
| 99 | 100 |
| 100 command.extend([branch, 'HEAD']) | 101 command.extend([branch, 'HEAD']) |
| 101 | 102 |
| 102 # Run diff tree | 103 # Run diff tree |
| 103 diff = subprocess.Popen(command, | 104 diff = subprocess.Popen(command, |
| 104 stdout=subprocess.PIPE, | 105 stdout=subprocess.PIPE, |
| 105 cwd=cwd).stdout.readlines() | 106 cwd=cwd).stdout.readlines() |
| 106 # Replace --- /dev/null with --- <new file name> | 107 # Replace --- /dev/null with --- <new file name> |
| 107 for i in range(len(diff)): | 108 for i in range(len(diff)): |
| 108 line = diff[i] | 109 line = diff[i] |
| 109 if line.startswith('--- /dev/null'): | 110 if line.startswith('--- /dev/null'): |
| 110 line = '--- %s' % diff[i+1][4:] | 111 line = '--- %s' % diff[i+1][4:] |
| 111 output.append(line) | 112 output.append(line) |
| 112 diff = output | 113 diff = output |
| 113 | 114 |
| 114 # Add root prefix | 115 # Add root prefix |
| 115 output = [] | 116 output = [] |
| 117 file_set = set() |
| 116 for line in diff: | 118 for line in diff: |
| 117 if line.startswith('--- ') or line.startswith('+++ '): | 119 if line.startswith('--- ') or line.startswith('+++ '): |
| 118 line = line[0:4] + os.path.join(prefix,line[4:]) | 120 filename = line[4:] |
| 121 line = line[0:4] + os.path.join(prefix, filename) |
| 122 file_set.add(filename.rstrip('\r\n')) |
| 119 output.append(line) | 123 output.append(line) |
| 120 | 124 |
| 121 munged_diff = ''.join(output) | 125 munged_diff = ''.join(output) |
| 122 if len(munged_diff.strip()) == 0: | 126 if len(munged_diff.strip()) == 0: |
| 123 raise Exception("Patch was empty, did you give the right remote branch?") | 127 raise Exception("Patch was empty, did you give the right remote branch?") |
| 124 | 128 |
| 125 return munged_diff | 129 return (munged_diff, list(file_set)) |
| 126 | 130 |
| 127 def OneRepositoryDiff(diff_file, patch_names, branch, prefix, sub_rep_path): | 131 def OneRepositoryDiff(diff_file, patch_names, branch, prefix, sub_rep_path): |
| 128 """Computes a diff for one git repository at a given path against a given | 132 """Computes a diff for one git repository at a given path against a given |
| 129 branch. Writes the diff into diff_file and appends a name to the | 133 branch. Writes the diff into diff_file and appends a name to the |
| 130 patch_names list.""" | 134 patch_names list. |
| 131 | 135 |
| 132 diff = GetMungedDiff(branch, prefix, sub_rep_path) | 136 Returns the list of files in the diff.""" |
| 137 |
| 138 (diff, file_list) = GetMungedDiff(branch, prefix, sub_rep_path) |
| 133 | 139 |
| 134 # Write the diff out | 140 # Write the diff out |
| 135 diff_file.write(diff) | 141 diff_file.write(diff) |
| 136 | 142 |
| 137 # Add patch name to list of patches | 143 # Add patch name to list of patches |
| 138 patch_name = GetPatchName(GetSubRepWorkingDir(sub_rep_path)) | 144 patch_name = GetPatchName(GetSubRepWorkingDir(sub_rep_path)) |
| 139 patch_names.extend([patch_name]) | 145 patch_names.extend([patch_name]) |
| 146 return file_list |
| 140 | 147 |
| 141 | 148 |
| 142 def ValidEmail(email): | 149 def ValidEmail(email): |
| 143 return re.match(r"^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email) | 150 return re.match(r"^[a-zA-Z0-9._%-+]+@[a-zA-Z0-9._%-]+.[a-zA-Z]{2,6}$", email) |
| 144 | 151 |
| 145 | 152 |
| 146 def GetEmail(): | 153 def GetEmail(): |
| 147 email = Backquote(['git', 'config', 'user.email']) | 154 email = Backquote(['git', 'config', 'user.email']) |
| 148 runmsg = "Try: git config user.email <EMAIL>" | 155 runmsg = "Try: git config user.email <EMAIL>" |
| 149 assert ValidEmail(email), "Email '%s' is not valid. %s" % (email, runmsg) | 156 assert ValidEmail(email), "Email '%s' is not valid. %s" % (email, runmsg) |
| 150 return email | 157 return email |
| 151 | 158 |
| 152 | 159 |
| 153 def TryChange(args): | 160 def TryChange(args, file_list): |
| 154 """Put a patch on the try server.""" | 161 """Put a patch on the try server.""" |
| 155 root_dir = Backquote(['git', 'rev-parse', '--show-cdup']) | 162 trychange.TryChange(args, file_list, False) |
| 156 trychange.checkout_root = os.path.abspath(root_dir) | |
| 157 trychange.TryChange(args, None, False) | |
| 158 | 163 |
| 159 | 164 |
| 160 if __name__ == '__main__': | 165 if __name__ == '__main__': |
| 161 parser = optparse.OptionParser( | 166 parser = optparse.OptionParser( |
| 162 usage='git try [options] [branch]', | 167 usage='git try [options] [branch]', |
| 163 description='Upload the current diff of branch...HEAD to the try server.') | 168 description='Upload the current diff of branch...HEAD to the try server.') |
| 164 parser.add_option("-b", "--bot", | 169 parser.add_option("-b", "--bot", |
| 165 help="Force the use of a specific build slave (eg mac, " | 170 help="Force the use of a specific build slave (eg mac, " |
| 166 "win, or linux)") | 171 "win, or linux)") |
| 167 parser.add_option("-c", "--clobber", action="store_true", | 172 parser.add_option("-c", "--clobber", action="store_true", |
| 168 help="Make the try run use be a clobber build") | 173 help="Make the try run use be a clobber build") |
| 169 parser.add_option("-r", "--revision", | 174 parser.add_option("-r", "--revision", |
| 170 help="Specify the SVN base revision to use") | 175 help="Specify the SVN base revision to use") |
| 171 parser.add_option("--root", default="src", metavar="PATH", | 176 parser.add_option("--root", default="src", metavar="PATH", |
| 172 help="Specify the root prefix that is appended to paths " | 177 help="Specify the root prefix that is prepended to paths " |
| 173 "in the patch") | 178 "in the patch") |
| 174 parser.add_option("--dry_run", action="store_true", | 179 parser.add_option("--dry_run", action="store_true", |
| 175 help="Print the diff but don't send it to the try bots") | 180 help="Print the diff but don't send it to the try bots") |
| 176 parser.add_option("--sub_rep", nargs=2, action="append", default=[], | 181 parser.add_option("--sub_rep", nargs=2, action="append", default=[], |
| 177 metavar="PATH BRANCH", | 182 metavar="PATH BRANCH", |
| 178 help="Specify a path to a git sub-repository and a branch " | 183 help="Specify a path to a git sub-repository and a branch " |
| 179 "to diff with in order to simultanously try changes " | 184 "to diff with in order to simultanously try changes " |
| 180 "in multiple git repositories. Option may be " | 185 "in multiple git repositories. Option may be " |
| 181 "specified multiple times.") | 186 "specified multiple times.") |
| 182 parser.add_option("--webkit", metavar="BRANCH", | 187 parser.add_option("--webkit", metavar="BRANCH", |
| 183 help="Specify webkit branch. Syntactic sugar for " | 188 help="Specify webkit branch. Syntactic sugar for " |
| 184 "--sub_rep third_party/WebKit/ <branch>") | 189 "--sub_rep third_party/WebKit/ <branch>") |
| 185 | 190 |
| 186 (options, args) = parser.parse_args(sys.argv) | 191 (options, args) = parser.parse_args(sys.argv) |
| 187 | 192 |
| 188 if options.webkit: | 193 if options.webkit: |
| 189 options.sub_rep.extend([('third_party/WebKit/', options.webkit)]) | 194 options.sub_rep.extend([('third_party/WebKit/', options.webkit)]) |
| 190 | 195 |
| 191 branch = None | 196 branch = None |
| 192 if len(args) > 1: | 197 if len(args) > 1: |
| 193 branch = args[1] | 198 branch = args[1] |
| 194 patch_names = [] | 199 patch_names = [] |
| 195 | 200 |
| 196 # Dump all diffs into one diff file. | 201 # Dump all diffs into one diff file. |
| 197 diff_file = tempfile.NamedTemporaryFile() | 202 diff_file = tempfile.NamedTemporaryFile() |
| 198 | 203 |
| 199 # Calculate diff for main git repository. | 204 # Calculate diff for main git repository. |
| 200 OneRepositoryDiff(diff_file, patch_names, branch, options.root, None) | 205 file_list = OneRepositoryDiff(diff_file, patch_names, branch, options.root, |
| 201 | 206 None) |
| 207 |
| 202 # Calculate diff for each extra git repository. | 208 # Calculate diff for each extra git repository. |
| 203 for path_and_branch in options.sub_rep: | 209 for path_and_branch in options.sub_rep: |
| 204 OneRepositoryDiff(diff_file, | 210 file_list.extend(OneRepositoryDiff(diff_file, |
| 205 patch_names, | 211 patch_names, |
| 206 path_and_branch[1], | 212 path_and_branch[1], |
| 207 options.root, | 213 options.root, |
| 208 path_and_branch[0]) | 214 path_and_branch[0])) |
| 209 # Make diff file ready for reading. | 215 # Make diff file ready for reading. |
| 210 diff_file.flush() | 216 diff_file.flush() |
| 211 | 217 |
| 212 # Concatenate patch names | 218 # Concatenate patch names |
| 213 # Prepare args for TryChange | 219 # Prepare args for TryChange |
| 214 email = GetEmail() | 220 email = GetEmail() |
| 215 user = email.partition('@')[0] | 221 user = email.partition('@')[0] |
| 216 args = [ | 222 args = [ |
| 217 '-u', user, | 223 '-u', user, |
| 218 '-e', email, | 224 '-e', email, |
| 219 '-n', '-'.join(patch_names), | 225 '-n', '-'.join(patch_names), |
| 220 '--diff', diff_file.name, | 226 '--diff', diff_file.name, |
| 221 ] | 227 ] |
| 222 | 228 |
| 223 # Send to try server via HTTP if we can parse the config, otherwise | 229 # Send to try server via HTTP if we can parse the config, otherwise |
| 224 # upload via SVN. | 230 # upload via SVN. |
| 225 config = GetTryServerConfig() | 231 config = GetTryServerConfig() |
| 226 if config is not None: | 232 if config is not None: |
| 227 sendmsg = "Sending %s using HTTP..." % '-'.join(patch_names) | 233 sendmsg = "Sending %s using HTTP..." % '-'.join(patch_names) |
| 228 args.extend(['--use_http']) | 234 args.extend(['--use_http']) |
| 229 if config['try_server_http_host'] is not None: | 235 if config['try_server_http_host'] is not None: |
| 230 args.extend(['--host', config['try_server_http_host']]) | 236 args.extend(['--host', config['try_server_http_host']]) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 250 args.extend([ | 256 args.extend([ |
| 251 '--issue', GetRietveldIssueNumber(), | 257 '--issue', GetRietveldIssueNumber(), |
| 252 '--patchset', GetRietveldPatchsetNumber(), | 258 '--patchset', GetRietveldPatchsetNumber(), |
| 253 ]) | 259 ]) |
| 254 | 260 |
| 255 if options.dry_run: | 261 if options.dry_run: |
| 256 print open(diff_file.name, 'r').read() | 262 print open(diff_file.name, 'r').read() |
| 257 exit(0) | 263 exit(0) |
| 258 | 264 |
| 259 print sendmsg | 265 print sendmsg |
| 260 TryChange(args=args) | 266 TryChange(args, file_list) |
| OLD | NEW |