def install(self, task_registrar, first=False, replace=False, before=None, after=None): """Installs the given task in this goal. The placement of the task in this goal's execution list defaults to the end but its position can be influenced by specifying exactly one of the following arguments: first: Places the task 1st in the execution list. replace: Removes all existing tasks in this goal and installs this task. before: Places the task before the named task in the execution list. after: Places the task after the named task in the execution list. :API: public """ if [bool(place) for place in [first, replace, before, after]].count(True) > 1: raise GoalError('Can only specify one of first, replace, before or after') task_name = task_registrar.name Optionable.validate_scope_name_component(task_name) options_scope = Goal.scope(self.name, task_name) # Currently we need to support registering the same task type multiple times in different # scopes. However we still want to have each task class know the options scope it was # registered in. So we create a synthetic subclass here. # TODO(benjy): Revisit this when we revisit the task lifecycle. We probably want to have # a task *instance* know its scope, but this means converting option registration from # a class method to an instance method, and instantiating the task much sooner in the # lifecycle. superclass = task_registrar.task_type subclass_name = b'{0}_{1}'.format(superclass.__name__, options_scope.replace('.', '_').replace('-', '_')) task_type = type(subclass_name, (superclass,), { '__doc__': superclass.__doc__, '__module__': superclass.__module__, 'options_scope': options_scope, '_stable_name': superclass.stable_name() }) otn = self._ordered_task_names if replace: for tt in self.task_types(): tt.options_scope = None del otn[:] self._task_type_by_name = {} if first: otn.insert(0, task_name) elif before in otn: otn.insert(otn.index(before), task_name) elif after in otn: otn.insert(otn.index(after) + 1, task_name) else: otn.append(task_name) self._task_type_by_name[task_name] = task_type if task_registrar.serialize: self.serialize = True return self
def install(self, task_registrar, first=False, replace=False, before=None, after=None): """Installs the given task in this goal. The placement of the task in this goal's execution list defaults to the end but its position can be influenced by specifying exactly one of the following arguments: first: Places the task 1st in the execution list. replace: Removes all existing tasks in this goal and installs this task. before: Places the task before the named task in the execution list. after: Places the task after the named task in the execution list. :API: public """ if [bool(place) for place in [first, replace, before, after]].count(True) > 1: raise GoalError( "Can only specify one of first, replace, before or after") otn = self._ordered_task_names if replace: for tt in self.task_types(): tt.options_scope = None del otn[:] self._task_type_by_name = {} task_name = task_registrar.name if task_name in self._task_type_by_name: raise GoalError( "Can only specify a task name once per goal, saw multiple values for {} in goal {}" .format(task_name, self.name)) Optionable.validate_scope_name_component(task_name) options_scope = Goal.scope(self.name, task_name) task_type = _create_stable_task_type(task_registrar.task_type, options_scope) if first: otn.insert(0, task_name) elif before in otn: otn.insert(otn.index(before), task_name) elif after in otn: otn.insert(otn.index(after) + 1, task_name) else: otn.append(task_name) self._task_type_by_name[task_name] = task_type if task_registrar.serialize: self.serialize = True return self
def __init__(self, name): """Don't call this directly. Create goals only through the Goal.by_name() factory. """ Optionable.validate_scope_name_component(name) self.name = name self._description = '' self.serialize = False self._task_type_by_name = {} # name -> Task subclass. self._ordered_task_names = [] # The task names, in the order imposed by registration.
def __init__(self, name): """Don't call this directly. Create goals only through the Goal.by_name() factory. """ Optionable.validate_scope_name_component(name) self.name = name self._description = '' self.serialize = False self._task_type_by_name = {} # name -> Task subclass. self._ordered_task_names = [ ] # The task names, in the order imposed by registration.
def install(self, task_registrar, first=False, replace=False, before=None, after=None): """Installs the given task in this goal. The placement of the task in this goal's execution list defaults to the end but its position can be influenced by specifying exactly one of the following arguments: first: Places the task 1st in the execution list. replace: Removes all existing tasks in this goal and installs this task. before: Places the task before the named task in the execution list. after: Places the task after the named task in the execution list. :API: public """ if [bool(place) for place in [first, replace, before, after]].count(True) > 1: raise GoalError('Can only specify one of first, replace, before or after') otn = self._ordered_task_names if replace: for tt in self.task_types(): tt.options_scope = None del otn[:] self._task_type_by_name = {} task_name = task_registrar.name if task_name in self._task_type_by_name: raise GoalError( 'Can only specify a task name once per goal, saw multiple values for {} in goal {}'.format( task_name, self.name)) Optionable.validate_scope_name_component(task_name) options_scope = Goal.scope(self.name, task_name) task_type = _create_stable_task_type(task_registrar.task_type, options_scope) if first: otn.insert(0, task_name) elif before in otn: otn.insert(otn.index(before), task_name) elif after in otn: otn.insert(otn.index(after) + 1, task_name) else: otn.append(task_name) self._task_type_by_name[task_name] = task_type if task_registrar.serialize: self.serialize = True return self
def check_false(s): self.assertFalse(Optionable.is_valid_scope_name_component(s))
def check_true(s): self.assertTrue(Optionable.is_valid_scope_name_component(s))
def install(self, task_registrar, first=False, replace=False, before=None, after=None): """Installs the given task in this goal. The placement of the task in this goal's execution list defaults to the end but its position can be influenced by specifying exactly one of the following arguments: first: Places the task 1st in the execution list. replace: Removes all existing tasks in this goal and installs this task. before: Places the task before the named task in the execution list. after: Places the task after the named task in the execution list. :API: public """ if [bool(place) for place in [first, replace, before, after]].count(True) > 1: raise GoalError( 'Can only specify one of first, replace, before or after') task_name = task_registrar.name Optionable.validate_scope_name_component(task_name) options_scope = Goal.scope(self.name, task_name) # Currently we need to support registering the same task type multiple times in different # scopes. However we still want to have each task class know the options scope it was # registered in. So we create a synthetic subclass here. # TODO(benjy): Revisit this when we revisit the task lifecycle. We probably want to have # a task *instance* know its scope, but this means converting option registration from # a class method to an instance method, and instantiating the task much sooner in the # lifecycle. superclass = task_registrar.task_type subclass_name = b'{0}_{1}'.format( superclass.__name__, options_scope.replace('.', '_').replace('-', '_')) task_type = type( subclass_name, (superclass, ), { '__doc__': superclass.__doc__, '__module__': superclass.__module__, 'options_scope': options_scope, '_stable_name': superclass.stable_name() }) otn = self._ordered_task_names if replace: for tt in self.task_types(): tt.options_scope = None del otn[:] self._task_type_by_name = {} if first: otn.insert(0, task_name) elif before in otn: otn.insert(otn.index(before), task_name) elif after in otn: otn.insert(otn.index(after) + 1, task_name) else: otn.append(task_name) self._task_type_by_name[task_name] = task_type if task_registrar.serialize: self.serialize = True return self