blob: 794c9d817036692cc3d44fe5f13300993347c7a3 [file] [log] [blame]
# Copyright 2013 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.
"""Common steps for recipes that use repo for source control."""
import re
from recipe_engine import recipe_api
class RepoApi(recipe_api.RecipeApi):
"""Provides methods to encapsulate repo operations."""
_REPO_LIST_RE = re.compile(r'^(.+) : (.+)$')
# WARNING: The version of repo checked into depot_tools doesn't support
# switching between branches correctly due to
# https://code.google.com/p/git-repo/issues/detail?id=46
def __init__(self, **kwargs):
super(RepoApi, self).__init__(**kwargs)
self._repo_path = None
@property
def repo_path(self):
if not self._repo_path:
self._repo_path = self.m.depot_tools.repo_resource('repo')
return self._repo_path
def __call__(self, args, name=None, **kwargs):
"""Executes 'repo' with the supplied arguments.
Args:
args: (list): A list of arguments to supply to 'repo'.
name (str): The name of the step. If None, generate a name from the args.
kwargs: Keyword arguments to pass to the 'step' call.
Returns:
See 'step.__call__'.
"""
name = name or ' '.join(args)
return self.m.step(name, [self.repo_path] + args, **kwargs)
def init(self, url, *args, **kwargs):
"""Perform a 'repo init' step with the given manifest url."""
kwargs.setdefault('infra_step', True)
kwargs.setdefault('name', 'repo init')
return self(['init', '-u', url] + list(args), **kwargs)
def sync(self, *args, **kwargs):
"""Sync an already-init'd repo."""
# NOTE: This does not set self.m.path['checkout']
kwargs.setdefault('infra_step', True)
if not 'name' in kwargs:
name = 'repo sync'
kwargs['name'] = name
return self(['sync'] + list(args), **kwargs)
def clean(self, *args, **kwargs):
"""Clean an already-init'd repo."""
kwargs.setdefault('infra_step', True)
kwargs.setdefault('name', 'repo forall git clean')
return self(['forall', '-c', 'git', 'clean', '-f', '-d'] + list(args),
**kwargs)
def reset(self, **kwargs):
"""Reset to HEAD an already-init'd repo."""
kwargs.setdefault('name', 'repo forall git reset')
return self(['forall', '-c', 'git', 'reset', '--hard', 'HEAD'], **kwargs)
def list(self, **kwargs):
"""Return (list): A list of (path, name) project tuples.
path (str): The relative path to the project's checkout.
name (str): The name of the project in the manifst.
"""
kwargs['stdout'] = self.m.raw_io.output_text()
kwargs.setdefault('name', 'repo list')
step_result = self(['list'], **kwargs)
result = []
for line in step_result.stdout.splitlines():
match = self._REPO_LIST_RE.match(line)
if match:
result.append(match.groups())
# Display the result in the step text.
if result:
step_result.presentation.step_text = '</br></br>'
step_result.presentation.step_text += '</br>'.join(
'%s : %s' % (path, name) for path, name in result)
return result