Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(589)

Unified Diff: gclient.py

Issue 503563002: Auto-update .gclient files for git. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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]
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698