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

Side by Side Diff: gclient_scm.py

Issue 189913020: gclient: print a warning if a dep would get deleted or moved in the future (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix warning Created 6 years, 8 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 | scm.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 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Gclient-specific SCM-specific operations.""" 5 """Gclient-specific SCM-specific operations."""
6 6
7 # TODO(borenet): Uncomment this once SCMWrapper._DeleteOrMove is enabled.
8 #import errno
iannucci 2014/04/04 00:49:54 Probably should just leave these comments out and
borenet 2014/04/07 14:24:02 Done.
7 import logging 9 import logging
8 import os 10 import os
9 import posixpath 11 import posixpath
10 import re 12 import re
11 import shlex 13 import shlex
12 import sys 14 import sys
13 import tempfile 15 import tempfile
14 import traceback 16 import traceback
15 import urlparse 17 import urlparse
16 18
17 import download_from_google_storage 19 import download_from_google_storage
18 import gclient_utils 20 import gclient_utils
19 import scm 21 import scm
22 # TODO(borenet): Uncomment this once SCMWrapper._DeleteOrMove is enabled.
23 #import shutil
20 import subprocess2 24 import subprocess2
21 25
22 26
23 THIS_FILE_PATH = os.path.abspath(__file__) 27 THIS_FILE_PATH = os.path.abspath(__file__)
24 28
25 GSUTIL_DEFAULT_PATH = os.path.join( 29 GSUTIL_DEFAULT_PATH = os.path.join(
26 os.path.dirname(os.path.abspath(__file__)), 30 os.path.dirname(os.path.abspath(__file__)),
27 'third_party', 'gsutil', 'gsutil') 31 'third_party', 'gsutil', 'gsutil')
28 32
29 33
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 162
159 actual_remote_url = self.GetActualRemoteURL() 163 actual_remote_url = self.GetActualRemoteURL()
160 if actual_remote_url: 164 if actual_remote_url:
161 return (gclient_utils.SplitUrlRevision(actual_remote_url)[0].rstrip('/') 165 return (gclient_utils.SplitUrlRevision(actual_remote_url)[0].rstrip('/')
162 == gclient_utils.SplitUrlRevision(self.url)[0].rstrip('/')) 166 == gclient_utils.SplitUrlRevision(self.url)[0].rstrip('/'))
163 else: 167 else:
164 # This may occur if the self.checkout_path exists but does not contain a 168 # This may occur if the self.checkout_path exists but does not contain a
165 # valid git or svn checkout. 169 # valid git or svn checkout.
166 return False 170 return False
167 171
172 # TODO(borenet): Remove this once SCMWrapper._DeleteOrMove is enabled.
173 # pylint: disable=R0201
174 def _DeleteOrMove(self, force):
175 """Delete the checkout directory or move it out of the way.
176
177 Args:
178 force: bool; if True, delete the directory. Otherwise, just move it.
179 """
180 # TODO(borenet): Uncomment the below implementation once we're sure nobody
181 # will trigger it accidentally.
182 gclient_utils.AddWarning('WARNING: Upcoming changes would cause %s to be '
iannucci 2014/04/04 00:49:54 Prep the cl to turn this feature on, and mention i
borenet 2014/04/07 14:24:02 Done.
183 'deleted or moved to the side. This is intended '
184 'to ease changes to DEPS in the future. If you '
185 'are seeing this warning and haven\'t changed the '
186 'DEPS file, please contact borenet@ immediately.'
187 % self.checkout_path)
188 # if force:
189 # print('_____ Conflicting directory found in %s. Removing.'
190 # % self.checkout_path)
191 # gclient_utils.rmtree(self.checkout_path)
192 # else:
193 # bad_scm_dir = os.path.join(self._root_dir, '_bad_scm',
194 # os.path.dirname(self.relpath))
195 #
196 # try:
197 # os.makedirs(bad_scm_dir)
198 # except OSError as e:
199 # if e.errno != errno.EEXIST:
200 # raise
201 #
202 # dest_path = tempfile.mkdtemp(
203 # prefix=os.path.basename(self.relpath),
204 # dir=bad_scm_dir)
205 # print('_____ Conflicting directory found in %s. Moving to %s.'
206 # % (self.checkout_path, dest_path))
207 # gclient_utils.AddWarning('Conflicting directory %s moved to %s.'
208 # % (self.checkout_path, dest_path))
209 # shutil.move(self.checkout_path, dest_path)
210
168 211
169 class GitWrapper(SCMWrapper): 212 class GitWrapper(SCMWrapper):
170 """Wrapper for Git""" 213 """Wrapper for Git"""
171 name = 'git' 214 name = 'git'
172 remote = 'origin' 215 remote = 'origin'
173 216
174 cache_dir = None 217 cache_dir = None
175 218
176 def __init__(self, url=None, root_dir=None, relpath=None): 219 def __init__(self, url=None, root_dir=None, relpath=None):
177 """Removes 'git+' fake prefix from git URL.""" 220 """Removes 'git+' fake prefix from git URL."""
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 # For compatibility with old naming, translate 'origin' to 'refs/heads' 362 # For compatibility with old naming, translate 'origin' to 'refs/heads'
320 revision = revision.replace(self.remote + '/', 'refs/heads/') 363 revision = revision.replace(self.remote + '/', 'refs/heads/')
321 rev_type = "branch" 364 rev_type = "branch"
322 else: 365 else:
323 # hash is also a tag, only make a distinction at checkout 366 # hash is also a tag, only make a distinction at checkout
324 rev_type = "hash" 367 rev_type = "hash"
325 368
326 if (not os.path.exists(self.checkout_path) or 369 if (not os.path.exists(self.checkout_path) or
327 (os.path.isdir(self.checkout_path) and 370 (os.path.isdir(self.checkout_path) and
328 not os.path.exists(os.path.join(self.checkout_path, '.git')))): 371 not os.path.exists(os.path.join(self.checkout_path, '.git')))):
372 if (os.path.isdir(self.checkout_path) and
373 not os.path.exists(os.path.join(self.checkout_path, '.git'))):
374 self._DeleteOrMove(options.force)
329 self._Clone(revision, url, options) 375 self._Clone(revision, url, options)
330 self.UpdateSubmoduleConfig() 376 self.UpdateSubmoduleConfig()
331 if file_list is not None: 377 if file_list is not None:
332 files = self._Capture(['ls-files']).splitlines() 378 files = self._Capture(['ls-files']).splitlines()
333 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) 379 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
334 if not verbose: 380 if not verbose:
335 # Make the output a little prettier. It's nice to have some whitespace 381 # Make the output a little prettier. It's nice to have some whitespace
336 # between projects when cloning. 382 # between projects when cloning.
337 print('') 383 print('')
338 return self._Capture(['rev-parse', '--verify', 'HEAD']) 384 return self._Capture(['rev-parse', '--verify', 'HEAD'])
339 385
340 if not managed: 386 if not managed:
341 self._UpdateBranchHeads(options, fetch=False) 387 self._UpdateBranchHeads(options, fetch=False)
342 self.UpdateSubmoduleConfig() 388 self.UpdateSubmoduleConfig()
343 print ('________ unmanaged solution; skipping %s' % self.relpath) 389 print ('________ unmanaged solution; skipping %s' % self.relpath)
344 return self._Capture(['rev-parse', '--verify', 'HEAD']) 390 return self._Capture(['rev-parse', '--verify', 'HEAD'])
345 391
346 if not os.path.exists(os.path.join(self.checkout_path, '.git')):
347 raise gclient_utils.Error('\n____ %s%s\n'
348 '\tPath is not a git repo. No .git dir.\n'
349 '\tTo resolve:\n'
350 '\t\trm -rf %s\n'
351 '\tAnd run gclient sync again\n'
352 % (self.relpath, rev_str, self.relpath))
353
354 # See if the url has changed (the unittests use git://foo for the url, let 392 # See if the url has changed (the unittests use git://foo for the url, let
355 # that through). 393 # that through).
356 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) 394 current_url = self._Capture(['config', 'remote.%s.url' % self.remote])
357 return_early = False 395 return_early = False
358 # TODO(maruel): Delete url != 'git://foo' since it's just to make the 396 # TODO(maruel): Delete url != 'git://foo' since it's just to make the
359 # unit test pass. (and update the comment above) 397 # unit test pass. (and update the comment above)
360 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. 398 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set.
361 # This allows devs to use experimental repos which have a different url 399 # This allows devs to use experimental repos which have a different url
362 # but whose branch(s) are the same as official repos. 400 # but whose branch(s) are the same as official repos.
363 if (current_url != url and 401 if (current_url.rstrip('/') != url.rstrip('/') and
364 url != 'git://foo' and 402 url != 'git://foo' and
365 subprocess2.capture( 403 subprocess2.capture(
366 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], 404 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote],
367 cwd=self.checkout_path).strip() != 'False'): 405 cwd=self.checkout_path).strip() != 'False'):
368 print('_____ switching %s to a new upstream' % self.relpath) 406 print('_____ switching %s to a new upstream' % self.relpath)
369 # Make sure it's clean 407 # Make sure it's clean
370 self._CheckClean(rev_str) 408 self._CheckClean(rev_str)
371 # Switch over to the new upstream 409 # Switch over to the new upstream
372 self._Run(['remote', 'set-url', self.remote, url], options) 410 self._Run(['remote', 'set-url', self.remote, url], options)
373 self._FetchAndReset(revision, file_list, options) 411 self._FetchAndReset(revision, file_list, options)
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 filter_fn=SvnDiffFilterer(self.relpath).Filter) 1055 filter_fn=SvnDiffFilterer(self.relpath).Filter)
1018 1056
1019 def update(self, options, args, file_list): 1057 def update(self, options, args, file_list):
1020 """Runs svn to update or transparently checkout the working copy. 1058 """Runs svn to update or transparently checkout the working copy.
1021 1059
1022 All updated files will be appended to file_list. 1060 All updated files will be appended to file_list.
1023 1061
1024 Raises: 1062 Raises:
1025 Error: if can't get URL for relative path. 1063 Error: if can't get URL for relative path.
1026 """ 1064 """
1027 # Only update if git or hg is not controlling the directory. 1065 # Only update if hg is not controlling the directory.
1028 git_path = os.path.join(self.checkout_path, '.git')
1029 if os.path.exists(git_path):
1030 print('________ found .git directory; skipping %s' % self.relpath)
1031 return
1032
1033 hg_path = os.path.join(self.checkout_path, '.hg') 1066 hg_path = os.path.join(self.checkout_path, '.hg')
1034 if os.path.exists(hg_path): 1067 if os.path.exists(hg_path):
1035 print('________ found .hg directory; skipping %s' % self.relpath) 1068 print('________ found .hg directory; skipping %s' % self.relpath)
1036 return 1069 return
1037 1070
1038 if args: 1071 if args:
1039 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) 1072 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))
1040 1073
1041 # revision is the revision to match. It is None if no revision is specified, 1074 # revision is the revision to match. It is None if no revision is specified,
1042 # i.e. the 'deps ain't pinned'. 1075 # i.e. the 'deps ain't pinned'.
(...skipping 10 matching lines...) Expand all
1053 # Reconstruct the url. 1086 # Reconstruct the url.
1054 url = '%s@%s' % (url, revision) 1087 url = '%s@%s' % (url, revision)
1055 rev_str = ' at %s' % revision 1088 rev_str = ' at %s' % revision
1056 else: 1089 else:
1057 managed = False 1090 managed = False
1058 revision = None 1091 revision = None
1059 else: 1092 else:
1060 forced_revision = False 1093 forced_revision = False
1061 rev_str = '' 1094 rev_str = ''
1062 1095
1096 exists = os.path.exists(self.checkout_path)
1097 if exists and managed:
1098 # Git is only okay if it's a git-svn checkout of the right repo.
1099 if scm.GIT.IsGitSvn(self.checkout_path):
1100 remote_url = scm.GIT.Capture(['config', '--local', '--get',
1101 'svn-remote.svn.url'],
1102 cwd=self.checkout_path).rstrip()
1103 if remote_url.rstrip('/') == base_url.rstrip('/'):
1104 print('\n_____ %s looks like a git-svn checkout. Skipping.'
1105 % self.relpath)
1106 return # TODO(borenet): Get the svn revision number?
1107
1063 # Get the existing scm url and the revision number of the current checkout. 1108 # Get the existing scm url and the revision number of the current checkout.
1064 exists = os.path.exists(self.checkout_path)
1065 if exists and managed: 1109 if exists and managed:
1066 try: 1110 try:
1067 from_info = scm.SVN.CaptureLocalInfo( 1111 from_info = scm.SVN.CaptureLocalInfo(
1068 [], os.path.join(self.checkout_path, '.')) 1112 [], os.path.join(self.checkout_path, '.'))
1069 except (gclient_utils.Error, subprocess2.CalledProcessError): 1113 except (gclient_utils.Error, subprocess2.CalledProcessError):
1070 if options.reset and options.delete_unversioned_trees: 1114 self._DeleteOrMove(options.force)
1071 print 'Removing troublesome path %s' % self.checkout_path 1115 exists = False
1072 gclient_utils.rmtree(self.checkout_path)
1073 exists = False
1074 else:
1075 msg = ('Can\'t update/checkout %s if an unversioned directory is '
1076 'present. Delete the directory and try again.')
1077 raise gclient_utils.Error(msg % self.checkout_path)
1078 1116
1079 BASE_URLS = { 1117 BASE_URLS = {
1080 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/', 1118 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/',
1081 '/blink/trunk': 'gs://chromium-svn-checkout/blink/', 1119 '/blink/trunk': 'gs://chromium-svn-checkout/blink/',
1082 } 1120 }
1083 WHITELISTED_ROOTS = [ 1121 WHITELISTED_ROOTS = [
1084 'svn://svn.chromium.org', 1122 'svn://svn.chromium.org',
1085 'svn://svn-mirror.golo.chromium.org', 1123 'svn://svn-mirror.golo.chromium.org',
1086 ] 1124 ]
1087 if not exists: 1125 if not exists:
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1147 1185
1148 gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path)) 1186 gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path))
1149 # We need to checkout. 1187 # We need to checkout.
1150 command = ['checkout', url, self.checkout_path] 1188 command = ['checkout', url, self.checkout_path]
1151 command = self._AddAdditionalUpdateFlags(command, options, revision) 1189 command = self._AddAdditionalUpdateFlags(command, options, revision)
1152 self._RunAndGetFileList(command, options, file_list, self._root_dir) 1190 self._RunAndGetFileList(command, options, file_list, self._root_dir)
1153 return self.Svnversion() 1191 return self.Svnversion()
1154 1192
1155 if not managed: 1193 if not managed:
1156 print ('________ unmanaged solution; skipping %s' % self.relpath) 1194 print ('________ unmanaged solution; skipping %s' % self.relpath)
1157 return self.Svnversion() 1195 if os.path.exists(os.path.join(self.checkout_path, '.svn')):
1196 return self.Svnversion()
1197 return
1158 1198
1159 if 'URL' not in from_info: 1199 if 'URL' not in from_info:
1160 raise gclient_utils.Error( 1200 raise gclient_utils.Error(
1161 ('gclient is confused. Couldn\'t get the url for %s.\n' 1201 ('gclient is confused. Couldn\'t get the url for %s.\n'
1162 'Try using @unmanaged.\n%s') % ( 1202 'Try using @unmanaged.\n%s') % (
1163 self.checkout_path, from_info)) 1203 self.checkout_path, from_info))
1164 1204
1165 # Look for locked directories. 1205 # Look for locked directories.
1166 dir_info = scm.SVN.CaptureStatus( 1206 dir_info = scm.SVN.CaptureStatus(
1167 None, os.path.join(self.checkout_path, '.')) 1207 None, os.path.join(self.checkout_path, '.'))
(...skipping 22 matching lines...) Expand all
1190 if d[0][0] == '!': 1230 if d[0][0] == '!':
1191 print 'You can pass --force to enable automatic removal.' 1231 print 'You can pass --force to enable automatic removal.'
1192 raise e 1232 raise e
1193 1233
1194 # Retrieve the current HEAD version because svn is slow at null updates. 1234 # Retrieve the current HEAD version because svn is slow at null updates.
1195 if options.manually_grab_svn_rev and not revision: 1235 if options.manually_grab_svn_rev and not revision:
1196 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) 1236 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL'])
1197 revision = str(from_info_live['Revision']) 1237 revision = str(from_info_live['Revision'])
1198 rev_str = ' at %s' % revision 1238 rev_str = ' at %s' % revision
1199 1239
1200 if from_info['URL'] != base_url: 1240 if from_info['URL'].rstrip('/') != base_url.rstrip('/'):
1201 # The repository url changed, need to switch. 1241 # The repository url changed, need to switch.
1202 try: 1242 try:
1203 to_info = scm.SVN.CaptureRemoteInfo(url) 1243 to_info = scm.SVN.CaptureRemoteInfo(url)
1204 except (gclient_utils.Error, subprocess2.CalledProcessError): 1244 except (gclient_utils.Error, subprocess2.CalledProcessError):
1205 # The url is invalid or the server is not accessible, it's safer to bail 1245 # The url is invalid or the server is not accessible, it's safer to bail
1206 # out right now. 1246 # out right now.
1207 raise gclient_utils.Error('This url is unreachable: %s' % url) 1247 raise gclient_utils.Error('This url is unreachable: %s' % url)
1208 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) 1248 can_switch = ((from_info['Repository Root'] != to_info['Repository Root'])
1209 and (from_info['UUID'] == to_info['UUID'])) 1249 and (from_info['UUID'] == to_info['UUID']))
1210 if can_switch: 1250 if can_switch:
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1426 new_command.append('--force') 1466 new_command.append('--force')
1427 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1467 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1428 new_command.extend(('--accept', 'theirs-conflict')) 1468 new_command.extend(('--accept', 'theirs-conflict'))
1429 elif options.manually_grab_svn_rev: 1469 elif options.manually_grab_svn_rev:
1430 new_command.append('--force') 1470 new_command.append('--force')
1431 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1471 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1432 new_command.extend(('--accept', 'postpone')) 1472 new_command.extend(('--accept', 'postpone'))
1433 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1473 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1434 new_command.extend(('--accept', 'postpone')) 1474 new_command.extend(('--accept', 'postpone'))
1435 return new_command 1475 return new_command
OLDNEW
« no previous file with comments | « no previous file | scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698