OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright 2008 Google Inc. All Rights Reserved. | 3 # Copyright 2008 Google Inc. All Rights Reserved. |
4 # | 4 # |
5 # Licensed under the Apache License, Version 2.0 (the "License"); | 5 # Licensed under the Apache License, Version 2.0 (the "License"); |
6 # you may not use this file except in compliance with the License. | 6 # you may not use this file except in compliance with the License. |
7 # You may obtain a copy of the License at | 7 # You may obtain a copy of the License at |
8 # | 8 # |
9 # http://www.apache.org/licenses/LICENSE-2.0 | 9 # http://www.apache.org/licenses/LICENSE-2.0 |
10 # | 10 # |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
255 --verbose : output additional diagnostics | 255 --verbose : output additional diagnostics |
256 """, | 256 """, |
257 "revinfo": | 257 "revinfo": |
258 """Outputs source path, server URL and revision information for every | 258 """Outputs source path, server URL and revision information for every |
259 dependency in all solutions (no local checkout required). | 259 dependency in all solutions (no local checkout required). |
260 | 260 |
261 usage: revinfo [options] | 261 usage: revinfo [options] |
262 """, | 262 """, |
263 } | 263 } |
264 | 264 |
265 # parameterized by (solution_name, solution_url, safesync_url) | 265 DEFAULT_CLIENT_FILE_TEXT = ("""\ |
266 DEFAULT_CLIENT_FILE_TEXT = ( | 266 # An element of this array (a "solution") describes a repository directory |
267 """ | |
268 # An element of this array (a \"solution\") describes a repository directory | |
269 # that will be checked out into your working copy. Each solution may | 267 # that will be checked out into your working copy. Each solution may |
270 # optionally define additional dependencies (via its DEPS file) to be | 268 # optionally define additional dependencies (via its DEPS file) to be |
271 # checked out alongside the solution's directory. A solution may also | 269 # checked out alongside the solution's directory. A solution may also |
272 # specify custom dependencies (via the \"custom_deps\" property) that | 270 # specify custom dependencies (via the "custom_deps" property) that |
273 # override or augment the dependencies specified by the DEPS file. | 271 # override or augment the dependencies specified by the DEPS file. |
274 # If a \"safesync_url\" is specified, it is assumed to reference the location of | 272 # If a "safesync_url" is specified, it is assumed to reference the location of |
275 # a text file which contains nothing but the last known good SCM revision to | 273 # a text file which contains nothing but the last known good SCM revision to |
276 # sync against. It is fetched if specified and used unless --head is passed | 274 # sync against. It is fetched if specified and used unless --head is passed |
| 275 |
277 solutions = [ | 276 solutions = [ |
278 { \"name\" : \"%s\", | 277 { "name" : "%(solution_name)s", |
279 \"url\" : \"%s\", | 278 "url" : "%(solution_url)s", |
280 \"custom_deps\" : { | 279 "custom_deps" : { |
281 # To use the trunk of a component instead of what's in DEPS: | 280 # To use the trunk of a component instead of what's in DEPS: |
282 #\"component\": \"https://svnserver/component/trunk/\", | 281 #"component": "https://svnserver/component/trunk/", |
283 # To exclude a component from your working copy: | 282 # To exclude a component from your working copy: |
284 #\"data/really_large_component\": None, | 283 #"data/really_large_component": None, |
285 }, | 284 }, |
286 \"safesync_url\": \"%s\" | 285 "safesync_url": "%(safesync_url)s" |
287 } | 286 }, |
288 ] | 287 ] |
289 """) | 288 """) |
290 | 289 |
291 | 290 |
292 ## Generic utils | 291 ## Generic utils |
293 | 292 |
294 def ParseXML(output): | 293 def ParseXML(output): |
295 try: | 294 try: |
296 return xml.dom.minidom.parseString(output) | 295 return xml.dom.minidom.parseString(output) |
297 except xml.parsers.expat.ExpatError: | 296 except xml.parsers.expat.ExpatError: |
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1124 while not os.path.exists(os.path.join(path, options.config_filename)): | 1123 while not os.path.exists(os.path.join(path, options.config_filename)): |
1125 next = os.path.split(path) | 1124 next = os.path.split(path) |
1126 if not next[1]: | 1125 if not next[1]: |
1127 return None | 1126 return None |
1128 path = next[0] | 1127 path = next[0] |
1129 client = GClient(path, options) | 1128 client = GClient(path, options) |
1130 client._LoadConfig() | 1129 client._LoadConfig() |
1131 return client | 1130 return client |
1132 | 1131 |
1133 def SetDefaultConfig(self, solution_name, solution_url, safesync_url): | 1132 def SetDefaultConfig(self, solution_name, solution_url, safesync_url): |
1134 self.SetConfig(DEFAULT_CLIENT_FILE_TEXT % ( | 1133 self.SetConfig(DEFAULT_CLIENT_FILE_TEXT % { |
1135 solution_name, solution_url, safesync_url | 1134 'solution_name': solution_name, |
1136 )) | 1135 'solution_url': solution_url, |
| 1136 'safesync_url' : safesync_url, |
| 1137 }) |
1137 | 1138 |
1138 def _SaveEntries(self, entries): | 1139 def _SaveEntries(self, entries): |
1139 """Creates a .gclient_entries file to record the list of unique checkouts. | 1140 """Creates a .gclient_entries file to record the list of unique checkouts. |
1140 | 1141 |
1141 The .gclient_entries file lives in the same directory as .gclient. | 1142 The .gclient_entries file lives in the same directory as .gclient. |
1142 | 1143 |
1143 Args: | 1144 Args: |
1144 entries: A sequence of solution names. | 1145 entries: A sequence of solution names. |
1145 """ | 1146 """ |
1146 text = "entries = [\n" | 1147 text = "entries = [\n" |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 # All known hooks are expected to run unconditionally regardless of working | 1425 # All known hooks are expected to run unconditionally regardless of working |
1425 # copy state, so skip the SCM status check. | 1426 # copy state, so skip the SCM status check. |
1426 run_scm = not (command == 'runhooks' and self._options.force) | 1427 run_scm = not (command == 'runhooks' and self._options.force) |
1427 | 1428 |
1428 entries = {} | 1429 entries = {} |
1429 entries_deps_content = {} | 1430 entries_deps_content = {} |
1430 file_list = [] | 1431 file_list = [] |
1431 # Run on the base solutions first. | 1432 # Run on the base solutions first. |
1432 for solution in solutions: | 1433 for solution in solutions: |
1433 name = solution["name"] | 1434 name = solution["name"] |
| 1435 deps_file = solution.get("deps_file", self._options.deps_file) |
| 1436 if '/' in deps_file or '\\' in deps_file: |
| 1437 raise Error("deps_file name must not be a path, just a filename.") |
1434 if name in entries: | 1438 if name in entries: |
1435 raise Error("solution %s specified more than once" % name) | 1439 raise Error("solution %s specified more than once" % name) |
1436 url = solution["url"] | 1440 url = solution["url"] |
1437 entries[name] = url | 1441 entries[name] = url |
1438 if run_scm: | 1442 if run_scm: |
1439 self._options.revision = revision_overrides.get(name) | 1443 self._options.revision = revision_overrides.get(name) |
1440 scm = SCMWrapper(url, self._root_dir, name) | 1444 scm = SCMWrapper(url, self._root_dir, name) |
1441 scm.RunCommand(command, self._options, args, file_list) | 1445 scm.RunCommand(command, self._options, args, file_list) |
1442 file_list = [os.path.join(name, file.strip()) for file in file_list] | 1446 file_list = [os.path.join(name, file.strip()) for file in file_list] |
1443 self._options.revision = None | 1447 self._options.revision = None |
1444 try: | 1448 try: |
1445 deps_content = FileRead(os.path.join(self._root_dir, name, | 1449 deps_content = FileRead(os.path.join(self._root_dir, name, |
1446 self._options.deps_file)) | 1450 deps_file)) |
1447 except IOError, e: | 1451 except IOError, e: |
1448 if e.errno != errno.ENOENT: | 1452 if e.errno != errno.ENOENT: |
1449 raise | 1453 raise |
1450 deps_content = "" | 1454 deps_content = "" |
1451 entries_deps_content[name] = deps_content | 1455 entries_deps_content[name] = deps_content |
1452 | 1456 |
1453 # Process the dependencies next (sort alphanumerically to ensure that | 1457 # Process the dependencies next (sort alphanumerically to ensure that |
1454 # containing directories get populated first and for readability) | 1458 # containing directories get populated first and for readability) |
1455 deps = self._ParseAllDeps(entries, entries_deps_content) | 1459 deps = self._ParseAllDeps(entries, entries_deps_content) |
1456 deps_to_process = deps.keys() | 1460 deps_to_process = deps.keys() |
(...skipping 19 matching lines...) Expand all Loading... |
1476 deps[d].module_name, | 1480 deps[d].module_name, |
1477 self._options.deps_file)), | 1481 self._options.deps_file)), |
1478 {}) | 1482 {}) |
1479 url = sub_deps[d] | 1483 url = sub_deps[d] |
1480 entries[d] = url | 1484 entries[d] = url |
1481 if run_scm: | 1485 if run_scm: |
1482 self._options.revision = revision_overrides.get(d) | 1486 self._options.revision = revision_overrides.get(d) |
1483 scm = SCMWrapper(url, self._root_dir, d) | 1487 scm = SCMWrapper(url, self._root_dir, d) |
1484 scm.RunCommand(command, self._options, args, file_list) | 1488 scm.RunCommand(command, self._options, args, file_list) |
1485 self._options.revision = None | 1489 self._options.revision = None |
1486 | 1490 |
1487 # Convert all absolute paths to relative. | 1491 # Convert all absolute paths to relative. |
1488 for i in range(len(file_list)): | 1492 for i in range(len(file_list)): |
1489 # TODO(phajdan.jr): We should know exactly when the paths are absolute. | 1493 # TODO(phajdan.jr): We should know exactly when the paths are absolute. |
1490 # It depends on the command being executed (like runhooks vs sync). | 1494 # It depends on the command being executed (like runhooks vs sync). |
1491 if not os.path.isabs(file_list[i]): | 1495 if not os.path.isabs(file_list[i]): |
1492 continue | 1496 continue |
1493 | 1497 |
1494 prefix = os.path.commonprefix([self._root_dir.lower(), | 1498 prefix = os.path.commonprefix([self._root_dir.lower(), |
1495 file_list[i].lower()]) | 1499 file_list[i].lower()]) |
1496 file_list[i] = file_list[i][len(prefix):] | 1500 file_list[i] = file_list[i][len(prefix):] |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1944 | 1948 |
1945 if "__main__" == __name__: | 1949 if "__main__" == __name__: |
1946 try: | 1950 try: |
1947 result = Main(sys.argv) | 1951 result = Main(sys.argv) |
1948 except Error, e: | 1952 except Error, e: |
1949 print >> sys.stderr, "Error: %s" % str(e) | 1953 print >> sys.stderr, "Error: %s" % str(e) |
1950 result = 1 | 1954 result = 1 |
1951 sys.exit(result) | 1955 sys.exit(result) |
1952 | 1956 |
1953 # vim: ts=2:sw=2:tw=80:et: | 1957 # vim: ts=2:sw=2:tw=80:et: |
OLD | NEW |