blob: f8c6a03bb905983eb0275f2ba26b12ac69343673 [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001"""
2BitBake 'Command' module
3
4Provide an interface to interact with the bitbake server through 'commands'
5"""
6
7# Copyright (C) 2006-2007 Richard Purdie
8#
Brad Bishopc342db32019-05-15 21:57:59 -04009# SPDX-License-Identifier: GPL-2.0-only
Patrick Williamsc124f4f2015-09-15 14:41:29 -050010#
Patrick Williamsc124f4f2015-09-15 14:41:29 -050011
12"""
13The bitbake server takes 'commands' from its UI/commandline.
14Commands are either synchronous or asynchronous.
15Async commands return data to the client in the form of events.
16Sync commands must only return data through the function return value
17and must not trigger events, directly or indirectly.
18Commands are queued in a CommandQueue
19"""
20
Brad Bishop6e60e8b2018-02-01 10:27:11 -050021from collections import OrderedDict, defaultdict
22
Patrick Williamsc124f4f2015-09-15 14:41:29 -050023import bb.event
24import bb.cooker
Brad Bishop6e60e8b2018-02-01 10:27:11 -050025import bb.remotedata
26
27class DataStoreConnectionHandle(object):
28 def __init__(self, dsindex=0):
29 self.dsindex = dsindex
Patrick Williamsc124f4f2015-09-15 14:41:29 -050030
31class CommandCompleted(bb.event.Event):
32 pass
33
34class CommandExit(bb.event.Event):
35 def __init__(self, exitcode):
36 bb.event.Event.__init__(self)
37 self.exitcode = int(exitcode)
38
39class CommandFailed(CommandExit):
40 def __init__(self, message):
41 self.error = message
42 CommandExit.__init__(self, 1)
Brad Bishopd7bf8c12018-02-25 22:55:05 -050043 def __str__(self):
44 return "Command execution failed: %s" % self.error
Patrick Williamsc124f4f2015-09-15 14:41:29 -050045
46class CommandError(Exception):
47 pass
48
49class Command:
50 """
51 A queue of asynchronous commands for bitbake
52 """
53 def __init__(self, cooker):
54 self.cooker = cooker
55 self.cmds_sync = CommandsSync()
56 self.cmds_async = CommandsAsync()
Andrew Geisslerc9f78652020-09-18 14:11:35 -050057 self.remotedatastores = None
Patrick Williamsc124f4f2015-09-15 14:41:29 -050058
59 # FIXME Add lock for this
60 self.currentAsyncCommand = None
61
62 def runCommand(self, commandline, ro_only = False):
63 command = commandline.pop(0)
Andrew Geisslerc9f78652020-09-18 14:11:35 -050064
65 # Ensure cooker is ready for commands
66 if command != "updateConfig" and command != "setFeatures":
67 self.cooker.init_configdata()
68 if not self.remotedatastores:
69 self.remotedatastores = bb.remotedata.RemoteDatastores(self.cooker)
70
Patrick Williamsc124f4f2015-09-15 14:41:29 -050071 if hasattr(CommandsSync, command):
72 # Can run synchronous commands straight away
73 command_method = getattr(self.cmds_sync, command)
74 if ro_only:
Andrew Geissler82c905d2020-04-13 13:39:40 -050075 if not hasattr(command_method, 'readonly') or not getattr(command_method, 'readonly'):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076 return None, "Not able to execute not readonly commands in readonly mode"
77 try:
Brad Bishopd7bf8c12018-02-25 22:55:05 -050078 self.cooker.process_inotify_updates()
79 if getattr(command_method, 'needconfig', True):
Patrick Williamsc124f4f2015-09-15 14:41:29 -050080 self.cooker.updateCacheSync()
81 result = command_method(self, commandline)
82 except CommandError as exc:
83 return None, exc.args[0]
84 except (Exception, SystemExit):
85 import traceback
86 return None, traceback.format_exc()
87 else:
88 return result, None
89 if self.currentAsyncCommand is not None:
90 return None, "Busy (%s in progress)" % self.currentAsyncCommand[0]
91 if command not in CommandsAsync.__dict__:
92 return None, "No such command"
93 self.currentAsyncCommand = (command, commandline)
Andrew Geissler635e0e42020-08-21 15:58:33 -050094 self.cooker.idleCallBackRegister(self.cooker.runCommands, self.cooker)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095 return True, None
96
97 def runAsyncCommand(self):
98 try:
Brad Bishopd7bf8c12018-02-25 22:55:05 -050099 self.cooker.process_inotify_updates()
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500100 if self.cooker.state in (bb.cooker.state.error, bb.cooker.state.shutdown, bb.cooker.state.forceshutdown):
101 # updateCache will trigger a shutdown of the parser
102 # and then raise BBHandledException triggering an exit
103 self.cooker.updateCache()
104 return False
105 if self.currentAsyncCommand is not None:
106 (command, options) = self.currentAsyncCommand
107 commandmethod = getattr(CommandsAsync, command)
108 needcache = getattr( commandmethod, "needcache" )
109 if needcache and self.cooker.state != bb.cooker.state.running:
110 self.cooker.updateCache()
111 return True
112 else:
113 commandmethod(self.cmds_async, self, options)
114 return False
115 else:
116 return False
117 except KeyboardInterrupt as exc:
118 self.finishAsyncCommand("Interrupted")
119 return False
120 except SystemExit as exc:
121 arg = exc.args[0]
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600122 if isinstance(arg, str):
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123 self.finishAsyncCommand(arg)
124 else:
125 self.finishAsyncCommand("Exited with %s" % arg)
126 return False
127 except Exception as exc:
128 import traceback
129 if isinstance(exc, bb.BBHandledException):
130 self.finishAsyncCommand("")
131 else:
132 self.finishAsyncCommand(traceback.format_exc())
133 return False
134
135 def finishAsyncCommand(self, msg=None, code=None):
136 if msg or msg == "":
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500137 bb.event.fire(CommandFailed(msg), self.cooker.data)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500138 elif code:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500139 bb.event.fire(CommandExit(code), self.cooker.data)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500140 else:
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500141 bb.event.fire(CommandCompleted(), self.cooker.data)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500142 self.currentAsyncCommand = None
143 self.cooker.finishcommand()
144
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500145 def reset(self):
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500146 if self.remotedatastores:
147 self.remotedatastores = bb.remotedata.RemoteDatastores(self.cooker)
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500148
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500149class CommandsSync:
150 """
151 A class of synchronous commands
152 These should run quickly so as not to hurt interactive performance.
153 These must not influence any running synchronous command.
154 """
155
156 def stateShutdown(self, command, params):
157 """
158 Trigger cooker 'shutdown' mode
159 """
160 command.cooker.shutdown(False)
161
162 def stateForceShutdown(self, command, params):
163 """
164 Stop the cooker
165 """
166 command.cooker.shutdown(True)
167
168 def getAllKeysWithFlags(self, command, params):
169 """
170 Returns a dump of the global state. Call with
171 variable flags to be retrieved as params.
172 """
173 flaglist = params[0]
174 return command.cooker.getAllKeysWithFlags(flaglist)
175 getAllKeysWithFlags.readonly = True
176
177 def getVariable(self, command, params):
178 """
179 Read the value of a variable from data
180 """
181 varname = params[0]
182 expand = True
183 if len(params) > 1:
184 expand = (params[1] == "True")
185
186 return command.cooker.data.getVar(varname, expand)
187 getVariable.readonly = True
188
189 def setVariable(self, command, params):
190 """
191 Set the value of variable in data
192 """
193 varname = params[0]
194 value = str(params[1])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500195 command.cooker.extraconfigdata[varname] = value
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500196 command.cooker.data.setVar(varname, value)
197
Patrick Williamsf1e5d692016-03-30 15:21:19 -0500198 def getSetVariable(self, command, params):
199 """
200 Read the value of a variable from data and set it into the datastore
201 which effectively expands and locks the value.
202 """
203 varname = params[0]
204 result = self.getVariable(command, params)
205 command.cooker.data.setVar(varname, result)
206 return result
207
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500208 def setConfig(self, command, params):
209 """
210 Set the value of variable in configuration
211 """
212 varname = params[0]
213 value = str(params[1])
214 setattr(command.cooker.configuration, varname, value)
215
216 def enableDataTracking(self, command, params):
217 """
218 Enable history tracking for variables
219 """
220 command.cooker.enableDataTracking()
221
222 def disableDataTracking(self, command, params):
223 """
224 Disable history tracking for variables
225 """
226 command.cooker.disableDataTracking()
227
228 def setPrePostConfFiles(self, command, params):
229 prefiles = params[0].split()
230 postfiles = params[1].split()
231 command.cooker.configuration.prefile = prefiles
232 command.cooker.configuration.postfile = postfiles
233 setPrePostConfFiles.needconfig = False
234
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500235 def matchFile(self, command, params):
236 fMatch = params[0]
Andrew Geissler5a43b432020-06-13 10:46:56 -0500237 try:
238 mc = params[0]
239 except IndexError:
240 mc = ''
241 return command.cooker.matchFile(fMatch, mc)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500242 matchFile.needconfig = False
243
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500244 def getUIHandlerNum(self, command, params):
245 return bb.event.get_uihandler()
246 getUIHandlerNum.needconfig = False
247 getUIHandlerNum.readonly = True
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500248
249 def setEventMask(self, command, params):
250 handlerNum = params[0]
251 llevel = params[1]
252 debug_domains = params[2]
253 mask = params[3]
254 return bb.event.set_UIHmask(handlerNum, llevel, debug_domains, mask)
255 setEventMask.needconfig = False
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500256 setEventMask.readonly = True
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500257
258 def setFeatures(self, command, params):
259 """
260 Set the cooker features to include the passed list of features
261 """
262 features = params[0]
263 command.cooker.setFeatures(features)
264 setFeatures.needconfig = False
265 # although we change the internal state of the cooker, this is transparent since
266 # we always take and leave the cooker in state.initial
267 setFeatures.readonly = True
268
269 def updateConfig(self, command, params):
270 options = params[0]
271 environment = params[1]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500272 cmdline = params[2]
273 command.cooker.updateConfigOpts(options, environment, cmdline)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500274 updateConfig.needconfig = False
275
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500276 def parseConfiguration(self, command, params):
277 """Instruct bitbake to parse its configuration
278 NOTE: it is only necessary to call this if you aren't calling any normal action
279 (otherwise parsing is taken care of automatically)
280 """
281 command.cooker.parseConfiguration()
282 parseConfiguration.needconfig = False
283
284 def getLayerPriorities(self, command, params):
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500285 command.cooker.parseConfiguration()
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500286 ret = []
287 # regex objects cannot be marshalled by xmlrpc
288 for collection, pattern, regex, pri in command.cooker.bbfile_config_priorities:
289 ret.append((collection, pattern, regex.pattern, pri))
290 return ret
291 getLayerPriorities.readonly = True
292
293 def getRecipes(self, command, params):
294 try:
295 mc = params[0]
296 except IndexError:
297 mc = ''
298 return list(command.cooker.recipecaches[mc].pkg_pn.items())
299 getRecipes.readonly = True
300
301 def getRecipeDepends(self, command, params):
302 try:
303 mc = params[0]
304 except IndexError:
305 mc = ''
306 return list(command.cooker.recipecaches[mc].deps.items())
307 getRecipeDepends.readonly = True
308
309 def getRecipeVersions(self, command, params):
310 try:
311 mc = params[0]
312 except IndexError:
313 mc = ''
314 return command.cooker.recipecaches[mc].pkg_pepvpr
315 getRecipeVersions.readonly = True
316
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500317 def getRecipeProvides(self, command, params):
318 try:
319 mc = params[0]
320 except IndexError:
321 mc = ''
322 return command.cooker.recipecaches[mc].fn_provides
323 getRecipeProvides.readonly = True
324
325 def getRecipePackages(self, command, params):
326 try:
327 mc = params[0]
328 except IndexError:
329 mc = ''
330 return command.cooker.recipecaches[mc].packages
331 getRecipePackages.readonly = True
332
333 def getRecipePackagesDynamic(self, command, params):
334 try:
335 mc = params[0]
336 except IndexError:
337 mc = ''
338 return command.cooker.recipecaches[mc].packages_dynamic
339 getRecipePackagesDynamic.readonly = True
340
341 def getRProviders(self, command, params):
342 try:
343 mc = params[0]
344 except IndexError:
345 mc = ''
346 return command.cooker.recipecaches[mc].rproviders
347 getRProviders.readonly = True
348
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500349 def getRuntimeDepends(self, command, params):
350 ret = []
351 try:
352 mc = params[0]
353 except IndexError:
354 mc = ''
355 rundeps = command.cooker.recipecaches[mc].rundeps
356 for key, value in rundeps.items():
357 if isinstance(value, defaultdict):
358 value = dict(value)
359 ret.append((key, value))
360 return ret
361 getRuntimeDepends.readonly = True
362
363 def getRuntimeRecommends(self, command, params):
364 ret = []
365 try:
366 mc = params[0]
367 except IndexError:
368 mc = ''
369 runrecs = command.cooker.recipecaches[mc].runrecs
370 for key, value in runrecs.items():
371 if isinstance(value, defaultdict):
372 value = dict(value)
373 ret.append((key, value))
374 return ret
375 getRuntimeRecommends.readonly = True
376
377 def getRecipeInherits(self, command, params):
378 try:
379 mc = params[0]
380 except IndexError:
381 mc = ''
382 return command.cooker.recipecaches[mc].inherits
383 getRecipeInherits.readonly = True
384
385 def getBbFilePriority(self, command, params):
386 try:
387 mc = params[0]
388 except IndexError:
389 mc = ''
390 return command.cooker.recipecaches[mc].bbfile_priority
391 getBbFilePriority.readonly = True
392
393 def getDefaultPreference(self, command, params):
394 try:
395 mc = params[0]
396 except IndexError:
397 mc = ''
398 return command.cooker.recipecaches[mc].pkg_dp
399 getDefaultPreference.readonly = True
400
401 def getSkippedRecipes(self, command, params):
402 # Return list sorted by reverse priority order
403 import bb.cache
Andrew Geissler5a43b432020-06-13 10:46:56 -0500404 def sortkey(x):
405 vfn, _ = x
406 realfn, _, mc = bb.cache.virtualfn2realfn(vfn)
Andrew Geisslerb7d28612020-07-24 16:15:54 -0500407 return (-command.cooker.collections[mc].calc_bbfile_priority(realfn)[0], vfn)
Andrew Geissler5a43b432020-06-13 10:46:56 -0500408
409 skipdict = OrderedDict(sorted(command.cooker.skiplist.items(), key=sortkey))
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500410 return list(skipdict.items())
411 getSkippedRecipes.readonly = True
412
413 def getOverlayedRecipes(self, command, params):
Andrew Geissler5a43b432020-06-13 10:46:56 -0500414 try:
415 mc = params[0]
416 except IndexError:
417 mc = ''
418 return list(command.cooker.collections[mc].overlayed.items())
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500419 getOverlayedRecipes.readonly = True
420
421 def getFileAppends(self, command, params):
422 fn = params[0]
Andrew Geissler5a43b432020-06-13 10:46:56 -0500423 try:
424 mc = params[1]
425 except IndexError:
426 mc = ''
427 return command.cooker.collections[mc].get_file_appends(fn)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500428 getFileAppends.readonly = True
429
430 def getAllAppends(self, command, params):
Andrew Geissler5a43b432020-06-13 10:46:56 -0500431 try:
432 mc = params[0]
433 except IndexError:
434 mc = ''
435 return command.cooker.collections[mc].bbappends
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500436 getAllAppends.readonly = True
437
438 def findProviders(self, command, params):
Andrew Geissler82c905d2020-04-13 13:39:40 -0500439 try:
440 mc = params[0]
441 except IndexError:
442 mc = ''
443 return command.cooker.findProviders(mc)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500444 findProviders.readonly = True
445
446 def findBestProvider(self, command, params):
Andrew Geissler5a43b432020-06-13 10:46:56 -0500447 (mc, pn) = bb.runqueue.split_mc(params[0])
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500448 return command.cooker.findBestProvider(pn, mc)
449 findBestProvider.readonly = True
450
451 def allProviders(self, command, params):
452 try:
453 mc = params[0]
454 except IndexError:
455 mc = ''
456 return list(bb.providers.allProviders(command.cooker.recipecaches[mc]).items())
457 allProviders.readonly = True
458
459 def getRuntimeProviders(self, command, params):
460 rprovide = params[0]
461 try:
462 mc = params[1]
463 except IndexError:
464 mc = ''
465 all_p = bb.providers.getRuntimeProviders(command.cooker.recipecaches[mc], rprovide)
466 if all_p:
467 best = bb.providers.filterProvidersRunTime(all_p, rprovide,
468 command.cooker.data,
469 command.cooker.recipecaches[mc])[0][0]
470 else:
471 best = None
472 return all_p, best
473 getRuntimeProviders.readonly = True
474
Andrew Geissler82c905d2020-04-13 13:39:40 -0500475 def dataStoreConnectorCmd(self, command, params):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500476 dsindex = params[0]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500477 method = params[1]
478 args = params[2]
479 kwargs = params[3]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500480
Andrew Geissler82c905d2020-04-13 13:39:40 -0500481 d = command.remotedatastores[dsindex]
482 ret = getattr(d, method)(*args, **kwargs)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500483
Andrew Geissler82c905d2020-04-13 13:39:40 -0500484 if isinstance(ret, bb.data_smart.DataSmart):
485 idx = command.remotedatastores.store(ret)
486 return DataStoreConnectionHandle(idx)
487
488 return ret
489
490 def dataStoreConnectorVarHistCmd(self, command, params):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500491 dsindex = params[0]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500492 method = params[1]
493 args = params[2]
494 kwargs = params[3]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500495
Andrew Geissler82c905d2020-04-13 13:39:40 -0500496 d = command.remotedatastores[dsindex].varhistory
497 return getattr(d, method)(*args, **kwargs)
498
499 def dataStoreConnectorIncHistCmd(self, command, params):
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500500 dsindex = params[0]
Andrew Geissler82c905d2020-04-13 13:39:40 -0500501 method = params[1]
502 args = params[2]
503 kwargs = params[3]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500504
Andrew Geissler82c905d2020-04-13 13:39:40 -0500505 d = command.remotedatastores[dsindex].inchistory
506 return getattr(d, method)(*args, **kwargs)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500507
508 def dataStoreConnectorRelease(self, command, params):
509 dsindex = params[0]
510 if dsindex <= 0:
511 raise CommandError('dataStoreConnectorRelease: invalid index %d' % dsindex)
512 command.remotedatastores.release(dsindex)
513
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500514 def parseRecipeFile(self, command, params):
515 """
516 Parse the specified recipe file (with or without bbappends)
517 and return a datastore object representing the environment
518 for the recipe.
519 """
520 fn = params[0]
Andrew Geissler5a43b432020-06-13 10:46:56 -0500521 mc = bb.runqueue.mc_from_tid(fn)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500522 appends = params[1]
523 appendlist = params[2]
524 if len(params) > 3:
Andrew Geissler82c905d2020-04-13 13:39:40 -0500525 config_data = command.remotedatastores[params[3]]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500526 else:
527 config_data = None
528
529 if appends:
530 if appendlist is not None:
531 appendfiles = appendlist
532 else:
Andrew Geissler5a43b432020-06-13 10:46:56 -0500533 appendfiles = command.cooker.collections[mc].get_file_appends(fn)
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500534 else:
535 appendfiles = []
536 # We are calling bb.cache locally here rather than on the server,
537 # but that's OK because it doesn't actually need anything from
538 # the server barring the global datastore (which we have a remote
539 # version of)
540 if config_data:
541 # We have to use a different function here if we're passing in a datastore
542 # NOTE: we took a copy above, so we don't do it here again
Andrew Geissler5a43b432020-06-13 10:46:56 -0500543 envdata = bb.cache.parse_recipe(config_data, fn, appendfiles, mc)['']
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500544 else:
545 # Use the standard path
546 parser = bb.cache.NoCache(command.cooker.databuilder)
547 envdata = parser.loadDataFull(fn, appendfiles)
548 idx = command.remotedatastores.store(envdata)
549 return DataStoreConnectionHandle(idx)
550 parseRecipeFile.readonly = True
551
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500552class CommandsAsync:
553 """
554 A class of asynchronous commands
555 These functions communicate via generated events.
556 Any function that requires metadata parsing should be here.
557 """
558
559 def buildFile(self, command, params):
560 """
561 Build a single specified .bb file
562 """
563 bfile = params[0]
564 task = params[1]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500565 if len(params) > 2:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500566 internal = params[2]
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500567 else:
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500568 internal = False
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500569
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500570 if internal:
571 command.cooker.buildFileInternal(bfile, task, fireevents=False, quietlog=True)
572 else:
573 command.cooker.buildFile(bfile, task)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500574 buildFile.needcache = False
575
576 def buildTargets(self, command, params):
577 """
578 Build a set of targets
579 """
580 pkgs_to_build = params[0]
581 task = params[1]
582
583 command.cooker.buildTargets(pkgs_to_build, task)
584 buildTargets.needcache = True
585
586 def generateDepTreeEvent(self, command, params):
587 """
588 Generate an event containing the dependency information
589 """
590 pkgs_to_build = params[0]
591 task = params[1]
592
593 command.cooker.generateDepTreeEvent(pkgs_to_build, task)
594 command.finishAsyncCommand()
595 generateDepTreeEvent.needcache = True
596
597 def generateDotGraph(self, command, params):
598 """
599 Dump dependency information to disk as .dot files
600 """
601 pkgs_to_build = params[0]
602 task = params[1]
603
604 command.cooker.generateDotGraphFiles(pkgs_to_build, task)
605 command.finishAsyncCommand()
606 generateDotGraph.needcache = True
607
608 def generateTargetsTree(self, command, params):
609 """
610 Generate a tree of buildable targets.
611 If klass is provided ensure all recipes that inherit the class are
612 included in the package list.
613 If pkg_list provided use that list (plus any extras brought in by
614 klass) rather than generating a tree for all packages.
615 """
616 klass = params[0]
617 pkg_list = params[1]
618
619 command.cooker.generateTargetsTree(klass, pkg_list)
620 command.finishAsyncCommand()
621 generateTargetsTree.needcache = True
622
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500623 def findConfigFiles(self, command, params):
624 """
625 Find config files which provide appropriate values
626 for the passed configuration variable. i.e. MACHINE
627 """
628 varname = params[0]
629
630 command.cooker.findConfigFiles(varname)
631 command.finishAsyncCommand()
632 findConfigFiles.needcache = False
633
634 def findFilesMatchingInDir(self, command, params):
635 """
636 Find implementation files matching the specified pattern
637 in the requested subdirectory of a BBPATH
638 """
639 pattern = params[0]
640 directory = params[1]
641
642 command.cooker.findFilesMatchingInDir(pattern, directory)
643 command.finishAsyncCommand()
644 findFilesMatchingInDir.needcache = False
645
646 def findConfigFilePath(self, command, params):
647 """
648 Find the path of the requested configuration file
649 """
650 configfile = params[0]
651
652 command.cooker.findConfigFilePath(configfile)
653 command.finishAsyncCommand()
654 findConfigFilePath.needcache = False
655
656 def showVersions(self, command, params):
657 """
658 Show the currently selected versions
659 """
660 command.cooker.showVersions()
661 command.finishAsyncCommand()
662 showVersions.needcache = True
663
664 def showEnvironmentTarget(self, command, params):
665 """
666 Print the environment of a target recipe
667 (needs the cache to work out which recipe to use)
668 """
669 pkg = params[0]
670
671 command.cooker.showEnvironment(None, pkg)
672 command.finishAsyncCommand()
673 showEnvironmentTarget.needcache = True
674
675 def showEnvironment(self, command, params):
676 """
677 Print the standard environment
678 or if specified the environment for a specified recipe
679 """
680 bfile = params[0]
681
682 command.cooker.showEnvironment(bfile)
683 command.finishAsyncCommand()
684 showEnvironment.needcache = False
685
686 def parseFiles(self, command, params):
687 """
688 Parse the .bb files
689 """
690 command.cooker.updateCache()
691 command.finishAsyncCommand()
692 parseFiles.needcache = True
693
694 def compareRevisions(self, command, params):
695 """
696 Parse the .bb files
697 """
698 if bb.fetch.fetcher_compare_revisions(command.cooker.data):
699 command.finishAsyncCommand(code=1)
700 else:
701 command.finishAsyncCommand()
702 compareRevisions.needcache = True
703
704 def triggerEvent(self, command, params):
705 """
706 Trigger a certain event
707 """
708 event = params[0]
709 bb.event.fire(eval(event), command.cooker.data)
710 command.currentAsyncCommand = None
711 triggerEvent.needcache = False
712
713 def resetCooker(self, command, params):
714 """
715 Reset the cooker to its initial state, thus forcing a reparse for
716 any async command that has the needcache property set to True
717 """
718 command.cooker.reset()
719 command.finishAsyncCommand()
720 resetCooker.needcache = False
721
Brad Bishop6e60e8b2018-02-01 10:27:11 -0500722 def clientComplete(self, command, params):
723 """
724 Do the right thing when the controlling client exits
725 """
726 command.cooker.clientComplete()
727 command.finishAsyncCommand()
728 clientComplete.needcache = False
729
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500730 def findSigInfo(self, command, params):
731 """
732 Find signature info files via the signature generator
733 """
Andrew Geissler635e0e42020-08-21 15:58:33 -0500734 (mc, pn) = bb.runqueue.split_mc(params[0])
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500735 taskname = params[1]
736 sigs = params[2]
Andrew Geissler635e0e42020-08-21 15:58:33 -0500737 res = bb.siggen.find_siginfo(pn, taskname, sigs, command.cooker.databuilder.mcdata[mc])
738 bb.event.fire(bb.event.FindSigInfoResult(res), command.cooker.databuilder.mcdata[mc])
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500739 command.finishAsyncCommand()
740 findSigInfo.needcache = False