| Index: deps2git.py
|
| diff --git a/deps2git.py b/deps2git.py
|
| index f29e67c989715d640c65a38bb97abe9fcceba76a..2f64ba62fcb0fe1f4bdd33bf170bf95685abbfc6 100755
|
| --- a/deps2git.py
|
| +++ b/deps2git.py
|
| @@ -6,6 +6,7 @@
|
| """Convert SVN based DEPS into .DEPS.git for use with NewGit."""
|
|
|
| import collections
|
| +from cStringIO import StringIO
|
| import json
|
| import optparse
|
| import os
|
| @@ -13,14 +14,29 @@ import Queue
|
| import shutil
|
| import subprocess
|
| import sys
|
| +import threading
|
| import time
|
|
|
| -from multiprocessing.pool import ThreadPool
|
| -
|
| import deps_utils
|
| import git_tools
|
| import svn_to_git_public
|
|
|
| +try:
|
| + import git_cache
|
| +except ImportError:
|
| + for p in os.environ['PATH'].split(os.pathsep):
|
| + if (os.path.basename(p) == 'depot_tools' and
|
| + os.path.exists(os.path.join(p, 'git_cache.py'))):
|
| + sys.path.append(p)
|
| + import git_cache
|
| +
|
| +Job = collections.namedtuple(
|
| + 'Job',
|
| + ['dep', 'git_url', 'dep_url', 'path', 'git_host', 'dep_rev', 'svn_branch'])
|
| +
|
| +ConversionResults = collections.namedtuple(
|
| + 'ConversionResults',
|
| + ['new_deps', 'deps_vars', 'bad_git_urls', 'bad_dep_urls', 'bad_git_hash'])
|
|
|
| # This is copied from depot_tools/gclient.py
|
| DEPS_OS_CHOICES = {
|
| @@ -36,6 +52,7 @@ DEPS_OS_CHOICES = {
|
| "android": "android",
|
| }
|
|
|
| +
|
| def SplitScmUrl(url):
|
| """Given a repository, return a set containing the URL and the revision."""
|
| url_split = url.split('@')
|
| @@ -46,14 +63,15 @@ def SplitScmUrl(url):
|
| return (scm_url, scm_rev)
|
|
|
|
|
| -def SvnRevToGitHash(svn_rev, git_url, repos_path, workspace, dep_path,
|
| - git_host, svn_branch_name=None, cache_dir=None):
|
| +def SvnRevToGitHash(
|
| + svn_rev, git_url, repos_path, workspace, dep_path, git_host,
|
| + svn_branch_name=None, cache_dir=None, outbuf=None, shallow=None):
|
| """Convert a SVN revision to a Git commit id."""
|
| git_repo = None
|
| if git_url.startswith(git_host):
|
| git_repo = git_url.replace(git_host, '')
|
| else:
|
| - raise Exception('Unknown git server %s, host %s' % (git_url, git_host))
|
| + raise RuntimeError('Unknown git server %s, host %s' % (git_url, git_host))
|
| if repos_path is None and workspace is None and cache_dir is None:
|
| # We're running without a repository directory (i.e. no -r option).
|
| # We cannot actually find the commit id, but this mode is useful
|
| @@ -64,11 +82,10 @@ def SvnRevToGitHash(svn_rev, git_url, repos_path, workspace, dep_path,
|
| mirror = True
|
| git_repo_path = os.path.join(repos_path, git_repo)
|
| if not os.path.exists(git_repo_path) or not os.listdir(git_repo_path):
|
| - git_tools.Clone(git_url, git_repo_path, mirror)
|
| + git_tools.Clone(git_url, git_repo_path, mirror, outbuf)
|
| elif cache_dir:
|
| - mirror = 'bare'
|
| - git_tools.Clone(git_url, None, mirror, cache_dir=cache_dir)
|
| - git_repo_path = git_tools.GetCacheRepoDir(git_url, cache_dir)
|
| + mirror = True
|
| + git_repo_path = git_tools.PopulateCache(git_url, shallow)
|
| else:
|
| mirror = False
|
| git_repo_path = os.path.join(workspace, dep_path)
|
| @@ -84,7 +101,7 @@ def SvnRevToGitHash(svn_rev, git_url, repos_path, workspace, dep_path,
|
| else:
|
| shutil.rmtree(git_repo_path)
|
| if not os.path.exists(git_repo_path):
|
| - git_tools.Clone(git_url, git_repo_path, mirror)
|
| + git_tools.Clone(git_url, git_repo_path, mirror, outbuf)
|
|
|
| if svn_branch_name:
|
| # svn branches are mirrored with:
|
| @@ -102,110 +119,59 @@ def SvnRevToGitHash(svn_rev, git_url, repos_path, workspace, dep_path,
|
| # Work-around for:
|
| # http://code.google.com/p/chromium/issues/detail?id=362222
|
| if (git_url.startswith('https://chromium.googlesource.com/external/pefile')
|
| - and int(svn_rev) == 63):
|
| + and int(svn_rev) in (63, 141)):
|
| return '1ceaa279daa62b71e3431e58f68be6a96dd1519a'
|
|
|
| - try:
|
| - return git_tools.Search(git_repo_path, svn_rev, mirror, refspec, git_url)
|
| - except Exception:
|
| - print >> sys.stderr, '%s <-> ERROR' % git_repo_path
|
| - raise
|
| + return git_tools.Search(git_repo_path, svn_rev, mirror, refspec, git_url)
|
|
|
| -def ConvertDepsToGit(deps, options, deps_vars, svn_to_git_objs):
|
| - """Convert a 'deps' section in a DEPS file from SVN to Git."""
|
| - new_deps = {}
|
| - bad_git_urls = set([])
|
| - bad_dep_urls = []
|
| - bad_override = []
|
| - bad_git_hash = []
|
|
|
| - # Populate our deps list.
|
| - deps_to_process = {}
|
| - for dep, dep_url in deps.iteritems():
|
| - if not dep_url: # dep is 'None' and emitted to exclude the dep
|
| - new_deps[dep] = None
|
| +def MessageMain(message_q, threads):
|
| + while True:
|
| + try:
|
| + msg = message_q.get(True, 10)
|
| + except Queue.Empty:
|
| + print >> sys.stderr, 'Still working on:'
|
| + for s in sorted([th.working_on for th in threads if th.working_on]):
|
| + print >> sys.stderr, ' %s' % s
|
| continue
|
| + if msg is Queue.Empty:
|
| + return
|
| + if msg:
|
| + print >> sys.stderr, msg
|
|
|
| - # Get the URL and the revision/hash for this dependency.
|
| - dep_url, dep_rev = SplitScmUrl(deps[dep])
|
| -
|
| - path = dep
|
| - git_url = dep_url
|
| - svn_branch = None
|
| - git_host = dep_url
|
| -
|
| - if not dep_url.endswith('.git'):
|
| - # Convert this SVN URL to a Git URL.
|
| - for svn_git_converter in svn_to_git_objs:
|
| - converted_data = svn_git_converter.SvnUrlToGitUrl(dep, dep_url)
|
| - if converted_data:
|
| - path, git_url, git_host = converted_data[:3]
|
| - if len(converted_data) > 3:
|
| - svn_branch = converted_data[3]
|
| - break
|
| - else:
|
| - # Make all match failures fatal to catch errors early. When a match is
|
| - # found, we break out of the loop so the exception is not thrown.
|
| - if options.no_fail_fast:
|
| - bad_dep_urls.append(dep_url)
|
| - continue
|
| - raise Exception('No match found for %s' % dep_url)
|
| -
|
| - Job = collections.namedtuple('Job', ['git_url', 'dep_url', 'path',
|
| - 'git_host', 'dep_rev', 'svn_branch'])
|
| - deps_to_process[dep] = Job(
|
| - git_url, dep_url, path, git_host, dep_rev, svn_branch)
|
|
|
| - # Lets pre-cache all of the git repos now if we have cache_dir turned on.
|
| - if options.cache_dir:
|
| - if not os.path.isdir(options.cache_dir):
|
| - os.makedirs(options.cache_dir)
|
| - pool = ThreadPool(processes=len(deps_to_process))
|
| - output_queue = Queue.Queue()
|
| - num_threads = 0
|
| - for git_url, _, _, _, _, _ in deps_to_process.itervalues():
|
| - print 'Populating cache for %s' % git_url
|
| - num_threads += 1
|
| - pool.apply_async(git_tools.Clone, (git_url, None, 'bare',
|
| - output_queue, options.cache_dir,
|
| - options.shallow))
|
| - pool.close()
|
| -
|
| - # Stream stdout line by line.
|
| - sec_since = 0
|
| - while num_threads > 0:
|
| - try:
|
| - line = output_queue.get(block=True, timeout=1)
|
| - sec_since = 0
|
| - except Queue.Empty:
|
| - sec_since += 1
|
| - line = ('Main> Heartbeat ping. We are still alive!! '
|
| - 'Seconds since last output: %d sec' % sec_since)
|
| - if line is None:
|
| - num_threads -= 1
|
| - else:
|
| - print line
|
| - pool.join()
|
| +def ConvertDepMain(dep_q, message_q, options, results):
|
| + cur_thread = threading.current_thread()
|
| + while True:
|
| + try:
|
| + job = dep_q.get(False)
|
| + dep, git_url, dep_url, path, git_host, dep_rev, svn_branch = job
|
| + cur_thread.working_on = dep
|
| + except Queue.Empty:
|
| + cur_thread.working_on = None
|
| + return
|
| +
|
| + outbuf = StringIO()
|
| + def _print(s):
|
| + for l in s.splitlines():
|
| + outbuf.write('[%s] %s\n' % (dep, l))
|
|
|
| - for dep, items in deps_to_process.iteritems():
|
| - git_url, dep_url, path, git_host, dep_rev, svn_branch = items
|
| if options.verify:
|
| delay = 0.5
|
| success = False
|
| for try_index in range(1, 6):
|
| - print >> sys.stderr, 'checking %s (try #%d) ...' % (git_url, try_index),
|
| + _print('checking %s (try #%d) ...' % (git_url, try_index))
|
| if git_tools.Ping(git_url, verbose=True):
|
| - print >> sys.stderr, ' success'
|
| + _print(' success')
|
| success = True
|
| break
|
| -
|
| - print >> sys.stderr, ' failure'
|
| - print >> sys.stderr, 'sleeping for %.01f seconds ...' % delay
|
| + _print(' failure')
|
| + _print('sleeping for %.01f seconds ...' % delay)
|
| time.sleep(delay)
|
| delay *= 2
|
|
|
| if not success:
|
| - bad_git_urls.update([git_url])
|
| + results.bad_git_urls.add(git_url)
|
|
|
| # Get the Git hash based off the SVN rev.
|
| git_hash = ''
|
| @@ -221,13 +187,13 @@ def ConvertDepsToGit(deps, options, deps_vars, svn_to_git_objs):
|
| git_host, svn_branch, options.cache_dir)
|
| except Exception as e:
|
| if options.no_fail_fast:
|
| - bad_git_hash.append(e)
|
| + results.bad_git_hash.append(e)
|
| continue
|
| raise
|
|
|
| # If this is webkit, we need to add the var for the hash.
|
| if dep == 'src/third_party/WebKit' and dep_rev:
|
| - deps_vars['webkit_rev'] = git_hash
|
| + results.deps_vars['webkit_rev'] = git_hash
|
| git_hash = 'VAR_WEBKIT_REV'
|
|
|
| # Hack to preserve the angle_revision variable in .DEPS.git.
|
| @@ -235,13 +201,78 @@ def ConvertDepsToGit(deps, options, deps_vars, svn_to_git_objs):
|
| if dep == 'src/third_party/angle' and git_hash:
|
| # Cut the leading '@' so this variable has the same semantics in
|
| # DEPS and .DEPS.git.
|
| - deps_vars['angle_revision'] = git_hash[1:]
|
| + results.deps_vars['angle_revision'] = git_hash[1:]
|
| git_hash = 'VAR_ANGLE_REVISION'
|
|
|
| # Add this Git dep to the new deps.
|
| - new_deps[path] = '%s%s' % (git_url, git_hash)
|
| + results.new_deps[path] = '%s%s' % (git_url, git_hash)
|
|
|
| - return new_deps, bad_git_urls, bad_dep_urls, bad_override, bad_git_hash
|
| + message_q.put(outbuf.getvalue())
|
| +
|
| +
|
| +def ConvertDepsToGit(deps, options, deps_vars, svn_to_git_objs):
|
| + """Convert a 'deps' section in a DEPS file from SVN to Git."""
|
| + results = ConversionResults(
|
| + new_deps={},
|
| + deps_vars=deps_vars,
|
| + bad_git_urls=set([]),
|
| + bad_dep_urls=[],
|
| + bad_git_hash=[]
|
| + )
|
| +
|
| + # Populate our deps list.
|
| + deps_to_process = Queue.Queue()
|
| + for dep, dep_url in deps.iteritems():
|
| + if not dep_url: # dep is 'None' and emitted to exclude the dep
|
| + results.new_deps[dep] = None
|
| + continue
|
| +
|
| + # Get the URL and the revision/hash for this dependency.
|
| + dep_url, dep_rev = SplitScmUrl(deps[dep])
|
| +
|
| + path = dep
|
| + git_url = dep_url
|
| + svn_branch = None
|
| + git_host = dep_url
|
| +
|
| + if not dep_url.endswith('.git'):
|
| + # Convert this SVN URL to a Git URL.
|
| + for svn_git_converter in svn_to_git_objs:
|
| + converted_data = svn_git_converter.SvnUrlToGitUrl(dep, dep_url)
|
| + if converted_data:
|
| + path, git_url, git_host = converted_data[:3]
|
| + if len(converted_data) > 3:
|
| + svn_branch = converted_data[3]
|
| + break
|
| + else:
|
| + # Make all match failures fatal to catch errors early. When a match is
|
| + # found, we break out of the loop so the exception is not thrown.
|
| + if options.no_fail_fast:
|
| + results.bad_dep_urls.append(dep_url)
|
| + continue
|
| + raise RuntimeError('No match found for %s' % dep_url)
|
| +
|
| + deps_to_process.put(
|
| + Job(dep, git_url, dep_url, path, git_host, dep_rev, svn_branch))
|
| +
|
| + threads = []
|
| + message_q = Queue.Queue()
|
| + thread_args = (deps_to_process, message_q, options, results)
|
| + num_threads = options.num_threads or deps_to_process.qsize()
|
| + for _ in xrange(num_threads):
|
| + th = threading.Thread(target=ConvertDepMain, args=thread_args)
|
| + th.working_on = None
|
| + th.start()
|
| + threads.append(th)
|
| + message_th = threading.Thread(target=MessageMain, args=(message_q, threads))
|
| + message_th.start()
|
| +
|
| + for th in threads:
|
| + th.join()
|
| + message_q.put(Queue.Empty)
|
| + message_th.join()
|
| +
|
| + return results
|
|
|
|
|
| def main():
|
| @@ -250,6 +281,8 @@ def main():
|
| help='path to the DEPS file to convert')
|
| parser.add_option('-o', '--out',
|
| help='path to the converted DEPS file (default: stdout)')
|
| + parser.add_option('-j', '--num-threads', type='int', default=4,
|
| + help='Maximum number of threads')
|
| parser.add_option('-t', '--type',
|
| help='[DEPRECATED] type of DEPS file (public, etc)')
|
| parser.add_option('-x', '--extra-rules',
|
| @@ -290,7 +323,7 @@ def main():
|
| options.cache_dir = os.path.abspath(options.cache_dir)
|
|
|
| if options.extra_rules and not os.path.exists(options.extra_rules):
|
| - raise Exception('Can\'t locate rules file "%s".' % options.extra_rules)
|
| + raise RuntimeError('Can\'t locate rules file "%s".' % options.extra_rules)
|
|
|
| # Create a var containing the Git and Webkit URL, this will make it easy for
|
| # people to use a mirror instead.
|
| @@ -332,6 +365,14 @@ def main():
|
| if not options.cache_dir and 'cache_dir' in gclient_dict:
|
| options.cache_dir = os.path.abspath(gclient_dict['cache_dir'])
|
|
|
| + if options.cache_dir:
|
| + git_cache.Mirror.SetCachePath(options.cache_dir)
|
| + else:
|
| + try:
|
| + options.cache_dir = git_cache.Mirror.GetCachePath()
|
| + except RuntimeError:
|
| + pass
|
| +
|
| # Do general pre-processing of the DEPS data.
|
| for svn_git_converter in svn_to_git_objs:
|
| if hasattr(svn_git_converter, 'CleanDeps'):
|
| @@ -339,44 +380,39 @@ def main():
|
| skip_child_includes, hooks)
|
|
|
| # Convert the DEPS file to Git.
|
| - deps, baddeps, badmaps, badvars, badhashes = ConvertDepsToGit(
|
| + results = ConvertDepsToGit(
|
| deps, options, deps_vars, svn_to_git_objs)
|
| for os_dep in deps_os:
|
| - result = ConvertDepsToGit(deps_os[os_dep], options, deps_vars,
|
| - svn_to_git_objs)
|
| - deps_os[os_dep] = result[0]
|
| - baddeps = baddeps.union(result[1])
|
| - badmaps.extend(result[2])
|
| - badvars.extend(result[3])
|
| - badhashes.extend(result[4])
|
| + os_results = ConvertDepsToGit(deps_os[os_dep], options, deps_vars,
|
| + svn_to_git_objs)
|
| + deps_os[os_dep] = os_results.new_deps
|
| + results.bad_git_urls.update(os_results.bad_git_urls)
|
| + results.bad_dep_urls.extend(os_results.bad_dep_urls)
|
| + results.bad_git_hash.extend(os_results.bad_git_hash)
|
|
|
| if options.json:
|
| with open(options.json, 'w') as f:
|
| - json.dump(list(baddeps), f, sort_keys=True, indent=2)
|
| + json.dump(list(results.bad_git_urls), f, sort_keys=True, indent=2)
|
|
|
| - if baddeps:
|
| + if results.bad_git_urls:
|
| print >> sys.stderr, ('\nUnable to resolve the following repositories. '
|
| 'Please make sure\nthat any svn URLs have a git mirror associated with '
|
| 'them.\nTo see the exact error, run `git ls-remote [repository]` where'
|
| '\n[repository] is the URL ending in .git (strip off the @revision\n'
|
| 'number.) For more information, visit http://code.google.com\n'
|
| '/p/chromium/wiki/UsingGit#Adding_new_repositories_to_DEPS.\n')
|
| - for dep in baddeps:
|
| + for dep in results.bad_git_urls:
|
| print >> sys.stderr, ' ' + dep
|
| - if badmaps:
|
| + if results.bad_dep_urls:
|
| print >> sys.stderr, '\nNo mappings found for the following urls:\n'
|
| - for bad in badmaps:
|
| - print >> sys.stderr, ' ' + bad
|
| - if badvars:
|
| - print >> sys.stderr, '\nMissing DEPS variables for overrides:\n'
|
| - for bad in badvars:
|
| + for bad in results.bad_dep_urls:
|
| print >> sys.stderr, ' ' + bad
|
| - if badhashes:
|
| + if results.bad_git_hash:
|
| print >> sys.stderr, '\nsvn rev to git hash failures:\n'
|
| - for bad in badhashes:
|
| + for bad in results.bad_git_hash:
|
| print >> sys.stderr, ' ' + str(bad)
|
|
|
| - if baddeps or badmaps or badvars or badhashes:
|
| + if (results.bad_git_urls or results.bad_dep_urls or results.bad_git_hash):
|
| return 2
|
|
|
| if options.verify:
|
| @@ -385,8 +421,8 @@ def main():
|
| return 0
|
|
|
| # Write the DEPS file to disk.
|
| - deps_utils.WriteDeps(options.out, deps_vars, deps, deps_os, include_rules,
|
| - skip_child_includes, hooks)
|
| + deps_utils.WriteDeps(options.out, deps_vars, results.new_deps, deps_os,
|
| + include_rules, skip_child_includes, hooks)
|
| return 0
|
|
|
|
|
|
|