| LEFT | RIGHT |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # | 2 # |
| 3 # Copyright 2007 Google Inc. | 3 # Copyright 2007 Google Inc. |
| 4 # | 4 # |
| 5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
| 7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
| 8 # | 8 # |
| 9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 # | 10 # |
| (...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 569 p.wait() | 569 p.wait() |
| 570 errout = p.stderr.read() | 570 errout = p.stderr.read() |
| 571 if print_output and errout: | 571 if print_output and errout: |
| 572 print >>sys.stderr, errout | 572 print >>sys.stderr, errout |
| 573 p.stdout.close() | 573 p.stdout.close() |
| 574 p.stderr.close() | 574 p.stderr.close() |
| 575 return output, p.returncode | 575 return output, p.returncode |
| 576 | 576 |
| 577 | 577 |
| 578 def RunShell(command, silent_ok=False, universal_newlines=True, | 578 def RunShell(command, silent_ok=False, universal_newlines=True, |
| 579 print_output=False): | 579 print_output=False,check_returncode=True): |
| 580 data, retcode = RunShellWithReturnCode(command, print_output, | 580 data, retcode = RunShellWithReturnCode(command, print_output, |
| 581 universal_newlines) | 581 universal_newlines) |
| 582 if retcode: | 582 |
| 583 if retcode and check_returncode: | |
| 583 ErrorExit("Got error status from %s:\n%s" % (command, data)) | 584 ErrorExit("Got error status from %s:\n%s" % (command, data)) |
| 584 if not silent_ok and not data: | 585 if not silent_ok and not data: |
| 585 ErrorExit("No output from %s" % command) | 586 ErrorExit("No output from %s" % command) |
| 586 return data | 587 return data |
| 587 | 588 |
| 588 | 589 |
| 589 class VersionControlSystem(object): | 590 class VersionControlSystem(object): |
| 590 """Abstract base class providing an interface to the VCS.""" | 591 """Abstract base class providing an interface to the VCS.""" |
| 591 | 592 |
| 592 def __init__(self, options): | 593 def __init__(self, options): |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 904 # If a file is copied its status will be "A +", which signifies | 905 # If a file is copied its status will be "A +", which signifies |
| 905 # "addition-with-history". See "svn st" for more information. We need to | 906 # "addition-with-history". See "svn st" for more information. We need to |
| 906 # upload the original file or else diff parsing will fail if the file was | 907 # upload the original file or else diff parsing will fail if the file was |
| 907 # edited. | 908 # edited. |
| 908 if status[0] == "A" and status[3] != "+": | 909 if status[0] == "A" and status[3] != "+": |
| 909 # We'll need to upload the new content if we're adding a binary file | 910 # We'll need to upload the new content if we're adding a binary file |
| 910 # since diff's output won't contain it. | 911 # since diff's output won't contain it. |
| 911 mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], | 912 mimetype = RunShell(["svn", "propget", "svn:mime-type", filename], |
| 912 silent_ok=True) | 913 silent_ok=True) |
| 913 base_content = "" | 914 base_content = "" |
| 914 is_binary = mimetype and not mimetype.startswith("text/") | 915 is_binary = bool(mimetype) and not mimetype.startswith("text/") |
| 915 if is_binary and self.IsImage(filename): | 916 if is_binary and self.IsImage(filename): |
| 916 new_content = self.ReadFile(filename) | 917 new_content = self.ReadFile(filename) |
| 917 elif (status[0] in ("M", "D", "R") or | 918 elif (status[0] in ("M", "D", "R") or |
| 918 (status[0] == "A" and status[3] == "+") or # Copied file. | 919 (status[0] == "A" and status[3] == "+") or # Copied file. |
| 919 (status[0] == " " and status[1] == "M")): # Property change. | 920 (status[0] == " " and status[1] == "M")): # Property change. |
| 920 args = [] | 921 args = [] |
| 921 if self.options.revision: | 922 if self.options.revision: |
| 922 url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) | 923 url = "%s/%s@%s" % (self.svn_base, filename, self.rev_start) |
| 923 else: | 924 else: |
| 924 # Don't change filename, it's needed later. | 925 # Don't change filename, it's needed later. |
| 925 url = filename | 926 url = filename |
| 926 args += ["-r", "BASE"] | 927 args += ["-r", "BASE"] |
| 927 cmd = ["svn"] + args + ["propget", "svn:mime-type", url] | 928 cmd = ["svn"] + args + ["propget", "svn:mime-type", url] |
| 928 mimetype, returncode = RunShellWithReturnCode(cmd) | 929 mimetype, returncode = RunShellWithReturnCode(cmd) |
| 929 if returncode: | 930 if returncode: |
| 930 # File does not exist in the requested revision. | 931 # File does not exist in the requested revision. |
| 931 # Reset mimetype, it contains an error message. | 932 # Reset mimetype, it contains an error message. |
| 932 mimetype = "" | 933 mimetype = "" |
| 933 get_base = False | 934 get_base = False |
| 934 is_binary = mimetype and not mimetype.startswith("text/") | 935 is_binary = bool(mimetype) and not mimetype.startswith("text/") |
| 935 if status[0] == " ": | 936 if status[0] == " ": |
| 936 # Empty base content just to force an upload. | 937 # Empty base content just to force an upload. |
| 937 base_content = "" | 938 base_content = "" |
| 938 elif is_binary: | 939 elif is_binary: |
| 939 if self.IsImage(filename): | 940 if self.IsImage(filename): |
| 940 get_base = True | 941 get_base = True |
| 941 if status[0] == "M": | 942 if status[0] == "M": |
| 942 if not self.rev_end: | 943 if not self.rev_end: |
| 943 new_content = self.ReadFile(filename) | 944 new_content = self.ReadFile(filename) |
| 944 else: | 945 else: |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1144 def GenerateDiff(self, args): | 1145 def GenerateDiff(self, args): |
| 1145 """Return the current diff as a string. | 1146 """Return the current diff as a string. |
| 1146 | 1147 |
| 1147 Args: | 1148 Args: |
| 1148 args: Extra arguments to pass to the diff command. | 1149 args: Extra arguments to pass to the diff command. |
| 1149 """ | 1150 """ |
| 1150 if self.options.revision: | 1151 if self.options.revision: |
| 1151 args = ["-r", self.options.revision] + args | 1152 args = ["-r", self.options.revision] + args |
| 1152 # We need check_returncode = False because bzr diff returns 1 if changes | 1153 # We need check_returncode = False because bzr diff returns 1 if changes |
| 1153 # are found. | 1154 # are found. |
| 1154 data = RunShell(["bzr", "diff"] + args, silent_ok=True, | 1155 |
| 1155 check_returncode=False) | 1156 data,retcode = RunShellWithReturnCode(["bzr", "diff"] + args, True) |
| 1156 filecount = 0 | 1157 filecount = 0 |
| 1157 lines = data.splitlines() | 1158 lines = data.splitlines() |
| 1158 for i, line in enumerate(lines): | 1159 for i, line in enumerate(lines): |
| 1159 match = re.match(r"^=== (added|removed|modified) file '(.*)'$", line) | 1160 match = re.match(r"^=== (added|removed|modified) file '(.*)'$", line) |
| 1160 if match: | 1161 if match: |
| 1161 # Modify line to make it look like as it comes from svn diff. | 1162 # Modify line to make it look like as it comes from svn diff. |
| 1162 lines[i] = "Index: %s" % match.group(2) | 1163 lines[i] = "Index: %s" % match.group(2) |
| 1163 filecount += 1 | 1164 filecount += 1 |
| 1164 logging.info(line) | 1165 logging.info(line) |
| 1165 if not filecount: | 1166 if not filecount: |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1180 | 1181 |
| 1181 def GetBaseFile(self, filename): | 1182 def GetBaseFile(self, filename): |
| 1182 """Get the content of the upstream version of a file. | 1183 """Get the content of the upstream version of a file. |
| 1183 | 1184 |
| 1184 Returns: | 1185 Returns: |
| 1185 A tuple (content, status) representing the file content and the status of | 1186 A tuple (content, status) representing the file content and the status of |
| 1186 the file. | 1187 the file. |
| 1187 """ | 1188 """ |
| 1188 st_args = [] | 1189 st_args = [] |
| 1189 cat_args = [] | 1190 cat_args = [] |
| 1191 new_content = None | |
| 1190 if self.options.revision: | 1192 if self.options.revision: |
| 1191 if '..' in self.options.revision: | 1193 if '..' in self.options.revision: |
| 1192 start_rev = self.options.revision.split('..', 1)[0] | 1194 start_rev = self.options.revision.split('..', 1)[0] |
| 1193 cat_args += ["-r", start_rev] | 1195 cat_args += ["-r", start_rev] |
| 1194 else: | 1196 else: |
| 1195 cat_args += ["-r", self.options.revision] | 1197 cat_args += ["-r", self.options.revision] |
| 1196 st_args += ["-r", self.options.revision] | 1198 st_args += ["-r", self.options.revision] |
| 1197 status = RunShell(["bzr", "status", "-S"] + st_args + [filename]) | 1199 status = RunShell(["bzr", "status", "-S"] + st_args + [filename]) |
| 1198 if status[1] == "N": | 1200 if status[1] == "N": |
| 1199 content = "" | 1201 content = "" |
| 1200 else: | 1202 else: |
| 1201 content = RunShell(["bzr", "cat"] + cat_args + [filename]) | 1203 content = RunShell(["bzr", "cat"] + cat_args + [filename]) |
| 1202 return content, status[0:4] | 1204 return content, new_content, False, status[0:4] |
| 1203 | 1205 |
| 1204 | 1206 |
| 1205 # NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. | 1207 # NOTE: The SplitPatch function is duplicated in engine.py, keep them in sync. |
| 1206 def SplitPatch(data): | 1208 def SplitPatch(data): |
| 1207 """Splits a patch into separate pieces for each file. | 1209 """Splits a patch into separate pieces for each file. |
| 1208 | 1210 |
| 1209 Args: | 1211 Args: |
| 1210 data: A string containing the output of svn diff. | 1212 data: A string containing the output of svn diff. |
| 1211 | 1213 |
| 1212 Returns: | 1214 Returns: |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1284 # Mercurial has a command to get the base directory of a repository | 1286 # Mercurial has a command to get the base directory of a repository |
| 1285 # Try running it, but don't die if we don't have hg installed. | 1287 # Try running it, but don't die if we don't have hg installed. |
| 1286 # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. | 1288 # NOTE: we try Mercurial first as it can sit on top of an SVN working copy. |
| 1287 try: | 1289 try: |
| 1288 out, returncode = RunShellWithReturnCode(["hg", "root"]) | 1290 out, returncode = RunShellWithReturnCode(["hg", "root"]) |
| 1289 if returncode == 0: | 1291 if returncode == 0: |
| 1290 return MercurialVCS(options, out.strip()) | 1292 return MercurialVCS(options, out.strip()) |
| 1291 except OSError, (errno, message): | 1293 except OSError, (errno, message): |
| 1292 if errno != 2: # ENOENT -- they don't have hg installed. | 1294 if errno != 2: # ENOENT -- they don't have hg installed. |
| 1293 raise | 1295 raise |
| 1294 | 1296 try: |
|
bialix
2009/03/24 22:49:23
I think you need either use command ["bzr", "--no-
| |
| 1297 out, returncode = RunShellWithReturnCode(["bzr", "root"]) | |
| 1298 if returncode == 0: | |
| 1299 os.chdir(out.strip()) | |
| 1300 return BazaarVCS(options) | |
| 1301 except OSError, (errno, message): | |
| 1302 if errno != 2: # ENOENT -- they don't have bzr installed. | |
| 1303 raise | |
| 1295 # Subversion has a .svn in all working directories. | 1304 # Subversion has a .svn in all working directories. |
| 1296 if os.path.isdir('.svn'): | 1305 if os.path.isdir('.svn'): |
| 1297 logging.info("Guessed VCS = Subversion") | 1306 logging.info("Guessed VCS = Subversion") |
| 1298 return SubversionVCS(options) | 1307 return SubversionVCS(options) |
| 1299 elif os.path.isdir(".bzr"): | 1308 |
| 1300 logging.info("Guessed VCS = Bazaar") | |
| 1301 return BazaarVCS(options) | |
| 1302 # Git has a command to test if you're in a git tree. | 1309 # Git has a command to test if you're in a git tree. |
| 1303 # Try running it, but don't die if we don't have git installed. | 1310 # Try running it, but don't die if we don't have git installed. |
| 1304 try: | 1311 try: |
| 1305 out, returncode = RunShellWithReturnCode(["git", "rev-parse", | 1312 out, returncode = RunShellWithReturnCode(["git", "rev-parse", |
| 1306 "--is-inside-work-tree"]) | 1313 "--is-inside-work-tree"]) |
| 1307 if returncode == 0: | 1314 if returncode == 0: |
| 1308 return GitVCS(options) | 1315 return GitVCS(options) |
| 1309 except OSError, (errno, message): | 1316 except OSError, (errno, message): |
| 1310 if errno != 2: # ENOENT -- they don't have git installed. | 1317 if errno != 2: # ENOENT -- they don't have git installed. |
| 1311 raise | 1318 raise |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1432 try: | 1439 try: |
| 1433 RealMain(sys.argv) | 1440 RealMain(sys.argv) |
| 1434 except KeyboardInterrupt: | 1441 except KeyboardInterrupt: |
| 1435 print | 1442 print |
| 1436 StatusUpdate("Interrupted.") | 1443 StatusUpdate("Interrupted.") |
| 1437 sys.exit(1) | 1444 sys.exit(1) |
| 1438 | 1445 |
| 1439 | 1446 |
| 1440 if __name__ == "__main__": | 1447 if __name__ == "__main__": |
| 1441 main() | 1448 main() |
| LEFT | RIGHT |