summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meta/classes/patch.bbclass88
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"
6def patch_init(d): 6def 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
396addtask patch after do_unpack 433addtask patch after do_unpack
397do_patch[dirs] = "${WORKDIR}" 434do_patch[dirs] = "${WORKDIR}"
435
398PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_staging" 436PATCHDEPENDENCY = "${PATCHTOOL}-native:do_populate_staging"
399do_patch[depends] = "${PATCHDEPENDENCY}" 437do_patch[depends] = "${PATCHDEPENDENCY}"
400 438