| 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 # Warning: this function can be called from any thread. Both | 144 # Warning: this function can be called from any thread. Both |
| 145 # self.dependencies and self.requirements are read and modified from | 145 # self.dependencies and self.requirements are read and modified from |
| 146 # multiple threads at the same time. Sad. | 146 # multiple threads at the same time. Sad. |
| 147 GClientKeywords.__init__(self) | 147 GClientKeywords.__init__(self) |
| 148 gclient_utils.WorkItem.__init__(self, name) | 148 gclient_utils.WorkItem.__init__(self, name) |
| 149 | 149 |
| 150 # These are not mutable: | 150 # These are not mutable: |
| 151 self._parent = parent | 151 self._parent = parent |
| 152 self._safesync_url = safesync_url | 152 self._safesync_url = safesync_url |
| 153 self._deps_file = deps_file | 153 self._deps_file = deps_file |
| 154 self._should_process = should_process | 154 self._should_process = should_process |
| 155 | 155 |
| 156 # This is in both .gclient and DEPS files: | 156 # This is in both .gclient and DEPS files: |
| 157 self.url = url | 157 self.url = url |
| 158 | 158 |
| 159 # These are only set in .gclient and not in DEPS files. | 159 # These are only set in .gclient and not in DEPS files. |
| 160 # 'managed' determines whether or not this dependency is synced/updated by |
| 161 # gclient after gclient checks it out initially. The difference between |
| 162 # 'managed' and 'should_process' (defined below) is that the user specifies |
| 163 # 'managed' via the --unmanaged command-line flag or a .gclient config, |
| 164 # where 'should_process' is dynamically set by gclient if it goes over its |
| 165 # recursion limit and controls gclient's behavior so it does not misbehave. |
| 166 self.managed = managed |
| 160 self.custom_vars = custom_vars or {} | 167 self.custom_vars = custom_vars or {} |
| 161 self.custom_deps = custom_deps or {} | 168 self.custom_deps = custom_deps or {} |
| 162 self.deps_hooks = [] | 169 self.deps_hooks = [] |
| 163 | 170 |
| 164 # Calculates properties: | 171 # Calculates properties: |
| 165 self.parsed_url = None | 172 self.parsed_url = None |
| 166 self.dependencies = [] | 173 self.dependencies = [] |
| 167 # A cache of the files affected by the current operation, necessary for | 174 # A cache of the files affected by the current operation, necessary for |
| 168 # hooks. | 175 # hooks. |
| 169 self._file_list = [] | 176 self._file_list = [] |
| (...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 395 logging.info('Won\'t process duplicate dependency %s' % tree[name]) | 402 logging.info('Won\'t process duplicate dependency %s' % tree[name]) |
| 396 # In theory we could keep it as a shadow of the other one. In | 403 # In theory we could keep it as a shadow of the other one. In |
| 397 # practice, simply ignore it. | 404 # practice, simply ignore it. |
| 398 #should_process = False | 405 #should_process = False |
| 399 continue | 406 continue |
| 400 else: | 407 else: |
| 401 raise gclient_utils.Error( | 408 raise gclient_utils.Error( |
| 402 'Dependency %s specified more than once:\n %s\nvs\n %s' % | 409 'Dependency %s specified more than once:\n %s\nvs\n %s' % |
| 403 (name, tree[name].hierarchy(), self.hierarchy())) | 410 (name, tree[name].hierarchy(), self.hierarchy())) |
| 404 self.dependencies.append(Dependency(self, name, url, None, None, None, | 411 self.dependencies.append(Dependency(self, name, url, None, None, None, |
| 405 self.deps_file, should_process)) | 412 None, self.deps_file, should_process)) |
| 406 logging.debug('Loaded: %s' % str(self)) | 413 logging.debug('Loaded: %s' % str(self)) |
| 407 | 414 |
| 408 # Arguments number differs from overridden method | 415 # Arguments number differs from overridden method |
| 409 # pylint: disable=W0221 | 416 # pylint: disable=W0221 |
| 410 def run(self, revision_overrides, command, args, work_queue, options): | 417 def run(self, revision_overrides, command, args, work_queue, options): |
| 411 """Runs 'command' before parsing the DEPS in case it's a initial checkout | 418 """Runs 'command' before parsing the DEPS in case it's a initial checkout |
| 412 or a revert.""" | 419 or a revert.""" |
| 413 | 420 |
| 414 def maybeGetParentRevision(options): | 421 def maybeGetParentRevision(options): |
| 415 """If we are performing an update and --transitive is set, set the | 422 """If we are performing an update and --transitive is set, set the |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 "linux": "unix", | 662 "linux": "unix", |
| 656 "linux2": "unix", | 663 "linux2": "unix", |
| 657 "linux3": "unix", | 664 "linux3": "unix", |
| 658 } | 665 } |
| 659 | 666 |
| 660 DEFAULT_CLIENT_FILE_TEXT = ("""\ | 667 DEFAULT_CLIENT_FILE_TEXT = ("""\ |
| 661 solutions = [ | 668 solutions = [ |
| 662 { "name" : "%(solution_name)s", | 669 { "name" : "%(solution_name)s", |
| 663 "url" : "%(solution_url)s", | 670 "url" : "%(solution_url)s", |
| 664 "deps_file" : "%(deps_file)s", | 671 "deps_file" : "%(deps_file)s", |
| 672 "managed" : %(managed)s, |
| 665 "custom_deps" : { | 673 "custom_deps" : { |
| 666 }, | 674 }, |
| 667 "safesync_url": "%(safesync_url)s", | 675 "safesync_url": "%(safesync_url)s", |
| 668 }, | 676 }, |
| 669 ] | 677 ] |
| 670 """) | 678 """) |
| 671 | 679 |
| 672 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ | 680 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ |
| 673 { "name" : "%(solution_name)s", | 681 { "name" : "%(solution_name)s", |
| 674 "url" : "%(solution_url)s", | 682 "url" : "%(solution_url)s", |
| 675 "deps_file" : "%(deps_file)s", | 683 "deps_file" : "%(deps_file)s", |
| 684 "managed" : %(managed)s, |
| 676 "custom_deps" : { | 685 "custom_deps" : { |
| 677 %(solution_deps)s }, | 686 %(solution_deps)s }, |
| 678 "safesync_url": "%(safesync_url)s", | 687 "safesync_url": "%(safesync_url)s", |
| 679 }, | 688 }, |
| 680 """) | 689 """) |
| 681 | 690 |
| 682 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ | 691 DEFAULT_SNAPSHOT_FILE_TEXT = ("""\ |
| 683 # Snapshot generated with gclient revinfo --snapshot | 692 # Snapshot generated with gclient revinfo --snapshot |
| 684 solutions = [ | 693 solutions = [ |
| 685 %(solution_list)s] | 694 %(solution_list)s] |
| 686 """) | 695 """) |
| 687 | 696 |
| 688 def __init__(self, root_dir, options): | 697 def __init__(self, root_dir, options): |
| 689 # Do not change previous behavior. Only solution level and immediate DEPS | 698 # Do not change previous behavior. Only solution level and immediate DEPS |
| 690 # are processed. | 699 # are processed. |
| 691 self._recursion_limit = 2 | 700 self._recursion_limit = 2 |
| 692 Dependency.__init__(self, None, None, None, None, None, None, 'unused', | 701 Dependency.__init__(self, None, None, None, None, True, None, None, |
| 693 True) | 702 'unused', True) |
| 694 self._options = options | 703 self._options = options |
| 695 if options.deps_os: | 704 if options.deps_os: |
| 696 enforced_os = options.deps_os.split(',') | 705 enforced_os = options.deps_os.split(',') |
| 697 else: | 706 else: |
| 698 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] | 707 enforced_os = [self.DEPS_OS_CHOICES.get(sys.platform, 'unix')] |
| 699 if 'all' in enforced_os: | 708 if 'all' in enforced_os: |
| 700 enforced_os = self.DEPS_OS_CHOICES.itervalues() | 709 enforced_os = self.DEPS_OS_CHOICES.itervalues() |
| 701 self._enforced_os = tuple(set(enforced_os)) | 710 self._enforced_os = tuple(set(enforced_os)) |
| 702 self._root_dir = root_dir | 711 self._root_dir = root_dir |
| 703 self.config_content = None | 712 self.config_content = None |
| 704 | 713 |
| 705 def SetConfig(self, content): | 714 def SetConfig(self, content): |
| 706 assert self.dependencies == [] | 715 assert self.dependencies == [] |
| 707 config_dict = {} | 716 config_dict = {} |
| 708 self.config_content = content | 717 self.config_content = content |
| 709 try: | 718 try: |
| 710 exec(content, config_dict) | 719 exec(content, config_dict) |
| 711 except SyntaxError, e: | 720 except SyntaxError, e: |
| 712 gclient_utils.SyntaxErrorToError('.gclient', e) | 721 gclient_utils.SyntaxErrorToError('.gclient', e) |
| 713 for s in config_dict.get('solutions', []): | 722 for s in config_dict.get('solutions', []): |
| 714 try: | 723 try: |
| 715 tree = dict((d.name, d) for d in self.root.subtree(False)) | 724 tree = dict((d.name, d) for d in self.root.subtree(False)) |
| 716 if s['name'] in tree: | 725 if s['name'] in tree: |
| 717 raise gclient_utils.Error( | 726 raise gclient_utils.Error( |
| 718 'Dependency %s specified more than once in .gclient' % s['name']) | 727 'Dependency %s specified more than once in .gclient' % s['name']) |
| 719 self.dependencies.append(Dependency( | 728 self.dependencies.append(Dependency( |
| 720 self, s['name'], s['url'], | 729 self, s['name'], s['url'], |
| 721 s.get('safesync_url', None), | 730 s.get('safesync_url', None), |
| 731 s.get('managed', True), |
| 722 s.get('custom_deps', {}), | 732 s.get('custom_deps', {}), |
| 723 s.get('custom_vars', {}), | 733 s.get('custom_vars', {}), |
| 724 s.get('deps_file', 'DEPS'), | 734 s.get('deps_file', 'DEPS'), |
| 725 True)) | 735 True)) |
| 726 except KeyError: | 736 except KeyError: |
| 727 raise gclient_utils.Error('Invalid .gclient file. Solution is ' | 737 raise gclient_utils.Error('Invalid .gclient file. Solution is ' |
| 728 'incomplete: %s' % s) | 738 'incomplete: %s' % s) |
| 729 # .gclient can have hooks. | 739 # .gclient can have hooks. |
| 730 self.deps_hooks = config_dict.get('hooks', []) | 740 self.deps_hooks = config_dict.get('hooks', []) |
| 731 self.deps_parsed = True | 741 self.deps_parsed = True |
| 732 | 742 |
| 733 def SaveConfig(self): | 743 def SaveConfig(self): |
| 734 gclient_utils.FileWrite(os.path.join(self.root_dir, | 744 gclient_utils.FileWrite(os.path.join(self.root_dir, |
| 735 self._options.config_filename), | 745 self._options.config_filename), |
| 736 self.config_content) | 746 self.config_content) |
| 737 | 747 |
| 738 @staticmethod | 748 @staticmethod |
| 739 def LoadCurrentConfig(options): | 749 def LoadCurrentConfig(options): |
| 740 """Searches for and loads a .gclient file relative to the current working | 750 """Searches for and loads a .gclient file relative to the current working |
| 741 dir. Returns a GClient object.""" | 751 dir. Returns a GClient object.""" |
| 742 path = gclient_utils.FindGclientRoot(os.getcwd(), options.config_filename) | 752 path = gclient_utils.FindGclientRoot(os.getcwd(), options.config_filename) |
| 743 if not path: | 753 if not path: |
| 744 return None | 754 return None |
| 745 client = GClient(path, options) | 755 client = GClient(path, options) |
| 746 client.SetConfig(gclient_utils.FileRead( | 756 client.SetConfig(gclient_utils.FileRead( |
| 747 os.path.join(path, options.config_filename))) | 757 os.path.join(path, options.config_filename))) |
| 748 return client | 758 return client |
| 749 | 759 |
| 750 def SetDefaultConfig(self, solution_name, deps_file, solution_url, | 760 def SetDefaultConfig(self, solution_name, deps_file, solution_url, |
| 751 safesync_url): | 761 safesync_url, managed=True): |
| 752 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { | 762 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { |
| 753 'solution_name': solution_name, | 763 'solution_name': solution_name, |
| 754 'solution_url': solution_url, | 764 'solution_url': solution_url, |
| 755 'deps_file': deps_file, | 765 'deps_file': deps_file, |
| 756 'safesync_url' : safesync_url, | 766 'safesync_url' : safesync_url, |
| 767 'managed': managed, |
| 757 }) | 768 }) |
| 758 | 769 |
| 759 def _SaveEntries(self): | 770 def _SaveEntries(self): |
| 760 """Creates a .gclient_entries file to record the list of unique checkouts. | 771 """Creates a .gclient_entries file to record the list of unique checkouts. |
| 761 | 772 |
| 762 The .gclient_entries file lives in the same directory as .gclient. | 773 The .gclient_entries file lives in the same directory as .gclient. |
| 763 """ | 774 """ |
| 764 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It | 775 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It |
| 765 # makes testing a bit too fun. | 776 # makes testing a bit too fun. |
| 766 result = 'entries = {\n' | 777 result = 'entries = {\n' |
| (...skipping 25 matching lines...) Expand all Loading... |
| 792 return scope['entries'] | 803 return scope['entries'] |
| 793 | 804 |
| 794 def _EnforceRevisions(self): | 805 def _EnforceRevisions(self): |
| 795 """Checks for revision overrides.""" | 806 """Checks for revision overrides.""" |
| 796 revision_overrides = {} | 807 revision_overrides = {} |
| 797 if self._options.head: | 808 if self._options.head: |
| 798 return revision_overrides | 809 return revision_overrides |
| 799 # Do not check safesync_url if one or more --revision flag is specified. | 810 # Do not check safesync_url if one or more --revision flag is specified. |
| 800 if not self._options.revisions: | 811 if not self._options.revisions: |
| 801 for s in self.dependencies: | 812 for s in self.dependencies: |
| 802 if not s.safesync_url: | 813 if not s.managed: |
| 803 continue | 814 self._options.revisions.append('%s@unmanaged' % s.name) |
| 804 handle = urllib.urlopen(s.safesync_url) | 815 elif s.safesync_url: |
| 805 rev = handle.read().strip() | 816 handle = urllib.urlopen(s.safesync_url) |
| 806 handle.close() | 817 rev = handle.read().strip() |
| 807 if len(rev): | 818 handle.close() |
| 808 self._options.revisions.append('%s@%s' % (s.name, rev)) | 819 if len(rev): |
| 820 self._options.revisions.append('%s@%s' % (s.name, rev)) |
| 809 if not self._options.revisions: | 821 if not self._options.revisions: |
| 810 return revision_overrides | 822 return revision_overrides |
| 811 solutions_names = [s.name for s in self.dependencies] | 823 solutions_names = [s.name for s in self.dependencies] |
| 812 index = 0 | 824 index = 0 |
| 813 for revision in self._options.revisions: | 825 for revision in self._options.revisions: |
| 814 if not '@' in revision: | 826 if not '@' in revision: |
| 815 # Support for --revision 123 | 827 # Support for --revision 123 |
| 816 revision = '%s@%s' % (solutions_names[index], revision) | 828 revision = '%s@%s' % (solutions_names[index], revision) |
| 817 sol, rev = revision.split('@', 1) | 829 sol, rev = revision.split('@', 1) |
| 818 if not sol in solutions_names: | 830 if not sol in solutions_names: |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 922 if entries[k]: | 934 if entries[k]: |
| 923 # Quotes aren't escaped... | 935 # Quotes aren't escaped... |
| 924 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) | 936 custom_deps.append(' \"%s\": \'%s\',\n' % (k, entries[k])) |
| 925 else: | 937 else: |
| 926 custom_deps.append(' \"%s\": None,\n' % k) | 938 custom_deps.append(' \"%s\": None,\n' % k) |
| 927 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { | 939 new_gclient += self.DEFAULT_SNAPSHOT_SOLUTION_TEXT % { |
| 928 'solution_name': d.name, | 940 'solution_name': d.name, |
| 929 'solution_url': d.url, | 941 'solution_url': d.url, |
| 930 'deps_file': d.deps_file, | 942 'deps_file': d.deps_file, |
| 931 'safesync_url' : d.safesync_url or '', | 943 'safesync_url' : d.safesync_url or '', |
| 944 'managed': d.managed, |
| 932 'solution_deps': ''.join(custom_deps), | 945 'solution_deps': ''.join(custom_deps), |
| 933 } | 946 } |
| 934 # Print the snapshot configuration file | 947 # Print the snapshot configuration file |
| 935 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) | 948 print(self.DEFAULT_SNAPSHOT_FILE_TEXT % {'solution_list': new_gclient}) |
| 936 else: | 949 else: |
| 937 entries = {} | 950 entries = {} |
| 938 for d in self.root.subtree(False): | 951 for d in self.root.subtree(False): |
| 939 if self._options.actual: | 952 if self._options.actual: |
| 940 entries[d.name] = GetURLAndRev(d) | 953 entries[d.name] = GetURLAndRev(d) |
| 941 else: | 954 else: |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1041 """ | 1054 """ |
| 1042 parser.add_option('--spec', | 1055 parser.add_option('--spec', |
| 1043 help='create a gclient file containing the provided ' | 1056 help='create a gclient file containing the provided ' |
| 1044 'string. Due to Cygwin/Python brokenness, it ' | 1057 'string. Due to Cygwin/Python brokenness, it ' |
| 1045 'probably can\'t contain any newlines.') | 1058 'probably can\'t contain any newlines.') |
| 1046 parser.add_option('--name', | 1059 parser.add_option('--name', |
| 1047 help='overrides the default name for the solution') | 1060 help='overrides the default name for the solution') |
| 1048 parser.add_option('--deps-file', default='DEPS', | 1061 parser.add_option('--deps-file', default='DEPS', |
| 1049 help='overrides the default name for the DEPS file for the' | 1062 help='overrides the default name for the DEPS file for the' |
| 1050 'main solutions and all sub-dependencies') | 1063 'main solutions and all sub-dependencies') |
| 1064 parser.add_option('--unmanaged', action='store_true', default=False, |
| 1065 help='overrides the default behavior to make it possible ' |
| 1066 'to have the main solution untouched by gclient ' |
| 1067 '(gclient will check out unmanaged dependencies but ' |
| 1068 'will never sync them)') |
| 1051 parser.add_option('--git-deps', action='store_true', | 1069 parser.add_option('--git-deps', action='store_true', |
| 1052 help='sets the deps file to ".DEPS.git" instead of "DEPS"') | 1070 help='sets the deps file to ".DEPS.git" instead of "DEPS"') |
| 1053 (options, args) = parser.parse_args(args) | 1071 (options, args) = parser.parse_args(args) |
| 1054 if ((options.spec and args) or len(args) > 2 or | 1072 if ((options.spec and args) or len(args) > 2 or |
| 1055 (not options.spec and not args)): | 1073 (not options.spec and not args)): |
| 1056 parser.error('Inconsistent arguments. Use either --spec or one or 2 args') | 1074 parser.error('Inconsistent arguments. Use either --spec or one or 2 args') |
| 1057 | 1075 |
| 1058 client = GClient('.', options) | 1076 client = GClient('.', options) |
| 1059 if options.spec: | 1077 if options.spec: |
| 1060 client.SetConfig(options.spec) | 1078 client.SetConfig(options.spec) |
| 1061 else: | 1079 else: |
| 1062 base_url = args[0].rstrip('/') | 1080 base_url = args[0].rstrip('/') |
| 1063 if not options.name: | 1081 if not options.name: |
| 1064 name = base_url.split('/')[-1] | 1082 name = base_url.split('/')[-1] |
| 1065 if name.endswith('.git'): | 1083 if name.endswith('.git'): |
| 1066 name = name[:-4] | 1084 name = name[:-4] |
| 1067 else: | 1085 else: |
| 1068 # specify an alternate relpath for the given URL. | 1086 # specify an alternate relpath for the given URL. |
| 1069 name = options.name | 1087 name = options.name |
| 1070 deps_file = options.deps_file | 1088 deps_file = options.deps_file |
| 1071 if options.git_deps: | 1089 if options.git_deps: |
| 1072 deps_file = '.DEPS.git' | 1090 deps_file = '.DEPS.git' |
| 1073 safesync_url = '' | 1091 safesync_url = '' |
| 1074 if len(args) > 1: | 1092 if len(args) > 1: |
| 1075 safesync_url = args[1] | 1093 safesync_url = args[1] |
| 1076 client.SetDefaultConfig(name, deps_file, base_url, safesync_url) | 1094 client.SetDefaultConfig(name, deps_file, base_url, safesync_url, |
| 1095 managed=not options.unmanaged) |
| 1077 client.SaveConfig() | 1096 client.SaveConfig() |
| 1078 return 0 | 1097 return 0 |
| 1079 | 1098 |
| 1080 | 1099 |
| 1081 @attr('epilog', """Example: | 1100 @attr('epilog', """Example: |
| 1082 gclient pack > patch.txt | 1101 gclient pack > patch.txt |
| 1083 generate simple patch for configured client and dependences | 1102 generate simple patch for configured client and dependences |
| 1084 """) | 1103 """) |
| 1085 def CMDpack(parser, args): | 1104 def CMDpack(parser, args): |
| 1086 """Generate a patch which can be applied at the root of the tree. | 1105 """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... |
| 1382 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 1401 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
| 1383 print >> sys.stderr, 'Error: %s' % str(e) | 1402 print >> sys.stderr, 'Error: %s' % str(e) |
| 1384 return 1 | 1403 return 1 |
| 1385 | 1404 |
| 1386 | 1405 |
| 1387 if '__main__' == __name__: | 1406 if '__main__' == __name__: |
| 1388 fix_encoding.fix_encoding() | 1407 fix_encoding.fix_encoding() |
| 1389 sys.exit(Main(sys.argv[1:])) | 1408 sys.exit(Main(sys.argv[1:])) |
| 1390 | 1409 |
| 1391 # vim: ts=2:sw=2:tw=80:et: | 1410 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |