1#! /usr/bin/env python
2# encoding: utf-8
3# Thomas Nagy, 2010 (ita)
4
5"""
6This tool modifies the task signature scheme to store and obtain
7information about the task execution (why it must run, etc)::
8
9	def configure(conf):
10		conf.load('why')
11
12After adding the tool, a full rebuild is necessary:
13waf clean build --zones=task
14"""
15
16from waflib import Task, Utils, Logs, Errors
17
18def signature(self):
19	# compute the result one time, and suppose the scan_signature will give the good result
20	try:
21		return self.cache_sig
22	except AttributeError:
23		pass
24
25	self.m = Utils.md5()
26	self.m.update(self.hcode)
27	id_sig = self.m.digest()
28
29	# explicit deps
30	self.m = Utils.md5()
31	self.sig_explicit_deps()
32	exp_sig = self.m.digest()
33
34	# env vars
35	self.m = Utils.md5()
36	self.sig_vars()
37	var_sig = self.m.digest()
38
39	# implicit deps / scanner results
40	self.m = Utils.md5()
41	if self.scan:
42		try:
43			self.sig_implicit_deps()
44		except Errors.TaskRescan:
45			return self.signature()
46	impl_sig = self.m.digest()
47
48	ret = self.cache_sig = impl_sig + id_sig + exp_sig + var_sig
49	return ret
50
51
52Task.Task.signature = signature
53
54old = Task.Task.runnable_status
55def runnable_status(self):
56	ret = old(self)
57	if ret == Task.RUN_ME:
58		try:
59			old_sigs = self.generator.bld.task_sigs[self.uid()]
60		except (KeyError, AttributeError):
61			Logs.debug("task: task must run as no previous signature exists")
62		else:
63			new_sigs = self.cache_sig
64			def v(x):
65				return Utils.to_hex(x)
66
67			Logs.debug('Task %r', self)
68			msgs = ['* Implicit or scanner dependency', '* Task code', '* Source file, explicit or manual dependency', '* Configuration data variable']
69			tmp = 'task: -> %s: %s %s'
70			for x in range(len(msgs)):
71				l = len(Utils.SIG_NIL)
72				a = new_sigs[x*l : (x+1)*l]
73				b = old_sigs[x*l : (x+1)*l]
74				if (a != b):
75					Logs.debug(tmp, msgs[x].ljust(35), v(a), v(b))
76	return ret
77Task.Task.runnable_status = runnable_status
78
79