mirror of
git://git.yoctoproject.org/poky.git
synced 2025-07-19 21:09:03 +02:00

With PATCHTOOL=git patches the changes in the patch_task_postfunc
of the classes/patch. This works OK when the S dir is a Git repo
but doesn't if the source is a tarball.
The while condition in the patch_task_patch_prefunc must be
jailed into the WORKDIR. In the opposite, when you are executing
the recipe out of a Git subtree the function simply fails but when
your recipes are into a Git repo the patch_task_postfunc execute a
commit over your BSP local Git repo adding the changes in an
arbitrary Git repo found in the path from the SOURCE directory to
the '/'. This situation is highly probable in cases like ~home
directories under the control of a .git repo or Yocto BSP which
manage the meta layers as git submodules.
This patch fix the changes introduced in
classes/patch: when PATCHTOOL = "git" double-check the repository
commit: 86ab56b551
Author: Paul Eggleton <paul.eggleton@linux.intel.com>
Date: Tue Dec 5 14:36:58 2017 +1300
classes/patch: when PATCHTOOL = "git" double-check the repository
If a bug is present or the user has set PATCHTOOL = "git" on a source
tree that isn't git, if we try to perform git operations (such as
committing or changing branches) when extracting source, then we might
in fact be running those operations on the metadata repository if the
build directory is underneath, say, poky or OE-Core, and that could
make a mess. Check if the source tree is a git repository and refuse
to continue if it isn't.
(From OE-Core rev: db6ce9d8838b1f9064604654ab579da3e237f361)
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
160 lines
5.2 KiB
Plaintext
160 lines
5.2 KiB
Plaintext
# Copyright (C) 2006 OpenedHand LTD
|
|
|
|
# Point to an empty file so any user's custom settings don't break things
|
|
QUILTRCFILE ?= "${STAGING_ETCDIR_NATIVE}/quiltrc"
|
|
|
|
PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_sysroot"
|
|
|
|
PATCH_GIT_USER_NAME ?= "OpenEmbedded"
|
|
PATCH_GIT_USER_EMAIL ?= "oe.patch@oe"
|
|
|
|
inherit terminal
|
|
|
|
python () {
|
|
if d.getVar('PATCHTOOL') == 'git' and d.getVar('PATCH_COMMIT_FUNCTIONS') == '1':
|
|
extratasks = bb.build.tasksbetween('do_unpack', 'do_patch', d)
|
|
try:
|
|
extratasks.remove('do_unpack')
|
|
except ValueError:
|
|
# For some recipes do_unpack doesn't exist, ignore it
|
|
pass
|
|
|
|
d.appendVarFlag('do_patch', 'prefuncs', ' patch_task_patch_prefunc')
|
|
for task in extratasks:
|
|
d.appendVarFlag(task, 'postfuncs', ' patch_task_postfunc')
|
|
}
|
|
|
|
python patch_task_patch_prefunc() {
|
|
# Prefunc for do_patch
|
|
srcsubdir = d.getVar('S')
|
|
|
|
workdir = os.path.abspath(d.getVar('WORKDIR'))
|
|
testsrcdir = os.path.abspath(srcsubdir)
|
|
if (testsrcdir + os.sep).startswith(workdir + os.sep):
|
|
# Double-check that either workdir or S or some directory in-between is a git repository
|
|
found = False
|
|
while testsrcdir != workdir:
|
|
if os.path.exists(os.path.join(testsrcdir, '.git')):
|
|
found = True
|
|
break
|
|
if testsrcdir == workdir:
|
|
break
|
|
testsrcdir = os.path.dirname(testsrcdir)
|
|
if not found:
|
|
bb.fatal('PATCHTOOL = "git" set for source tree that is not a git repository. Refusing to continue as that may result in commits being made in your metadata repository.')
|
|
|
|
patchdir = os.path.join(srcsubdir, 'patches')
|
|
if os.path.exists(patchdir):
|
|
if os.listdir(patchdir):
|
|
d.setVar('PATCH_HAS_PATCHES_DIR', '1')
|
|
else:
|
|
os.rmdir(patchdir)
|
|
}
|
|
|
|
python patch_task_postfunc() {
|
|
# Prefunc for task functions between do_unpack and do_patch
|
|
import oe.patch
|
|
import shutil
|
|
func = d.getVar('BB_RUNTASK')
|
|
srcsubdir = d.getVar('S')
|
|
|
|
if os.path.exists(srcsubdir):
|
|
if func == 'do_patch':
|
|
haspatches = (d.getVar('PATCH_HAS_PATCHES_DIR') == '1')
|
|
patchdir = os.path.join(srcsubdir, 'patches')
|
|
if os.path.exists(patchdir):
|
|
shutil.rmtree(patchdir)
|
|
if haspatches:
|
|
stdout, _ = bb.process.run('git status --porcelain patches', cwd=srcsubdir)
|
|
if stdout:
|
|
bb.process.run('git checkout patches', cwd=srcsubdir)
|
|
stdout, _ = bb.process.run('git status --porcelain .', cwd=srcsubdir)
|
|
if stdout:
|
|
useroptions = []
|
|
oe.patch.GitApplyTree.gitCommandUserOptions(useroptions, d=d)
|
|
bb.process.run('git add .; git %s commit -a -m "Committing changes from %s\n\n%s"' % (' '.join(useroptions), func, oe.patch.GitApplyTree.ignore_commit_prefix + ' - from %s' % func), cwd=srcsubdir)
|
|
}
|
|
|
|
def src_patches(d, all=False, expand=True):
|
|
import oe.patch
|
|
return oe.patch.src_patches(d, all, expand)
|
|
|
|
def should_apply(parm, d):
|
|
"""Determine if we should apply the given patch"""
|
|
import oe.patch
|
|
return oe.patch.should_apply(parm, d)
|
|
|
|
should_apply[vardepsexclude] = "DATE SRCDATE"
|
|
|
|
python patch_do_patch() {
|
|
import oe.patch
|
|
|
|
patchsetmap = {
|
|
"patch": oe.patch.PatchTree,
|
|
"quilt": oe.patch.QuiltTree,
|
|
"git": oe.patch.GitApplyTree,
|
|
}
|
|
|
|
cls = patchsetmap[d.getVar('PATCHTOOL') or 'quilt']
|
|
|
|
resolvermap = {
|
|
"noop": oe.patch.NOOPResolver,
|
|
"user": oe.patch.UserResolver,
|
|
}
|
|
|
|
rcls = resolvermap[d.getVar('PATCHRESOLVE') or 'user']
|
|
|
|
classes = {}
|
|
|
|
s = d.getVar('S')
|
|
|
|
os.putenv('PATH', d.getVar('PATH'))
|
|
|
|
# We must use one TMPDIR per process so that the "patch" processes
|
|
# don't generate the same temp file name.
|
|
|
|
import tempfile
|
|
process_tmpdir = tempfile.mkdtemp()
|
|
os.environ['TMPDIR'] = process_tmpdir
|
|
|
|
for patch in src_patches(d):
|
|
_, _, local, _, _, parm = bb.fetch.decodeurl(patch)
|
|
|
|
if "patchdir" in parm:
|
|
patchdir = parm["patchdir"]
|
|
if not os.path.isabs(patchdir):
|
|
patchdir = os.path.join(s, patchdir)
|
|
else:
|
|
patchdir = s
|
|
|
|
if not patchdir in classes:
|
|
patchset = cls(patchdir, d)
|
|
resolver = rcls(patchset, oe_terminal)
|
|
classes[patchdir] = (patchset, resolver)
|
|
patchset.Clean()
|
|
else:
|
|
patchset, resolver = classes[patchdir]
|
|
|
|
bb.note("Applying patch '%s' (%s)" % (parm['patchname'], oe.path.format_display(local, d)))
|
|
try:
|
|
patchset.Import({"file":local, "strippath": parm['striplevel']}, True)
|
|
except Exception as exc:
|
|
bb.utils.remove(process_tmpdir, True)
|
|
bb.fatal(str(exc))
|
|
try:
|
|
resolver.Resolve()
|
|
except bb.BBHandledException as e:
|
|
bb.utils.remove(process_tmpdir, True)
|
|
bb.fatal(str(e))
|
|
|
|
bb.utils.remove(process_tmpdir, True)
|
|
del os.environ['TMPDIR']
|
|
}
|
|
patch_do_patch[vardepsexclude] = "PATCHRESOLVE"
|
|
|
|
addtask patch after do_unpack
|
|
do_patch[dirs] = "${WORKDIR}"
|
|
do_patch[depends] = "${PATCHDEPENDENCY}"
|
|
|
|
EXPORT_FUNCTIONS do_patch
|