| 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 |