Skip to content

Commit

Permalink
Auto-update .gclient files for git.
Browse files Browse the repository at this point in the history
[email protected],[email protected]

Review URL: https://codereview.chromium.org/503563002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@291567 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
[email protected] committed Aug 23, 2014
1 parent beea0b0 commit 7b8b6de
Showing 1 changed file with 130 additions and 5 deletions.
135 changes: 130 additions & 5 deletions gclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@

__version__ = '0.7'

import ast
import copy
import json
import logging
Expand All @@ -103,6 +104,57 @@
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):
Expand Down Expand Up @@ -168,7 +220,10 @@ def __init__(
# 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
Expand Down Expand Up @@ -1196,6 +1251,79 @@ def SaveConfig(self):
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
Expand All @@ -1210,6 +1338,7 @@ def LoadCurrentConfig(options):
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
Expand Down Expand Up @@ -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 '
Expand All @@ -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]
Expand Down

0 comments on commit 7b8b6de

Please sign in to comment.