Index: gclient.py |
diff --git a/gclient.py b/gclient.py |
index 94a981d50248079d0e3fa5d6f7891b766125aa79..a92cce05c0426d817b7ed9bfe6a99b0c394ad7ae 100755 |
--- a/gclient.py |
+++ b/gclient.py |
@@ -78,6 +78,7 @@ |
__version__ = '0.7' |
+import ast |
import copy |
import json |
import logging |
@@ -103,6 +104,57 @@ import subcommand |
import subprocess2 |
from third_party import colorama |
+CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src.git' |
+ |
+ |
+def ast_dict_index(dnode, key): |
+ """Search an ast.Dict for the argument key, and return its index.""" |
+ idx = [i for i in range(len(dnode.keys)) if ( |
+ type(dnode.keys[i]) is ast.Str and dnode.keys[i].s == key)] |
+ if not idx: |
+ return -1 |
+ elif len(idx) > 1: |
+ raise gclient_utils.Error('Multiple dict entries with same key in AST') |
+ return idx[-1] |
+ |
+def ast2str(node, indent=0): |
+ """Return a pretty-printed rendition of an ast.Node.""" |
+ t = type(node) |
+ if t is ast.Module: |
+ return '\n'.join([ast2str(x, indent) for x in node.body]) |
+ elif t is ast.Assign: |
+ return ((' ' * indent) + |
+ ' = '.join([ast2str(x) for x in node.targets] + |
+ [ast2str(node.value, indent)]) + '\n') |
+ elif t is ast.Name: |
+ return node.id |
+ elif t is ast.List: |
+ if not node.elts: |
+ return '[]' |
+ elif len(node.elts) == 1: |
+ return '[' + ast2str(node.elts[0], indent) + ']' |
+ return ('[\n' + (' ' * (indent + 1)) + |
+ (',\n' + (' ' * (indent + 1))).join( |
+ [ast2str(x, indent + 1) for x in node.elts]) + |
+ '\n' + (' ' * indent) + ']') |
+ elif t is ast.Dict: |
+ if not node.keys: |
+ return '{}' |
+ elif len(node.keys) == 1: |
+ return '{%s: %s}' % (ast2str(node.keys[0]), |
+ ast2str(node.values[0], indent + 1)) |
+ return ('{\n' + (' ' * (indent + 1)) + |
+ (',\n' + (' ' * (indent + 1))).join( |
+ ['%s: %s' % (ast2str(node.keys[i]), |
+ ast2str(node.values[i], indent + 1)) |
+ for i in range(len(node.keys))]) + |
+ '\n' + (' ' * indent) + '}') |
+ elif t is ast.Str: |
+ return "'%s'" % node.s |
+ else: |
+ raise gclient_utils.Error("Unexpected AST node at line %d, column %d: %s" |
+ % (node.lineno, node.col_offset, t)) |
+ |
class GClientKeywords(object): |
class FromImpl(object): |
@@ -168,7 +220,10 @@ class DependencySettings(GClientKeywords): |
# These are not mutable: |
self._parent = parent |
self._safesync_url = safesync_url |
- self._deps_file = deps_file |
+ if url == CHROMIUM_SRC_URL: |
+ self._deps_file = 'DEPS' |
+ else: |
+ self._deps_file = deps_file |
self._url = url |
# 'managed' determines whether or not this dependency is synced/updated by |
# gclient after gclient checks it out initially. The difference between |
@@ -1196,6 +1251,79 @@ want to set 'managed': False in .gclient. |
self._options.config_filename), |
self.config_content) |
+ def MigrateConfigToGit(self, path, options): |
+ svn_url_re = re.compile('^(https?://src\.chromium\.org/svn|' |
+ 'svn://svn\.chromium\.org/chrome)/' |
+ '(trunk|branches/[^/]+)/src') |
+ old_git_re = re.compile('^(https?://git\.chromium\.org|' |
+ 'ssh://([a-zA-Z_][a-zA-Z0-9_-]*@)?' |
+ 'gerrit\.chromium\.org(:2941[89])?)/' |
+ 'chromium/src\.git') |
+ # Scan existing .gclient file for obsolete settings. It would be simpler |
+ # to traverse self.dependencies, but working with the AST allows the code to |
+ # dump an updated .gclient file that preserves the ordering of the original. |
+ a = ast.parse(self.config_content, options.config_filename, 'exec') |
+ modified = False |
+ solutions = [elem for elem in a.body if 'solutions' in |
+ [target.id for target in elem.targets]] |
+ if not solutions: |
+ return self |
+ solutions = solutions[-1] |
+ for solution in solutions.value.elts: |
+ # Check for obsolete URL's |
+ url_idx = ast_dict_index(solution, 'url') |
+ if url_idx == -1: |
+ continue |
+ url_val = solution.values[url_idx] |
+ if type(url_val) is not ast.Str: |
+ continue |
+ if (svn_url_re.match(url_val.s.strip())): |
+ raise gclient_utils.Error( |
+""" |
+The chromium code repository has migrated completely to git. |
+Your SVN-based checkout is now obsolete; you need to create a brand-new |
+git checkout by following these instructions: |
+ |
+http://www.chromium.org/developers/how-tos/get-the-code |
+""") |
+ if (old_git_re.match(url_val.s.strip())): |
+ url_val.s = CHROMIUM_SRC_URL |
+ modified = True |
+ |
+ # Check for obsolete deps_file |
+ if url_val.s == CHROMIUM_SRC_URL: |
+ deps_file_idx = ast_dict_index(solution, 'deps_file') |
+ if deps_file_idx == -1: |
+ continue |
+ deps_file_val = solution.values[deps_file_idx] |
+ if type(deps_file_val) is not ast.Str: |
+ continue |
+ if deps_file_val.s == '.DEPS.git': |
+ solution.keys[deps_file_idx:deps_file_idx + 1] = [] |
+ solution.values[deps_file_idx:deps_file_idx + 1] = [] |
+ modified = True |
+ |
+ if not modified: |
+ return self |
+ |
+ print( |
+""" |
+WARNING: gclient detected an obsolete setting in your %s file. The file has |
+been automagically updated. The previous version is available at %s.old. |
+""" % (options.config_filename, options.config_filename)) |
+ |
+ # Replace existing .gclient with the updated version. |
+ # Return a new GClient instance based on the new content. |
+ new_content = ast2str(a) |
+ dot_gclient_fn = os.path.join(path, options.config_filename) |
+ os.rename(dot_gclient_fn, dot_gclient_fn + '.old') |
+ fh = open(dot_gclient_fn, 'w') |
+ fh.write(new_content) |
+ fh.close() |
+ client = GClient(path, options) |
+ client.SetConfig(new_content) |
+ return client |
+ |
@staticmethod |
def LoadCurrentConfig(options): |
"""Searches for and loads a .gclient file relative to the current working |
@@ -1210,6 +1338,7 @@ want to set 'managed': False in .gclient. |
client = GClient(path, options) |
client.SetConfig(gclient_utils.FileRead( |
os.path.join(path, options.config_filename))) |
+ client = client.MigrateConfigToGit(path, options) |
if (options.revisions and |
len(client.dependencies) > 1 and |
@@ -1646,8 +1775,6 @@ def CMDconfig(parser, args): |
'to have the main solution untouched by gclient ' |
'(gclient will check out unmanaged dependencies but ' |
'will never sync them)') |
- parser.add_option('--git-deps', action='store_true', |
- help='sets the deps file to ".DEPS.git" instead of "DEPS"') |
parser.add_option('--cache-dir', |
help='(git only) Cache all git repos into this dir and do ' |
'shared clones from the cache, instead of cloning ' |
@@ -1673,8 +1800,6 @@ def CMDconfig(parser, args): |
# specify an alternate relpath for the given URL. |
name = options.name |
deps_file = options.deps_file |
- if options.git_deps: |
- deps_file = '.DEPS.git' |
safesync_url = '' |
if len(args) > 1: |
safesync_url = args[1] |