| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | # Copyright (C) 2006  OpenedHand LTD | 
|  | 2 |  | 
|  | 3 | # Point to an empty file so any user's custom settings don't break things | 
|  | 4 | QUILTRCFILE ?= "${STAGING_ETCDIR_NATIVE}/quiltrc" | 
|  | 5 |  | 
|  | 6 | PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_sysroot" | 
|  | 7 |  | 
|  | 8 | inherit terminal | 
|  | 9 |  | 
|  | 10 | def src_patches(d, all = False ): | 
|  | 11 | workdir = d.getVar('WORKDIR', True) | 
|  | 12 | fetch = bb.fetch2.Fetch([], d) | 
|  | 13 | patches = [] | 
|  | 14 | sources = [] | 
|  | 15 | for url in fetch.urls: | 
|  | 16 | local = patch_path(url, fetch, workdir) | 
|  | 17 | if not local: | 
|  | 18 | if all: | 
|  | 19 | local = fetch.localpath(url) | 
|  | 20 | sources.append(local) | 
|  | 21 | continue | 
|  | 22 |  | 
|  | 23 | urldata = fetch.ud[url] | 
|  | 24 | parm = urldata.parm | 
|  | 25 | patchname = parm.get('pname') or os.path.basename(local) | 
|  | 26 |  | 
|  | 27 | apply, reason = should_apply(parm, d) | 
|  | 28 | if not apply: | 
|  | 29 | if reason: | 
|  | 30 | bb.note("Patch %s %s" % (patchname, reason)) | 
|  | 31 | continue | 
|  | 32 |  | 
|  | 33 | patchparm = {'patchname': patchname} | 
|  | 34 | if "striplevel" in parm: | 
|  | 35 | striplevel = parm["striplevel"] | 
|  | 36 | elif "pnum" in parm: | 
|  | 37 | #bb.msg.warn(None, "Deprecated usage of 'pnum' url parameter in '%s', please use 'striplevel'" % url) | 
|  | 38 | striplevel = parm["pnum"] | 
|  | 39 | else: | 
|  | 40 | striplevel = '1' | 
|  | 41 | patchparm['striplevel'] = striplevel | 
|  | 42 |  | 
|  | 43 | patchdir = parm.get('patchdir') | 
|  | 44 | if patchdir: | 
|  | 45 | patchparm['patchdir'] = patchdir | 
|  | 46 |  | 
|  | 47 | localurl = bb.fetch.encodeurl(('file', '', local, '', '', patchparm)) | 
|  | 48 | patches.append(localurl) | 
|  | 49 |  | 
|  | 50 | if all: | 
|  | 51 | return sources | 
|  | 52 |  | 
|  | 53 | return patches | 
|  | 54 |  | 
|  | 55 | def patch_path(url, fetch, workdir): | 
|  | 56 | """Return the local path of a patch, or None if this isn't a patch""" | 
|  | 57 |  | 
|  | 58 | local = fetch.localpath(url) | 
|  | 59 | base, ext = os.path.splitext(os.path.basename(local)) | 
|  | 60 | if ext in ('.gz', '.bz2', '.Z'): | 
|  | 61 | local = os.path.join(workdir, base) | 
|  | 62 | ext = os.path.splitext(base)[1] | 
|  | 63 |  | 
|  | 64 | urldata = fetch.ud[url] | 
|  | 65 | if "apply" in urldata.parm: | 
|  | 66 | apply = oe.types.boolean(urldata.parm["apply"]) | 
|  | 67 | if not apply: | 
|  | 68 | return | 
|  | 69 | elif ext not in (".diff", ".patch"): | 
|  | 70 | return | 
|  | 71 |  | 
|  | 72 | return local | 
|  | 73 |  | 
|  | 74 | def should_apply(parm, d): | 
|  | 75 | """Determine if we should apply the given patch""" | 
|  | 76 |  | 
|  | 77 | if "mindate" in parm or "maxdate" in parm: | 
|  | 78 | pn = d.getVar('PN', True) | 
|  | 79 | srcdate = d.getVar('SRCDATE_%s' % pn, True) | 
|  | 80 | if not srcdate: | 
|  | 81 | srcdate = d.getVar('SRCDATE', True) | 
|  | 82 |  | 
|  | 83 | if srcdate == "now": | 
|  | 84 | srcdate = d.getVar('DATE', True) | 
|  | 85 |  | 
|  | 86 | if "maxdate" in parm and parm["maxdate"] < srcdate: | 
|  | 87 | return False, 'is outdated' | 
|  | 88 |  | 
|  | 89 | if "mindate" in parm and parm["mindate"] > srcdate: | 
|  | 90 | return False, 'is predated' | 
|  | 91 |  | 
|  | 92 |  | 
|  | 93 | if "minrev" in parm: | 
|  | 94 | srcrev = d.getVar('SRCREV', True) | 
|  | 95 | if srcrev and srcrev < parm["minrev"]: | 
|  | 96 | return False, 'applies to later revisions' | 
|  | 97 |  | 
|  | 98 | if "maxrev" in parm: | 
|  | 99 | srcrev = d.getVar('SRCREV', True) | 
|  | 100 | if srcrev and srcrev > parm["maxrev"]: | 
|  | 101 | return False, 'applies to earlier revisions' | 
|  | 102 |  | 
|  | 103 | if "rev" in parm: | 
|  | 104 | srcrev = d.getVar('SRCREV', True) | 
|  | 105 | if srcrev and parm["rev"] not in srcrev: | 
|  | 106 | return False, "doesn't apply to revision" | 
|  | 107 |  | 
|  | 108 | if "notrev" in parm: | 
|  | 109 | srcrev = d.getVar('SRCREV', True) | 
|  | 110 | if srcrev and parm["notrev"] in srcrev: | 
|  | 111 | return False, "doesn't apply to revision" | 
|  | 112 |  | 
|  | 113 | return True, None | 
|  | 114 |  | 
|  | 115 | should_apply[vardepsexclude] = "DATE SRCDATE" | 
|  | 116 |  | 
|  | 117 | python patch_do_patch() { | 
|  | 118 | import oe.patch | 
|  | 119 |  | 
|  | 120 | patchsetmap = { | 
|  | 121 | "patch": oe.patch.PatchTree, | 
|  | 122 | "quilt": oe.patch.QuiltTree, | 
|  | 123 | "git": oe.patch.GitApplyTree, | 
|  | 124 | } | 
|  | 125 |  | 
|  | 126 | cls = patchsetmap[d.getVar('PATCHTOOL', True) or 'quilt'] | 
|  | 127 |  | 
|  | 128 | resolvermap = { | 
|  | 129 | "noop": oe.patch.NOOPResolver, | 
|  | 130 | "user": oe.patch.UserResolver, | 
|  | 131 | } | 
|  | 132 |  | 
|  | 133 | rcls = resolvermap[d.getVar('PATCHRESOLVE', True) or 'user'] | 
|  | 134 |  | 
|  | 135 | classes = {} | 
|  | 136 |  | 
|  | 137 | s = d.getVar('S', True) | 
|  | 138 |  | 
| Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 139 | os.putenv('PATH', d.getVar('PATH', True)) | 
|  | 140 |  | 
|  | 141 | # We must use one TMPDIR per process so that the "patch" processes | 
|  | 142 | # don't generate the same temp file name. | 
|  | 143 |  | 
|  | 144 | import tempfile | 
|  | 145 | process_tmpdir = tempfile.mkdtemp() | 
|  | 146 | os.environ['TMPDIR'] = process_tmpdir | 
|  | 147 |  | 
|  | 148 | for patch in src_patches(d): | 
|  | 149 | _, _, local, _, _, parm = bb.fetch.decodeurl(patch) | 
|  | 150 |  | 
|  | 151 | if "patchdir" in parm: | 
|  | 152 | patchdir = parm["patchdir"] | 
|  | 153 | if not os.path.isabs(patchdir): | 
|  | 154 | patchdir = os.path.join(s, patchdir) | 
|  | 155 | else: | 
|  | 156 | patchdir = s | 
|  | 157 |  | 
|  | 158 | if not patchdir in classes: | 
|  | 159 | patchset = cls(patchdir, d) | 
|  | 160 | resolver = rcls(patchset, oe_terminal) | 
|  | 161 | classes[patchdir] = (patchset, resolver) | 
|  | 162 | patchset.Clean() | 
|  | 163 | else: | 
|  | 164 | patchset, resolver = classes[patchdir] | 
|  | 165 |  | 
|  | 166 | bb.note("Applying patch '%s' (%s)" % (parm['patchname'], oe.path.format_display(local, d))) | 
|  | 167 | try: | 
|  | 168 | patchset.Import({"file":local, "strippath": parm['striplevel']}, True) | 
|  | 169 | except Exception as exc: | 
|  | 170 | bb.utils.remove(process_tmpdir, True) | 
|  | 171 | bb.fatal(str(exc)) | 
|  | 172 | try: | 
|  | 173 | resolver.Resolve() | 
|  | 174 | except bb.BBHandledException as e: | 
|  | 175 | bb.utils.remove(process_tmpdir, True) | 
|  | 176 | bb.fatal(str(e)) | 
|  | 177 |  | 
|  | 178 | bb.utils.remove(process_tmpdir, True) | 
|  | 179 | del os.environ['TMPDIR'] | 
|  | 180 | } | 
|  | 181 | patch_do_patch[vardepsexclude] = "PATCHRESOLVE" | 
|  | 182 |  | 
|  | 183 | addtask patch after do_unpack | 
|  | 184 | do_patch[dirs] = "${WORKDIR}" | 
|  | 185 | do_patch[depends] = "${PATCHDEPENDENCY}" | 
|  | 186 |  | 
|  | 187 | EXPORT_FUNCTIONS do_patch |