import os import shutil import subprocess import pytest from buildstream.testing import Repo from buildstream.testing._utils.site import GIT, GIT_ENV, HAVE_GIT class Git(Repo): def __init__(self, directory, subdir): if not HAVE_GIT: pytest.skip("git is not available") self.submodules = {} super().__init__(directory, subdir) def _run_git(self, *args, **kwargs): argv = [GIT] argv.extend(args) if 'env' not in kwargs: kwargs['env'] = dict(GIT_ENV, PWD=self.repo) kwargs.setdefault('cwd', self.repo) kwargs.setdefault('check', True) return subprocess.run(argv, **kwargs) def create(self, directory): self.copy_directory(directory, self.repo) self._run_git('init', '.') self._run_git('add', '.') self._run_git('commit', '-m', 'Initial commit') return self.latest_commit() def add_tag(self, tag): self._run_git('tag', tag) def add_annotated_tag(self, tag, message): self._run_git('tag', '-a', tag, '-m', message) def add_commit(self): self._run_git('commit', '--allow-empty', '-m', 'Additional commit') return self.latest_commit() def add_file(self, filename): shutil.copy(filename, self.repo) self._run_git('add', os.path.basename(filename)) self._run_git('commit', '-m', 'Added {}'.format(os.path.basename(filename))) return self.latest_commit() def modify_file(self, new_file, path): shutil.copy(new_file, os.path.join(self.repo, path)) self._run_git('commit', path, '-m', 'Modified {}'.format(os.path.basename(path))) return self.latest_commit() def add_submodule(self, subdir, url=None, checkout=None): submodule = {} if checkout is not None: submodule['checkout'] = checkout if url is not None: submodule['url'] = url self.submodules[subdir] = submodule self._run_git('submodule', 'add', url, subdir) self._run_git('commit', '-m', 'Added the submodule') return self.latest_commit() # This can also be used to a file or a submodule def remove_path(self, path): self._run_git('rm', path) self._run_git('commit', '-m', 'Removing {}'.format(path)) return self.latest_commit() def source_config(self, ref=None, checkout_submodules=None): config = { 'kind': 'git', 'url': 'file://' + self.repo, 'track': 'master' } if ref is not None: config['ref'] = ref if checkout_submodules is not None: config['checkout-submodules'] = checkout_submodules if self.submodules: config['submodules'] = dict(self.submodules) return config def latest_commit(self): return self._run_git( 'rev-parse', 'HEAD', stdout=subprocess.PIPE, universal_newlines=True, ).stdout.strip() def branch(self, branch_name): self._run_git('checkout', '-b', branch_name) def delete_tag(self, tag_name): self._run_git('tag', '-d', tag_name) def checkout(self, commit): self._run_git('checkout', commit) def merge(self, commit): self._run_git('merge', '-m', 'Merge', commit) return self.latest_commit() def rev_parse(self, rev): return self._run_git( 'rev-parse', rev, stdout=subprocess.PIPE, universal_newlines=True, ).stdout.strip()