summaryrefslogtreecommitdiff
path: root/classes/task-metadata-track.bbclass
diff options
context:
space:
mode:
Diffstat (limited to 'classes/task-metadata-track.bbclass')
-rw-r--r--classes/task-metadata-track.bbclass96
1 files changed, 96 insertions, 0 deletions
diff --git a/classes/task-metadata-track.bbclass b/classes/task-metadata-track.bbclass
new file mode 100644
index 0000000000..d3622aef68
--- /dev/null
+++ b/classes/task-metadata-track.bbclass
@@ -0,0 +1,96 @@
+# Copyright (C) 2009 Chris Larson <clarson@kergoth.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+#
+# This class uses events to capture the state of the datastore when the task
+# starts, and after it completes. It diffs those captured states, and emits
+# messages showing which variables changed, and what their values were changed
+# to.
+#
+# It provides a mechanism to blacklist variables you expect to change, both
+# globally and on a per-task basis.
+#
+# Known instances of tasks changing metadata:
+#
+# PSTAGE_PKGMANAGER changes by calls to pstage_set_pkgmanager in:
+# do_clean, do_setscene, do_package_stage
+#
+# Subpackage metadata, read by the pkgdata functions in base.bbclass, in:
+# do_package, do_package_stage, do_package_write_*
+
+
+TASK_METADATA_BLACKLIST = "\
+ __RUNQUEUE_DO_NOT_USE_EXTERNALLY \
+"
+
+#TASK_METADATA_BLACKLIST_do_clean = "\
+# PSTAGE_PKGMANAGER \
+#"
+
+
+def dict_diff(olddict, newdict):
+ diff = {}
+ for key in set(olddict).union(set(newdict)):
+ old = olddict.get(key)
+ new = newdict.get(key)
+ if old != new:
+ diff[key] = (old, new)
+
+ return diff
+
+def dict_for_data(data):
+ newdict = {}
+ for key in data.keys():
+ newdict[key] = data.getVar(key, False)
+ return newdict
+
+def task_metadata_track_start(task, data):
+ originaldata = dict_for_data(data)
+ data.setVar("__originaldata_%s" % task, originaldata)
+
+def task_metadata_track_stop(task, data):
+ from bb import note
+
+ pf = data.getVar("PF", True)
+ def emit(msg):
+ note("%s: %s" % (pf, msg))
+
+ originaldata = data.getVar("__originaldata_%s" % task, False)
+ newdata = dict_for_data(data)
+ blacklist = data.getVar("TASK_METADATA_BLACKLIST", True).split() + \
+ (data.getVar("TASK_METADATA_BLACKLIST_%s" % task, True) or "").split()
+
+ diff = dict_diff(originaldata, newdata)
+ diff_clean = [key for key in diff \
+ if not key in blacklist and \
+ not key.startswith("__originaldata_")]
+
+ if diff_clean:
+ emit("Variables changed by %s:" % task)
+ for key in diff_clean:
+ (old, new) = diff[key]
+ emit(" %s:" % key)
+ emit(" '%s' -> '%s'" % (old, new))
+
+python __task_metadata_track_eh () {
+ from bb.build import TaskStarted, TaskSucceeded
+
+ if isinstance(e, TaskStarted):
+ if e.data is None:
+ from bb import fatal
+ fatal("e.data is none for %s" % e)
+ task_metadata_track_start(e.task, e.data)
+ elif isinstance(e, TaskSucceeded):
+ task_metadata_track_stop(e.task, e.data)
+}
+addhandler __task_metadata_track_eh
+
+addtask py_listtasks
+do_py_listtasks[nostamp] = "1"
+do_py_listtasks[recrdeptask] = "do_py_listtasks"
+python do_py_listtasks() {
+ import sys
+ for e in d.keys():
+ if d.getVarFlag(e, "task") and \
+ d.getVarFlag(e, "python"):
+ sys.stdout.write("%s\n" % e)
+}