Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 | 7 |
| 8 Files | 8 Files |
| 9 .gclient : Current client configuration, written by 'config' command. | 9 .gclient : Current client configuration, written by 'config' command. |
| 10 Format is a Python script defining 'solutions', a list whose | 10 Format is a Python script defining 'solutions', a list whose |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 if var_name in self._custom_vars: | 132 if var_name in self._custom_vars: |
| 133 return self._custom_vars[var_name] | 133 return self._custom_vars[var_name] |
| 134 elif var_name in self._local_scope.get("vars", {}): | 134 elif var_name in self._local_scope.get("vars", {}): |
| 135 return self._local_scope["vars"][var_name] | 135 return self._local_scope["vars"][var_name] |
| 136 raise gclient_utils.Error("Var is not defined: %s" % var_name) | 136 raise gclient_utils.Error("Var is not defined: %s" % var_name) |
| 137 | 137 |
| 138 | 138 |
| 139 class Dependency(GClientKeywords, gclient_utils.WorkItem): | 139 class Dependency(GClientKeywords, gclient_utils.WorkItem): |
| 140 """Object that represents a dependency checkout.""" | 140 """Object that represents a dependency checkout.""" |
| 141 | 141 |
| 142 def __init__(self, parent, name, url, safesync_url, custom_deps, | 142 def __init__(self, parent, name, url, safesync_url, managed, custom_deps, |
| 143 custom_vars, deps_file, should_process): | 143 custom_vars, deps_file, should_process): |
| 144 GClientKeywords.__init__(self) | 144 GClientKeywords.__init__(self) |
| 145 gclient_utils.WorkItem.__init__(self) | 145 gclient_utils.WorkItem.__init__(self) |
| 146 self.parent = parent | 146 self.parent = parent |
| 147 self.name = name | 147 self.name = name |
| 148 self.url = url | 148 self.url = url |
| 149 self.parsed_url = None | 149 self.parsed_url = None |
| 150 # These 2 are only set in .gclient and not in DEPS files. | 150 # These 2 are only set in .gclient and not in DEPS files. |
| 151 self.safesync_url = safesync_url | 151 self.safesync_url = safesync_url |
| 152 self.managed = managed | |
| 152 self.custom_vars = custom_vars or {} | 153 self.custom_vars = custom_vars or {} |
| 153 self.custom_deps = custom_deps or {} | 154 self.custom_deps = custom_deps or {} |
| 154 self.deps_hooks = [] | 155 self.deps_hooks = [] |
| 155 self.dependencies = [] | 156 self.dependencies = [] |
| 156 self.deps_file = deps_file | 157 self.deps_file = deps_file |
| 157 # A cache of the files affected by the current operation, necessary for | 158 # A cache of the files affected by the current operation, necessary for |
| 158 # hooks. | 159 # hooks. |
| 159 self._file_list = [] | 160 self._file_list = [] |
| 160 # If it is not set to True, the dependency wasn't processed for its child | 161 # If it is not set to True, the dependency wasn't processed for its child |
| 161 # dependency, i.e. its DEPS wasn't read. | 162 # dependency, i.e. its DEPS wasn't read. |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 324 logging.info('Won\'t process duplicate dependency %s' % tree[name]) | 325 logging.info('Won\'t process duplicate dependency %s' % tree[name]) |
| 325 # In theory we could keep it as a shadow of the other one. In | 326 # In theory we could keep it as a shadow of the other one. In |
| 326 # practice, simply ignore it. | 327 # practice, simply ignore it. |
| 327 #should_process = False | 328 #should_process = False |
| 328 continue | 329 continue |
| 329 else: | 330 else: |
| 330 raise gclient_utils.Error( | 331 raise gclient_utils.Error( |
| 331 'Dependency %s specified more than once:\n %s\nvs\n %s' % | 332 'Dependency %s specified more than once:\n %s\nvs\n %s' % |
| 332 (name, tree[name].hierarchy(), self.hierarchy())) | 333 (name, tree[name].hierarchy(), self.hierarchy())) |
| 333 self.dependencies.append(Dependency(self, name, url, None, None, None, | 334 self.dependencies.append(Dependency(self, name, url, None, None, None, |
| 334 self.deps_file, should_process)) | 335 None, self.deps_file, should_process)) |
|
M-A Ruel
2011/08/28 13:03:31
So it's not inheritable?
nsylvain
2011/08/29 18:03:58
Right
| |
| 335 logging.debug('Loaded: %s' % str(self)) | 336 logging.debug('Loaded: %s' % str(self)) |
| 336 | 337 |
| 337 # Arguments number differs from overridden method | 338 # Arguments number differs from overridden method |
| 338 # pylint: disable=W0221 | 339 # pylint: disable=W0221 |
| 339 def run(self, revision_overrides, command, args, work_queue, options): | 340 def run(self, revision_overrides, command, args, work_queue, options): |
| 340 """Runs 'command' before parsing the DEPS in case it's a initial checkout | 341 """Runs 'command' before parsing the DEPS in case it's a initial checkout |
| 341 or a revert.""" | 342 or a revert.""" |
| 342 | 343 |
| 343 def maybeGetParentRevision(options): | 344 def maybeGetParentRevision(options): |
| 344 """If we are performing an update and --transitive is set, set the | 345 """If we are performing an update and --transitive is set, set the |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 self.root_dir(), | 391 self.root_dir(), |
| 391 self.name) | 392 self.name) |
| 392 scm.RunCommand('updatesingle', options, | 393 scm.RunCommand('updatesingle', options, |
| 393 args + [self.parsed_url.GetFilename()], | 394 args + [self.parsed_url.GetFilename()], |
| 394 self._file_list) | 395 self._file_list) |
| 395 else: | 396 else: |
| 396 # Create a shallow copy to mutate revision. | 397 # Create a shallow copy to mutate revision. |
| 397 options = copy.copy(options) | 398 options = copy.copy(options) |
| 398 options.revision = revision_overrides.get(self.name) | 399 options.revision = revision_overrides.get(self.name) |
| 399 maybeGetParentRevision(options) | 400 maybeGetParentRevision(options) |
| 400 scm = gclient_scm.CreateSCM(self.parsed_url, self.root_dir(), self.name) | 401 scm = gclient_scm.CreateSCM(self.parsed_url, self.root_dir(), self.name) |
|
M-A Ruel
2011/08/28 13:03:31
I'd modify it here instead. I'd probably make a me
nsylvain
2011/08/29 18:03:58
I'll look into this
| |
| 401 scm.RunCommand(command, options, args, self._file_list) | 402 scm.RunCommand(command, options, args, self._file_list) |
| 402 maybeConvertToDateRevision(options) | 403 maybeConvertToDateRevision(options) |
| 403 self._file_list = [os.path.join(self.name, f.strip()) | 404 self._file_list = [os.path.join(self.name, f.strip()) |
| 404 for f in self._file_list] | 405 for f in self._file_list] |
| 405 self.processed = True | 406 self.processed = True |
| 406 if self.recursion_limit() > 0: | 407 if self.recursion_limit() > 0: |
| 407 # Then we can parse the DEPS file. | 408 # Then we can parse the DEPS file. |
| 408 self.ParseDepsFile() | 409 self.ParseDepsFile() |
| 409 # Adjust the implicit dependency requirement; e.g. if a DEPS file contains | 410 # Adjust the implicit dependency requirement; e.g. if a DEPS file contains |
| 410 # both src/foo and src/foo/bar, src/foo/bar is implicitly dependent of | 411 # both src/foo and src/foo/bar, src/foo/bar is implicitly dependent of |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 "linux": "unix", | 581 "linux": "unix", |
| 581 "linux2": "unix", | 582 "linux2": "unix", |
| 582 "linux3": "unix", | 583 "linux3": "unix", |
| 583 } | 584 } |
| 584 | 585 |
| 585 DEFAULT_CLIENT_FILE_TEXT = ("""\ | 586 DEFAULT_CLIENT_FILE_TEXT = ("""\ |
| 586 solutions = [ | 587 solutions = [ |
| 587 { "name" : "%(solution_name)s", | 588 { "name" : "%(solution_name)s", |
| 588 "url" : "%(solution_url)s", | 589 "url" : "%(solution_url)s", |
| 589 "deps_file" : "%(deps_file)s", | 590 "deps_file" : "%(deps_file)s", |
| 591 "managed" : %(managed)s, | |
| 590 "custom_deps" : { | 592 "custom_deps" : { |
| 591 }, | 593 }, |
| 592 "safesync_url": "%(safesync_url)s", | 594 "safesync_url": "%(safesync_url)s", |
| 593 }, | 595 }, |
| 594 ] | 596 ] |
| 595 """) | 597 """) |
| 596 | 598 |
| 597 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ | 599 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ |
| 598 { "name" : "%(solution_name)s", | 600 { "name" : "%(solution_name)s", |
| 599 "url" : "%(solution_url)s", | 601 "url" : "%(solution_url)s", |
| 600 "deps_file" : "%(deps_file)s", | 602 "deps_file" : "%(deps_file)s", |
| 603 "managed" : %(managed)s, | |
| 601 "custom_deps" : { | 604 "custom_deps" : { |
| 602 %(solution_deps)s }, | 605 %(solution_deps)s }, |
| 603 "safesync_url": "%(safesync_url)s", | 606 "safesync_url": "%(safesync_url)s", |
| 604 }, | 607 }, |
| 605 """) | 608 """) |
| 606 | 609 |
| 607 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ | 610 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ |
| 608 # Snapshot generated with gclient revinfo --snapshot | 611 # Snapshot generated with gclient revinfo --snapshot |
| 609 solutions = [ | 612 solutions = [ |
| 610 %(solution_list)s] | 613 %(solution_list)s] |
| 611 """) | 614 """) |
| 612 | 615 |
| 613 def __init__(self, root_dir, options): | 616 def __init__(self, root_dir, options): |
| 614 # Do not change previous behavior. Only solution level and immediate DEPS | 617 # Do not change previous behavior. Only solution level and immediate DEPS |
| 615 # are processed. | 618 # are processed. |
| 616 self._recursion_limit = 2 | 619 self._recursion_limit = 2 |
| 617 Dependency.__init__(self, None, None, None, None, None, None, 'unused', | 620 Dependency.__init__(self, None, None, None, None, None, None, None, |
| 618 True) | 621 'unused', True) |
| 619 self._options = options | 622 self._options = options |
| 620 if options.deps_os: | 623 if options.deps_os: |
| 621 enforced_os = options.deps_os.split(',') | 624 enforced_os = options.deps_os.split(',') |
| 622 else: | 625 else: |
| 623 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] | 626 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] |
| 624 if 'all' in enforced_os: | 627 if 'all' in enforced_os: |
| 625 enforced_os = self.DEPS_OS_CHOICES.itervalues() | 628 enforced_os = self.DEPS_OS_CHOICES.itervalues() |
| 626 self._enforced_os = list(set(enforced_os)) | 629 self._enforced_os = list(set(enforced_os)) |
| 627 self._root_dir = root_dir | 630 self._root_dir = root_dir |
| 628 self.config_content = None | 631 self.config_content = None |
| 629 | 632 |
| 630 def SetConfig(self, content): | 633 def SetConfig(self, content): |
| 631 assert self.dependencies == [] | 634 assert self.dependencies == [] |
| 632 config_dict = {} | 635 config_dict = {} |
| 633 self.config_content = content | 636 self.config_content = content |
| 634 try: | 637 try: |
| 635 exec(content, config_dict) | 638 exec(content, config_dict) |
| 636 except SyntaxError, e: | 639 except SyntaxError, e: |
| 637 gclient_utils.SyntaxErrorToError('.gclient', e) | 640 gclient_utils.SyntaxErrorToError('.gclient', e) |
| 638 for s in config_dict.get('solutions', []): | 641 for s in config_dict.get('solutions', []): |
| 639 try: | 642 try: |
| 640 tree = dict((d.name, d) for d in self.tree(False)) | 643 tree = dict((d.name, d) for d in self.tree(False)) |
| 641 if s['name'] in tree: | 644 if s['name'] in tree: |
| 642 raise gclient_utils.Error( | 645 raise gclient_utils.Error( |
| 643 'Dependency %s specified more than once in .gclient' % s['name']) | 646 'Dependency %s specified more than once in .gclient' % s['name']) |
| 644 self.dependencies.append(Dependency( | 647 self.dependencies.append(Dependency( |
| 645 self, s['name'], s['url'], | 648 self, s['name'], s['url'], |
| 646 s.get('safesync_url', None), | 649 s.get('safesync_url', None), |
| 650 s.get('managed', True), | |
| 647 s.get('custom_deps', {}), | 651 s.get('custom_deps', {}), |
| 648 s.get('custom_vars', {}), | 652 s.get('custom_vars', {}), |
| 649 s.get('deps_file', 'DEPS'), | 653 s.get('deps_file', 'DEPS'), |
| 650 True)) | 654 True)) |
| 651 except KeyError: | 655 except KeyError: |
| 652 raise gclient_utils.Error('Invalid .gclient file. Solution is ' | 656 raise gclient_utils.Error('Invalid .gclient file. Solution is ' |
| 653 'incomplete: %s' % s) | 657 'incomplete: %s' % s) |
| 654 # .gclient can have hooks. | 658 # .gclient can have hooks. |
| 655 self.deps_hooks = config_dict.get('hooks', []) | 659 self.deps_hooks = config_dict.get('hooks', []) |
| 656 self.deps_parsed = True | 660 self.deps_parsed = True |
| 657 | 661 |
| 658 def SaveConfig(self): | 662 def SaveConfig(self): |
| 659 gclient_utils.FileWrite(os.path.join(self.root_dir(), | 663 gclient_utils.FileWrite(os.path.join(self.root_dir(), |
| 660 self._options.config_filename), | 664 self._options.config_filename), |
| 661 self.config_content) | 665 self.config_content) |
| 662 | 666 |
| 663 @staticmethod | 667 @staticmethod |
| 664 def LoadCurrentConfig(options): | 668 def LoadCurrentConfig(options): |
| 665 """Searches for and loads a .gclient file relative to the current working | 669 """Searches for and loads a .gclient file relative to the current working |
| 666 dir. Returns a GClient object.""" | 670 dir. Returns a GClient object.""" |
| 667 path = gclient_utils.FindGclientRoot(os.getcwd(), options.config_filename) | 671 path = gclient_utils.FindGclientRoot(os.getcwd(), options.config_filename) |
| 668 if not path: | 672 if not path: |
| 669 return None | 673 return None |
| 670 client = GClient(path, options) | 674 client = GClient(path, options) |
| 671 client.SetConfig(gclient_utils.FileRead( | 675 client.SetConfig(gclient_utils.FileRead( |
| 672 os.path.join(path, options.config_filename))) | 676 os.path.join(path, options.config_filename))) |
| 673 return client | 677 return client |
| 674 | 678 |
| 675 def SetDefaultConfig(self, solution_name, deps_file, solution_url, | 679 def SetDefaultConfig(self, solution_name, deps_file, solution_url, |
| 676 safesync_url): | 680 safesync_url, managed): |
| 677 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { | 681 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { |
| 678 'solution_name': solution_name, | 682 'solution_name': solution_name, |
| 679 'solution_url': solution_url, | 683 'solution_url': solution_url, |
| 680 'deps_file': deps_file, | 684 'deps_file': deps_file, |
| 681 'safesync_url' : safesync_url, | 685 'safesync_url' : safesync_url, |
| 686 'managed': managed, | |
| 682 }) | 687 }) |
| 683 | 688 |
| 684 def _SaveEntries(self): | 689 def _SaveEntries(self): |
| 685 """Creates a .gclient_entries file to record the list of unique checkouts. | 690 """Creates a .gclient_entries file to record the list of unique checkouts. |
| 686 | 691 |
| 687 The .gclient_entries file lives in the same directory as .gclient. | 692 The .gclient_entries file lives in the same directory as .gclient. |
| 688 """ | 693 """ |
| 689 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It | 694 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It |
| 690 # makes testing a bit too fun. | 695 # makes testing a bit too fun. |
| 691 result = 'entries = {\n' | 696 result = 'entries = {\n' |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 717 return scope['entries'] | 722 return scope['entries'] |
| 718 | 723 |
| 719 def _EnforceRevisions(self): | 724 def _EnforceRevisions(self): |
| 720 """Checks for revision overrides.""" | 725 """Checks for revision overrides.""" |
| 721 revision_overrides = {} | 726 revision_overrides = {} |
| 722 if self._options.head: | 727 if self._options.head: |
| 723 return revision_overrides | 728 return revision_overrides |
| 724 # Do not check safesync_url if one or more --revision flag is specified. | 729 # Do not check safesync_url if one or more --revision flag is specified. |
| 725 if not self._options.revisions: | 730 if not self._options.revisions: |
| 726 for s in self.dependencies: | 731 for s in self.dependencies: |
| 727 if not s.safesync_url: | 732 if not s.managed: |
| 728 continue | 733 self._options.revisions.append('%s@unmanaged' % s.name) |
| 729 handle = urllib.urlopen(s.safesync_url) | 734 elif s.safesync_url: |
| 730 rev = handle.read().strip() | 735 handle = urllib.urlopen(s.safesync_url) |
| 731 handle.close() | 736 rev = handle.read().strip() |
| 732 if len(rev): | 737 handle.close() |
| 733 self._options.revisions.append('%s@%s' % (s.name, rev)) | 738 if len(rev): |
| 739 self._options.revisions.append('%s@%s' % (s.name, rev)) | |
| 734 if not self._options.revisions: | 740 if not self._options.revisions: |
| 735 return revision_overrides | 741 return revision_overrides |
| 736 solutions_names = [s.name for s in self.dependencies] | 742 solutions_names = [s.name for s in self.dependencies] |
| 737 index = 0 | 743 index = 0 |
| 738 for revision in self._options.revisions: | 744 for revision in self._options.revisions: |
| 739 if not '@' in revision: | 745 if not '@' in revision: |
| 740 # Support for --revision 123 | 746 # Support for --revision 123 |
| 741 revision = '%s@%s' % (solutions_names[index], revision) | 747 revision = '%s@%s' % (solutions_names[index], revision) |
| 742 sol, rev = revision.split('@', 1) | 748 sol, rev = revision.split('@', 1) |
| 743 if not sol in solutions_names: | 749 if not sol in solutions_names: |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 847 if entries[k]: | 853 if entries[k]: |
| 848 # Quotes aren't escaped... | 854 # Quotes aren't escaped... |
| 849 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) | 855 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) |
| 850 else: | 856 else: |
| 851 custom_deps.append(' \"%s\": None,\n' % k) | 857 custom_deps.append(' \"%s\": None,\n' % k) |
| 852 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { | 858 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { |
| 853 'solution_name': d.name, | 859 'solution_name': d.name, |
| 854 'solution_url': d.url, | 860 'solution_url': d.url, |
| 855 'deps_file': d.deps_file, | 861 'deps_file': d.deps_file, |
| 856 'safesync_url' : d.safesync_url or '', | 862 'safesync_url' : d.safesync_url or '', |
| 863 'managed': d.managed, | |
| 857 'solution_deps': ''.join(custom_deps), | 864 'solution_deps': ''.join(custom_deps), |
| 858 } | 865 } |
| 859 # Print the snapshot configuration file | 866 # Print the snapshot configuration file |
| 860 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) | 867 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) |
| 861 else: | 868 else: |
| 862 entries = {} | 869 entries = {} |
| 863 for d in self.tree(False): | 870 for d in self.tree(False): |
| 864 if self._options.actual: | 871 if self._options.actual: |
| 865 entries[d.name] = GetURLAndRev(d) | 872 entries[d.name] = GetURLAndRev(d) |
| 866 else: | 873 else: |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 967 """ | 974 """ |
| 968 parser.add_option('--spec', | 975 parser.add_option('--spec', |
| 969 help='create a gclient file containing the provided ' | 976 help='create a gclient file containing the provided ' |
| 970 'string. Due to Cygwin/Python brokenness, it ' | 977 'string. Due to Cygwin/Python brokenness, it ' |
| 971 'probably can\'t contain any newlines.') | 978 'probably can\'t contain any newlines.') |
| 972 parser.add_option('--name', | 979 parser.add_option('--name', |
| 973 help='overrides the default name for the solution') | 980 help='overrides the default name for the solution') |
| 974 parser.add_option('--deps-file', default='DEPS', | 981 parser.add_option('--deps-file', default='DEPS', |
| 975 help='overrides the default name for the DEPS file for the' | 982 help='overrides the default name for the DEPS file for the' |
| 976 'main solutions and all sub-dependencies') | 983 'main solutions and all sub-dependencies') |
| 984 parser.add_option('--unmanaged', action='store_true', | |
|
M-A Ruel
2011/08/28 13:03:31
Why add the flag if it's accessible from .gclient?
nsylvain
2011/08/29 18:03:58
because it's user friendly? Same reason we have --
Dirk Pranke
2011/08/29 20:56:13
It's unclear to me if both of these options are ne
| |
| 985 help='overrides the default behavior to make it possible to' | |
| 986 'have the main solution untouched by gclient') | |
| 977 parser.add_option('--git-deps', action='store_true', | 987 parser.add_option('--git-deps', action='store_true', |
| 978 help='sets the deps file to ".DEPS.git" instead of "DEPS"') | 988 help='sets the deps file to ".DEPS.git" instead of "DEPS"') |
| 979 (options, args) = parser.parse_args(args) | 989 (options, args) = parser.parse_args(args) |
| 980 if ((options.spec and args) or len(args) > 2 or | 990 if ((options.spec and args) or len(args) > 2 or |
| 981 (not options.spec and not args)): | 991 (not options.spec and not args)): |
| 982 parser.error('Inconsistent arguments. Use either --spec or one or 2 args') | 992 parser.error('Inconsistent arguments. Use either --spec or one or 2 args') |
| 983 | 993 |
| 984 client = GClient('.', options) | 994 client = GClient('.', options) |
| 985 if options.spec: | 995 if options.spec: |
| 986 client.SetConfig(options.spec) | 996 client.SetConfig(options.spec) |
| 987 else: | 997 else: |
| 988 base_url = args[0].rstrip('/') | 998 base_url = args[0].rstrip('/') |
| 989 if not options.name: | 999 if not options.name: |
| 990 name = base_url.split('/')[-1] | 1000 name = base_url.split('/')[-1] |
| 991 if name.endswith('.git'): | 1001 if name.endswith('.git'): |
| 992 name = name[:-4] | 1002 name = name[:-4] |
| 993 else: | 1003 else: |
| 994 # specify an alternate relpath for the given URL. | 1004 # specify an alternate relpath for the given URL. |
| 995 name = options.name | 1005 name = options.name |
| 996 deps_file = options.deps_file | 1006 deps_file = options.deps_file |
| 997 if options.git_deps: | 1007 if options.git_deps: |
| 998 deps_file = '.DEPS.git' | 1008 deps_file = '.DEPS.git' |
| 1009 managed = True | |
| 1010 if options.unmanaged: | |
| 1011 managed = False | |
| 999 safesync_url = '' | 1012 safesync_url = '' |
| 1000 if len(args) > 1: | 1013 if len(args) > 1: |
| 1001 safesync_url = args[1] | 1014 safesync_url = args[1] |
| 1002 client.SetDefaultConfig(name, deps_file, base_url, safesync_url) | 1015 client.SetDefaultConfig(name, deps_file, base_url, safesync_url, managed) |
| 1003 client.SaveConfig() | 1016 client.SaveConfig() |
| 1004 return 0 | 1017 return 0 |
| 1005 | 1018 |
| 1006 | 1019 |
| 1007 @attr('epilog', """Example: | 1020 @attr('epilog', """Example: |
| 1008 gclient pack > patch.txt | 1021 gclient pack > patch.txt |
| 1009 generate simple patch for configured client and dependences | 1022 generate simple patch for configured client and dependences |
| 1010 """) | 1023 """) |
| 1011 def CMDpack(parser, args): | 1024 def CMDpack(parser, args): |
| 1012 """Generate a patch which can be applied at the root of the tree. | 1025 """Generate a patch which can be applied at the root of the tree. |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1308 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 1321 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
| 1309 print >> sys.stderr, 'Error: %s' % str(e) | 1322 print >> sys.stderr, 'Error: %s' % str(e) |
| 1310 return 1 | 1323 return 1 |
| 1311 | 1324 |
| 1312 | 1325 |
| 1313 if '__main__' == __name__: | 1326 if '__main__' == __name__: |
| 1314 fix_encoding.fix_encoding() | 1327 fix_encoding.fix_encoding() |
| 1315 sys.exit(Main(sys.argv[1:])) | 1328 sys.exit(Main(sys.argv[1:])) |
| 1316 | 1329 |
| 1317 # vim: ts=2:sw=2:tw=80:et: | 1330 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |