def step(self, step_context): # Request default Variants for the subject, so that if there are any we can propagate # them to task nodes. variants = self.variants if type(self.subject) is Address and self.product is not Variants: dep_state = step_context.select_for(self._variant_selector, self.subject, self.variants) if type(dep_state) is Waiting: return dep_state elif type(dep_state) is Return: # A subject's variants are overridden by any dependent's requested variants, so # we merge them left to right here. variants = Variants.merge(dep_state.value.default.items(), self.variants) # If there is a variant_key, see whether it has been configured. if type(self.selector) is SelectVariant: variant_values = [value for key, value in variants if key == self.variant_key] if variants else None if not variant_values: # Select cannot be satisfied: no variant configured for this key. return Noop('Variant key {} was not configured in variants {}', self.variant_key, variants) variant_value = variant_values[0] else: variant_value = None # If the Subject "is a" or "has a" Product, then we're done. literal_value = self._select_literal(self.subject, variant_value) if literal_value is not None: return Return(literal_value) # Else, attempt to use a configured task to compute the value. dependencies = [] matches = [] for dep, dep_state in step_context.get_nodes_and_states_for(self.subject, self.product, variants): if type(dep_state) is Waiting: dependencies.extend(dep_state.dependencies) elif type(dep_state) is Return: # We computed a value: see whether we can use it. literal_value = self._select_literal(dep_state.value, variant_value) if literal_value is not None: matches.append((dep, literal_value)) elif type(dep_state) is Throw: return dep_state elif type(dep_state) is Noop: continue else: State.raise_unrecognized(dep_state) # If any dependencies were unavailable, wait for them; otherwise, determine whether # a value was successfully selected. if dependencies: return Waiting(dependencies) elif len(matches) == 0: return Noop('No source of {}.', self) elif len(matches) > 1: # TODO: Multiple successful tasks are not currently supported. We should allow for this # by adding support for "mergeable" products. see: # https://github.com/pantsbuild/pants/issues/2526 return Throw(ConflictingProducersError.create(self.subject, self.product, matches)) else: return Return(matches[0][1])
def step(self, dependency_states, step_context): # Request default Variants for the subject, so that if there are any we can propagate # them to task nodes. variants = self.variants variants_node = self._variants_node() if variants_node: dep_state = dependency_states.get(variants_node, None) if dep_state is None or type(dep_state) == Waiting: return Waiting([variants_node]) elif type(dep_state) == Return: # A subject's variants are overridden by any dependent's requested variants, so # we merge them left to right here. variants = Variants.merge(dep_state.value.default.items(), variants) # If there is a variant_key, see whether it has been configured. variant_value = None if self.variant_key: variant_values = [value for key, value in variants if key == self.variant_key] if variants else None if not variant_values: # Select cannot be satisfied: no variant configured for this key. return Noop('Variant key {} was not configured in variants {}'.format( self.variant_key, variants)) variant_value = variant_values[0] # If the Subject "is a" or "has a" Product, then we're done. literal_value = self._select_literal(self.subject, variant_value) if literal_value is not None: return Return(literal_value) # Else, attempt to use a configured task to compute the value. has_waiting_dep = False dependencies = list(step_context.gen_nodes(self.subject, self.product, variants)) matches = {} for dep in dependencies: dep_state = dependency_states.get(dep, None) if dep_state is None or type(dep_state) == Waiting: has_waiting_dep = True continue elif type(dep_state) == Throw: return dep_state elif type(dep_state) == Noop: continue elif type(dep_state) != Return: State.raise_unrecognized(dep_state) # We computed a value: see whether we can use it. literal_value = self._select_literal(dep_state.value, variant_value) if literal_value is not None: matches[dep] = literal_value if has_waiting_dep: return Waiting(dependencies) elif len(matches) > 1: # TODO: Multiple successful tasks are not currently supported. We should allow for this # by adding support for "mergeable" products. see: # https://github.com/pantsbuild/pants/issues/2526 return Throw(ConflictingProducersError.create(self.subject, self.product, matches)) elif len(matches) == 1: return Return(matches.values()[0]) return Noop('No source of {}.'.format(self))
def _dependency_nodes(self, step_context, dep_product): for dependency in getattr(dep_product, self.field or 'dependencies'): variants = self.variants if isinstance(dependency, Address): # If a subject has literal variants for particular dependencies, they win over all else. dependency, literal_variants = parse_variants(dependency) variants = Variants.merge(variants, literal_variants) yield SelectNode(dependency, self.product, variants, None)
def step(self, dependency_states, step_context): # Request default Variants for the subject, so that if there are any we can propagate # them to task nodes. variants = self.variants variants_node = self._variants_node() if variants_node: dep_state = dependency_states.get(variants_node, None) if dep_state is None or type(dep_state) == Waiting: return Waiting([variants_node]) elif type(dep_state) == Return: # A subject's variants are overridden by any dependent's requested variants, so # we merge them left to right here. variants = Variants.merge(dep_state.value.default.items(), variants) # If there is a variant_key, see whether it has been configured. variant_value = None if self.variant_key: variant_values = [value for key, value in variants if key == self.variant_key] if variants else None if not variant_values: # Select cannot be satisfied: no variant configured for this key. return Noop("Variant key {} was not configured in variants {}".format(self.variant_key, variants)) variant_value = variant_values[0] # If the Subject "is a" or "has a" Product, then we're done. literal_value = self._select_literal(self.subject, variant_value) if literal_value is not None: return Return(literal_value) # Else, attempt to use a configured task to compute the value. has_waiting_dep = False dependencies = list(step_context.gen_nodes(self.subject, self.product, variants)) matches = {} for dep in dependencies: dep_state = dependency_states.get(dep, None) if dep_state is None or type(dep_state) == Waiting: has_waiting_dep = True continue elif type(dep_state) == Throw: return dep_state elif type(dep_state) == Noop: continue elif type(dep_state) != Return: State.raise_unrecognized(dep_state) # We computed a value: see whether we can use it. literal_value = self._select_literal(dep_state.value, variant_value) if literal_value is not None: matches[dep] = literal_value if has_waiting_dep: return Waiting(dependencies) elif len(matches) > 1: # TODO: Multiple successful tasks are not currently supported. We should allow for this # by adding support for "mergeable" products. see: # https://github.com/pantsbuild/pants/issues/2526 return Throw(ConflictingProducersError.create(self.subject, self.product, matches)) elif len(matches) == 1: return Return(matches.values()[0]) return Noop("No source of {}.".format(self))
def step(self, step_context): # Request default Variants for the subject, so that if there are any we can propagate # them to task nodes. variants = self.variants if type(self.subject) is Address and self.product is not Variants: dep_state = step_context.select_for(self._variant_selector, self.subject, self.variants) if type(dep_state) is Waiting: return dep_state elif type(dep_state) is Return: # A subject's variants are overridden by any dependent's requested variants, so # we merge them left to right here. variants = Variants.merge(dep_state.value.default.items(), self.variants) # If there is a variant_key, see whether it has been configured. if type(self.selector) is SelectVariant: variant_values = [ value for key, value in variants if key == self.variant_key ] if variants else None if not variant_values: # Select cannot be satisfied: no variant configured for this key. return Noop('Variant key {} was not configured in variants {}', self.variant_key, variants) variant_value = variant_values[0] else: variant_value = None # If the Subject "is a" or "has a" Product, then we're done. literal_value = self._select_literal(self.subject, variant_value) if literal_value is not None: return Return(literal_value) # Else, attempt to use a configured task to compute the value. dependencies = [] matches = [] for dep, dep_state in step_context.get_nodes_and_states_for( self.subject, self.product, variants): if type(dep_state) is Waiting: dependencies.extend(dep_state.dependencies) elif type(dep_state) is Return: # We computed a value: see whether we can use it. literal_value = self._select_literal(dep_state.value, variant_value) if literal_value is not None: matches.append((dep, literal_value)) elif type(dep_state) is Throw: return dep_state elif type(dep_state) is Noop: continue else: State.raise_unrecognized(dep_state) # If any dependencies were unavailable, wait for them; otherwise, determine whether # a value was successfully selected. if dependencies: return Waiting(dependencies) elif len(matches) == 0: return Noop('No source of {}.', self) elif len(matches) > 1: # TODO: Multiple successful tasks are not currently supported. We should allow for this # by adding support for "mergeable" products. see: # https://github.com/pantsbuild/pants/issues/2526 return Throw( ConflictingProducersError.create(self.subject, self.product, matches)) else: return Return(matches[0][1])