Source code for autotest.client.shared.git

"""
Code that helps to deal with content from git repositories
"""

import logging
import os

from autotest.client import utils, os_dep

import error

__all__ = ["GitRepoHelper", "get_repo"]


[docs]class GitRepoHelper(object): ''' Helps to deal with git repos, mostly fetching content from a repo ''' def __init__(self, uri, branch='master', lbranch=None, commit=None, destination_dir=None, base_uri=None): ''' Instantiates a new GitRepoHelper :type uri: string :param uri: git repository url :type branch: string :param branch: git remote branch :type destination_dir: string :param destination_dir: path of a dir where to save downloaded code :type commit: string :param commit: specific commit to download :type lbranch: string :param lbranch: git local branch name, if different from remote :type base_uri: string :param base_uri: a closer, usually local, git repository url from where to fetch content first ''' self.uri = uri self.base_uri = base_uri self.branch = branch self.commit = commit if destination_dir is None: uri_basename = uri.split("/")[-1] self.destination_dir = os.path.join("/tmp", uri_basename) else: self.destination_dir = destination_dir if lbranch is None: self.lbranch = branch else: self.lbranch = lbranch self.cmd = os_dep.command('git')
[docs] def init(self): ''' Initializes a directory for receiving a verbatim copy of git repo This creates a directory if necessary, and either resets or inits the repo ''' if not os.path.exists(self.destination_dir): logging.debug('Creating directory %s for git repo %s', self.destination_dir, self.uri) os.makedirs(self.destination_dir) os.chdir(self.destination_dir) if os.path.exists('.git'): logging.debug('Resetting previously existing git repo at %s for ' 'receiving git repo %s', self.destination_dir, self.uri) self.git_cmd('reset --hard') else: logging.debug('Initializing new git repo at %s for receiving ' 'git repo %s', self.destination_dir, self.uri) self.git_cmd('init')
[docs] def git_cmd(self, cmd, ignore_status=False): ''' Wraps git commands. :param cmd: Command to be executed. :param ignore_status: Whether we should suppress error.CmdError exceptions if the command did return exit code !=0 (True), or not suppress them (False). ''' os.chdir(self.destination_dir) return utils.run(r"%s %s" % (self.cmd, utils.sh_escape(cmd)), ignore_status=ignore_status)
[docs] def fetch(self, uri): ''' Performs a git fetch from the remote repo ''' logging.info("Fetching git [REP '%s' BRANCH '%s'] -> %s", uri, self.branch, self.destination_dir) self.git_cmd("fetch -q -f -u -t %s %s:%s" % (uri, self.branch, self.lbranch))
[docs] def get_top_commit(self): ''' Returns the topmost commit id for the current branch. :return: Commit id. ''' return self.git_cmd('log --pretty=format:%H -1').stdout.strip()
[docs] def get_top_tag(self): ''' Returns the topmost tag for the current branch. :return: Tag. ''' try: return self.git_cmd('describe').stdout.strip() except error.CmdError: return None
[docs] def checkout(self, branch=None, commit=None): ''' Performs a git checkout for a given branch and start point (commit) :param branch: Remote branch name. :param commit: Specific commit hash. ''' if branch is None: branch = self.branch logging.debug('Checking out branch %s', branch) self.git_cmd("checkout %s" % branch) if commit is None: commit = self.commit if commit is not None: logging.debug('Checking out commit %s', self.commit) self.git_cmd("checkout %s" % self.commit) else: logging.debug('Specific commit not specified') top_commit = self.get_top_commit() top_tag = self.get_top_tag() if top_tag is None: top_tag_desc = 'no tag found' else: top_tag_desc = 'tag %s' % top_tag logging.info("git commit ID is %s (%s)", top_commit, top_tag_desc)
[docs] def execute(self): ''' Performs all steps necessary to initialize and download a git repo. This includes the init, fetch and checkout steps in one single utility method. ''' self.init() if self.base_uri is not None: self.fetch(self.base_uri) self.fetch(self.uri) self.checkout()
[docs]def get_repo(uri, branch='master', lbranch=None, commit=None, destination_dir=None, base_uri=None): """ Utility function that retrieves a given git code repository. :type uri: string :param uri: git repository url :type branch: string :param branch: git remote branch :type destination_dir: string :param destination_dir: path of a dir where to save downloaded code :type commit: string :param commit: specific commit to download :type lbranch: string :param lbranch: git local branch name, if different from remote :type base_uri: string :param uri: a closer, usually local, git repository url from where to fetch content first from """ if lbranch is None: lbranch = branch repo = GitRepoHelper(uri, branch, lbranch, commit, destination_dir, base_uri) repo.execute() return repo.destination_dir