1 # Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
2 # Released under the MIT license (see COPYING.MIT for the terms)
4 # This class uses events to capture the state of the datastore when the task
5 # starts, and after it completes. It diffs those captured states, and emits
6 # messages showing which variables changed, and what their values were changed
9 # It provides a mechanism to blacklist variables you expect to change, both
10 # globally and on a per-task basis.
12 # Known instances of tasks changing metadata:
14 # PSTAGE_PKGMANAGER changes by calls to pstage_set_pkgmanager in:
15 # do_clean, do_setscene, do_package_stage
17 # Subpackage metadata, read by the pkgdata functions in base.bbclass, in:
18 # do_package, do_package_stage, do_package_write_*
21 TASK_METADATA_BLACKLIST = "\
22 __RUNQUEUE_DO_NOT_USE_EXTERNALLY \
25 #TASK_METADATA_BLACKLIST_do_clean = "\
30 def dict_diff(olddict, newdict):
32 for key in set(olddict).union(set(newdict)):
33 old = olddict.get(key)
34 new = newdict.get(key)
36 diff[key] = (old, new)
40 def dict_for_data(data):
42 for key in data.keys():
43 newdict[key] = data.getVar(key, False)
46 def task_metadata_track_start(task, data):
47 originaldata = dict_for_data(data)
48 data.setVar("__originaldata_%s" % task, originaldata)
50 def task_metadata_track_stop(task, data):
53 pf = data.getVar("PF", True)
55 note("%s: %s" % (pf, msg))
57 originaldata = data.getVar("__originaldata_%s" % task, False)
58 newdata = dict_for_data(data)
59 blacklist = data.getVar("TASK_METADATA_BLACKLIST", True).split() + \
60 (data.getVar("TASK_METADATA_BLACKLIST_%s" % task, True) or "").split()
62 diff = dict_diff(originaldata, newdata)
63 diff_clean = [key for key in diff \
64 if not key in blacklist and \
65 not key.startswith("__originaldata_")]
68 emit("Variables changed by %s:" % task)
69 for key in diff_clean:
70 (old, new) = diff[key]
72 emit(" '%s' -> '%s'" % (old, new))
74 python __task_metadata_track_eh () {
75 from bb.build import TaskStarted, TaskSucceeded
77 if isinstance(e, TaskStarted):
80 fatal("e.data is none for %s" % e)
81 task_metadata_track_start(e.task, e.data)
82 elif isinstance(e, TaskSucceeded):
83 task_metadata_track_stop(e.task, e.data)
85 addhandler __task_metadata_track_eh
88 do_py_listtasks[nostamp] = "1"
89 do_py_listtasks[recrdeptask] = "do_py_listtasks"
90 python do_py_listtasks() {
93 if d.getVarFlag(e, "task") and \
94 d.getVarFlag(e, "python"):
95 sys.stdout.write("%s\n" % e)