| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 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 """A wrapper script to manage a set of client modules in different SCM. | 6 """A wrapper script to manage a set of client modules in different SCM. |
| 7 | 7 |
| 8 This script is intended to be used to help basic management of client | 8 This script is intended to be used to help basic management of client |
| 9 program sources residing in one or more Subversion modules and Git | 9 program sources residing in one or more Subversion modules and Git |
| 10 repositories, along with other modules it depends on, also in Subversion or Git, | 10 repositories, along with other modules it depends on, also in Subversion or Git, |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 | 422 |
| 423 class FromImpl: | 423 class FromImpl: |
| 424 """Used to implement the From syntax.""" | 424 """Used to implement the From syntax.""" |
| 425 | 425 |
| 426 def __init__(self, module_name): | 426 def __init__(self, module_name): |
| 427 self.module_name = module_name | 427 self.module_name = module_name |
| 428 | 428 |
| 429 def __str__(self): | 429 def __str__(self): |
| 430 return 'From("%s")' % self.module_name | 430 return 'From("%s")' % self.module_name |
| 431 | 431 |
| 432 class FileImpl: |
| 433 """Used to implement the File('') syntax which lets you sync a single file |
| 434 from an SVN repo.""" |
| 435 |
| 436 def __init__(self, file_location): |
| 437 self.file_location = file_location |
| 438 |
| 439 def __str__(self): |
| 440 return 'File("%s")' % self.file_location |
| 441 |
| 442 def GetPath(self): |
| 443 return os.path.split(self.file_location)[0] |
| 444 |
| 445 def GetFilename(self): |
| 446 rev_tokens = self.file_location.split('@') |
| 447 return os.path.split(rev_tokens[0])[1] |
| 448 |
| 449 def GetRevision(self): |
| 450 rev_tokens = self.file_location.split('@') |
| 451 if len(rev_tokens) > 1: |
| 452 return rev_tokens[1] |
| 453 return None |
| 454 |
| 432 class _VarImpl: | 455 class _VarImpl: |
| 433 def __init__(self, custom_vars, local_scope): | 456 def __init__(self, custom_vars, local_scope): |
| 434 self._custom_vars = custom_vars | 457 self._custom_vars = custom_vars |
| 435 self._local_scope = local_scope | 458 self._local_scope = local_scope |
| 436 | 459 |
| 437 def Lookup(self, var_name): | 460 def Lookup(self, var_name): |
| 438 """Implements the Var syntax.""" | 461 """Implements the Var syntax.""" |
| 439 if var_name in self._custom_vars: | 462 if var_name in self._custom_vars: |
| 440 return self._custom_vars[var_name] | 463 return self._custom_vars[var_name] |
| 441 elif var_name in self._local_scope.get("vars", {}): | 464 elif var_name in self._local_scope.get("vars", {}): |
| (...skipping 12 matching lines...) Expand all Loading... |
| 454 Returns: | 477 Returns: |
| 455 A dict mapping module names (as relative paths) to URLs or an empty | 478 A dict mapping module names (as relative paths) to URLs or an empty |
| 456 dict if the solution does not have a DEPS file. | 479 dict if the solution does not have a DEPS file. |
| 457 """ | 480 """ |
| 458 # Skip empty | 481 # Skip empty |
| 459 if not solution_deps_content: | 482 if not solution_deps_content: |
| 460 return {} | 483 return {} |
| 461 # Eval the content | 484 # Eval the content |
| 462 local_scope = {} | 485 local_scope = {} |
| 463 var = self._VarImpl(custom_vars, local_scope) | 486 var = self._VarImpl(custom_vars, local_scope) |
| 464 global_scope = {"From": self.FromImpl, "Var": var.Lookup, "deps_os": {}} | 487 global_scope = { |
| 488 "File": self.FileImpl, |
| 489 "From": self.FromImpl, |
| 490 "Var": var.Lookup, |
| 491 "deps_os": {}, |
| 492 } |
| 465 exec(solution_deps_content, global_scope, local_scope) | 493 exec(solution_deps_content, global_scope, local_scope) |
| 466 deps = local_scope.get("deps", {}) | 494 deps = local_scope.get("deps", {}) |
| 467 | 495 |
| 468 # load os specific dependencies if defined. these dependencies may | 496 # load os specific dependencies if defined. these dependencies may |
| 469 # override or extend the values defined by the 'deps' member. | 497 # override or extend the values defined by the 'deps' member. |
| 470 if "deps_os" in local_scope: | 498 if "deps_os" in local_scope: |
| 471 deps_os_choices = { | 499 deps_os_choices = { |
| 472 "win32": "win", | 500 "win32": "win", |
| 473 "win": "win", | 501 "win": "win", |
| 474 "cygwin": "win", | 502 "cygwin": "win", |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 if url is None: | 581 if url is None: |
| 554 continue | 582 continue |
| 555 else: | 583 else: |
| 556 url = solution_deps[d] | 584 url = solution_deps[d] |
| 557 # if we have a From reference dependent on another solution, then | 585 # if we have a From reference dependent on another solution, then |
| 558 # just skip the From reference. When we pull deps for the solution, | 586 # just skip the From reference. When we pull deps for the solution, |
| 559 # we will take care of this dependency. | 587 # we will take care of this dependency. |
| 560 # | 588 # |
| 561 # If multiple solutions all have the same From reference, then we | 589 # If multiple solutions all have the same From reference, then we |
| 562 # should only add one to our list of dependencies. | 590 # should only add one to our list of dependencies. |
| 563 if type(url) != str: | 591 if isinstance(url, self.FromImpl): |
| 564 if url.module_name in solution_urls: | 592 if url.module_name in solution_urls: |
| 565 # Already parsed. | 593 # Already parsed. |
| 566 continue | 594 continue |
| 567 if d in deps and type(deps[d]) != str: | 595 if d in deps and type(deps[d]) != str: |
| 568 if url.module_name == deps[d].module_name: | 596 if url.module_name == deps[d].module_name: |
| 569 continue | 597 continue |
| 570 else: | 598 elif isinstance(url, str): |
| 571 parsed_url = urlparse.urlparse(url) | 599 parsed_url = urlparse.urlparse(url) |
| 572 scheme = parsed_url[0] | 600 scheme = parsed_url[0] |
| 573 if not scheme: | 601 if not scheme: |
| 574 # A relative url. Fetch the real base. | 602 # A relative url. Fetch the real base. |
| 575 path = parsed_url[2] | 603 path = parsed_url[2] |
| 576 if path[0] != "/": | 604 if path[0] != "/": |
| 577 raise gclient_utils.Error( | 605 raise gclient_utils.Error( |
| 578 "relative DEPS entry \"%s\" must begin with a slash" % d) | 606 "relative DEPS entry \"%s\" must begin with a slash" % d) |
| 579 # Create a scm just to query the full url. | 607 # Create a scm just to query the full url. |
| 580 scm = gclient_scm.CreateSCM(solution["url"], self._root_dir, | 608 scm = gclient_scm.CreateSCM(solution["url"], self._root_dir, |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 721 if command == 'update' and not self._options.verbose: | 749 if command == 'update' and not self._options.verbose: |
| 722 pm.update() | 750 pm.update() |
| 723 if type(deps[d]) == str: | 751 if type(deps[d]) == str: |
| 724 url = deps[d] | 752 url = deps[d] |
| 725 entries[d] = url | 753 entries[d] = url |
| 726 if run_scm: | 754 if run_scm: |
| 727 self._options.revision = revision_overrides.get(d) | 755 self._options.revision = revision_overrides.get(d) |
| 728 scm = gclient_scm.CreateSCM(url, self._root_dir, d) | 756 scm = gclient_scm.CreateSCM(url, self._root_dir, d) |
| 729 scm.RunCommand(command, self._options, args, file_list) | 757 scm.RunCommand(command, self._options, args, file_list) |
| 730 self._options.revision = None | 758 self._options.revision = None |
| 759 elif isinstance(deps[d], self.FileImpl): |
| 760 file = deps[d] |
| 761 self._options.revision = file.GetRevision() |
| 762 if run_scm: |
| 763 scm = gclient_scm.CreateSCM(file.GetPath(), self._root_dir, d) |
| 764 scm.RunCommand("updatesingle", self._options, |
| 765 args + [file.GetFilename()], file_list) |
| 766 |
| 731 if command == 'update' and not self._options.verbose: | 767 if command == 'update' and not self._options.verbose: |
| 732 pm.end() | 768 pm.end() |
| 733 | 769 |
| 734 # Second pass for inherited deps (via the From keyword) | 770 # Second pass for inherited deps (via the From keyword) |
| 735 for d in deps_to_process: | 771 for d in deps_to_process: |
| 736 if type(deps[d]) != str: | 772 if isinstance(deps[d], self.FromImpl): |
| 737 filename = os.path.join(self._root_dir, | 773 filename = os.path.join(self._root_dir, |
| 738 deps[d].module_name, | 774 deps[d].module_name, |
| 739 self._options.deps_file) | 775 self._options.deps_file) |
| 740 content = gclient_utils.FileRead(filename) | 776 content = gclient_utils.FileRead(filename) |
| 741 sub_deps = self._ParseSolutionDeps(deps[d].module_name, content, {}) | 777 sub_deps = self._ParseSolutionDeps(deps[d].module_name, content, {}) |
| 742 url = sub_deps[d] | 778 url = sub_deps[d] |
| 743 entries[d] = url | 779 entries[d] = url |
| 744 if run_scm: | 780 if run_scm: |
| 745 self._options.revision = revision_overrides.get(d) | 781 self._options.revision = revision_overrides.get(d) |
| 746 scm = gclient_scm.CreateSCM(url, self._root_dir, d) | 782 scm = gclient_scm.CreateSCM(url, self._root_dir, d) |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 878 deps_to_process.sort() | 914 deps_to_process.sort() |
| 879 | 915 |
| 880 # First pass for direct dependencies. | 916 # First pass for direct dependencies. |
| 881 for d in deps_to_process: | 917 for d in deps_to_process: |
| 882 if type(deps[d]) == str: | 918 if type(deps[d]) == str: |
| 883 (url, rev) = GetURLAndRev(d, deps[d]) | 919 (url, rev) = GetURLAndRev(d, deps[d]) |
| 884 entries[d] = "%s@%s" % (url, rev) | 920 entries[d] = "%s@%s" % (url, rev) |
| 885 | 921 |
| 886 # Second pass for inherited deps (via the From keyword) | 922 # Second pass for inherited deps (via the From keyword) |
| 887 for d in deps_to_process: | 923 for d in deps_to_process: |
| 888 if type(deps[d]) != str: | 924 if isinstance(deps[d], self.FromImpl): |
| 889 deps_parent_url = entries[deps[d].module_name] | 925 deps_parent_url = entries[deps[d].module_name] |
| 890 if deps_parent_url.find("@") < 0: | 926 if deps_parent_url.find("@") < 0: |
| 891 raise gclient_utils.Error("From %s missing revisioned url" % | 927 raise gclient_utils.Error("From %s missing revisioned url" % |
| 892 deps[d].module_name) | 928 deps[d].module_name) |
| 893 content = gclient_utils.FileRead(os.path.join( | 929 content = gclient_utils.FileRead(os.path.join( |
| 894 self._root_dir, | 930 self._root_dir, |
| 895 deps[d].module_name, | 931 deps[d].module_name, |
| 896 self._options.deps_file)) | 932 self._options.deps_file)) |
| 897 sub_deps = self._ParseSolutionDeps(deps[d].module_name, content, {}) | 933 sub_deps = self._ParseSolutionDeps(deps[d].module_name, content, {}) |
| 898 (url, rev) = GetURLAndRev(d, sub_deps[d]) | 934 (url, rev) = GetURLAndRev(d, sub_deps[d]) |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 | 1287 |
| 1252 if "__main__" == __name__: | 1288 if "__main__" == __name__: |
| 1253 try: | 1289 try: |
| 1254 result = Main(sys.argv) | 1290 result = Main(sys.argv) |
| 1255 except gclient_utils.Error, e: | 1291 except gclient_utils.Error, e: |
| 1256 print >> sys.stderr, "Error: %s" % str(e) | 1292 print >> sys.stderr, "Error: %s" % str(e) |
| 1257 result = 1 | 1293 result = 1 |
| 1258 sys.exit(result) | 1294 sys.exit(result) |
| 1259 | 1295 |
| 1260 # vim: ts=2:sw=2:tw=80:et: | 1296 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |