diff options
Diffstat (limited to 'meta/classes/patch.bbclass')
| -rw-r--r-- | meta/classes/patch.bbclass | 251 |
1 files changed, 131 insertions, 120 deletions
diff --git a/meta/classes/patch.bbclass b/meta/classes/patch.bbclass index 80fd45f0e3..8f35cb4f95 100644 --- a/meta/classes/patch.bbclass +++ b/meta/classes/patch.bbclass @@ -1,131 +1,142 @@ # Copyright (C) 2006 OpenedHand LTD # Point to an empty file so any user's custom settings don't break things -QUILTRCFILE ?= "${STAGING_BINDIR_NATIVE}/quiltrc" +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 + func = d.getVar('BB_RUNTASK') + srcsubdir = d.getVar('S') + + 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 - - src_uri = (bb.data.getVar('SRC_URI', d, 1) or '').split() - if not src_uri: - return - - patchsetmap = { - "patch": oe.patch.PatchTree, - "quilt": oe.patch.QuiltTree, - "git": oe.patch.GitApplyTree, - } - - cls = patchsetmap[bb.data.getVar('PATCHTOOL', d, 1) or 'quilt'] - - resolvermap = { - "noop": oe.patch.NOOPResolver, - "user": oe.patch.UserResolver, - } - - rcls = resolvermap[bb.data.getVar('PATCHRESOLVE', d, 1) or 'user'] - - s = bb.data.getVar('S', d, 1) - - path = os.getenv('PATH') - os.putenv('PATH', bb.data.getVar('PATH', d, 1)) - patchset = cls(s, d) - patchset.Clean() - - resolver = rcls(patchset) - - workdir = bb.data.getVar('WORKDIR', d, 1) - for url in src_uri: - (type, host, path, user, pswd, parm) = bb.decodeurl(url) - - local = None - base, ext = os.path.splitext(os.path.basename(path)) - if ext in ('.gz', '.bz2', '.Z'): - local = os.path.join(workdir, base) - ext = os.path.splitext(base)[1] - - if "apply" in parm: - apply = parm["apply"] - if apply != "yes": - if apply != "no": - bb.msg.warn(None, "Unsupported value '%s' for 'apply' url param in '%s', please use 'yes' or 'no'" % (apply, url)) - continue - #elif "patch" in parm: - #bb.msg.warn(None, "Deprecated usage of 'patch' url param in '%s', please use 'apply={yes,no}'" % url) - elif ext not in (".diff", ".patch"): - continue - - if not local: - url = bb.encodeurl((type, host, path, user, pswd, [])) - local = os.path.join('/', bb.fetch2.localpath(url, d)) - local = bb.data.expand(local, d) - - if "striplevel" in parm: - striplevel = parm["striplevel"] - elif "pnum" in parm: - #bb.msg.warn(None, "Deprecated usage of 'pnum' url parameter in '%s', please use 'striplevel'" % url) - striplevel = parm["pnum"] - else: - striplevel = '1' - - if "pname" in parm: - pname = parm["pname"] - else: - pname = os.path.basename(local) - - if "mindate" in parm or "maxdate" in parm: - pn = bb.data.getVar('PN', d, 1) - srcdate = bb.data.getVar('SRCDATE_%s' % pn, d, 1) - if not srcdate: - srcdate = bb.data.getVar('SRCDATE', d, 1) - - if srcdate == "now": - srcdate = bb.data.getVar('DATE', d, 1) - - if "maxdate" in parm and parm["maxdate"] < srcdate: - bb.note("Patch '%s' is outdated" % pname) - continue - - if "mindate" in parm and parm["mindate"] > srcdate: - bb.note("Patch '%s' is predated" % pname) - continue - - - if "minrev" in parm: - srcrev = bb.data.getVar('SRCREV', d, 1) - if srcrev and srcrev < parm["minrev"]: - bb.note("Patch '%s' applies to later revisions" % pname) - continue - - if "maxrev" in parm: - srcrev = bb.data.getVar('SRCREV', d, 1) - if srcrev and srcrev > parm["maxrev"]: - bb.note("Patch '%s' applies to earlier revisions" % pname) - continue - - if "rev" in parm: - srcrev = bb.data.getVar('SRCREV', d, 1) - if srcrev and parm["rev"] not in srcrev: - bb.note("Patch '%s' doesn't apply to revision" % pname) - continue - - if "notrev" in parm: - srcrev = bb.data.getVar('SRCREV', d, 1) - if srcrev and parm["notrev"] in srcrev: - bb.note("Patch '%s' doesn't apply to revision" % pname) - continue - - bb.note("Applying patch '%s' (%s)" % (pname, oe.path.format_display(local, d))) - try: - patchset.Import({"file":local, "remote":url, "strippath": striplevel}, True) - except Exception: - import sys - raise bb.build.FuncFailed(str(sys.exc_value)) - resolver.Resolve() + 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] = "DATE SRCDATE" +patch_do_patch[vardepsexclude] = "PATCHRESOLVE" addtask patch after do_unpack do_patch[dirs] = "${WORKDIR}" |
