diff options
| -rw-r--r-- | meta/classes/patch.bbclass | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/meta/classes/patch.bbclass b/meta/classes/patch.bbclass index 28fdf07982..2cc1c36792 100644 --- a/meta/classes/patch.bbclass +++ b/meta/classes/patch.bbclass | |||
| @@ -6,11 +6,29 @@ QUILTRCFILE ?= "${STAGING_BINDIR_NATIVE}/quiltrc" | |||
| 6 | def patch_init(d): | 6 | def patch_init(d): |
| 7 | import os, sys | 7 | import os, sys |
| 8 | 8 | ||
| 9 | class NotFoundError(Exception): | ||
| 10 | def __init__(self, path): | ||
| 11 | self.path = path | ||
| 12 | def __str__(self): | ||
| 13 | return "Error: %s not found." % self.path | ||
| 14 | |||
| 9 | def md5sum(fname): | 15 | def md5sum(fname): |
| 10 | import md5, sys | 16 | import sys |
| 17 | |||
| 18 | # when we move to Python 2.5 as minimal supported | ||
| 19 | # we can kill that try/except as hashlib is 2.5+ | ||
| 20 | try: | ||
| 21 | import hashlib | ||
| 22 | m = hashlib.md5() | ||
| 23 | except ImportError: | ||
| 24 | import md5 | ||
| 25 | m = md5.new() | ||
| 26 | |||
| 27 | try: | ||
| 28 | f = file(fname, 'rb') | ||
| 29 | except IOError: | ||
| 30 | raise NotFoundError(fname) | ||
| 11 | 31 | ||
| 12 | f = file(fname, 'rb') | ||
| 13 | m = md5.new() | ||
| 14 | while True: | 32 | while True: |
| 15 | d = f.read(8096) | 33 | d = f.read(8096) |
| 16 | if not d: | 34 | if not d: |
| @@ -27,11 +45,6 @@ def patch_init(d): | |||
| 27 | def __str__(self): | 45 | def __str__(self): |
| 28 | return "Command Error: exit status: %d Output:\n%s" % (self.status, self.output) | 46 | return "Command Error: exit status: %d Output:\n%s" % (self.status, self.output) |
| 29 | 47 | ||
| 30 | class NotFoundError(Exception): | ||
| 31 | def __init__(self, path): | ||
| 32 | self.path = path | ||
| 33 | def __str__(self): | ||
| 34 | return "Error: %s not found." % self.path | ||
| 35 | 48 | ||
| 36 | def runcmd(args, dir = None): | 49 | def runcmd(args, dir = None): |
| 37 | import commands | 50 | import commands |
| @@ -41,7 +54,7 @@ def patch_init(d): | |||
| 41 | if not os.path.exists(dir): | 54 | if not os.path.exists(dir): |
| 42 | raise NotFoundError(dir) | 55 | raise NotFoundError(dir) |
| 43 | os.chdir(dir) | 56 | os.chdir(dir) |
| 44 | # print("cwd: %s -> %s" % (olddir, self.dir)) | 57 | # print("cwd: %s -> %s" % (olddir, dir)) |
| 45 | 58 | ||
| 46 | try: | 59 | try: |
| 47 | args = [ commands.mkarg(str(arg)) for arg in args ] | 60 | args = [ commands.mkarg(str(arg)) for arg in args ] |
| @@ -126,11 +139,14 @@ def patch_init(d): | |||
| 126 | i = 0 | 139 | i = 0 |
| 127 | self.patches.insert(i, patch) | 140 | self.patches.insert(i, patch) |
| 128 | 141 | ||
| 129 | def _applypatch(self, patch, force = None, reverse = None): | 142 | def _applypatch(self, patch, force = False, reverse = False, run = True): |
| 130 | shellcmd = ["cat", patch['file'], "|", "patch", "-p", patch['strippath']] | 143 | shellcmd = ["cat", patch['file'], "|", "patch", "-p", patch['strippath']] |
| 131 | if reverse: | 144 | if reverse: |
| 132 | shellcmd.append('-R') | 145 | shellcmd.append('-R') |
| 133 | 146 | ||
| 147 | if not run: | ||
| 148 | return "sh" + "-c" + " ".join(shellcmd) | ||
| 149 | |||
| 134 | if not force: | 150 | if not force: |
| 135 | shellcmd.append('--dry-run') | 151 | shellcmd.append('--dry-run') |
| 136 | 152 | ||
| @@ -143,7 +159,7 @@ def patch_init(d): | |||
| 143 | output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) | 159 | output = runcmd(["sh", "-c", " ".join(shellcmd)], self.dir) |
| 144 | return output | 160 | return output |
| 145 | 161 | ||
| 146 | def Push(self, force = None, all = None): | 162 | def Push(self, force = False, all = False, run = True): |
| 147 | if all: | 163 | if all: |
| 148 | for i in self.patches: | 164 | for i in self.patches: |
| 149 | if self._current is not None: | 165 | if self._current is not None: |
| @@ -158,7 +174,7 @@ def patch_init(d): | |||
| 158 | else: | 174 | else: |
| 159 | self._current = 0 | 175 | self._current = 0 |
| 160 | bb.note("applying patch %s" % self.patches[self._current]) | 176 | bb.note("applying patch %s" % self.patches[self._current]) |
| 161 | self._applypatch(self.patches[self._current], force) | 177 | return self._applypatch(self.patches[self._current], force) |
| 162 | 178 | ||
| 163 | 179 | ||
| 164 | def Pop(self, force = None, all = None): | 180 | def Pop(self, force = None, all = None): |
| @@ -172,8 +188,10 @@ def patch_init(d): | |||
| 172 | """""" | 188 | """""" |
| 173 | 189 | ||
| 174 | class QuiltTree(PatchSet): | 190 | class QuiltTree(PatchSet): |
| 175 | def _runcmd(self, args): | 191 | def _runcmd(self, args, run = True): |
| 176 | quiltrc = bb.data.getVar('QUILTRCFILE', self.d, 1) | 192 | quiltrc = bb.data.getVar('QUILTRCFILE', self.d, 1) |
| 193 | if not run: | ||
| 194 | return ["quilt"] + ["--quiltrc"] + [quiltrc] + args | ||
| 177 | runcmd(["quilt"] + ["--quiltrc"] + [quiltrc] + args, self.dir) | 195 | runcmd(["quilt"] + ["--quiltrc"] + [quiltrc] + args, self.dir) |
| 178 | 196 | ||
| 179 | def _quiltpatchpath(self, file): | 197 | def _quiltpatchpath(self, file): |
| @@ -248,7 +266,7 @@ def patch_init(d): | |||
| 248 | self.patches.insert(self._current or 0, patch) | 266 | self.patches.insert(self._current or 0, patch) |
| 249 | 267 | ||
| 250 | 268 | ||
| 251 | def Push(self, force = None, all = None): | 269 | def Push(self, force = False, all = False, run = True): |
| 252 | # quilt push [-f] | 270 | # quilt push [-f] |
| 253 | 271 | ||
| 254 | args = ["push"] | 272 | args = ["push"] |
| @@ -256,6 +274,8 @@ def patch_init(d): | |||
| 256 | args.append("-f") | 274 | args.append("-f") |
| 257 | if all: | 275 | if all: |
| 258 | args.append("-a") | 276 | args.append("-a") |
| 277 | if not run: | ||
| 278 | return self._runcmd(args, run) | ||
| 259 | 279 | ||
| 260 | self._runcmd(args) | 280 | self._runcmd(args) |
| 261 | 281 | ||
| @@ -342,17 +362,34 @@ def patch_init(d): | |||
| 342 | 362 | ||
| 343 | olddir = os.path.abspath(os.curdir) | 363 | olddir = os.path.abspath(os.curdir) |
| 344 | os.chdir(self.patchset.dir) | 364 | os.chdir(self.patchset.dir) |
| 345 | try: | 365 | try: |
| 346 | self.patchset.Push(True) | 366 | self.patchset.Push(False) |
| 347 | except CmdError, v: | 367 | except CmdError, v: |
| 348 | # Patch application failed | 368 | # Patch application failed |
| 349 | if sys.exc_value.output.strip() == "No patches applied": | 369 | patchcmd = self.patchset.Push(True, False, False) |
| 350 | return | 370 | |
| 351 | print(sys.exc_value) | 371 | t = bb.data.getVar('T', d, 1) |
| 352 | print('NOTE: dropping user into a shell, so that patch rejects can be fixed manually.') | 372 | if not t: |
| 353 | print('Press CTRL+D to exit.') | 373 | bb.msg.fatal(bb.msg.domain.Build, "T not set") |
| 354 | 374 | bb.mkdirhier(t) | |
| 355 | os.system('/bin/sh') | 375 | import random |
| 376 | rcfile = "%s/bashrc.%s.%s" % (t, str(os.getpid()), random.random()) | ||
| 377 | f = open(rcfile, "w") | ||
| 378 | f.write("echo '*** Manual patch resolution mode ***'\n") | ||
| 379 | f.write("echo 'Dropping to a shell, so patch rejects can be fixed manually.'\n") | ||
| 380 | f.write("echo 'Run \"quilt refresh\" when patch is corrected, press CTRL+D to exit.'\n") | ||
| 381 | f.write("echo ''\n") | ||
| 382 | f.write(" ".join(patchcmd) + "\n") | ||
| 383 | f.write("#" + bb.data.getVar('TERMCMDRUN', d, 1)) | ||
| 384 | f.close() | ||
| 385 | os.chmod(rcfile, 0775) | ||
| 386 | |||
| 387 | os.environ['TERMWINDOWTITLE'] = "Bitbake: Please fix patch rejects manually" | ||
| 388 | os.environ['TERMRCFILE'] = rcfile | ||
| 389 | rc = os.system(bb.data.getVar('TERMCMDRUN', d, 1)) | ||
| 390 | if os.WIFEXITED(rc) and os.WEXITSTATUS(rc) != 0: | ||
| 391 | bb.msg.fatal(bb.msg.domain.Build, ("Cannot proceed with manual patch resolution - '%s' not found. " \ | ||
| 392 | + "Check TERMCMDRUN variable.") % bb.data.getVar('TERMCMDRUN', d, 1)) | ||
| 356 | 393 | ||
| 357 | # Construct a new PatchSet after the user's changes, compare the | 394 | # Construct a new PatchSet after the user's changes, compare the |
| 358 | # sets, checking patches for modifications, and doing a remote | 395 | # sets, checking patches for modifications, and doing a remote |
| @@ -395,6 +432,7 @@ def patch_init(d): | |||
| 395 | 432 | ||
| 396 | addtask patch after do_unpack | 433 | addtask patch after do_unpack |
| 397 | do_patch[dirs] = "${WORKDIR}" | 434 | do_patch[dirs] = "${WORKDIR}" |
| 435 | |||
| 398 | PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_staging" | 436 | PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_staging" |
| 399 | do_patch[depends] = "${PATCHDEPENDENCY}" | 437 | do_patch[depends] = "${PATCHDEPENDENCY}" |
| 400 | 438 | ||
