blob: 92532b8cb66b77b3e01e8c43e8353c2301a3cf7c [file] [log] [blame]
# Copyright 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# Functions in this file relies on depot_tools been checked-out as a sibling
# of infra.git.
import logging
import os
import re
import subprocess
BASE_DIR = os.path.dirname(
os.path.dirname(
os.path.dirname(
os.path.dirname(os.path.realpath(__file__)))))
def parse_revinfo(revinfo):
"""Parse the output of "gclient revinfo -a"
Args:
revinfo (str): string containing gclient stdout.
Returns:
revinfo_d (dict): <directory>: (URL, revision)
"""
revision_expr = re.compile('(.*)@([^@]*)')
revinfo_d = {}
for line in revinfo.splitlines():
if ':' not in line:
continue
# TODO: this fails when the file name contains a colon.
path, line = line.split(':', 1)
if '@' in line:
url, revision = revision_expr.match(line).groups()
revision = revision.strip()
else:
# Split at the last @
url, revision = line.strip(), None
path = path.strip()
url = url.strip()
revinfo_d[path] = {'source_url': url, 'revision': revision}
return revinfo_d
def get_revinfo(cwd=None): # pragma: no cover
"""Call gclient to get the list of all revisions actually checked out on disk.
gclient is expected to be under depot_tools/ sibling to infra/.
If gclient can't be found or fail to run returns {}.
Args:
cwd (str): working directory where to run gclient. If None, use the
current working directory.
Returns:
revinfo (dict): keys are local paths, values are dicts with keys:
'source_url' or 'revision'. The latter can be a git SHA1 or an svn
revision.
"""
cmd = [os.path.join(BASE_DIR, 'depot_tools', 'gclient'), 'revinfo', '-a']
logging.debug('Running: %s', ' '.join(cmd))
revinfo = ''
try:
revinfo = subprocess.check_output(cmd, cwd=cwd)
except (subprocess.CalledProcessError, OSError):
logging.exception('Command failed to run: %s', ' '.join(cmd))
return parse_revinfo(revinfo)