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

Side by Side Diff: gcl.py

Issue 399009: Reapply 32057, 32058, 32059, 32062 and fixes problems introduced by these changes. (Closed)
Patch Set: Created 11 years, 1 month 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
« no previous file with comments | « no previous file | gclient.py » ('j') | 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/python 1 #!/usr/bin/python
2 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2006-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 """Wrapper script around Rietveld's upload.py that groups files into 6 """Wrapper script around Rietveld's upload.py that groups files into
7 changelists.""" 7 changelists."""
8 8
9 import getpass 9 import getpass
10 import os 10 import os
11 import random 11 import random
12 import re 12 import re
13 import shutil 13 import shutil
14 import string 14 import string
15 import subprocess 15 import subprocess
16 import sys 16 import sys
17 import tempfile 17 import tempfile
18 import upload 18 import upload
19 import urllib2 19 import urllib2
20 20
21 # gcl now depends on gclient. 21 # gcl now depends on gclient.
22 import gclient_scm 22 from scm import SVN
23 import gclient_utils 23 import gclient_utils
24 24
25 __version__ = '1.1.1' 25 __version__ = '1.1.2'
26 26
27 27
28 CODEREVIEW_SETTINGS = { 28 CODEREVIEW_SETTINGS = {
29 # Default values. 29 # Default values.
30 "CODE_REVIEW_SERVER": "codereview.chromium.org", 30 "CODE_REVIEW_SERVER": "codereview.chromium.org",
31 "CC_LIST": "chromium-reviews@googlegroups.com", 31 "CC_LIST": "chromium-reviews@googlegroups.com",
32 "VIEW_VC": "http://src.chromium.org/viewvc/chrome?view=rev&revision=", 32 "VIEW_VC": "http://src.chromium.org/viewvc/chrome?view=rev&revision=",
33 } 33 }
34 34
35 # globals that store the root of the current repository and the directory where 35 # globals that store the root of the current repository and the directory where
36 # we store information about changelists. 36 # we store information about changelists.
37 REPOSITORY_ROOT = "" 37 REPOSITORY_ROOT = ""
38 38
39 # Filename where we store repository specific information for gcl. 39 # Filename where we store repository specific information for gcl.
40 CODEREVIEW_SETTINGS_FILE = "codereview.settings" 40 CODEREVIEW_SETTINGS_FILE = "codereview.settings"
41 41
42 # Warning message when the change appears to be missing tests. 42 # Warning message when the change appears to be missing tests.
43 MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!" 43 MISSING_TEST_MSG = "Change contains new or modified methods, but no new tests!"
44 44
45 # Global cache of files cached in GetCacheDir(). 45 # Global cache of files cached in GetCacheDir().
46 FILES_CACHE = {} 46 FILES_CACHE = {}
47 47
48 48
49 ### SVN Functions
50
51 def IsSVNMoved(filename):
52 """Determine if a file has been added through svn mv"""
53 info = gclient_scm.CaptureSVNInfo(filename)
54 return (info.get('Copied From URL') and
55 info.get('Copied From Rev') and
56 info.get('Schedule') == 'add')
57
58
59 def GetSVNFileProperty(file, property_name):
60 """Returns the value of an SVN property for the given file.
61
62 Args:
63 file: The file to check
64 property_name: The name of the SVN property, e.g. "svn:mime-type"
65
66 Returns:
67 The value of the property, which will be the empty string if the property
68 is not set on the file. If the file is not under version control, the
69 empty string is also returned.
70 """
71 output = RunShell(["svn", "propget", property_name, file])
72 if (output.startswith("svn: ") and
73 output.endswith("is not under version control")):
74 return ""
75 else:
76 return output
77
78
79 def UnknownFiles(extra_args): 49 def UnknownFiles(extra_args):
80 """Runs svn status and prints unknown files. 50 """Runs svn status and returns unknown files.
81 51
82 Any args in |extra_args| are passed to the tool to support giving alternate 52 Any args in |extra_args| are passed to the tool to support giving alternate
83 code locations. 53 code locations.
84 """ 54 """
85 return [item[1] for item in gclient_scm.CaptureSVNStatus(extra_args) 55 return [item[1] for item in SVN.CaptureStatus(extra_args)
86 if item[0][0] == '?'] 56 if item[0][0] == '?']
87 57
88 58
89 def GetRepositoryRoot(): 59 def GetRepositoryRoot():
90 """Returns the top level directory of the current repository. 60 """Returns the top level directory of the current repository.
91 61
92 The directory is returned as an absolute path. 62 The directory is returned as an absolute path.
93 """ 63 """
94 global REPOSITORY_ROOT 64 global REPOSITORY_ROOT
95 if not REPOSITORY_ROOT: 65 if not REPOSITORY_ROOT:
96 infos = gclient_scm.CaptureSVNInfo(os.getcwd(), print_error=False) 66 infos = SVN.CaptureInfo(os.getcwd(), print_error=False)
97 cur_dir_repo_root = infos.get("Repository Root") 67 cur_dir_repo_root = infos.get("Repository Root")
98 if not cur_dir_repo_root: 68 if not cur_dir_repo_root:
99 raise gclient_utils.Error("gcl run outside of repository") 69 raise gclient_utils.Error("gcl run outside of repository")
100 70
101 REPOSITORY_ROOT = os.getcwd() 71 REPOSITORY_ROOT = os.getcwd()
102 while True: 72 while True:
103 parent = os.path.dirname(REPOSITORY_ROOT) 73 parent = os.path.dirname(REPOSITORY_ROOT)
104 if (gclient_scm.CaptureSVNInfo(parent, print_error=False).get( 74 if (SVN.CaptureInfo(parent, print_error=False).get(
105 "Repository Root") != cur_dir_repo_root): 75 "Repository Root") != cur_dir_repo_root):
106 break 76 break
107 REPOSITORY_ROOT = parent 77 REPOSITORY_ROOT = parent
108 return REPOSITORY_ROOT 78 return REPOSITORY_ROOT
109 79
110 80
111 def GetInfoDir(): 81 def GetInfoDir():
112 """Returns the directory where gcl info files are stored.""" 82 """Returns the directory where gcl info files are stored."""
113 return os.path.join(GetRepositoryRoot(), '.svn', 'gcl_info') 83 return os.path.join(GetRepositoryRoot(), '.svn', 'gcl_info')
114 84
(...skipping 24 matching lines...) Expand all
139 FILES_CACHE[filename] = None 109 FILES_CACHE[filename] = None
140 # First we check if we have a cached version. 110 # First we check if we have a cached version.
141 try: 111 try:
142 cached_file = os.path.join(GetCacheDir(), filename) 112 cached_file = os.path.join(GetCacheDir(), filename)
143 except gclient_utils.Error: 113 except gclient_utils.Error:
144 return None 114 return None
145 if (not os.path.exists(cached_file) or 115 if (not os.path.exists(cached_file) or
146 os.stat(cached_file).st_mtime > max_age): 116 os.stat(cached_file).st_mtime > max_age):
147 local_dir = os.path.dirname(os.path.abspath(filename)) 117 local_dir = os.path.dirname(os.path.abspath(filename))
148 local_base = os.path.basename(filename) 118 local_base = os.path.basename(filename)
149 dir_info = gclient_scm.CaptureSVNInfo(".") 119 dir_info = SVN.CaptureInfo(".")
150 repo_root = dir_info["Repository Root"] 120 repo_root = dir_info["Repository Root"]
151 if use_root: 121 if use_root:
152 url_path = repo_root 122 url_path = repo_root
153 else: 123 else:
154 url_path = dir_info["URL"] 124 url_path = dir_info["URL"]
155 content = "" 125 content = ""
156 while True: 126 while True:
157 # First, look for a locally modified version of the file if we can. 127 # First, look for a locally modified version of the file if we can.
158 r = "" 128 r = ""
159 if not use_root: 129 if not use_root:
160 local_path = os.path.join(local_dir, local_base) 130 local_path = os.path.join(local_dir, local_base)
161 r = gclient_scm.CaptureSVNStatus((local_path,)) 131 r = SVN.CaptureStatus((local_path,))
162 rc = -1 132 rc = -1
163 if r: 133 if r:
164 status = r[0][0] 134 status = r[0][0]
165 rc = 0 135 rc = 0
166 if not rc and status[0] in ('A','M'): 136 if not rc and status[0] in ('A','M'):
167 content = ReadFile(local_path) 137 content = ReadFile(local_path)
168 rc = 0 138 rc = 0
169 else: 139 else:
170 # Look in the repository if we didn't find something local. 140 # Look in the repository if we didn't find something local.
171 svn_path = url_path + "/" + filename 141 svn_path = url_path + "/" + filename
(...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 files = [] 441 files = []
472 for line in split_data[1].splitlines(): 442 for line in split_data[1].splitlines():
473 status = line[:7] 443 status = line[:7]
474 filename = line[7:] 444 filename = line[7:]
475 files.append((status, filename)) 445 files.append((status, filename))
476 description = split_data[2] 446 description = split_data[2]
477 save = False 447 save = False
478 if update_status: 448 if update_status:
479 for item in files: 449 for item in files:
480 filename = os.path.join(local_root, item[1]) 450 filename = os.path.join(local_root, item[1])
481 status_result = gclient_scm.CaptureSVNStatus(filename) 451 status_result = SVN.CaptureStatus(filename)
482 if not status_result or not status_result[0][0]: 452 if not status_result or not status_result[0][0]:
483 # File has been reverted. 453 # File has been reverted.
484 save = True 454 save = True
485 files.remove(item) 455 files.remove(item)
486 continue 456 continue
487 status = status_result[0][0] 457 status = status_result[0][0]
488 if status != item[0]: 458 if status != item[0]:
489 save = True 459 save = True
490 files[files.index(item)] = (status, item[1]) 460 files[files.index(item)] = (status, item[1])
491 change_info = ChangeInfo(changename, issue, patchset, description, files, 461 change_info = ChangeInfo(changename, issue, patchset, description, files,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 525
556 # Get a list of all files in changelists. 526 # Get a list of all files in changelists.
557 files_in_cl = {} 527 files_in_cl = {}
558 for cl in GetCLs(): 528 for cl in GetCLs():
559 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(), 529 change_info = ChangeInfo.Load(cl, GetRepositoryRoot(),
560 fail_on_not_found=True, update_status=False) 530 fail_on_not_found=True, update_status=False)
561 for status, filename in change_info.GetFiles(): 531 for status, filename in change_info.GetFiles():
562 files_in_cl[filename] = change_info.name 532 files_in_cl[filename] = change_info.name
563 533
564 # Get all the modified files. 534 # Get all the modified files.
565 status_result = gclient_scm.CaptureSVNStatus(None) 535 status_result = SVN.CaptureStatus(None)
566 for line in status_result: 536 for line in status_result:
567 status = line[0] 537 status = line[0]
568 filename = line[1] 538 filename = line[1]
569 if status[0] == "?": 539 if status[0] == "?":
570 continue 540 continue
571 if dir_prefix: 541 if dir_prefix:
572 filename = os.path.join(dir_prefix, filename) 542 filename = os.path.join(dir_prefix, filename)
573 change_list_name = "" 543 change_list_name = ""
574 if filename in files_in_cl: 544 if filename in files_in_cl:
575 change_list_name = files_in_cl[filename] 545 change_list_name = files_in_cl[filename]
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 used. 712 used.
743 """ 713 """
744 previous_cwd = os.getcwd() 714 previous_cwd = os.getcwd()
745 if root is None: 715 if root is None:
746 os.chdir(GetRepositoryRoot()) 716 os.chdir(GetRepositoryRoot())
747 else: 717 else:
748 os.chdir(root) 718 os.chdir(root)
749 719
750 diff = [] 720 diff = []
751 for filename in files: 721 for filename in files:
722 # TODO(maruel): Use SVN.DiffItem().
752 # Use svn info output instead of os.path.isdir because the latter fails 723 # Use svn info output instead of os.path.isdir because the latter fails
753 # when the file is deleted. 724 # when the file is deleted.
754 if gclient_scm.CaptureSVNInfo(filename).get("Node Kind") in ("dir", 725 if SVN.CaptureInfo(filename).get('Node Kind') == 'directory':
755 "directory"):
756 continue 726 continue
757 # If the user specified a custom diff command in their svn config file, 727 # If the user specified a custom diff command in their svn config file,
758 # then it'll be used when we do svn diff, which we don't want to happen 728 # then it'll be used when we do svn diff, which we don't want to happen
759 # since we want the unified diff. Using --diff-cmd=diff doesn't always 729 # since we want the unified diff. Using --diff-cmd=diff doesn't always
760 # work, since they can have another diff executable in their path that 730 # work, since they can have another diff executable in their path that
761 # gives different line endings. So we use a bogus temp directory as the 731 # gives different line endings. So we use a bogus temp directory as the
762 # config directory, which gets around these problems. 732 # config directory, which gets around these problems.
763 if sys.platform.startswith("win"): 733 if sys.platform.startswith("win"):
764 parent_dir = tempfile.gettempdir() 734 parent_dir = tempfile.gettempdir()
765 else: 735 else:
766 parent_dir = sys.path[0] # tempdir is not secure. 736 parent_dir = sys.path[0] # tempdir is not secure.
767 bogus_dir = os.path.join(parent_dir, "temp_svn_config") 737 bogus_dir = os.path.join(parent_dir, "temp_svn_config")
768 if not os.path.exists(bogus_dir): 738 if not os.path.exists(bogus_dir):
769 os.mkdir(bogus_dir) 739 os.mkdir(bogus_dir)
770 output = RunShell(["svn", "diff", "--config-dir", bogus_dir, filename]) 740 output = RunShell(["svn", "diff", "--config-dir", bogus_dir, filename])
771 if output: 741 if output:
772 diff.append(output) 742 diff.append(output)
773 elif IsSVNMoved(filename): 743 elif SVN.IsMoved(filename):
774 # svn diff on a mv/cp'd file outputs nothing. 744 # svn diff on a mv/cp'd file outputs nothing.
775 # We put in an empty Index entry so upload.py knows about them. 745 # We put in an empty Index entry so upload.py knows about them.
776 diff.append("\nIndex: %s\n" % filename) 746 diff.append("\nIndex: %s\n" % filename)
777 else: 747 else:
778 # The file is not modified anymore. It should be removed from the set. 748 # The file is not modified anymore. It should be removed from the set.
779 pass 749 pass
780 os.chdir(previous_cwd) 750 os.chdir(previous_cwd)
781 return "".join(diff) 751 return "".join(diff)
782 752
783 753
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 change_info.description += "\nCommitted: " + viewvc_url + revision 959 change_info.description += "\nCommitted: " + viewvc_url + revision
990 change_info.CloseIssue() 960 change_info.CloseIssue()
991 os.chdir(previous_cwd) 961 os.chdir(previous_cwd)
992 962
993 963
994 def Change(change_info, args): 964 def Change(change_info, args):
995 """Creates/edits a changelist.""" 965 """Creates/edits a changelist."""
996 silent = FilterFlag(args, "--silent") 966 silent = FilterFlag(args, "--silent")
997 967
998 # Verify the user is running the change command from a read-write checkout. 968 # Verify the user is running the change command from a read-write checkout.
999 svn_info = gclient_scm.CaptureSVNInfo('.') 969 svn_info = SVN.CaptureInfo('.')
1000 if not svn_info: 970 if not svn_info:
1001 ErrorExit("Current checkout is unversioned. Please retry with a versioned " 971 ErrorExit("Current checkout is unversioned. Please retry with a versioned "
1002 "directory.") 972 "directory.")
1003 973
1004 if (len(args) == 1): 974 if (len(args) == 1):
1005 filename = args[0] 975 filename = args[0]
1006 f = open(filename, 'rU') 976 f = open(filename, 'rU')
1007 override_description = f.read() 977 override_description = f.read()
1008 f.close() 978 f.close()
1009 else: 979 else:
1010 override_description = None 980 override_description = None
1011 981
1012 if change_info.issue: 982 if change_info.issue:
1013 try: 983 try:
1014 description = GetIssueDescription(change_info.issue) 984 description = GetIssueDescription(change_info.issue)
1015 except urllib2.HTTPError, err: 985 except urllib2.HTTPError, err:
1016 if err.code == 404: 986 if err.code == 404:
1017 # The user deleted the issue in Rietveld, so forget the old issue id. 987 # The user deleted the issue in Rietveld, so forget the old issue id.
1018 description = change_info.description 988 description = change_info.description
1019 change_info.issue = 0 989 change_info.issue = 0
1020 change_info.Save() 990 change_info.Save()
1021 else: 991 else:
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 return 0 1264 return 0
1295 args =["svn", command] 1265 args =["svn", command]
1296 root = GetRepositoryRoot() 1266 root = GetRepositoryRoot()
1297 args.extend([os.path.join(root, x) for x in change_info.GetFileNames()]) 1267 args.extend([os.path.join(root, x) for x in change_info.GetFileNames()])
1298 RunShell(args, True) 1268 RunShell(args, True)
1299 return 0 1269 return 0
1300 1270
1301 1271
1302 if __name__ == "__main__": 1272 if __name__ == "__main__":
1303 sys.exit(main()) 1273 sys.exit(main())
OLDNEW
« no previous file with comments | « no previous file | gclient.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698