| 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 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 880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 891 solutions = [ | 891 solutions = [ |
| 892 { "name" : "%(solution_name)s", | 892 { "name" : "%(solution_name)s", |
| 893 "url" : "%(solution_url)s", | 893 "url" : "%(solution_url)s", |
| 894 "deps_file" : "%(deps_file)s", | 894 "deps_file" : "%(deps_file)s", |
| 895 "managed" : %(managed)s, | 895 "managed" : %(managed)s, |
| 896 "custom_deps" : { | 896 "custom_deps" : { |
| 897 }, | 897 }, |
| 898 "safesync_url": "%(safesync_url)s", | 898 "safesync_url": "%(safesync_url)s", |
| 899 }, | 899 }, |
| 900 ] | 900 ] |
| 901 cache_dir = %(cache_dir)r |
| 901 """) | 902 """) |
| 902 | 903 |
| 903 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ | 904 DEFAULT_SNAPSHOT_SOLUTION_TEXT = ("""\ |
| 904 { "name" : "%(solution_name)s", | 905 { "name" : "%(solution_name)s", |
| 905 "url" : "%(solution_url)s", | 906 "url" : "%(solution_url)s", |
| 906 "deps_file" : "%(deps_file)s", | 907 "deps_file" : "%(deps_file)s", |
| 907 "managed" : %(managed)s, | 908 "managed" : %(managed)s, |
| 908 "custom_deps" : { | 909 "custom_deps" : { |
| 909 %(solution_deps)s }, | 910 %(solution_deps)s }, |
| 910 "safesync_url": "%(safesync_url)s", | 911 "safesync_url": "%(safesync_url)s", |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 943 except SyntaxError, e: | 944 except SyntaxError, e: |
| 944 gclient_utils.SyntaxErrorToError('.gclient', e) | 945 gclient_utils.SyntaxErrorToError('.gclient', e) |
| 945 | 946 |
| 946 # Append any target OS that is not already being enforced to the tuple. | 947 # Append any target OS that is not already being enforced to the tuple. |
| 947 target_os = config_dict.get('target_os', []) | 948 target_os = config_dict.get('target_os', []) |
| 948 if config_dict.get('target_os_only', False): | 949 if config_dict.get('target_os_only', False): |
| 949 self._enforced_os = tuple(set(target_os)) | 950 self._enforced_os = tuple(set(target_os)) |
| 950 else: | 951 else: |
| 951 self._enforced_os = tuple(set(self._enforced_os).union(target_os)) | 952 self._enforced_os = tuple(set(self._enforced_os).union(target_os)) |
| 952 | 953 |
| 954 gclient_scm.GitWrapper.cache_dir = config_dict.get('cache_dir') |
| 955 |
| 953 if not target_os and config_dict.get('target_os_only', False): | 956 if not target_os and config_dict.get('target_os_only', False): |
| 954 raise gclient_utils.Error('Can\'t use target_os_only if target_os is ' | 957 raise gclient_utils.Error('Can\'t use target_os_only if target_os is ' |
| 955 'not specified') | 958 'not specified') |
| 956 | 959 |
| 957 deps_to_add = [] | 960 deps_to_add = [] |
| 958 for s in config_dict.get('solutions', []): | 961 for s in config_dict.get('solutions', []): |
| 959 try: | 962 try: |
| 960 deps_to_add.append(Dependency( | 963 deps_to_add.append(Dependency( |
| 961 self, s['name'], s['url'], | 964 self, s['name'], s['url'], |
| 962 s.get('safesync_url', None), | 965 s.get('safesync_url', None), |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 997 print >> sys.stderr, ( | 1000 print >> sys.stderr, ( |
| 998 'You must specify the full solution name like --revision %s@%s\n' | 1001 'You must specify the full solution name like --revision %s@%s\n' |
| 999 'when you have multiple solutions setup in your .gclient file.\n' | 1002 'when you have multiple solutions setup in your .gclient file.\n' |
| 1000 'Other solutions present are: %s.') % ( | 1003 'Other solutions present are: %s.') % ( |
| 1001 client.dependencies[0].name, | 1004 client.dependencies[0].name, |
| 1002 options.revisions[0], | 1005 options.revisions[0], |
| 1003 ', '.join(s.name for s in client.dependencies[1:])) | 1006 ', '.join(s.name for s in client.dependencies[1:])) |
| 1004 return client | 1007 return client |
| 1005 | 1008 |
| 1006 def SetDefaultConfig(self, solution_name, deps_file, solution_url, | 1009 def SetDefaultConfig(self, solution_name, deps_file, solution_url, |
| 1007 safesync_url, managed=True): | 1010 safesync_url, managed=True, cache_dir=None): |
| 1008 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { | 1011 self.SetConfig(self.DEFAULT_CLIENT_FILE_TEXT % { |
| 1009 'solution_name': solution_name, | 1012 'solution_name': solution_name, |
| 1010 'solution_url': solution_url, | 1013 'solution_url': solution_url, |
| 1011 'deps_file': deps_file, | 1014 'deps_file': deps_file, |
| 1012 'safesync_url' : safesync_url, | 1015 'safesync_url' : safesync_url, |
| 1013 'managed': managed, | 1016 'managed': managed, |
| 1017 'cache_dir': cache_dir, |
| 1014 }) | 1018 }) |
| 1015 | 1019 |
| 1016 def _SaveEntries(self): | 1020 def _SaveEntries(self): |
| 1017 """Creates a .gclient_entries file to record the list of unique checkouts. | 1021 """Creates a .gclient_entries file to record the list of unique checkouts. |
| 1018 | 1022 |
| 1019 The .gclient_entries file lives in the same directory as .gclient. | 1023 The .gclient_entries file lives in the same directory as .gclient. |
| 1020 """ | 1024 """ |
| 1021 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It | 1025 # Sometimes pprint.pformat will use {', sometimes it'll use { ' ... It |
| 1022 # makes testing a bit too fun. | 1026 # makes testing a bit too fun. |
| 1023 result = 'entries = {\n' | 1027 result = 'entries = {\n' |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1398 parser.add_option('--deps-file', default='DEPS', | 1402 parser.add_option('--deps-file', default='DEPS', |
| 1399 help='overrides the default name for the DEPS file for the' | 1403 help='overrides the default name for the DEPS file for the' |
| 1400 'main solutions and all sub-dependencies') | 1404 'main solutions and all sub-dependencies') |
| 1401 parser.add_option('--unmanaged', action='store_true', default=False, | 1405 parser.add_option('--unmanaged', action='store_true', default=False, |
| 1402 help='overrides the default behavior to make it possible ' | 1406 help='overrides the default behavior to make it possible ' |
| 1403 'to have the main solution untouched by gclient ' | 1407 'to have the main solution untouched by gclient ' |
| 1404 '(gclient will check out unmanaged dependencies but ' | 1408 '(gclient will check out unmanaged dependencies but ' |
| 1405 'will never sync them)') | 1409 'will never sync them)') |
| 1406 parser.add_option('--git-deps', action='store_true', | 1410 parser.add_option('--git-deps', action='store_true', |
| 1407 help='sets the deps file to ".DEPS.git" instead of "DEPS"') | 1411 help='sets the deps file to ".DEPS.git" instead of "DEPS"') |
| 1412 parser.add_option('--cache-dir', |
| 1413 help='(git only) Cache all git repos into this dir and do ' |
| 1414 'shared clones from the cache, instead of cloning ' |
| 1415 'directly from the remote. (experimental)') |
| 1408 parser.set_defaults(config_filename=None) | 1416 parser.set_defaults(config_filename=None) |
| 1409 (options, args) = parser.parse_args(args) | 1417 (options, args) = parser.parse_args(args) |
| 1410 if options.output_config_file: | 1418 if options.output_config_file: |
| 1411 setattr(options, 'config_filename', getattr(options, 'output_config_file')) | 1419 setattr(options, 'config_filename', getattr(options, 'output_config_file')) |
| 1412 if ((options.spec and args) or len(args) > 2 or | 1420 if ((options.spec and args) or len(args) > 2 or |
| 1413 (not options.spec and not args)): | 1421 (not options.spec and not args)): |
| 1414 parser.error('Inconsistent arguments. Use either --spec or one or 2 args') | 1422 parser.error('Inconsistent arguments. Use either --spec or one or 2 args') |
| 1415 | 1423 |
| 1416 client = GClient('.', options) | 1424 client = GClient('.', options) |
| 1417 if options.spec: | 1425 if options.spec: |
| 1418 client.SetConfig(options.spec) | 1426 client.SetConfig(options.spec) |
| 1419 else: | 1427 else: |
| 1420 base_url = args[0].rstrip('/') | 1428 base_url = args[0].rstrip('/') |
| 1421 if not options.name: | 1429 if not options.name: |
| 1422 name = base_url.split('/')[-1] | 1430 name = base_url.split('/')[-1] |
| 1423 if name.endswith('.git'): | 1431 if name.endswith('.git'): |
| 1424 name = name[:-4] | 1432 name = name[:-4] |
| 1425 else: | 1433 else: |
| 1426 # specify an alternate relpath for the given URL. | 1434 # specify an alternate relpath for the given URL. |
| 1427 name = options.name | 1435 name = options.name |
| 1428 deps_file = options.deps_file | 1436 deps_file = options.deps_file |
| 1429 if options.git_deps: | 1437 if options.git_deps: |
| 1430 deps_file = '.DEPS.git' | 1438 deps_file = '.DEPS.git' |
| 1431 safesync_url = '' | 1439 safesync_url = '' |
| 1432 if len(args) > 1: | 1440 if len(args) > 1: |
| 1433 safesync_url = args[1] | 1441 safesync_url = args[1] |
| 1434 client.SetDefaultConfig(name, deps_file, base_url, safesync_url, | 1442 client.SetDefaultConfig(name, deps_file, base_url, safesync_url, |
| 1435 managed=not options.unmanaged) | 1443 managed=not options.unmanaged, |
| 1444 cache_dir=options.cache_dir) |
| 1436 client.SaveConfig() | 1445 client.SaveConfig() |
| 1437 return 0 | 1446 return 0 |
| 1438 | 1447 |
| 1439 | 1448 |
| 1440 @attr('epilog', """Example: | 1449 @attr('epilog', """Example: |
| 1441 gclient pack > patch.txt | 1450 gclient pack > patch.txt |
| 1442 generate simple patch for configured client and dependences | 1451 generate simple patch for configured client and dependences |
| 1443 """) | 1452 """) |
| 1444 def CMDpack(parser, args): | 1453 def CMDpack(parser, args): |
| 1445 """Generate a patch which can be applied at the root of the tree. | 1454 """Generate a patch which can be applied at the root of the tree. |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1713 parser.add_option('--gclientfile', dest='config_filename', | 1722 parser.add_option('--gclientfile', dest='config_filename', |
| 1714 default=None, | 1723 default=None, |
| 1715 help='Specify an alternate %s file' % gclientfile_default) | 1724 help='Specify an alternate %s file' % gclientfile_default) |
| 1716 parser.add_option('--spec', | 1725 parser.add_option('--spec', |
| 1717 default=None, | 1726 default=None, |
| 1718 help='create a gclient file containing the provided ' | 1727 help='create a gclient file containing the provided ' |
| 1719 'string. Due to Cygwin/Python brokenness, it ' | 1728 'string. Due to Cygwin/Python brokenness, it ' |
| 1720 'probably can\'t contain any newlines.') | 1729 'probably can\'t contain any newlines.') |
| 1721 parser.add_option('--no-nag-max', default=False, action='store_true', | 1730 parser.add_option('--no-nag-max', default=False, action='store_true', |
| 1722 help='If a subprocess runs for too long without generating' | 1731 help='If a subprocess runs for too long without generating' |
| 1723 ' terminal output, generate warnings, but do not kill' | 1732 ' terminal output, generate warnings, but do not kill' |
| 1724 ' the process.') | 1733 ' the process.') |
| 1725 # Integrate standard options processing. | 1734 # Integrate standard options processing. |
| 1726 old_parser = parser.parse_args | 1735 old_parser = parser.parse_args |
| 1727 def Parse(args): | 1736 def Parse(args): |
| 1728 (options, args) = old_parser(args) | 1737 (options, args) = old_parser(args) |
| 1729 level = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ | 1738 level = [logging.ERROR, logging.WARNING, logging.INFO, logging.DEBUG][ |
| 1730 min(options.verbose, 3)] | 1739 min(options.verbose, 3)] |
| 1731 logging.basicConfig(level=level, | 1740 logging.basicConfig(level=level, |
| 1732 format='%(module)s(%(lineno)d) %(funcName)s:%(message)s') | 1741 format='%(module)s(%(lineno)d) %(funcName)s:%(message)s') |
| 1733 if options.config_filename and options.spec: | 1742 if options.config_filename and options.spec: |
| 1734 parser.error('Cannot specifiy both --gclientfile and --spec') | 1743 parser.error('Cannot specifiy both --gclientfile and --spec') |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 except (gclient_utils.Error, subprocess2.CalledProcessError), e: | 1816 except (gclient_utils.Error, subprocess2.CalledProcessError), e: |
| 1808 print >> sys.stderr, 'Error: %s' % str(e) | 1817 print >> sys.stderr, 'Error: %s' % str(e) |
| 1809 return 1 | 1818 return 1 |
| 1810 | 1819 |
| 1811 | 1820 |
| 1812 if '__main__' == __name__: | 1821 if '__main__' == __name__: |
| 1813 fix_encoding.fix_encoding() | 1822 fix_encoding.fix_encoding() |
| 1814 sys.exit(Main(sys.argv[1:])) | 1823 sys.exit(Main(sys.argv[1:])) |
| 1815 | 1824 |
| 1816 # vim: ts=2:sw=2:tw=80:et: | 1825 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |