summaryrefslogtreecommitdiffstats
path: root/bitbake
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2024-08-12 15:53:06 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2024-08-13 15:47:55 +0100
commit5226f46342cae47cb96fafb725dc082ef206f9e8 (patch)
treef48ab32e3419d2a947e2309c5a4981dbd85abc8c /bitbake
parent36f98fc1f27015a1724f1677495227927341b0ff (diff)
downloadpoky-5226f46342cae47cb96fafb725dc082ef206f9e8.tar.gz
bitbake: BBHandler/ast: Improve addtask handling
The recent addtask improvement to handle comments complicated the regex significantly and there are already a number of corner cases in that code which aren't handled well. Instead of trying to complicate the regex further, switch to code logic instead. This means the following cases are now handled: * addtask with multiple task names * addtask with multiple before constraints * addtask with multiple after constraints The testcase is updated to match the improvements. (Bitbake rev: 417016b83c21fca7616b2ee768d5d08e1edd1e06) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake')
-rw-r--r--bitbake/lib/bb/parse/ast.py26
-rw-r--r--bitbake/lib/bb/parse/parse_py/BBHandler.py41
-rw-r--r--bitbake/lib/bb/tests/parse.py15
3 files changed, 38 insertions, 44 deletions
diff --git a/bitbake/lib/bb/parse/ast.py b/bitbake/lib/bb/parse/ast.py
index 7581d003fd..001ba8d289 100644
--- a/bitbake/lib/bb/parse/ast.py
+++ b/bitbake/lib/bb/parse/ast.py
@@ -240,14 +240,16 @@ class ExportFuncsNode(AstNode):
240 data.setVar(func, sentinel + " " + calledfunc + "\n", parsing=True) 240 data.setVar(func, sentinel + " " + calledfunc + "\n", parsing=True)
241 241
242class AddTaskNode(AstNode): 242class AddTaskNode(AstNode):
243 def __init__(self, filename, lineno, func, before, after): 243 def __init__(self, filename, lineno, tasks, before, after):
244 AstNode.__init__(self, filename, lineno) 244 AstNode.__init__(self, filename, lineno)
245 self.func = func 245 self.tasks = tasks
246 self.before = before 246 self.before = before
247 self.after = after 247 self.after = after
248 248
249 def eval(self, data): 249 def eval(self, data):
250 bb.build.addtask(self.func, self.before, self.after, data) 250 tasks = self.tasks.split()
251 for task in tasks:
252 bb.build.addtask(task, self.before, self.after, data)
251 253
252class DelTaskNode(AstNode): 254class DelTaskNode(AstNode):
253 def __init__(self, filename, lineno, tasks): 255 def __init__(self, filename, lineno, tasks):
@@ -348,21 +350,11 @@ def handlePythonMethod(statements, filename, lineno, funcname, modulename, body)
348def handleExportFuncs(statements, filename, lineno, m, classname): 350def handleExportFuncs(statements, filename, lineno, m, classname):
349 statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname)) 351 statements.append(ExportFuncsNode(filename, lineno, m.group(1), classname))
350 352
351def handleAddTask(statements, filename, lineno, m): 353def handleAddTask(statements, filename, lineno, tasks, before, after):
352 func = m.group("func") 354 statements.append(AddTaskNode(filename, lineno, tasks, before, after))
353 before = m.group("before")
354 after = m.group("after")
355 if func is None:
356 return
357
358 statements.append(AddTaskNode(filename, lineno, func, before, after))
359
360def handleDelTask(statements, filename, lineno, m):
361 func = m.group(1)
362 if func is None:
363 return
364 355
365 statements.append(DelTaskNode(filename, lineno, func)) 356def handleDelTask(statements, filename, lineno, tasks):
357 statements.append(DelTaskNode(filename, lineno, tasks))
366 358
367def handleBBHandlers(statements, filename, lineno, m): 359def handleBBHandlers(statements, filename, lineno, m):
368 statements.append(BBHandlerNode(filename, lineno, m.group(1))) 360 statements.append(BBHandlerNode(filename, lineno, m.group(1)))
diff --git a/bitbake/lib/bb/parse/parse_py/BBHandler.py b/bitbake/lib/bb/parse/parse_py/BBHandler.py
index c1653faeee..4bdb11994f 100644
--- a/bitbake/lib/bb/parse/parse_py/BBHandler.py
+++ b/bitbake/lib/bb/parse/parse_py/BBHandler.py
@@ -23,7 +23,7 @@ __func_start_regexp__ = re.compile(r"(((?P<py>python(?=(\s|\()))|(?P<fr>faker
23__inherit_regexp__ = re.compile(r"inherit\s+(.+)" ) 23__inherit_regexp__ = re.compile(r"inherit\s+(.+)" )
24__inherit_def_regexp__ = re.compile(r"inherit_defer\s+(.+)" ) 24__inherit_def_regexp__ = re.compile(r"inherit_defer\s+(.+)" )
25__export_func_regexp__ = re.compile(r"EXPORT_FUNCTIONS\s+(.+)" ) 25__export_func_regexp__ = re.compile(r"EXPORT_FUNCTIONS\s+(.+)" )
26__addtask_regexp__ = re.compile(r"addtask\s+(?P<func>\w+)\s*((before\s*(?P<before>(([^#\n]*(?=after))|([^#\n]*))))|(after\s*(?P<after>(([^#\n]*(?=before))|([^#\n]*)))))*(?P<comment>#.*|.*?)") 26__addtask_regexp__ = re.compile(r"addtask\s+([^#\n]+)(?P<comment>#.*|.*?)")
27__deltask_regexp__ = re.compile(r"deltask\s+([^#\n]+)(?P<comment>#.*|.*?)") 27__deltask_regexp__ = re.compile(r"deltask\s+([^#\n]+)(?P<comment>#.*|.*?)")
28__addhandler_regexp__ = re.compile(r"addhandler\s+(.+)" ) 28__addhandler_regexp__ = re.compile(r"addhandler\s+(.+)" )
29__def_regexp__ = re.compile(r"def\s+(\w+).*:" ) 29__def_regexp__ = re.compile(r"def\s+(\w+).*:" )
@@ -239,29 +239,38 @@ def feeder(lineno, s, fn, root, statements, eof=False):
239 239
240 m = __addtask_regexp__.match(s) 240 m = __addtask_regexp__.match(s)
241 if m: 241 if m:
242 if len(m.group().split()) == 2: 242 after = ""
243 # Check and warn for "addtask task1 task2" 243 before = ""
244 m2 = re.match(r"addtask\s+(?P<func>\w+)(?P<ignores>.*)", s) 244
245 if m2 and m2.group('ignores'): 245 # This code splits on 'before' and 'after' instead of on whitespace so we can defer
246 logger.warning('addtask ignored: "%s"' % m2.group('ignores')) 246 # evaluation to as late as possible.
247 247 tasks = m.group(1).split(" before ")[0].split(" after ")[0]
248 # Check and warn for "addtask task1 before task2 before task3", the 248
249 # similar to "after" 249 for exp in m.group(1).split(" before "):
250 taskexpression = s.split() 250 exp2 = exp.split(" after ")
251 for word in ('before', 'after'): 251 if len(exp2) > 1:
252 if taskexpression.count(word) > 1: 252 after = after + " ".join(exp2[1:])
253 logger.warning("addtask contained multiple '%s' keywords, only one is supported" % word)
254 253
255 # Check and warn for having task with exprssion as part of task name 254 for exp in m.group(1).split(" after "):
255 exp2 = exp.split(" before ")
256 if len(exp2) > 1:
257 before = before + " ".join(exp2[1:])
258
259 # Check and warn for having task with a keyword as part of task name
260 taskexpression = s.split()
256 for te in taskexpression: 261 for te in taskexpression:
257 if any( ( "%s_" % keyword ) in te for keyword in bb.data_smart.__setvar_keyword__ ): 262 if any( ( "%s_" % keyword ) in te for keyword in bb.data_smart.__setvar_keyword__ ):
258 raise ParseError("Task name '%s' contains a keyword which is not recommended/supported.\nPlease rename the task not to include the keyword.\n%s" % (te, ("\n".join(map(str, bb.data_smart.__setvar_keyword__)))), fn) 263 raise ParseError("Task name '%s' contains a keyword which is not recommended/supported.\nPlease rename the task not to include the keyword.\n%s" % (te, ("\n".join(map(str, bb.data_smart.__setvar_keyword__)))), fn)
259 ast.handleAddTask(statements, fn, lineno, m) 264
265 if tasks is not None:
266 ast.handleAddTask(statements, fn, lineno, tasks, before, after)
260 return 267 return
261 268
262 m = __deltask_regexp__.match(s) 269 m = __deltask_regexp__.match(s)
263 if m: 270 if m:
264 ast.handleDelTask(statements, fn, lineno, m) 271 task = m.group(1)
272 if task is not None:
273 ast.handleDelTask(statements, fn, lineno, task)
265 return 274 return
266 275
267 m = __addhandler_regexp__.match(s) 276 m = __addhandler_regexp__.match(s)
diff --git a/bitbake/lib/bb/tests/parse.py b/bitbake/lib/bb/tests/parse.py
index d076fcc208..97df2c4590 100644
--- a/bitbake/lib/bb/tests/parse.py
+++ b/bitbake/lib/bb/tests/parse.py
@@ -177,7 +177,7 @@ python () {
177 177
178 addtask_deltask = """ 178 addtask_deltask = """
179addtask do_patch after do_foo after do_unpack before do_configure before do_compile 179addtask do_patch after do_foo after do_unpack before do_configure before do_compile
180addtask do_fetch do_patch 180addtask do_fetch2 do_patch2
181 181
182addtask do_myplaintask 182addtask do_myplaintask
183addtask do_myplaintask2 183addtask do_myplaintask2
@@ -194,18 +194,11 @@ deltask do_fetch ${MYVAR} ${EMPTYVAR}
194deltask ${EMPTYVAR} 194deltask ${EMPTYVAR}
195""" 195"""
196 def test_parse_addtask_deltask(self): 196 def test_parse_addtask_deltask(self):
197 import sys
198 197
199 with self.assertLogs() as logs: 198 f = self.parsehelper(self.addtask_deltask)
200 f = self.parsehelper(self.addtask_deltask) 199 d = bb.parse.handle(f.name, self.d)['']
201 d = bb.parse.handle(f.name, self.d)['']
202 200
203 output = "".join(logs.output) 201 self.assertEqual(['do_fetch2', 'do_patch2', 'do_myplaintask', 'do_mytask', 'do_mytask2'], d.getVar("__BBTASKS"))
204 self.assertTrue("addtask contained multiple 'before' keywords" in output)
205 self.assertTrue("addtask contained multiple 'after' keywords" in output)
206 self.assertTrue('addtask ignored: " do_patch"' in output)
207 self.assertEqual(['do_myplaintask', 'do_mytask', 'do_mytask2'], d.getVar("__BBTASKS"))
208 #self.assertTrue('dependent task do_foo for do_patch does not exist' in output)
209 202
210 broken_multiline_comment = """ 203 broken_multiline_comment = """
211# First line of comment \\ 204# First line of comment \\