Add a task status 'canceled'

The purpose is to skip safely the tasks that have
missing dependencies due to build errors.
This commit is contained in:
Thomas Nagy 2017-01-21 23:47:44 +01:00
parent f1487eab44
commit 57b406aaff
No known key found for this signature in database
GPG Key ID: 49B4C67C05277AAA
2 changed files with 31 additions and 8 deletions

View File

@ -239,6 +239,12 @@ class Parallel(object):
"""
tsk.hasrun = Task.SKIPPED
def cancel(self, tsk):
"""
Mark a task as failed because of unsatisfiable dependencies
"""
tsk.hasrun = Task.CANCELED
def error_handler(self, tsk):
"""
Called when a task cannot be executed. The flag :py:attr:`waflib.Runner.Parallel.stop` is set, unless
@ -274,7 +280,7 @@ class Parallel(object):
if not self.stop and self.bld.keep:
self.skip(tsk)
if self.bld.keep == 1:
# if -k stop at the first exception, if -kk try to go as far as possible
# if -k stop on the first exception, if -kk try to go as far as possible
if Logs.verbose > 1 or not self.error:
self.error.append(tsk)
self.stop = True
@ -316,10 +322,9 @@ class Parallel(object):
self.processed += 1
continue
if self.stop: # stop immediately after a failure was detected
if self.stop: # stop immediately after a failure is detected
break
st = self.task_status(tsk)
if st == Task.RUN_ME:
self.count += 1
@ -333,12 +338,19 @@ class Parallel(object):
self.out.put(tsk)
else:
self.add_task(tsk)
if st == Task.ASK_LATER:
elif st == Task.ASK_LATER:
self.postpone(tsk)
elif st == Task.SKIP_ME:
self.processed += 1
self.skip(tsk)
self.add_more_tasks(tsk)
elif st == Task.CANCEL_ME:
# A dependency problem has occured, and the
# build is most likely run with `waf -k`
if Logs.verbose > 1:
self.error.append(tsk)
self.processed += 1
self.cancel(tsk)
# self.count represents the tasks that have been made available to the consumer threads
# collect all the tasks after an error else the message may be incomplete

View File

@ -22,6 +22,9 @@ CRASHED = 2
EXCEPTION = 3
"""An exception occured in the task execution"""
CANCELED = 4
"""A dependency for the task is missing so it was cancelled"""
SKIPPED = 8
"""The task did not have to be executed"""
@ -37,6 +40,9 @@ SKIP_ME = -2
RUN_ME = -3
"""The task must be executed"""
CANCEL_ME = -4
"""The task cannot be executed because of a dependency problem"""
COMPILE_TEMPLATE_SHELL = '''
def f(tsk):
env = tsk.env
@ -260,7 +266,8 @@ class TaskBase(evil):
"""
Returns the Task status
:return: a task state in :py:const:`waflib.Task.RUN_ME`, :py:const:`waflib.Task.SKIP_ME` or :py:const:`waflib.Task.ASK_LATER`.
:return: a task state in :py:const:`waflib.Task.RUN_ME`,
:py:const:`waflib.Task.SKIP_ME`, :py:const:`waflib.Task.CANCEL_ME` or :py:const:`waflib.Task.ASK_LATER`.
:rtype: int
"""
return RUN_ME
@ -276,7 +283,8 @@ class TaskBase(evil):
def process(self):
"""
Assume that the task has had a ``master`` which is an instance of :py:class:`waflib.Runner.Parallel`.
Execute the task and then put it back in the queue :py:attr:`waflib.Runner.Parallel.out` (may be replaced by subclassing).
Execute the task and then put it back in the queue :py:attr:`waflib.Runner.Parallel.out`
(may be replaced by subclassing).
:return: 0 or None if everything is fine
:rtype: integer
@ -426,6 +434,8 @@ class TaskBase(evil):
return ' -> task in %r failed%s' % (name, msg)
elif self.hasrun == MISSING:
return ' -> missing files in %r%s' % (name, msg)
elif self.hasrun == CANCELED:
return ' -> %r canceled because of missing dependencies' % name
else:
return 'invalid status for task in %r: %r' % (name, self.hasrun)
@ -646,11 +656,12 @@ class Task(TaskBase):
"""
See :py:meth:`waflib.Task.TaskBase.runnable_status`
"""
#return 0 # benchmarking
for t in self.run_after:
if not t.hasrun:
return ASK_LATER
elif t.hasrun < SKIPPED:
# a dependency has an error
return CANCEL_ME
# first compute the signature
try: