1
0
mirror of https://git.yoctoproject.org/poky synced 2026-05-31 00:39:46 +00:00

patchtest: repo: refactor to use GitPython

The repo module currently uses a custom _exec() function in order to run
various git commands as part of the patchtest setup/test process. These
can more efficiently be done with the GitPython module, so use that
instead and reduce the amount of custom code to be maintained for
patchtest in the process. Some specifics replaced using GitPython:

- get branch list
- use repo.active_branch to determine current branch
- use execute() for checkout, merge check, abort, rev-parse, reset

The _exec() function is removed entirely with this change.

(From OE-Core rev: 8ab3a0d7cb68746d7b7e1c7ff8bdf9a84a4d075d)

Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Trevor Gamblin
2024-05-03 09:10:30 -04:00
committed by Richard Purdie
parent e73ea1a868
commit 9132e3904a
+17 -71
View File
@@ -11,6 +11,7 @@
import os
import utils
import logging
import git
from patch import PatchTestPatch
logger = logging.getLogger('patchtest')
@@ -21,15 +22,17 @@ class PatchTestRepo(object):
# prefixes used for temporal branches/stashes
prefix = 'patchtest'
def __init__(self, patch, repodir, commit=None, branch=None):
self._repodir = repodir
self._repo = git.Repo.init(repodir)
self._patch = PatchTestPatch(patch)
self._current_branch = self._get_current_branch()
self._current_branch = self._repo.active_branch.name
# targeted branch defined on the patch may be invalid, so make sure there
# is a corresponding remote branch
valid_patch_branch = None
if self._patch.branch in self.upstream_branches():
if self._patch.branch in self._repo.branches:
valid_patch_branch = self._patch.branch
# Target Branch
@@ -52,22 +55,19 @@ class PatchTestRepo(object):
self._workingbranch = "%s_%s" % (PatchTestRepo.prefix, os.getpid())
# create working branch
self._exec({'cmd': ['git', 'checkout', '-b', self._workingbranch, self._commit]})
# create working branch. Use the '-B' flag so that we just
# check out the existing one if it's there
self._repo.git.execute(['git', 'checkout', '-B', self._workingbranch, self._commit])
self._patchmerged = False
# Check if patch can be merged using git-am
self._patchcanbemerged = True
try:
self._exec({'cmd': ['git', 'am', '--keep-cr'], 'input': self._patch.contents})
except utils.CmdException as ce:
self._exec({'cmd': ['git', 'am', '--abort']})
# Make sure to get the absolute path of the file
self._repo.git.execute(['git', 'apply', '--check', os.path.abspath(self._patch.path)], with_exceptions=True)
except git.exc.GitCommandError as ce:
self._patchcanbemerged = False
finally:
# if patch was applied, remove it
if self._patchcanbemerged:
self._exec({'cmd':['git', 'reset', '--hard', self._commit]})
# for debugging purposes, print all repo parameters
logger.debug("Parameters")
@@ -97,78 +97,24 @@ class PatchTestRepo(object):
def canbemerged(self):
return self._patchcanbemerged
def _exec(self, cmds):
_cmds = []
if isinstance(cmds, dict):
_cmds.append(cmds)
elif isinstance(cmds, list):
_cmds = cmds
else:
raise utils.CmdException({'cmd':str(cmds)})
results = []
cmdfailure = False
try:
results = utils.exec_cmds(_cmds, self._repodir)
except utils.CmdException as ce:
cmdfailure = True
raise ce
finally:
if cmdfailure:
for cmd in _cmds:
logger.debug("CMD: %s" % ' '.join(cmd['cmd']))
else:
for result in results:
cmd, rc, stdout, stderr = ' '.join(result['cmd']), result['returncode'], result['stdout'], result['stderr']
logger.debug("CMD: %s RCODE: %s STDOUT: %s STDERR: %s" % (cmd, rc, stdout, stderr))
return results
def _get_current_branch(self, commit='HEAD'):
cmd = {'cmd':['git', 'rev-parse', '--abbrev-ref', commit]}
cb = self._exec(cmd)[0]['stdout']
if cb == commit:
logger.warning('You may be detached so patchtest will checkout to master after execution')
cb = 'master'
return cb
def _get_commitid(self, commit):
if not commit:
return None
try:
cmd = {'cmd':['git', 'rev-parse', '--short', commit]}
return self._exec(cmd)[0]['stdout']
except utils.CmdException as ce:
# try getting the commit under any remotes
cmd = {'cmd':['git', 'remote']}
remotes = self._exec(cmd)[0]['stdout']
for remote in remotes.splitlines():
cmd = {'cmd':['git', 'rev-parse', '--short', '%s/%s' % (remote, commit)]}
try:
return self._exec(cmd)[0]['stdout']
except utils.CmdException:
pass
return self._repo.rev_parse(commit).hexsha
except Exception as e:
print(f"Couldn't find commit {commit} in repo")
return None
def upstream_branches(self):
cmd = {'cmd':['git', 'branch', '--remotes']}
remote_branches = self._exec(cmd)[0]['stdout']
# just get the names, without the remote name
branches = set(branch.split('/')[-1] for branch in remote_branches.splitlines())
return branches
def merge(self):
if self._patchcanbemerged:
self._exec({'cmd': ['git', 'am', '--keep-cr'],
'input': self._patch.contents,
'updateenv': {'PTRESOURCE':self._patch.path}})
self._repo.git.execute(['git', 'am', '--keep-cr', os.path.abspath(self._patch.path)])
self._patchmerged = True
def clean(self):
self._exec({'cmd':['git', 'checkout', '%s' % self._current_branch]})
self._exec({'cmd':['git', 'branch', '-D', self._workingbranch]})
self._repo.git.execute(['git', 'checkout', self._current_branch])
self._repo.git.execute(['git', 'branch', '-D', self._workingbranch])
self._patchmerged = False