OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 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 """Meta checkout manager supporting both Subversion and GIT.""" | 6 """Meta checkout manager supporting both Subversion and GIT.""" |
7 # Files | 7 # Files |
8 # .gclient : Current client configuration, written by 'config' command. | 8 # .gclient : Current client configuration, written by 'config' command. |
9 # Format is a Python script defining 'solutions', a list whose | 9 # Format is a Python script defining 'solutions', a list whose |
10 # entries each are maps binding the strings "name" and "url" | 10 # entries each are maps binding the strings "name" and "url" |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 if var_name in self._custom_vars: | 206 if var_name in self._custom_vars: |
207 return self._custom_vars[var_name] | 207 return self._custom_vars[var_name] |
208 elif var_name in self._local_scope.get("vars", {}): | 208 elif var_name in self._local_scope.get("vars", {}): |
209 return self._local_scope["vars"][var_name] | 209 return self._local_scope["vars"][var_name] |
210 raise gclient_utils.Error("Var is not defined: %s" % var_name) | 210 raise gclient_utils.Error("Var is not defined: %s" % var_name) |
211 | 211 |
212 | 212 |
213 class DependencySettings(GClientKeywords): | 213 class DependencySettings(GClientKeywords): |
214 """Immutable configuration settings.""" | 214 """Immutable configuration settings.""" |
215 def __init__( | 215 def __init__( |
216 self, parent, url, safesync_url, managed, custom_deps, custom_vars, | 216 self, parent, url, managed, custom_deps, custom_vars, |
217 custom_hooks, deps_file, should_process): | 217 custom_hooks, deps_file, should_process): |
218 GClientKeywords.__init__(self) | 218 GClientKeywords.__init__(self) |
219 | 219 |
220 # These are not mutable: | 220 # These are not mutable: |
221 self._parent = parent | 221 self._parent = parent |
222 self._safesync_url = safesync_url | |
223 self._deps_file = deps_file | 222 self._deps_file = deps_file |
224 self._url = url | 223 self._url = url |
225 # 'managed' determines whether or not this dependency is synced/updated by | 224 # 'managed' determines whether or not this dependency is synced/updated by |
226 # gclient after gclient checks it out initially. The difference between | 225 # gclient after gclient checks it out initially. The difference between |
227 # 'managed' and 'should_process' is that the user specifies 'managed' via | 226 # 'managed' and 'should_process' is that the user specifies 'managed' via |
228 # the --unmanaged command-line flag or a .gclient config, where | 227 # the --unmanaged command-line flag or a .gclient config, where |
229 # 'should_process' is dynamically set by gclient if it goes over its | 228 # 'should_process' is dynamically set by gclient if it goes over its |
230 # recursion limit and controls gclient's behavior so it does not misbehave. | 229 # recursion limit and controls gclient's behavior so it does not misbehave. |
231 self._managed = managed | 230 self._managed = managed |
232 self._should_process = should_process | 231 self._should_process = should_process |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 274 |
276 @property | 275 @property |
277 def root(self): | 276 def root(self): |
278 """Returns the root node, a GClient object.""" | 277 """Returns the root node, a GClient object.""" |
279 if not self.parent: | 278 if not self.parent: |
280 # This line is to signal pylint that it could be a GClient instance. | 279 # This line is to signal pylint that it could be a GClient instance. |
281 return self or GClient(None, None) | 280 return self or GClient(None, None) |
282 return self.parent.root | 281 return self.parent.root |
283 | 282 |
284 @property | 283 @property |
285 def safesync_url(self): | |
286 return self._safesync_url | |
287 | |
288 @property | |
289 def should_process(self): | 284 def should_process(self): |
290 """True if this dependency should be processed, i.e. checked out.""" | 285 """True if this dependency should be processed, i.e. checked out.""" |
291 return self._should_process | 286 return self._should_process |
292 | 287 |
293 @property | 288 @property |
294 def custom_vars(self): | 289 def custom_vars(self): |
295 return self._custom_vars.copy() | 290 return self._custom_vars.copy() |
296 | 291 |
297 @property | 292 @property |
298 def custom_deps(self): | 293 def custom_deps(self): |
(...skipping 18 matching lines...) Expand all Loading... |
317 """Returns a custom deps if applicable.""" | 312 """Returns a custom deps if applicable.""" |
318 if self.parent: | 313 if self.parent: |
319 url = self.parent.get_custom_deps(name, url) | 314 url = self.parent.get_custom_deps(name, url) |
320 # None is a valid return value to disable a dependency. | 315 # None is a valid return value to disable a dependency. |
321 return self.custom_deps.get(name, url) | 316 return self.custom_deps.get(name, url) |
322 | 317 |
323 | 318 |
324 class Dependency(gclient_utils.WorkItem, DependencySettings): | 319 class Dependency(gclient_utils.WorkItem, DependencySettings): |
325 """Object that represents a dependency checkout.""" | 320 """Object that represents a dependency checkout.""" |
326 | 321 |
327 def __init__(self, parent, name, url, safesync_url, managed, custom_deps, | 322 def __init__(self, parent, name, url, managed, custom_deps, |
328 custom_vars, custom_hooks, deps_file, should_process): | 323 custom_vars, custom_hooks, deps_file, should_process): |
329 gclient_utils.WorkItem.__init__(self, name) | 324 gclient_utils.WorkItem.__init__(self, name) |
330 DependencySettings.__init__( | 325 DependencySettings.__init__( |
331 self, parent, url, safesync_url, managed, custom_deps, custom_vars, | 326 self, parent, url, managed, custom_deps, custom_vars, |
332 custom_hooks, deps_file, should_process) | 327 custom_hooks, deps_file, should_process) |
333 | 328 |
334 # This is in both .gclient and DEPS files: | 329 # This is in both .gclient and DEPS files: |
335 self._deps_hooks = [] | 330 self._deps_hooks = [] |
336 | 331 |
337 self._pre_deps_hooks = [] | 332 self._pre_deps_hooks = [] |
338 | 333 |
339 # Calculates properties: | 334 # Calculates properties: |
340 self._parsed_url = None | 335 self._parsed_url = None |
341 self._dependencies = [] | 336 self._dependencies = [] |
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
720 # Convert the deps into real Dependency. | 715 # Convert the deps into real Dependency. |
721 deps_to_add = [] | 716 deps_to_add = [] |
722 for name, url in deps.iteritems(): | 717 for name, url in deps.iteritems(): |
723 should_process = self.recursion_limit and self.should_process | 718 should_process = self.recursion_limit and self.should_process |
724 deps_file = self.deps_file | 719 deps_file = self.deps_file |
725 if self.recursedeps is not None: | 720 if self.recursedeps is not None: |
726 ent = self.recursedeps.get(name) | 721 ent = self.recursedeps.get(name) |
727 if ent is not None: | 722 if ent is not None: |
728 deps_file = ent['deps_file'] | 723 deps_file = ent['deps_file'] |
729 deps_to_add.append(Dependency( | 724 deps_to_add.append(Dependency( |
730 self, name, url, None, None, None, self.custom_vars, None, | 725 self, name, url, None, None, self.custom_vars, None, |
731 deps_file, should_process)) | 726 deps_file, should_process)) |
732 deps_to_add.sort(key=lambda x: x.name) | 727 deps_to_add.sort(key=lambda x: x.name) |
733 | 728 |
734 # override named sets of hooks by the custom hooks | 729 # override named sets of hooks by the custom hooks |
735 hooks_to_run = [] | 730 hooks_to_run = [] |
736 hook_names_to_suppress = [c.get('name', '') for c in self.custom_hooks] | 731 hook_names_to_suppress = [c.get('name', '') for c in self.custom_hooks] |
737 for hook in local_scope.get('hooks', []): | 732 for hook in local_scope.get('hooks', []): |
738 if hook.get('name', '') not in hook_names_to_suppress: | 733 if hook.get('name', '') not in hook_names_to_suppress: |
739 hooks_to_run.append(hook) | 734 hooks_to_run.append(hook) |
740 | 735 |
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1127 | 1122 |
1128 @property | 1123 @property |
1129 def file_list_and_children(self): | 1124 def file_list_and_children(self): |
1130 result = list(self.file_list) | 1125 result = list(self.file_list) |
1131 for d in self.dependencies: | 1126 for d in self.dependencies: |
1132 result.extend(d.file_list_and_children) | 1127 result.extend(d.file_list_and_children) |
1133 return tuple(result) | 1128 return tuple(result) |
1134 | 1129 |
1135 def __str__(self): | 1130 def __str__(self): |
1136 out = [] | 1131 out = [] |
1137 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', | 1132 for i in ('name', 'url', 'parsed_url', 'custom_deps', |
1138 'custom_vars', 'deps_hooks', 'file_list', 'should_process', | 1133 'custom_vars', 'deps_hooks', 'file_list', 'should_process', |
1139 'processed', 'hooks_ran', 'deps_parsed', 'requirements', | 1134 'processed', 'hooks_ran', 'deps_parsed', 'requirements', |
1140 'allowed_hosts'): | 1135 'allowed_hosts'): |
1141 # First try the native property if it exists. | 1136 # First try the native property if it exists. |
1142 if hasattr(self, '_' + i): | 1137 if hasattr(self, '_' + i): |
1143 value = getattr(self, '_' + i, False) | 1138 value = getattr(self, '_' + i, False) |
1144 else: | 1139 else: |
1145 value = getattr(self, i, False) | 1140 value = getattr(self, i, False) |
1146 if value: | 1141 if value: |
1147 out.append('%s: %s' % (i, value)) | 1142 out.append('%s: %s' % (i, value)) |
(...skipping 28 matching lines...) Expand all Loading... |
1176 "mac": "mac", | 1171 "mac": "mac", |
1177 "unix": "unix", | 1172 "unix": "unix", |
1178 "linux": "unix", | 1173 "linux": "unix", |
1179 "linux2": "unix", | 1174 "linux2": "unix", |
1180 "linux3": "unix", | 1175 "linux3": "unix", |
1181 "android": "android", | 1176 "android": "android", |
1182 } | 1177 } |
1183 | 1178 |
1184 DEFAULT_CLIENT_FILE_TEXT = ("""\ | 1179 DEFAULT_CLIENT_FILE_TEXT = ("""\ |
1185 solutions = [ | 1180 solutions = [ |
1186 { "name" : "%(solution_name)s", | 1181 { |
| 1182 "name" : "%(solution_name)s", |
1187 "url" : "%(solution_url)s", | 1183 "url" : "%(solution_url)s", |
1188 "deps_file" : "%(deps_file)s", | 1184 "deps_file" : "%(deps_file)s", |
1189 "managed" : %(managed)s, | 1185 "managed" : %(managed)s, |
1190 "custom_deps" : { | 1186 "custom_deps" : {}, |
1191 }, | |
1192 "safesync_url": "%(safesync_url)s", | |
1193 }, | 1187 }, |
1194 ] | 1188 ] |
1195 cache_dir = %(cache_dir)r | 1189 cache_dir = %(cache_dir)r |
1196 """) | 1190 """) |
1197 | 1191 |
1198 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ | 1192 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ |
1199 { "name" : "%(solution_name)s", | 1193 { |
| 1194 "name" : "%(solution_name)s", |
1200 "url" : "%(solution_url)s", | 1195 "url" : "%(solution_url)s", |
1201 "deps_file" : "%(deps_file)s", | 1196 "deps_file" : "%(deps_file)s", |
1202 "managed" : %(managed)s, | 1197 "managed" : %(managed)s, |
1203 "custom_deps" : { | 1198 "custom_deps" : { |
1204 %(solution_deps)s }, | 1199 %(solution_deps)s |
1205 "safesync_url": "%(safesync_url)s", | 1200 }, |
1206 }, | 1201 }, |
1207 """) | 1202 """) |
1208 | 1203 |
1209 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ | 1204 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ |
1210 # Snapshot generated with gclient revinfo --snapshot | 1205 # Snapshot generated with gclient revinfo --snapshot |
1211 solutions = [ | 1206 solutions = [ |
1212 %(solution_list)s] | 1207 %(solution_list)s] |
1213 """) | 1208 """) |
1214 | 1209 |
1215 def __init__(self, root_dir, options): | 1210 def __init__(self, root_dir, options): |
1216 # Do not change previous behavior. Only solution level and immediate DEPS | 1211 # Do not change previous behavior. Only solution level and immediate DEPS |
1217 # are processed. | 1212 # are processed. |
1218 self._recursion_limit = 2 | 1213 self._recursion_limit = 2 |
1219 Dependency.__init__(self, None, None, None, None, True, None, None, None, | 1214 Dependency.__init__(self, None, None, None, True, None, None, None, |
1220 'unused', True) | 1215 'unused', True) |
1221 self._options = options | 1216 self._options = options |
1222 if options.deps_os: | 1217 if options.deps_os: |
1223 enforced_os = options.deps_os.split(',') | 1218 enforced_os = options.deps_os.split(',') |
1224 else: | 1219 else: |
1225 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] | 1220 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] |
1226 if 'all' in enforced_os: | 1221 if 'all' in enforced_os: |
1227 enforced_os = self.DEPS_OS_CHOICES.itervalues() | 1222 enforced_os = self.DEPS_OS_CHOICES.itervalues() |
1228 self._enforced_os = tuple(set(enforced_os)) | 1223 self._enforced_os = tuple(set(enforced_os)) |
1229 self._root_dir = root_dir | 1224 self._root_dir = root_dir |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1292 cache_dir, '--force', '--all']) | 1287 cache_dir, '--force', '--all']) |
1293 gclient_scm.GitWrapper.cache_dir = cache_dir | 1288 gclient_scm.GitWrapper.cache_dir = cache_dir |
1294 git_cache.Mirror.SetCachePath(cache_dir) | 1289 git_cache.Mirror.SetCachePath(cache_dir) |
1295 | 1290 |
1296 if not target_os and config_dict.get('target_os_only', False): | 1291 if not target_os and config_dict.get('target_os_only', False): |
1297 raise gclient_utils.Error('Can\'t use target_os_only if target_os is ' | 1292 raise gclient_utils.Error('Can\'t use target_os_only if target_os is ' |
1298 'not specified') | 1293 'not specified') |
1299 | 1294 |
1300 deps_to_add = [] | 1295 deps_to_add = [] |
1301 for s in config_dict.get('solutions', []): | 1296 for s in config_dict.get('solutions', []): |
| 1297 if s.get('safesync_url'): |
| 1298 raise gclient_utils.Error('safesync_url is not supported anymore. ' |
| 1299 'Please remove it from your .gclient file.') |
1302 try: | 1300 try: |
1303 deps_to_add.append(Dependency( | 1301 deps_to_add.append(Dependency( |
1304 self, s['name'], s['url'], | 1302 self, s['name'], s['url'], |
1305 s.get('safesync_url', None), | |
1306 s.get('managed', True), | 1303 s.get('managed', True), |
1307 s.get('custom_deps', {}), | 1304 s.get('custom_deps', {}), |
1308 s.get('custom_vars', {}), | 1305 s.get('custom_vars', {}), |
1309 s.get('custom_hooks', []), | 1306 s.get('custom_hooks', []), |
1310 s.get('deps_file', 'DEPS'), | 1307 s.get('deps_file', 'DEPS'), |
1311 True)) | 1308 True)) |
1312 except KeyError: | 1309 except KeyError: |
1313 raise gclient_utils.Error('Invalid .gclient file. Solution is ' | 1310 raise gclient_utils.Error('Invalid .gclient file. Solution is ' |
1314 'incomplete: %s' % s) | 1311 'incomplete: %s' % s) |
1315 self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', [])) | 1312 self.add_dependencies_and_close(deps_to_add, config_dict.get('hooks', [])) |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1422 ('You must specify the full solution name like --revision %s@%s\n' | 1419 ('You must specify the full solution name like --revision %s@%s\n' |
1423 'when you have multiple solutions setup in your .gclient file.\n' | 1420 'when you have multiple solutions setup in your .gclient file.\n' |
1424 'Other solutions present are: %s.') % ( | 1421 'Other solutions present are: %s.') % ( |
1425 client.dependencies[0].name, | 1422 client.dependencies[0].name, |
1426 options.revisions[0], | 1423 options.revisions[0], |
1427 ', '.join(s.name for s in client.dependencies[1:])), | 1424 ', '.join(s.name for s in client.dependencies[1:])), |
1428 file=sys.stderr) | 1425 file=sys.stderr) |
1429 return client | 1426 return client |
1430 | 1427 |
1431 def SetDefaultConfig(self, solution_name, deps_file, solution_url, | 1428 def SetDefaultConfig(self, solution_name, deps_file, solution_url, |
1432 safesync_url, managed=True, cache_dir=None): | 1429 managed=True, cache_dir=None): |
1433 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { | 1430 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { |
1434 'solution_name': solution_name, | 1431 'solution_name': solution_name, |
1435 'solution_url': solution_url, | 1432 'solution_url': solution_url, |
1436 'deps_file': deps_file, | 1433 'deps_file': deps_file, |
1437 'safesync_url' : safesync_url, | |
1438 'managed': managed, | 1434 'managed': managed, |
1439 'cache_dir': cache_dir, | 1435 'cache_dir': cache_dir, |
1440 }) | 1436 }) |
1441 | 1437 |
1442 def _SaveEntries(self): | 1438 def _SaveEntries(self): |
1443 """Creates a .gclient_entries file to record the list of unique checkouts. | 1439 """Creates a .gclient_entries file to record the list of unique checkouts. |
1444 | 1440 |
1445 The .gclient_entries file lives in the same directory as .gclient. | 1441 The .gclient_entries file lives in the same directory as .gclient. |
1446 """ | 1442 """ |
1447 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It | 1443 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It |
(...skipping 22 matching lines...) Expand all Loading... |
1470 return {} | 1466 return {} |
1471 try: | 1467 try: |
1472 exec(gclient_utils.FileRead(filename), scope) | 1468 exec(gclient_utils.FileRead(filename), scope) |
1473 except SyntaxError as e: | 1469 except SyntaxError as e: |
1474 gclient_utils.SyntaxErrorToError(filename, e) | 1470 gclient_utils.SyntaxErrorToError(filename, e) |
1475 return scope['entries'] | 1471 return scope['entries'] |
1476 | 1472 |
1477 def _EnforceRevisions(self): | 1473 def _EnforceRevisions(self): |
1478 """Checks for revision overrides.""" | 1474 """Checks for revision overrides.""" |
1479 revision_overrides = {} | 1475 revision_overrides = {} |
1480 if self._options.head: | |
1481 return revision_overrides | |
1482 # Do not check safesync_url if one or more --revision flag is specified. | |
1483 if not self._options.revisions: | 1476 if not self._options.revisions: |
1484 for s in self.dependencies: | 1477 for s in self.dependencies: |
1485 if not s.managed: | 1478 if not s.managed: |
1486 self._options.revisions.append('%s@unmanaged' % s.name) | 1479 self._options.revisions.append('%s@unmanaged' % s.name) |
1487 elif s.safesync_url: | |
1488 self._ApplySafeSyncRev(dep=s) | |
1489 if not self._options.revisions: | 1480 if not self._options.revisions: |
1490 return revision_overrides | 1481 return revision_overrides |
1491 solutions_names = [s.name for s in self.dependencies] | 1482 solutions_names = [s.name for s in self.dependencies] |
1492 index = 0 | 1483 index = 0 |
1493 for revision in self._options.revisions: | 1484 for revision in self._options.revisions: |
1494 if not '@' in revision: | 1485 if not '@' in revision: |
1495 # Support for --revision 123 | 1486 # Support for --revision 123 |
1496 revision = '%s@%s' % (solutions_names[index], revision) | 1487 revision = '%s@%s' % (solutions_names[index], revision) |
1497 name, rev = revision.split('@', 1) | 1488 name, rev = revision.split('@', 1) |
1498 revision_overrides[name] = rev | 1489 revision_overrides[name] = rev |
1499 index += 1 | 1490 index += 1 |
1500 return revision_overrides | 1491 return revision_overrides |
1501 | 1492 |
1502 def _ApplySafeSyncRev(self, dep): | |
1503 """Finds a valid revision from the content of the safesync_url and apply it | |
1504 by appending revisions to the revision list. Throws if revision appears to | |
1505 be invalid for the given |dep|.""" | |
1506 assert len(dep.safesync_url) > 0 | |
1507 handle = urllib.urlopen(dep.safesync_url) | |
1508 rev = handle.read().strip() | |
1509 handle.close() | |
1510 if not rev: | |
1511 raise gclient_utils.Error( | |
1512 'It appears your safesync_url (%s) is not working properly\n' | |
1513 '(as it returned an empty response). Check your config.' % | |
1514 dep.safesync_url) | |
1515 scm = gclient_scm.CreateSCM( | |
1516 dep.url, dep.root.root_dir, dep.name, self.outbuf) | |
1517 safe_rev = scm.GetUsableRev(rev, self._options) | |
1518 if self._options.verbose: | |
1519 print('Using safesync_url revision: %s.\n' % safe_rev) | |
1520 self._options.revisions.append('%s@%s' % (dep.name, safe_rev)) | |
1521 | |
1522 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True): | 1493 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True): |
1523 """Runs a command on each dependency in a client and its dependencies. | 1494 """Runs a command on each dependency in a client and its dependencies. |
1524 | 1495 |
1525 Args: | 1496 Args: |
1526 command: The command to use (e.g., 'status' or 'diff') | 1497 command: The command to use (e.g., 'status' or 'diff') |
1527 args: list of str - extra arguments to add to the command line. | 1498 args: list of str - extra arguments to add to the command line. |
1528 """ | 1499 """ |
1529 if not self.dependencies: | 1500 if not self.dependencies: |
1530 raise gclient_utils.Error('No solution specified') | 1501 raise gclient_utils.Error('No solution specified') |
1531 | 1502 |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1696 for k in sorted(entries.keys()): | 1667 for k in sorted(entries.keys()): |
1697 if entries[k]: | 1668 if entries[k]: |
1698 # Quotes aren't escaped... | 1669 # Quotes aren't escaped... |
1699 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) | 1670 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) |
1700 else: | 1671 else: |
1701 custom_deps.append(' \"%s\": None,\n' % k) | 1672 custom_deps.append(' \"%s\": None,\n' % k) |
1702 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { | 1673 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { |
1703 'solution_name': d.name, | 1674 'solution_name': d.name, |
1704 'solution_url': d.url, | 1675 'solution_url': d.url, |
1705 'deps_file': d.deps_file, | 1676 'deps_file': d.deps_file, |
1706 'safesync_url' : d.safesync_url or '', | |
1707 'managed': d.managed, | 1677 'managed': d.managed, |
1708 'solution_deps': ''.join(custom_deps), | 1678 'solution_deps': ''.join(custom_deps), |
1709 } | 1679 } |
1710 # Print the snapshot configuration file | 1680 # Print the snapshot configuration file |
1711 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) | 1681 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) |
1712 else: | 1682 else: |
1713 entries = {} | 1683 entries = {} |
1714 for d in self.root.subtree(False): | 1684 for d in self.root.subtree(False): |
1715 if self._options.actual: | 1685 if self._options.actual: |
1716 entries[d.name] = GetURLAndRev(d) | 1686 entries[d.name] = GetURLAndRev(d) |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1862 def CMDroot(parser, args): | 1832 def CMDroot(parser, args): |
1863 """Outputs the solution root (or current dir if there isn't one).""" | 1833 """Outputs the solution root (or current dir if there isn't one).""" |
1864 (options, args) = parser.parse_args(args) | 1834 (options, args) = parser.parse_args(args) |
1865 client = GClient.LoadCurrentConfig(options) | 1835 client = GClient.LoadCurrentConfig(options) |
1866 if client: | 1836 if client: |
1867 print(os.path.abspath(client.root_dir)) | 1837 print(os.path.abspath(client.root_dir)) |
1868 else: | 1838 else: |
1869 print(os.path.abspath('.')) | 1839 print(os.path.abspath('.')) |
1870 | 1840 |
1871 | 1841 |
1872 @subcommand.usage('[url] [safesync url]') | 1842 @subcommand.usage('[url]') |
1873 def CMDconfig(parser, args): | 1843 def CMDconfig(parser, args): |
1874 """Creates a .gclient file in the current directory. | 1844 """Creates a .gclient file in the current directory. |
1875 | 1845 |
1876 This specifies the configuration for further commands. After update/sync, | 1846 This specifies the configuration for further commands. After update/sync, |
1877 top-level DEPS files in each module are read to determine dependent | 1847 top-level DEPS files in each module are read to determine dependent |
1878 modules to operate on as well. If optional [url] parameter is | 1848 modules to operate on as well. If optional [url] parameter is |
1879 provided, then configuration is read from a specified Subversion server | 1849 provided, then configuration is read from a specified Subversion server |
1880 URL. | 1850 URL. |
1881 """ | 1851 """ |
1882 # We do a little dance with the --gclientfile option. 'gclient config' is the | 1852 # We do a little dance with the --gclientfile option. 'gclient config' is the |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1921 else: | 1891 else: |
1922 # specify an alternate relpath for the given URL. | 1892 # specify an alternate relpath for the given URL. |
1923 name = options.name | 1893 name = options.name |
1924 if not os.path.abspath(os.path.join(os.getcwd(), name)).startswith( | 1894 if not os.path.abspath(os.path.join(os.getcwd(), name)).startswith( |
1925 os.getcwd()): | 1895 os.getcwd()): |
1926 parser.error('Do not pass a relative path for --name.') | 1896 parser.error('Do not pass a relative path for --name.') |
1927 if any(x in ('..', '.', '/', '\\') for x in name.split(os.sep)): | 1897 if any(x in ('..', '.', '/', '\\') for x in name.split(os.sep)): |
1928 parser.error('Do not include relative path components in --name.') | 1898 parser.error('Do not include relative path components in --name.') |
1929 | 1899 |
1930 deps_file = options.deps_file | 1900 deps_file = options.deps_file |
1931 safesync_url = '' | 1901 client.SetDefaultConfig(name, deps_file, base_url, |
1932 if len(args) > 1: | |
1933 safesync_url = args[1] | |
1934 client.SetDefaultConfig(name, deps_file, base_url, safesync_url, | |
1935 managed=not options.unmanaged, | 1902 managed=not options.unmanaged, |
1936 cache_dir=options.cache_dir) | 1903 cache_dir=options.cache_dir) |
1937 client.SaveConfig() | 1904 client.SaveConfig() |
1938 return 0 | 1905 return 0 |
1939 | 1906 |
1940 | 1907 |
1941 @subcommand.epilog("""Example: | 1908 @subcommand.epilog("""Example: |
1942 gclient pack > patch.txt | 1909 gclient pack > patch.txt |
1943 generate simple patch for configured client and dependences | 1910 generate simple patch for configured client and dependences |
1944 """) | 1911 """) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2013 parser.add_option('-n', '--nohooks', action='store_true', | 1980 parser.add_option('-n', '--nohooks', action='store_true', |
2014 help='don\'t run hooks after the update is complete') | 1981 help='don\'t run hooks after the update is complete') |
2015 parser.add_option('-p', '--noprehooks', action='store_true', | 1982 parser.add_option('-p', '--noprehooks', action='store_true', |
2016 help='don\'t run pre-DEPS hooks', default=False) | 1983 help='don\'t run pre-DEPS hooks', default=False) |
2017 parser.add_option('-r', '--revision', action='append', | 1984 parser.add_option('-r', '--revision', action='append', |
2018 dest='revisions', metavar='REV', default=[], | 1985 dest='revisions', metavar='REV', default=[], |
2019 help='Enforces revision/hash for the solutions with the ' | 1986 help='Enforces revision/hash for the solutions with the ' |
2020 'format src@rev. The src@ part is optional and can be ' | 1987 'format src@rev. The src@ part is optional and can be ' |
2021 'skipped. -r can be used multiple times when .gclient ' | 1988 'skipped. -r can be used multiple times when .gclient ' |
2022 'has multiple solutions configured and will work even ' | 1989 'has multiple solutions configured and will work even ' |
2023 'if the src@ part is skipped. Note that specifying ' | 1990 'if the src@ part is skipped.') |
2024 '--revision means your safesync_url gets ignored.') | |
2025 parser.add_option('--with_branch_heads', action='store_true', | 1991 parser.add_option('--with_branch_heads', action='store_true', |
2026 help='Clone git "branch_heads" refspecs in addition to ' | 1992 help='Clone git "branch_heads" refspecs in addition to ' |
2027 'the default refspecs. This adds about 1/2GB to a ' | 1993 'the default refspecs. This adds about 1/2GB to a ' |
2028 'full checkout. (git only)') | 1994 'full checkout. (git only)') |
2029 parser.add_option('--with_tags', action='store_true', | 1995 parser.add_option('--with_tags', action='store_true', |
2030 help='Clone git tags in addition to the default refspecs.') | 1996 help='Clone git tags in addition to the default refspecs.') |
2031 parser.add_option('-t', '--transitive', action='store_true', | 1997 parser.add_option('-t', '--transitive', action='store_true', |
2032 help='When a revision is specified (in the DEPS file or ' | 1998 help='When a revision is specified (in the DEPS file or ' |
2033 'with the command-line flag), transitively update ' | 1999 'with the command-line flag), transitively update ' |
2034 'the dependencies to the date of the given revision. ' | 2000 'the dependencies to the date of the given revision. ' |
2035 'Only supported for SVN repositories.') | 2001 'Only supported for SVN repositories.') |
2036 parser.add_option('-H', '--head', action='store_true', | |
2037 help='skips any safesync_urls specified in ' | |
2038 'configured solutions and sync to head instead') | |
2039 parser.add_option('-D', '--delete_unversioned_trees', action='store_true', | 2002 parser.add_option('-D', '--delete_unversioned_trees', action='store_true', |
2040 help='Deletes from the working copy any dependencies that ' | 2003 help='Deletes from the working copy any dependencies that ' |
2041 'have been removed since the last sync, as long as ' | 2004 'have been removed since the last sync, as long as ' |
2042 'there are no local modifications. When used with ' | 2005 'there are no local modifications. When used with ' |
2043 '--force, such dependencies are removed even if they ' | 2006 '--force, such dependencies are removed even if they ' |
2044 'have local modifications. When used with --reset, ' | 2007 'have local modifications. When used with --reset, ' |
2045 'all untracked directories are removed from the ' | 2008 'all untracked directories are removed from the ' |
2046 'working copy, excluding those which are explicitly ' | 2009 'working copy, excluding those which are explicitly ' |
2047 'ignored in the repository.') | 2010 'ignored in the repository.') |
2048 parser.add_option('-R', '--reset', action='store_true', | 2011 parser.add_option('-R', '--reset', action='store_true', |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2083 'thing operating on the git repos (e.g. on a bot).') | 2046 'thing operating on the git repos (e.g. on a bot).') |
2084 parser.add_option('--lock_timeout', type='int', default=5000, | 2047 parser.add_option('--lock_timeout', type='int', default=5000, |
2085 help='GIT ONLY - Deadline (in seconds) to wait for git ' | 2048 help='GIT ONLY - Deadline (in seconds) to wait for git ' |
2086 'cache lock to become available. Default is %default.') | 2049 'cache lock to become available. Default is %default.') |
2087 (options, args) = parser.parse_args(args) | 2050 (options, args) = parser.parse_args(args) |
2088 client = GClient.LoadCurrentConfig(options) | 2051 client = GClient.LoadCurrentConfig(options) |
2089 | 2052 |
2090 if not client: | 2053 if not client: |
2091 raise gclient_utils.Error('client not configured; see \'gclient config\'') | 2054 raise gclient_utils.Error('client not configured; see \'gclient config\'') |
2092 | 2055 |
2093 if options.revisions and options.head: | |
2094 # TODO(maruel): Make it a parser.error if it doesn't break any builder. | |
2095 print('Warning: you cannot use both --head and --revision') | |
2096 | |
2097 if options.verbose: | 2056 if options.verbose: |
2098 client.PrintLocationAndContents() | 2057 client.PrintLocationAndContents() |
2099 ret = client.RunOnDeps('update', args) | 2058 ret = client.RunOnDeps('update', args) |
2100 if options.output_json: | 2059 if options.output_json: |
2101 slns = {} | 2060 slns = {} |
2102 for d in client.subtree(True): | 2061 for d in client.subtree(True): |
2103 normed = d.name.replace('\\', '/').rstrip('/') + '/' | 2062 normed = d.name.replace('\\', '/').rstrip('/') + '/' |
2104 slns[normed] = { | 2063 slns[normed] = { |
2105 'revision': d.got_revision, | 2064 'revision': d.got_revision, |
2106 'scm': d.used_scm.name if d.used_scm else None, | 2065 'scm': d.used_scm.name if d.used_scm else None, |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2293 if not options.config_filename: | 2252 if not options.config_filename: |
2294 options.config_filename = self.gclientfile_default | 2253 options.config_filename = self.gclientfile_default |
2295 options.entries_filename = options.config_filename + '_entries' | 2254 options.entries_filename = options.config_filename + '_entries' |
2296 if options.jobs < 1: | 2255 if options.jobs < 1: |
2297 self.error('--jobs must be 1 or higher') | 2256 self.error('--jobs must be 1 or higher') |
2298 | 2257 |
2299 # These hacks need to die. | 2258 # These hacks need to die. |
2300 if not hasattr(options, 'revisions'): | 2259 if not hasattr(options, 'revisions'): |
2301 # GClient.RunOnDeps expects it even if not applicable. | 2260 # GClient.RunOnDeps expects it even if not applicable. |
2302 options.revisions = [] | 2261 options.revisions = [] |
2303 if not hasattr(options, 'head'): | |
2304 options.head = None | |
2305 if not hasattr(options, 'nohooks'): | 2262 if not hasattr(options, 'nohooks'): |
2306 options.nohooks = True | 2263 options.nohooks = True |
2307 if not hasattr(options, 'noprehooks'): | 2264 if not hasattr(options, 'noprehooks'): |
2308 options.noprehooks = True | 2265 options.noprehooks = True |
2309 if not hasattr(options, 'deps_os'): | 2266 if not hasattr(options, 'deps_os'): |
2310 options.deps_os = None | 2267 options.deps_os = None |
2311 if not hasattr(options, 'manually_grab_svn_rev'): | 2268 if not hasattr(options, 'manually_grab_svn_rev'): |
2312 options.manually_grab_svn_rev = None | 2269 options.manually_grab_svn_rev = None |
2313 if not hasattr(options, 'force'): | 2270 if not hasattr(options, 'force'): |
2314 options.force = None | 2271 options.force = None |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2355 | 2312 |
2356 | 2313 |
2357 if '__main__' == __name__: | 2314 if '__main__' == __name__: |
2358 try: | 2315 try: |
2359 sys.exit(main(sys.argv[1:])) | 2316 sys.exit(main(sys.argv[1:])) |
2360 except KeyboardInterrupt: | 2317 except KeyboardInterrupt: |
2361 sys.stderr.write('interrupted\n') | 2318 sys.stderr.write('interrupted\n') |
2362 sys.exit(1) | 2319 sys.exit(1) |
2363 | 2320 |
2364 # vim: ts=2:sw=2:tw=80:et: | 2321 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |