mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-17 02:49:02 +02:00

Replace full license headers with SPDX identifiers and adjust all patchtest-related code to use GPL-2.0-only. (From OE-Core rev: 9bea6b39074296bb8d8719a3300636e316f19d1b) Signed-off-by: Trevor Gamblin <tgamblin@baylibre.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
176 lines
5.8 KiB
Python
176 lines
5.8 KiB
Python
# ex:ts=4:sw=4:sts=4:et
|
|
# -*- tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
|
|
#
|
|
# patchtestrepo: PatchTestRepo class used mainly to control a git repo from patchtest
|
|
#
|
|
# Copyright (C) 2016 Intel Corporation
|
|
#
|
|
# SPDX-License-Identifier: GPL-2.0-only
|
|
#
|
|
|
|
import os
|
|
import utils
|
|
import logging
|
|
import json
|
|
from patch import PatchTestPatch
|
|
|
|
logger = logging.getLogger('patchtest')
|
|
info=logger.info
|
|
|
|
class PatchTestRepo(object):
|
|
|
|
# prefixes used for temporal branches/stashes
|
|
prefix = 'patchtest'
|
|
|
|
def __init__(self, patch, repodir, commit=None, branch=None):
|
|
self._repodir = repodir
|
|
self._patch = PatchTestPatch(patch)
|
|
self._current_branch = self._get_current_branch()
|
|
|
|
# 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():
|
|
valid_patch_branch = self._patch.branch
|
|
|
|
# Target Branch
|
|
# Priority (top has highest priority):
|
|
# 1. branch given at cmd line
|
|
# 2. branch given at the patch
|
|
# 3. current branch
|
|
self._branch = branch or valid_patch_branch or self._current_branch
|
|
|
|
# Target Commit
|
|
# Priority (top has highest priority):
|
|
# 1. commit given at cmd line
|
|
# 2. branch given at cmd line
|
|
# 3. branch given at the patch
|
|
# 3. current HEAD
|
|
self._commit = self._get_commitid(commit) or \
|
|
self._get_commitid(branch) or \
|
|
self._get_commitid(valid_patch_branch) or \
|
|
self._get_commitid('HEAD')
|
|
|
|
self._workingbranch = "%s_%s" % (PatchTestRepo.prefix, os.getpid())
|
|
|
|
# create working branch
|
|
self._exec({'cmd': ['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']})
|
|
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")
|
|
logger.debug("\tRepository : %s" % self._repodir)
|
|
logger.debug("\tTarget Commit : %s" % self._commit)
|
|
logger.debug("\tTarget Branch : %s" % self._branch)
|
|
logger.debug("\tWorking branch : %s" % self._workingbranch)
|
|
logger.debug("\tPatch : %s" % self._patch)
|
|
|
|
@property
|
|
def patch(self):
|
|
return self._patch.path
|
|
|
|
@property
|
|
def branch(self):
|
|
return self._branch
|
|
|
|
@property
|
|
def commit(self):
|
|
return self._commit
|
|
|
|
@property
|
|
def ismerged(self):
|
|
return self._patchmerged
|
|
|
|
@property
|
|
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 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._patchmerged = True
|
|
|
|
def clean(self):
|
|
self._exec({'cmd':['git', 'checkout', '%s' % self._current_branch]})
|
|
self._exec({'cmd':['git', 'branch', '-D', self._workingbranch]})
|
|
self._patchmerged = False
|