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