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 dependency manager for Git.""" | 6 """Meta checkout dependency manager for 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 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 if var_name in self._custom_vars: | 183 if var_name in self._custom_vars: |
184 return self._custom_vars[var_name] | 184 return self._custom_vars[var_name] |
185 elif var_name in self._local_scope.get("vars", {}): | 185 elif var_name in self._local_scope.get("vars", {}): |
186 return self._local_scope["vars"][var_name] | 186 return self._local_scope["vars"][var_name] |
187 raise gclient_utils.Error("Var is not defined: %s" % var_name) | 187 raise gclient_utils.Error("Var is not defined: %s" % var_name) |
188 | 188 |
189 | 189 |
190 class DependencySettings(GClientKeywords): | 190 class DependencySettings(GClientKeywords): |
191 """Immutable configuration settings.""" | 191 """Immutable configuration settings.""" |
192 def __init__( | 192 def __init__( |
193 self, parent, url, safesync_url, managed, custom_deps, custom_vars, | 193 self, parent, url, managed, custom_deps, custom_vars, |
194 custom_hooks, deps_file, should_process, relative): | 194 custom_hooks, deps_file, should_process, relative): |
195 GClientKeywords.__init__(self) | 195 GClientKeywords.__init__(self) |
196 | 196 |
197 # These are not mutable: | 197 # These are not mutable: |
198 self._parent = parent | 198 self._parent = parent |
199 self._safesync_url = safesync_url | |
200 self._deps_file = deps_file | 199 self._deps_file = deps_file |
201 self._url = url | 200 self._url = url |
202 # 'managed' determines whether or not this dependency is synced/updated by | 201 # 'managed' determines whether or not this dependency is synced/updated by |
203 # gclient after gclient checks it out initially. The difference between | 202 # gclient after gclient checks it out initially. The difference between |
204 # 'managed' and 'should_process' is that the user specifies 'managed' via | 203 # 'managed' and 'should_process' is that the user specifies 'managed' via |
205 # the --unmanaged command-line flag or a .gclient config, where | 204 # the --unmanaged command-line flag or a .gclient config, where |
206 # 'should_process' is dynamically set by gclient if it goes over its | 205 # 'should_process' is dynamically set by gclient if it goes over its |
207 # recursion limit and controls gclient's behavior so it does not misbehave. | 206 # recursion limit and controls gclient's behavior so it does not misbehave. |
208 self._managed = managed | 207 self._managed = managed |
209 self._should_process = should_process | 208 self._should_process = should_process |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 247 |
249 @property | 248 @property |
250 def root(self): | 249 def root(self): |
251 """Returns the root node, a GClient object.""" | 250 """Returns the root node, a GClient object.""" |
252 if not self.parent: | 251 if not self.parent: |
253 # This line is to signal pylint that it could be a GClient instance. | 252 # This line is to signal pylint that it could be a GClient instance. |
254 return self or GClient(None, None) | 253 return self or GClient(None, None) |
255 return self.parent.root | 254 return self.parent.root |
256 | 255 |
257 @property | 256 @property |
258 def safesync_url(self): | |
259 return self._safesync_url | |
260 | |
261 @property | |
262 def should_process(self): | 257 def should_process(self): |
263 """True if this dependency should be processed, i.e. checked out.""" | 258 """True if this dependency should be processed, i.e. checked out.""" |
264 return self._should_process | 259 return self._should_process |
265 | 260 |
266 @property | 261 @property |
267 def custom_vars(self): | 262 def custom_vars(self): |
268 return self._custom_vars.copy() | 263 return self._custom_vars.copy() |
269 | 264 |
270 @property | 265 @property |
271 def custom_deps(self): | 266 def custom_deps(self): |
(...skipping 18 matching lines...) Expand all Loading... |
290 """Returns a custom deps if applicable.""" | 285 """Returns a custom deps if applicable.""" |
291 if self.parent: | 286 if self.parent: |
292 url = self.parent.get_custom_deps(name, url) | 287 url = self.parent.get_custom_deps(name, url) |
293 # None is a valid return value to disable a dependency. | 288 # None is a valid return value to disable a dependency. |
294 return self.custom_deps.get(name, url) | 289 return self.custom_deps.get(name, url) |
295 | 290 |
296 | 291 |
297 class Dependency(gclient_utils.WorkItem, DependencySettings): | 292 class Dependency(gclient_utils.WorkItem, DependencySettings): |
298 """Object that represents a dependency checkout.""" | 293 """Object that represents a dependency checkout.""" |
299 | 294 |
300 def __init__(self, parent, name, url, safesync_url, managed, custom_deps, | 295 def __init__(self, parent, name, url, managed, custom_deps, |
301 custom_vars, custom_hooks, deps_file, should_process, | 296 custom_vars, custom_hooks, deps_file, should_process, |
302 relative): | 297 relative): |
303 gclient_utils.WorkItem.__init__(self, name) | 298 gclient_utils.WorkItem.__init__(self, name) |
304 DependencySettings.__init__( | 299 DependencySettings.__init__( |
305 self, parent, url, safesync_url, managed, custom_deps, custom_vars, | 300 self, parent, url, managed, custom_deps, custom_vars, |
306 custom_hooks, deps_file, should_process, relative) | 301 custom_hooks, deps_file, should_process, relative) |
307 | 302 |
308 # This is in both .gclient and DEPS files: | 303 # This is in both .gclient and DEPS files: |
309 self._deps_hooks = [] | 304 self._deps_hooks = [] |
310 | 305 |
311 self._pre_deps_hooks = [] | 306 self._pre_deps_hooks = [] |
312 | 307 |
313 # Calculates properties: | 308 # Calculates properties: |
314 self._parsed_url = None | 309 self._parsed_url = None |
315 self._dependencies = [] | 310 self._dependencies = [] |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 # Convert the deps into real Dependency. | 691 # Convert the deps into real Dependency. |
697 deps_to_add = [] | 692 deps_to_add = [] |
698 for name, url in deps.iteritems(): | 693 for name, url in deps.iteritems(): |
699 should_process = self.recursion_limit and self.should_process | 694 should_process = self.recursion_limit and self.should_process |
700 deps_file = self.deps_file | 695 deps_file = self.deps_file |
701 if self.recursedeps is not None: | 696 if self.recursedeps is not None: |
702 ent = self.recursedeps.get(name) | 697 ent = self.recursedeps.get(name) |
703 if ent is not None: | 698 if ent is not None: |
704 deps_file = ent['deps_file'] | 699 deps_file = ent['deps_file'] |
705 deps_to_add.append(Dependency( | 700 deps_to_add.append(Dependency( |
706 self, name, url, None, None, None, self.custom_vars, None, | 701 self, name, url, None, None, self.custom_vars, None, |
707 deps_file, should_process, use_relative_paths)) | 702 deps_file, should_process, use_relative_paths)) |
708 deps_to_add.sort(key=lambda x: x.name) | 703 deps_to_add.sort(key=lambda x: x.name) |
709 | 704 |
710 # override named sets of hooks by the custom hooks | 705 # override named sets of hooks by the custom hooks |
711 hooks_to_run = [] | 706 hooks_to_run = [] |
712 hook_names_to_suppress = [c.get('name', '') for c in self.custom_hooks] | 707 hook_names_to_suppress = [c.get('name', '') for c in self.custom_hooks] |
713 for hook in local_scope.get('hooks', []): | 708 for hook in local_scope.get('hooks', []): |
714 if hook.get('name', '') not in hook_names_to_suppress: | 709 if hook.get('name', '') not in hook_names_to_suppress: |
715 hooks_to_run.append(hook) | 710 hooks_to_run.append(hook) |
716 | 711 |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 | 1047 |
1053 @property | 1048 @property |
1054 def file_list_and_children(self): | 1049 def file_list_and_children(self): |
1055 result = list(self.file_list) | 1050 result = list(self.file_list) |
1056 for d in self.dependencies: | 1051 for d in self.dependencies: |
1057 result.extend(d.file_list_and_children) | 1052 result.extend(d.file_list_and_children) |
1058 return tuple(result) | 1053 return tuple(result) |
1059 | 1054 |
1060 def __str__(self): | 1055 def __str__(self): |
1061 out = [] | 1056 out = [] |
1062 for i in ('name', 'url', 'parsed_url', 'safesync_url', 'custom_deps', | 1057 for i in ('name', 'url', 'parsed_url', 'custom_deps', |
1063 'custom_vars', 'deps_hooks', 'file_list', 'should_process', | 1058 'custom_vars', 'deps_hooks', 'file_list', 'should_process', |
1064 'processed', 'hooks_ran', 'deps_parsed', 'requirements', | 1059 'processed', 'hooks_ran', 'deps_parsed', 'requirements', |
1065 'allowed_hosts'): | 1060 'allowed_hosts'): |
1066 # First try the native property if it exists. | 1061 # First try the native property if it exists. |
1067 if hasattr(self, '_' + i): | 1062 if hasattr(self, '_' + i): |
1068 value = getattr(self, '_' + i, False) | 1063 value = getattr(self, '_' + i, False) |
1069 else: | 1064 else: |
1070 value = getattr(self, i, False) | 1065 value = getattr(self, i, False) |
1071 if value: | 1066 if value: |
1072 out.append('%s: %s' % (i, value)) | 1067 out.append('%s: %s' % (i, value)) |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 } | 1102 } |
1108 | 1103 |
1109 DEFAULT_CLIENT_FILE_TEXT = ("""\ | 1104 DEFAULT_CLIENT_FILE_TEXT = ("""\ |
1110 solutions = [ | 1105 solutions = [ |
1111 { "name" : "%(solution_name)s", | 1106 { "name" : "%(solution_name)s", |
1112 "url" : "%(solution_url)s", | 1107 "url" : "%(solution_url)s", |
1113 "deps_file" : "%(deps_file)s", | 1108 "deps_file" : "%(deps_file)s", |
1114 "managed" : %(managed)s, | 1109 "managed" : %(managed)s, |
1115 "custom_deps" : { | 1110 "custom_deps" : { |
1116 }, | 1111 }, |
1117 "safesync_url": "%(safesync_url)s", | |
1118 }, | 1112 }, |
1119 ] | 1113 ] |
1120 cache_dir = %(cache_dir)r | 1114 cache_dir = %(cache_dir)r |
1121 """) | 1115 """) |
1122 | 1116 |
1123 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ | 1117 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ |
1124 { "name" : "%(solution_name)s", | 1118 { "name" : "%(solution_name)s", |
1125 "url" : "%(solution_url)s", | 1119 "url" : "%(solution_url)s", |
1126 "deps_file" : "%(deps_file)s", | 1120 "deps_file" : "%(deps_file)s", |
1127 "managed" : %(managed)s, | 1121 "managed" : %(managed)s, |
1128 "custom_deps" : { | 1122 "custom_deps" : { |
1129 %(solution_deps)s }, | 1123 %(solution_deps)s }, |
1130 "safesync_url": "%(safesync_url)s", | |
1131 }, | 1124 }, |
1132 """) | 1125 """) |
1133 | 1126 |
1134 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ | 1127 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ |
1135 # Snapshot generated with gclient revinfo --snapshot | 1128 # Snapshot generated with gclient revinfo --snapshot |
1136 solutions = [ | 1129 solutions = [ |
1137 %(solution_list)s] | 1130 %(solution_list)s] |
1138 """) | 1131 """) |
1139 | 1132 |
1140 def __init__(self, root_dir, options): | 1133 def __init__(self, root_dir, options): |
1141 # Do not change previous behavior. Only solution level and immediate DEPS | 1134 # Do not change previous behavior. Only solution level and immediate DEPS |
1142 # are processed. | 1135 # are processed. |
1143 self._recursion_limit = 2 | 1136 self._recursion_limit = 2 |
1144 Dependency.__init__(self, None, None, None, None, True, None, None, None, | 1137 Dependency.__init__(self, None, None, None, True, None, None, None, |
1145 'unused', True, None) | 1138 'unused', True, None) |
1146 self._options = options | 1139 self._options = options |
1147 if options.deps_os: | 1140 if options.deps_os: |
1148 enforced_os = options.deps_os.split(',') | 1141 enforced_os = options.deps_os.split(',') |
1149 else: | 1142 else: |
1150 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] | 1143 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] |
1151 if 'all' in enforced_os: | 1144 if 'all' in enforced_os: |
1152 enforced_os = self.DEPS_OS_CHOICES.itervalues() | 1145 enforced_os = self.DEPS_OS_CHOICES.itervalues() |
1153 self._enforced_os = tuple(set(enforced_os)) | 1146 self._enforced_os = tuple(set(enforced_os)) |
1154 self._root_dir = root_dir | 1147 self._root_dir = root_dir |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 | 1211 |
1219 if not target_os and config_dict.get('target_os_only', False): | 1212 if not target_os and config_dict.get('target_os_only', False): |
1220 raise gclient_utils.Error('Can\'t use target_os_only if target_os is ' | 1213 raise gclient_utils.Error('Can\'t use target_os_only if target_os is ' |
1221 'not specified') | 1214 'not specified') |
1222 | 1215 |
1223 deps_to_add = [] | 1216 deps_to_add = [] |
1224 for s in config_dict.get('solutions', []): | 1217 for s in config_dict.get('solutions', []): |
1225 try: | 1218 try: |
1226 deps_to_add.append(Dependency( | 1219 deps_to_add.append(Dependency( |
1227 self, s['name'], s['url'], | 1220 self, s['name'], s['url'], |
1228 s.get('safesync_url', None), | |
1229 s.get('managed', True), | 1221 s.get('managed', True), |
1230 s.get('custom_deps', {}), | 1222 s.get('custom_deps', {}), |
1231 s.get('custom_vars', {}), | 1223 s.get('custom_vars', {}), |
1232 s.get('custom_hooks', []), | 1224 s.get('custom_hooks', []), |
1233 s.get('deps_file', 'DEPS'), | 1225 s.get('deps_file', 'DEPS'), |
1234 True, | 1226 True, |
1235 None)) | 1227 None)) |
1236 except KeyError: | 1228 except KeyError: |
1237 raise gclient_utils.Error('Invalid .gclient file. Solution is ' | 1229 raise gclient_utils.Error('Invalid .gclient file. Solution is ' |
1238 'incomplete: %s' % s) | 1230 'incomplete: %s' % s) |
(...skipping 30 matching lines...) Expand all Loading... |
1269 ('You must specify the full solution name like --revision %s@%s\n' | 1261 ('You must specify the full solution name like --revision %s@%s\n' |
1270 'when you have multiple solutions setup in your .gclient file.\n' | 1262 'when you have multiple solutions setup in your .gclient file.\n' |
1271 'Other solutions present are: %s.') % ( | 1263 'Other solutions present are: %s.') % ( |
1272 client.dependencies[0].name, | 1264 client.dependencies[0].name, |
1273 options.revisions[0], | 1265 options.revisions[0], |
1274 ', '.join(s.name for s in client.dependencies[1:])), | 1266 ', '.join(s.name for s in client.dependencies[1:])), |
1275 file=sys.stderr) | 1267 file=sys.stderr) |
1276 return client | 1268 return client |
1277 | 1269 |
1278 def SetDefaultConfig(self, solution_name, deps_file, solution_url, | 1270 def SetDefaultConfig(self, solution_name, deps_file, solution_url, |
1279 safesync_url, managed=True, cache_dir=None): | 1271 managed=True, cache_dir=None): |
1280 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { | 1272 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { |
1281 'solution_name': solution_name, | 1273 'solution_name': solution_name, |
1282 'solution_url': solution_url, | 1274 'solution_url': solution_url, |
1283 'deps_file': deps_file, | 1275 'deps_file': deps_file, |
1284 'safesync_url' : safesync_url, | |
1285 'managed': managed, | 1276 'managed': managed, |
1286 'cache_dir': cache_dir, | 1277 'cache_dir': cache_dir, |
1287 }) | 1278 }) |
1288 | 1279 |
1289 def _SaveEntries(self): | 1280 def _SaveEntries(self): |
1290 """Creates a .gclient_entries file to record the list of unique checkouts. | 1281 """Creates a .gclient_entries file to record the list of unique checkouts. |
1291 | 1282 |
1292 The .gclient_entries file lives in the same directory as .gclient. | 1283 The .gclient_entries file lives in the same directory as .gclient. |
1293 """ | 1284 """ |
1294 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It | 1285 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It |
(...skipping 22 matching lines...) Expand all Loading... |
1317 exec(gclient_utils.FileRead(filename), scope) | 1308 exec(gclient_utils.FileRead(filename), scope) |
1318 except SyntaxError as e: | 1309 except SyntaxError as e: |
1319 gclient_utils.SyntaxErrorToError(filename, e) | 1310 gclient_utils.SyntaxErrorToError(filename, e) |
1320 return scope['entries'] | 1311 return scope['entries'] |
1321 | 1312 |
1322 def _EnforceRevisions(self): | 1313 def _EnforceRevisions(self): |
1323 """Checks for revision overrides.""" | 1314 """Checks for revision overrides.""" |
1324 revision_overrides = {} | 1315 revision_overrides = {} |
1325 if self._options.head: | 1316 if self._options.head: |
1326 return revision_overrides | 1317 return revision_overrides |
1327 # Do not check safesync_url if one or more --revision flag is specified. | |
1328 if not self._options.revisions: | 1318 if not self._options.revisions: |
1329 for s in self.dependencies: | 1319 for s in self.dependencies: |
1330 if not s.managed: | 1320 if not s.managed: |
1331 self._options.revisions.append('%s@unmanaged' % s.name) | 1321 self._options.revisions.append('%s@unmanaged' % s.name) |
1332 elif s.safesync_url: | |
1333 self._ApplySafeSyncRev(dep=s) | |
1334 if not self._options.revisions: | 1322 if not self._options.revisions: |
1335 return revision_overrides | 1323 return revision_overrides |
1336 solutions_names = [s.name for s in self.dependencies] | 1324 solutions_names = [s.name for s in self.dependencies] |
1337 index = 0 | 1325 index = 0 |
1338 for revision in self._options.revisions: | 1326 for revision in self._options.revisions: |
1339 if not '@' in revision: | 1327 if not '@' in revision: |
1340 # Support for --revision 123 | 1328 # Support for --revision 123 |
1341 revision = '%s@%s' % (solutions_names[index], revision) | 1329 revision = '%s@%s' % (solutions_names[index], revision) |
1342 name, rev = revision.split('@', 1) | 1330 name, rev = revision.split('@', 1) |
1343 revision_overrides[name] = rev | 1331 revision_overrides[name] = rev |
1344 index += 1 | 1332 index += 1 |
1345 return revision_overrides | 1333 return revision_overrides |
1346 | 1334 |
1347 def _ApplySafeSyncRev(self, dep): | |
1348 """Finds a valid revision from the content of the safesync_url and apply it | |
1349 by appending revisions to the revision list. Throws if revision appears to | |
1350 be invalid for the given |dep|.""" | |
1351 assert len(dep.safesync_url) > 0 | |
1352 handle = urllib.urlopen(dep.safesync_url) | |
1353 rev = handle.read().strip() | |
1354 handle.close() | |
1355 if not rev: | |
1356 raise gclient_utils.Error( | |
1357 'It appears your safesync_url (%s) is not working properly\n' | |
1358 '(as it returned an empty response). Check your config.' % | |
1359 dep.safesync_url) | |
1360 scm = gclient_scm.CreateSCM( | |
1361 dep.url, dep.root.root_dir, dep.name, self.outbuf) | |
1362 safe_rev = scm.GetUsableRev(rev, self._options) | |
1363 if self._options.verbose: | |
1364 print('Using safesync_url revision: %s.\n' % safe_rev) | |
1365 self._options.revisions.append('%s@%s' % (dep.name, safe_rev)) | |
1366 | |
1367 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True): | 1335 def RunOnDeps(self, command, args, ignore_requirements=False, progress=True): |
1368 """Runs a command on each dependency in a client and its dependencies. | 1336 """Runs a command on each dependency in a client and its dependencies. |
1369 | 1337 |
1370 Args: | 1338 Args: |
1371 command: The command to use (e.g., 'status' or 'diff') | 1339 command: The command to use (e.g., 'status' or 'diff') |
1372 args: list of str - extra arguments to add to the command line. | 1340 args: list of str - extra arguments to add to the command line. |
1373 """ | 1341 """ |
1374 if not self.dependencies: | 1342 if not self.dependencies: |
1375 raise gclient_utils.Error('No solution specified') | 1343 raise gclient_utils.Error('No solution specified') |
1376 | 1344 |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1532 for k in sorted(entries.keys()): | 1500 for k in sorted(entries.keys()): |
1533 if entries[k]: | 1501 if entries[k]: |
1534 # Quotes aren't escaped... | 1502 # Quotes aren't escaped... |
1535 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) | 1503 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) |
1536 else: | 1504 else: |
1537 custom_deps.append(' \"%s\": None,\n' % k) | 1505 custom_deps.append(' \"%s\": None,\n' % k) |
1538 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { | 1506 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { |
1539 'solution_name': d.name, | 1507 'solution_name': d.name, |
1540 'solution_url': d.url, | 1508 'solution_url': d.url, |
1541 'deps_file': d.deps_file, | 1509 'deps_file': d.deps_file, |
1542 'safesync_url' : d.safesync_url or '', | |
1543 'managed': d.managed, | 1510 'managed': d.managed, |
1544 'solution_deps': ''.join(custom_deps), | 1511 'solution_deps': ''.join(custom_deps), |
1545 } | 1512 } |
1546 # Print the snapshot configuration file | 1513 # Print the snapshot configuration file |
1547 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) | 1514 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) |
1548 else: | 1515 else: |
1549 entries = {} | 1516 entries = {} |
1550 for d in self.root.subtree(False): | 1517 for d in self.root.subtree(False): |
1551 if self._options.actual: | 1518 if self._options.actual: |
1552 entries[d.name] = GetURLAndRev(d) | 1519 entries[d.name] = GetURLAndRev(d) |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1698 def CMDroot(parser, args): | 1665 def CMDroot(parser, args): |
1699 """Outputs the solution root (or current dir if there isn't one).""" | 1666 """Outputs the solution root (or current dir if there isn't one).""" |
1700 (options, args) = parser.parse_args(args) | 1667 (options, args) = parser.parse_args(args) |
1701 client = GClient.LoadCurrentConfig(options) | 1668 client = GClient.LoadCurrentConfig(options) |
1702 if client: | 1669 if client: |
1703 print(os.path.abspath(client.root_dir)) | 1670 print(os.path.abspath(client.root_dir)) |
1704 else: | 1671 else: |
1705 print(os.path.abspath('.')) | 1672 print(os.path.abspath('.')) |
1706 | 1673 |
1707 | 1674 |
1708 @subcommand.usage('[url] [safesync url]') | 1675 @subcommand.usage('[url]') |
1709 def CMDconfig(parser, args): | 1676 def CMDconfig(parser, args): |
1710 """Creates a .gclient file in the current directory. | 1677 """Creates a .gclient file in the current directory. |
1711 | 1678 |
1712 This specifies the configuration for further commands. After update/sync, | 1679 This specifies the configuration for further commands. After update/sync, |
1713 top-level DEPS files in each module are read to determine dependent | 1680 top-level DEPS files in each module are read to determine dependent |
1714 modules to operate on as well. If optional [url] parameter is | 1681 modules to operate on as well. If optional [url] parameter is |
1715 provided, then configuration is read from a specified Subversion server | 1682 provided, then configuration is read from a specified Subversion server |
1716 URL. | 1683 URL. |
1717 """ | 1684 """ |
1718 # We do a little dance with the --gclientfile option. 'gclient config' is the | 1685 # 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... |
1757 else: | 1724 else: |
1758 # specify an alternate relpath for the given URL. | 1725 # specify an alternate relpath for the given URL. |
1759 name = options.name | 1726 name = options.name |
1760 if not os.path.abspath(os.path.join(os.getcwd(), name)).startswith( | 1727 if not os.path.abspath(os.path.join(os.getcwd(), name)).startswith( |
1761 os.getcwd()): | 1728 os.getcwd()): |
1762 parser.error('Do not pass a relative path for --name.') | 1729 parser.error('Do not pass a relative path for --name.') |
1763 if any(x in ('..', '.', '/', '\\') for x in name.split(os.sep)): | 1730 if any(x in ('..', '.', '/', '\\') for x in name.split(os.sep)): |
1764 parser.error('Do not include relative path components in --name.') | 1731 parser.error('Do not include relative path components in --name.') |
1765 | 1732 |
1766 deps_file = options.deps_file | 1733 deps_file = options.deps_file |
1767 safesync_url = '' | 1734 client.SetDefaultConfig(name, deps_file, base_url, |
1768 if len(args) > 1: | |
1769 safesync_url = args[1] | |
1770 client.SetDefaultConfig(name, deps_file, base_url, safesync_url, | |
1771 managed=not options.unmanaged, | 1735 managed=not options.unmanaged, |
1772 cache_dir=options.cache_dir) | 1736 cache_dir=options.cache_dir) |
1773 client.SaveConfig() | 1737 client.SaveConfig() |
1774 return 0 | 1738 return 0 |
1775 | 1739 |
1776 | 1740 |
1777 @subcommand.epilog("""Example: | 1741 @subcommand.epilog("""Example: |
1778 gclient pack > patch.txt | 1742 gclient pack > patch.txt |
1779 generate simple patch for configured client and dependences | 1743 generate simple patch for configured client and dependences |
1780 """) | 1744 """) |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1849 parser.add_option('-n', '--nohooks', action='store_true', | 1813 parser.add_option('-n', '--nohooks', action='store_true', |
1850 help='don\'t run hooks after the update is complete') | 1814 help='don\'t run hooks after the update is complete') |
1851 parser.add_option('-p', '--noprehooks', action='store_true', | 1815 parser.add_option('-p', '--noprehooks', action='store_true', |
1852 help='don\'t run pre-DEPS hooks', default=False) | 1816 help='don\'t run pre-DEPS hooks', default=False) |
1853 parser.add_option('-r', '--revision', action='append', | 1817 parser.add_option('-r', '--revision', action='append', |
1854 dest='revisions', metavar='REV', default=[], | 1818 dest='revisions', metavar='REV', default=[], |
1855 help='Enforces revision/hash for the solutions with the ' | 1819 help='Enforces revision/hash for the solutions with the ' |
1856 'format src@rev. The src@ part is optional and can be ' | 1820 'format src@rev. The src@ part is optional and can be ' |
1857 'skipped. -r can be used multiple times when .gclient ' | 1821 'skipped. -r can be used multiple times when .gclient ' |
1858 'has multiple solutions configured and will work even ' | 1822 'has multiple solutions configured and will work even ' |
1859 'if the src@ part is skipped. Note that specifying ' | 1823 'if the src@ part is skipped.') |
1860 '--revision means your safesync_url gets ignored.') | |
1861 parser.add_option('--with_branch_heads', action='store_true', | 1824 parser.add_option('--with_branch_heads', action='store_true', |
1862 help='Clone git "branch_heads" refspecs in addition to ' | 1825 help='Clone git "branch_heads" refspecs in addition to ' |
1863 'the default refspecs. This adds about 1/2GB to a ' | 1826 'the default refspecs. This adds about 1/2GB to a ' |
1864 'full checkout. (git only)') | 1827 'full checkout. (git only)') |
1865 parser.add_option('--with_tags', action='store_true', | 1828 parser.add_option('--with_tags', action='store_true', |
1866 help='Clone git tags in addition to the default refspecs.') | 1829 help='Clone git tags in addition to the default refspecs.') |
1867 parser.add_option('-H', '--head', action='store_true', | 1830 parser.add_option('-H', '--head', action='store_true', |
1868 help='skips any safesync_urls specified in ' | 1831 help='DEPRECATED: only made sense with safesync urls.') |
1869 'configured solutions and sync to head instead') | |
1870 parser.add_option('-D', '--delete_unversioned_trees', action='store_true', | 1832 parser.add_option('-D', '--delete_unversioned_trees', action='store_true', |
1871 help='Deletes from the working copy any dependencies that ' | 1833 help='Deletes from the working copy any dependencies that ' |
1872 'have been removed since the last sync, as long as ' | 1834 'have been removed since the last sync, as long as ' |
1873 'there are no local modifications. When used with ' | 1835 'there are no local modifications. When used with ' |
1874 '--force, such dependencies are removed even if they ' | 1836 '--force, such dependencies are removed even if they ' |
1875 'have local modifications. When used with --reset, ' | 1837 'have local modifications. When used with --reset, ' |
1876 'all untracked directories are removed from the ' | 1838 'all untracked directories are removed from the ' |
1877 'working copy, excluding those which are explicitly ' | 1839 'working copy, excluding those which are explicitly ' |
1878 'ignored in the repository.') | 1840 'ignored in the repository.') |
1879 parser.add_option('-R', '--reset', action='store_true', | 1841 parser.add_option('-R', '--reset', action='store_true', |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2180 | 2142 |
2181 | 2143 |
2182 if '__main__' == __name__: | 2144 if '__main__' == __name__: |
2183 try: | 2145 try: |
2184 sys.exit(main(sys.argv[1:])) | 2146 sys.exit(main(sys.argv[1:])) |
2185 except KeyboardInterrupt: | 2147 except KeyboardInterrupt: |
2186 sys.stderr.write('interrupted\n') | 2148 sys.stderr.write('interrupted\n') |
2187 sys.exit(1) | 2149 sys.exit(1) |
2188 | 2150 |
2189 # vim: ts=2:sw=2:tw=80:et: | 2151 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |