コード例 #1
0
    def __init__(self, goals, tasks, project_tree, native, graph_lock=None):
        """
    :param goals: A dict from a goal name to a product type. A goal is just an alias for a
           particular (possibly synthetic) product.
    :param tasks: A set of (output, input selection clause, task function) triples which
           is used to compute values in the product graph.
    :param project_tree: An instance of ProjectTree for the current build root.
    :param native: An instance of engine.subsystem.native.Native.
    :param graph_lock: A re-entrant lock to use for guarding access to the internal product Graph
                       instance. Defaults to creating a new threading.RLock().
    """
        self._products_by_goal = goals
        self._project_tree = project_tree
        self._native = native
        self._product_graph_lock = graph_lock or threading.RLock()
        self._run_count = 0

        # Create a handle for the ExternContext (which must be kept alive as long as this object), and
        # the native Scheduler.
        self._context = ExternContext()
        self._context_handle = native.new_handle(self._context)

        # TODO: The only (?) case where we use inheritance rather than exact type unions.
        has_products_constraint = TypeConstraint(
            self._to_id(SubclassesOf(HasProducts)))

        scheduler = native.lib.scheduler_create(
            self._context_handle, extern_key_for, extern_id_to_str,
            extern_val_to_str, extern_satisfied_by, extern_store_list,
            extern_project, extern_project_multi, self._to_key('name'),
            self._to_key('products'), self._to_key('default'),
            self._to_constraint(Address), has_products_constraint,
            self._to_constraint(Variants))
        self._scheduler = native.gc(scheduler, native.lib.scheduler_destroy)
        self._execution_request = None

        # Validate and register all provided and intrinsic tasks.
        select_product = lambda product: Select(product)
        # TODO: This bounding of input Subject types allows for closed-world validation, but is not
        # strictly necessary for execution. We might eventually be able to remove it by only executing
        # validation below the execution roots (and thus not considering paths that aren't in use).
        root_selector_fns = {
            Address: select_product,
            AscendantAddresses: select_product,
            DescendantAddresses: select_product,
            PathGlobs: select_product,
            SiblingAddresses: select_product,
            SingleAddress: select_product,
        }
        intrinsics = create_fs_intrinsics(
            project_tree) + create_snapshot_intrinsics(project_tree)
        singletons = create_snapshot_singletons(project_tree)
        node_builder = NodeBuilder.create(tasks, intrinsics, singletons)
        RulesetValidator(node_builder, goals, root_selector_fns).validate()
        self._register_tasks(node_builder.tasks)
        self._register_intrinsics(node_builder.intrinsics)
        self._register_singletons(node_builder.singletons)
コード例 #2
0
    def rule_subgraph_visualization(self, root_subject_type, product_type):
        root_type_id = TypeId(self._to_id(root_subject_type))

        product_type_id = TypeConstraint(
            self._to_id(constraint_for(product_type)))
        with temporary_file_path() as path:
            self._native.lib.rule_subgraph_visualize(self._scheduler,
                                                     root_type_id,
                                                     product_type_id,
                                                     bytes(path))
            with open(path) as fd:
                for line in fd.readlines():
                    yield line.rstrip()
コード例 #3
0
 def _to_constraint(self, type_or_constraint):
     return TypeConstraint(self._to_id(constraint_for(type_or_constraint)))