Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(472)

Side by Side Diff: third_party/upload.py

Issue 1868313002: git cl upload: commit subject is default patchset title (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: s/Current/MostRecent/ Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # coding: utf-8 2 # coding: utf-8
3 # 3 #
4 # Copyright 2007 Google Inc. 4 # Copyright 2007 Google Inc.
5 # 5 #
6 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License. 7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at 8 # You may obtain a copy of the License at
9 # 9 #
10 # http://www.apache.org/licenses/LICENSE-2.0 10 # http://www.apache.org/licenses/LICENSE-2.0
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after
937 new_content: For text files, this is empty. For binary files, this is 937 new_content: For text files, this is empty. For binary files, this is
938 the contents of the new file, since the diff output won't contain 938 the contents of the new file, since the diff output won't contain
939 information to reconstruct the current file. 939 information to reconstruct the current file.
940 is_binary: True iff the file is binary. 940 is_binary: True iff the file is binary.
941 status: The status of the file. 941 status: The status of the file.
942 """ 942 """
943 943
944 raise NotImplementedError( 944 raise NotImplementedError(
945 "abstract method -- subclass %s must override" % self.__class__) 945 "abstract method -- subclass %s must override" % self.__class__)
946 946
947
948 def GetBaseFiles(self, diff): 947 def GetBaseFiles(self, diff):
949 """Helper that calls GetBase file for each file in the patch. 948 """Helper that calls GetBase file for each file in the patch.
950 949
951 Returns: 950 Returns:
952 A dictionary that maps from filename to GetBaseFile's tuple. Filenames 951 A dictionary that maps from filename to GetBaseFile's tuple. Filenames
953 are retrieved based on lines that start with "Index:" or 952 are retrieved based on lines that start with "Index:" or
954 "Property changes on:". 953 "Property changes on:".
955 """ 954 """
956 files = {} 955 files = {}
957 for line in diff.splitlines(True): 956 for line in diff.splitlines(True):
958 if line.startswith('Index:') or line.startswith('Property changes on:'): 957 if line.startswith('Index:') or line.startswith('Property changes on:'):
959 unused, filename = line.split(':', 1) 958 unused, filename = line.split(':', 1)
960 # On Windows if a file has property changes its filename uses '\' 959 # On Windows if a file has property changes its filename uses '\'
961 # instead of '/'. 960 # instead of '/'.
962 filename = filename.strip().replace('\\', '/') 961 filename = filename.strip().replace('\\', '/')
963 files[filename] = self.GetBaseFile(filename) 962 files[filename] = self.GetBaseFile(filename)
964 return files 963 return files
965 964
966
967 def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options, 965 def UploadBaseFiles(self, issue, rpc_server, patch_list, patchset, options,
968 files): 966 files):
969 """Uploads the base files (and if necessary, the current ones as well).""" 967 """Uploads the base files (and if necessary, the current ones as well)."""
970 968
971 def UploadFile(filename, file_id, content, is_binary, status, is_base): 969 def UploadFile(filename, file_id, content, is_binary, status, is_base):
972 """Uploads a file to the server.""" 970 """Uploads a file to the server."""
973 file_too_large = False 971 file_too_large = False
974 if is_base: 972 if is_base:
975 type = "base" 973 type = "base"
976 else: 974 else:
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1026 file_id, base_content, is_binary, status, True)) 1024 file_id, base_content, is_binary, status, True))
1027 threads.append(t) 1025 threads.append(t)
1028 if new_content != None: 1026 if new_content != None:
1029 t = thread_pool.apply_async(UploadFile, args=(filename, 1027 t = thread_pool.apply_async(UploadFile, args=(filename,
1030 file_id, new_content, is_binary, status, False)) 1028 file_id, new_content, is_binary, status, False))
1031 threads.append(t) 1029 threads.append(t)
1032 1030
1033 for t in threads: 1031 for t in threads:
1034 print t.get(timeout=60) 1032 print t.get(timeout=60)
1035 1033
1036
1037 def IsImage(self, filename): 1034 def IsImage(self, filename):
1038 """Returns true if the filename has an image extension.""" 1035 """Returns true if the filename has an image extension."""
1039 mimetype = mimetypes.guess_type(filename)[0] 1036 mimetype = mimetypes.guess_type(filename)[0]
1040 if not mimetype: 1037 if not mimetype:
1041 return False 1038 return False
1042 return (mimetype.startswith("image/") and 1039 return (mimetype.startswith("image/") and
1043 not mimetype.startswith("image/svg")) 1040 not mimetype.startswith("image/svg"))
1044 1041
1045 def IsBinaryData(self, data): 1042 def IsBinaryData(self, data):
1046 """Returns true if data contains a null byte.""" 1043 """Returns true if data contains a null byte."""
1047 # Derived from how Mercurial's heuristic, see 1044 # Derived from how Mercurial's heuristic, see
1048 # http://selenic.com/hg/file/848a6658069e/mercurial/util.py#l229 1045 # http://selenic.com/hg/file/848a6658069e/mercurial/util.py#l229
1049 return bool(data and "\0" in data) 1046 return bool(data and "\0" in data)
1050 1047
1048 def GetMostRecentCommitSummary(self):
1049 """Returns a one line summary of the current commit."""
1050 return ""
1051
1051 1052
1052 class SubversionVCS(VersionControlSystem): 1053 class SubversionVCS(VersionControlSystem):
1053 """Implementation of the VersionControlSystem interface for Subversion.""" 1054 """Implementation of the VersionControlSystem interface for Subversion."""
1054 1055
1055 def __init__(self, options): 1056 def __init__(self, options):
1056 super(SubversionVCS, self).__init__(options) 1057 super(SubversionVCS, self).__init__(options)
1057 if self.options.revision: 1058 if self.options.revision:
1058 match = re.match(r"(\d+)(:(\d+))?", self.options.revision) 1059 match = re.match(r"(\d+)(:(\d+))?", self.options.revision)
1059 if not match: 1060 if not match:
1060 ErrorExit("Invalid Subversion revision %s." % self.options.revision) 1061 ErrorExit("Invalid Subversion revision %s." % self.options.revision)
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
1504 1505
1505 # Only include the "after" file if it's an image; otherwise it 1506 # Only include the "after" file if it's an image; otherwise it
1506 # it is reconstructed from the diff. 1507 # it is reconstructed from the diff.
1507 if hash_after: 1508 if hash_after:
1508 new_content = self.GetFileContent(hash_after) 1509 new_content = self.GetFileContent(hash_after)
1509 is_binary = is_binary or self.IsBinaryData(new_content) 1510 is_binary = is_binary or self.IsBinaryData(new_content)
1510 if not is_binary: 1511 if not is_binary:
1511 new_content = None 1512 new_content = None
1512 return (base_content, new_content, is_binary, status) 1513 return (base_content, new_content, is_binary, status)
1513 1514
1515 def GetMostRecentCommitSummary(self):
1516 return RunShell(["git", "log", "-1", "--format=%s"], silent_ok=True).strip()
1517
1514 1518
1515 class CVSVCS(VersionControlSystem): 1519 class CVSVCS(VersionControlSystem):
1516 """Implementation of the VersionControlSystem interface for CVS.""" 1520 """Implementation of the VersionControlSystem interface for CVS."""
1517 1521
1518 def __init__(self, options): 1522 def __init__(self, options):
1519 super(CVSVCS, self).__init__(options) 1523 super(CVSVCS, self).__init__(options)
1520 1524
1521 def GetGUID(self): 1525 def GetGUID(self):
1522 """For now we don't know how to get repository ID for CVS""" 1526 """For now we don't know how to get repository ID for CVS"""
1523 return 1527 return
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after
2428 2432
2429 # Process --message, --title and --file. 2433 # Process --message, --title and --file.
2430 message = options.message or "" 2434 message = options.message or ""
2431 title = options.title or "" 2435 title = options.title or ""
2432 if options.file: 2436 if options.file:
2433 if options.message: 2437 if options.message:
2434 ErrorExit("Can't specify both message and message file options") 2438 ErrorExit("Can't specify both message and message file options")
2435 file = open(options.file, 'r') 2439 file = open(options.file, 'r')
2436 message = file.read() 2440 message = file.read()
2437 file.close() 2441 file.close()
2438 if options.issue: 2442 title = title or message.split('\n', 1)[0].strip()
2439 prompt = "Title describing this patch set: " 2443 if not title:
2440 else: 2444 if options.issue:
2441 prompt = "New issue subject: " 2445 prompt = "Title describing this patch set"
2442 title = ( 2446 else:
2443 title or message.split('\n', 1)[0].strip() or raw_input(prompt).strip()) 2447 prompt = "New issue subject"
2448 title_default = vcs.GetMostRecentCommitSummary()
2449 if title_default:
2450 prompt += " [%s]" % title_default
2451 title = raw_input(prompt + ": ").strip() or title_default
2444 if not title and not options.issue: 2452 if not title and not options.issue:
2445 ErrorExit("A non-empty title is required for a new issue") 2453 ErrorExit("A non-empty title is required for a new issue")
2446 # For existing issues, it's fine to give a patchset an empty name. Rietveld 2454 # For existing issues, it's fine to give a patchset an empty name. Rietveld
2447 # doesn't accept that so use a whitespace. 2455 # doesn't accept that so use a whitespace.
2448 title = title or " " 2456 title = title or " "
2449 if len(title) > 100: 2457 if len(title) > 100:
2450 title = title[:99] + '…' 2458 title = title[:99] + '…'
2451 if title and not options.issue: 2459 if title and not options.issue:
2452 message = message or title 2460 message = message or title
2453 2461
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
2535 print 2543 print
2536 StatusUpdate("Interrupted.") 2544 StatusUpdate("Interrupted.")
2537 sys.exit(1) 2545 sys.exit(1)
2538 except auth.AuthenticationError as e: 2546 except auth.AuthenticationError as e:
2539 print >> sys.stderr, e 2547 print >> sys.stderr, e
2540 sys.exit(1) 2548 sys.exit(1)
2541 2549
2542 2550
2543 if __name__ == "__main__": 2551 if __name__ == "__main__":
2544 main() 2552 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698