Example #1
0
    def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,
                         check_updates, update, alias_ref=None):
        """ creates and adds a new node to the dependency graph
        """
        result = self._proxy.get_recipe(requirement.conan_reference,
                                        check_updates, update)
        conanfile_path, remote = result
        output = ScopedOutput(str(requirement.conan_reference), self._output)
        dep_conanfile = self._loader.load_conan(conanfile_path, output,
                                                reference=requirement.conan_reference)

        if getattr(dep_conanfile, "alias", None):
            alias_reference = alias_ref or requirement.conan_reference
            requirement.conan_reference = ConanFileReference.loads(dep_conanfile.alias)
            aliased[alias_reference] = requirement.conan_reference
            return self._create_new_node(current_node, dep_graph, requirement, public_deps,
                                         name_req, aliased, check_updates, update,
                                         alias_ref=alias_reference)

        new_node = Node(requirement.conan_reference, dep_conanfile)
        new_node.remote = remote
        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement.private)
        if not requirement.private:
            public_deps[name_req] = new_node, None
        return new_node
Example #2
0
 def root(self, content, profile):
     conan_path = os.path.join(self.folder, "data", "root.py")
     save(conan_path, content)
     conanfile = self.loader.load_consumer(conan_path, profile)
     node = Node(None, conanfile, "rootpath")
     node.recipe = RECIPE_CONSUMER
     return node
Example #3
0
    def _load_root_consumer(self, path, graph_lock, profile, ref):
        """ load a CONSUMER node from a user space conanfile.py or conanfile.txt
        install|info|create|graph <path>
        :path full path to a conanfile
        :graph_lock: might be None, information of lockfiles
        :profile: data to inject to the consumer node: settings, options
        :ref: previous reference of a previous command. Can be used for finding itself in
              the lockfile, or to initialize
        """
        if path.endswith(".py"):
            lock_python_requires = None
            if graph_lock:
                if ref.name is None:
                    # If the graph_info information is not there, better get what we can from
                    # the conanfile
                    # Using load_named() to run set_name() set_version() and get them
                    # so it can be found by name in the lockfile
                    conanfile = self._loader.load_named(
                        path, None, None, None, None)
                    ref = ConanFileReference(ref.name or conanfile.name,
                                             ref.version or conanfile.version,
                                             ref.user,
                                             ref.channel,
                                             validate=False)
                node_id = graph_lock.get_consumer(ref)
                lock_python_requires = graph_lock.python_requires(node_id)

            conanfile = self._loader.load_consumer(
                path,
                profile,
                name=ref.name,
                version=ref.version,
                user=ref.user,
                channel=ref.channel,
                lock_python_requires=lock_python_requires)

            ref = ConanFileReference(conanfile.name,
                                     conanfile.version,
                                     ref.user,
                                     ref.channel,
                                     validate=False)
            root_node = Node(ref,
                             conanfile,
                             context=CONTEXT_HOST,
                             recipe=RECIPE_CONSUMER,
                             path=path)
        else:
            conanfile = self._loader.load_conanfile_txt(path, profile, ref=ref)
            root_node = Node(None,
                             conanfile,
                             context=CONTEXT_HOST,
                             recipe=RECIPE_CONSUMER,
                             path=path)

        if graph_lock:  # Find the Node ID in the lock of current root
            node_id = graph_lock.get_consumer(root_node.ref)
            root_node.id = node_id

        return root_node
Example #4
0
    def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,
                         check_updates, update, remote_name, processed_profile, alias_ref=None):
        """ creates and adds a new node to the dependency graph
        """
        workspace_package = self._workspace[requirement.ref] if self._workspace else None

        if workspace_package:
            conanfile_path = workspace_package.conanfile_path
            recipe_status = RECIPE_WORKSPACE
            remote = WORKSPACE_FILE
            new_ref = requirement.ref
        else:
            try:
                result = self._proxy.get_recipe(requirement.ref,
                                                check_updates, update, remote_name, self._recorder)
            except ConanException as e:
                if current_node.ref:
                    self._output.error("Failed requirement '%s' from '%s'"
                                       % (requirement.ref,
                                          current_node.conanfile.display_name))
                raise e
            conanfile_path, recipe_status, remote, new_ref = result

        dep_conanfile = self._loader.load_conanfile(conanfile_path, processed_profile,
                                                    ref=requirement.ref)
        if recipe_status == RECIPE_EDITABLE:
            dep_conanfile.in_local_cache = False

        if workspace_package:
            workspace_package.conanfile = dep_conanfile
        if getattr(dep_conanfile, "alias", None):
            alias_ref = alias_ref or new_ref.copy_clear_rev()
            requirement.ref = ConanFileReference.loads(dep_conanfile.alias)
            aliased[alias_ref] = requirement.ref
            return self._create_new_node(current_node, dep_graph, requirement, public_deps,
                                         name_req, aliased, check_updates, update,
                                         remote_name, processed_profile,
                                         alias_ref=alias_ref)

        logger.debug("GRAPH: new_node: %s" % str(new_ref))
        new_node = Node(new_ref, dep_conanfile)
        new_node.revision_pinned = requirement.ref.revision is not None
        new_node.recipe = recipe_status
        new_node.remote = remote
        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement.private)
        if not requirement.private:
            public_deps[name_req] = new_node, None
        return new_node
Example #5
0
 def _load_root_test_package(self, path, create_reference, graph_lock,
                             profile):
     """ when a test_package/conanfile.py is provided, together with the reference that is
     being created and need to be tested
     :return a CONSUMER root_node with a conanfile.py with an injected requires to the
     created reference
     """
     test = str(create_reference)
     # do not try apply lock_python_requires for test_package/conanfile.py consumer
     conanfile = self._loader.load_consumer(
         path,
         profile,
         user=create_reference.user,
         channel=create_reference.channel)
     conanfile.display_name = "%s (test package)" % str(test)
     conanfile.output.scope = conanfile.display_name
     # Injecting the tested reference
     require = conanfile.requires.get(create_reference.name)
     if require:
         require.ref = require.range_ref = create_reference
     else:
         conanfile.requires.add_ref(create_reference)
     ref = ConanFileReference(conanfile.name,
                              conanfile.version,
                              create_reference.user,
                              create_reference.channel,
                              validate=False)
     root_node = Node(ref, conanfile, recipe=RECIPE_CONSUMER, path=path)
     if graph_lock:
         node_id = graph_lock.get_node(create_reference)
         locked_ref = graph_lock.pref(node_id).ref
         conanfile.requires[create_reference.name].lock(locked_ref, node_id)
     return root_node
Example #6
0
    def _load_root_direct_reference(self, reference, graph_lock, profile,
                                    lockfile_node_id, is_build_require,
                                    require_overrides):
        """ When a full reference is provided:
        install|info|graph <ref> or export-pkg .
        :return a VIRTUAL root_node with a conanfile that requires the reference
        """
        if not self._cache.config.revisions_enabled and reference.revision is not None:
            raise ConanException(
                "Revisions not enabled in the client, specify a "
                "reference without revision")

        conanfile = self._loader.load_virtual(
            [reference],
            profile,
            is_build_require=is_build_require,
            require_overrides=require_overrides)
        root_node = Node(ref=None,
                         conanfile=conanfile,
                         context=CONTEXT_HOST,
                         recipe=RECIPE_VIRTUAL)
        # Build_requires cannot be found as early as this, because there is no require yet
        if graph_lock and not is_build_require:  # Find the Node ID in the lock of current root
            graph_lock.find_require_and_lock(reference, conanfile,
                                             lockfile_node_id)
        return root_node
Example #7
0
    def _load_root_node(self, reference, create_reference, profile_host, graph_lock, root_ref,
                        lockfile_node_id):
        """ creates the first, root node of the graph, loading or creating a conanfile
        and initializing it (settings, options) as necessary. Also locking with lockfile
        information
        """
        profile_host.dev_reference = create_reference  # Make sure the created one has develop=True

        if isinstance(reference, list):  # Install workspace with multiple root nodes
            conanfile = self._loader.load_virtual(reference, profile_host, scope_options=False)
            # Locking in workspaces not implemented yet
            return Node(ref=None, context=CONTEXT_HOST, conanfile=conanfile, recipe=RECIPE_VIRTUAL)

        # create (without test_package), install|info|graph|export-pkg <ref>
        if isinstance(reference, ConanFileReference):
            return self._load_root_direct_reference(reference, graph_lock, profile_host,
                                                    lockfile_node_id)

        path = reference  # The reference must be pointing to a user space conanfile
        if create_reference:  # Test_package -> tested reference
            return self._load_root_test_package(path, create_reference, graph_lock, profile_host)

        # It is a path to conanfile.py or conanfile.txt
        root_node = self._load_root_consumer(path, graph_lock, profile_host, root_ref)
        return root_node
Example #8
0
    def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,
                         check_updates, update, remote_name, processed_profile, alias_ref=None):
        """ creates and adds a new node to the dependency graph
        """
        output = ScopedOutput(str(requirement.conan_reference), self._output)
        workspace_package = self._workspace[requirement.conan_reference] if self._workspace else None

        if workspace_package:
            conanfile_path = workspace_package.conanfile_path
            recipe_status = RECIPE_WORKSPACE
            remote = WORKSPACE_FILE
            new_ref = requirement.conan_reference
        else:
            try:
                result = self._proxy.get_recipe(requirement.conan_reference,
                                                check_updates, update, remote_name, self._recorder)
            except ConanException as e:
                base_ref = str(current_node.conan_ref or "PROJECT")
                self._output.error("Failed requirement '%s' from '%s'"
                                   % (requirement.conan_reference, base_ref))
                raise e
            conanfile_path, recipe_status, remote, new_ref = result
            
        dep_conanfile = self._loader.load_conanfile(conanfile_path, output, processed_profile,
                                                    reference=requirement.conan_reference)

        if workspace_package:
            workspace_package.conanfile = dep_conanfile
        if getattr(dep_conanfile, "alias", None):
            alias_reference = alias_ref or new_ref.copy_clear_rev()
            requirement.conan_reference = ConanFileReference.loads(dep_conanfile.alias)
            aliased[alias_reference] = requirement.conan_reference
            return self._create_new_node(current_node, dep_graph, requirement, public_deps,
                                         name_req, aliased, check_updates, update,
                                         remote_name, processed_profile,
                                         alias_ref=alias_reference)

        new_node = Node(new_ref, dep_conanfile)
        new_node.revision_pinned = requirement.conan_reference.revision is not None
        new_node.recipe = recipe_status
        new_node.remote = remote
        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement.private)
        if not requirement.private:
            public_deps[name_req] = new_node, None
        return new_node
Example #9
0
 def root(self, content, processed_profile):
     conan_path = os.path.join(self.folder, "root.py")
     save(conan_path, content)
     conanfile = self.loader.load_conanfile(conan_path,
                                            self.output,
                                            processed_profile,
                                            consumer=True)
     return Node(None, conanfile)
Example #10
0
    def _load_root_test_package(self, path, create_reference, graph_lock,
                                profile, require_overrides):
        """ when a test_package/conanfile.py is provided, together with the reference that is
        being created and need to be tested
        :return a CONSUMER root_node with a conanfile.py with an injected requires to the
        created reference
        """
        test = str(create_reference)
        # do not try apply lock_python_requires for test_package/conanfile.py consumer
        conanfile = self._loader.load_consumer(
            path,
            profile,
            user=create_reference.user,
            channel=create_reference.channel,
            require_overrides=require_overrides)
        conanfile.display_name = "%s (test package)" % str(test)
        conanfile.output.scope = conanfile.display_name
        conanfile.tested_reference_str = repr(create_reference)

        # Injection of the tested reference
        test_type = getattr(conanfile, "test_type", ("requires", ))
        if not isinstance(test_type, (list, tuple)):
            test_type = (test_type, )

        if "explicit" not in test_type:  # 2.0 mode, not automatically add the require, always explicit
            if "build_requires" in test_type:
                if getattr(conanfile, "build_requires", None):
                    # Injecting the tested reference
                    existing = conanfile.build_requires
                    if not isinstance(existing, (list, tuple)):
                        existing = [existing]
                    conanfile.build_requires = list(existing) + [
                        create_reference
                    ]
                else:
                    conanfile.build_requires = str(create_reference)
            if "requires" in test_type:
                require = conanfile.requires.get(create_reference.name)
                if require:
                    require.ref = require.range_ref = create_reference
                else:
                    conanfile.requires.add_ref(create_reference)

        ref = ConanFileReference(conanfile.name,
                                 conanfile.version,
                                 create_reference.user,
                                 create_reference.channel,
                                 validate=False)
        root_node = Node(ref,
                         conanfile,
                         recipe=RECIPE_CONSUMER,
                         context=CONTEXT_HOST,
                         path=path)
        if graph_lock:
            graph_lock.find_require_and_lock(create_reference, conanfile)
        return root_node
Example #11
0
    def load_graph(self, reference, create_reference, profile, build_mode,
                   check_updates, update, remote_name, recorder, workspace):
        def _inject_require(conanfile, reference):
            """ test_package functionality requires injecting the tested package as requirement
            before running the install
            """
            require = conanfile.requires.get(reference.name)
            if require:
                require.conan_reference = require.range_reference = reference
            else:
                conanfile.requires(str(reference))
            conanfile._conan_user = reference.user
            conanfile._conan_channel = reference.channel

        # Computing the full dependency graph
        cache_settings = self._client_cache.settings.copy()
        cache_settings.values = profile.settings_values
        settings_preprocessor.preprocess(cache_settings)
        processed_profile = ProcessedProfile(cache_settings, profile,
                                             create_reference)
        if isinstance(reference,
                      list):  # Install workspace with multiple root nodes
            conanfile = self._loader.load_virtual(reference, processed_profile)
        elif isinstance(reference, ConanFileReference):
            # create without test_package and install <ref>
            conanfile = self._loader.load_virtual([reference],
                                                  processed_profile)
        else:
            output = ScopedOutput("PROJECT", self._output)
            if reference.endswith(".py"):
                conanfile = self._loader.load_conanfile(reference,
                                                        output,
                                                        processed_profile,
                                                        consumer=True)
                if create_reference:  # create with test_package
                    _inject_require(conanfile, create_reference)
            else:
                conanfile = self._loader.load_conanfile_txt(
                    reference, output, processed_profile)

        build_mode = BuildMode(build_mode, self._output)
        root_node = Node(None, conanfile)
        deps_graph = self._load_graph(
            root_node,
            check_updates,
            update,
            build_mode=build_mode,
            remote_name=remote_name,
            profile_build_requires=profile.build_requires,
            recorder=recorder,
            workspace=workspace,
            processed_profile=processed_profile)
        build_mode.report_matches()
        return deps_graph, conanfile, cache_settings
Example #12
0
    def _load_root_direct_reference(self, reference, graph_lock, profile):
        """ When a full reference is provided:
        install|info|graph <ref> or export-pkg .
        :return a VIRTUAL root_node with a conanfile that requires the reference
        """
        if not self._cache.config.revisions_enabled and reference.revision is not None:
            raise ConanException("Revisions not enabled in the client, specify a "
                                 "reference without revision")

        conanfile = self._loader.load_virtual([reference], profile)
        root_node = Node(ref=None, conanfile=conanfile, context=CONTEXT_HOST, recipe=RECIPE_VIRTUAL)
        if graph_lock:  # Find the Node ID in the lock of current root
            graph_lock.find_require_and_lock(reference, conanfile)
        return root_node
Example #13
0
    def _create_new_node(self,
                         current_node,
                         dep_graph,
                         requirement,
                         name_req,
                         check_updates,
                         update,
                         remote_name,
                         processed_profile,
                         alias_ref=None):
        """ creates and adds a new node to the dependency graph
        """

        try:
            result = self._proxy.get_recipe(requirement.ref, check_updates,
                                            update, remote_name,
                                            self._recorder)
        except ConanException as e:
            if current_node.ref:
                self._output.error(
                    "Failed requirement '%s' from '%s'" %
                    (requirement.ref, current_node.conanfile.display_name))
            raise e
        conanfile_path, recipe_status, remote, new_ref = result

        dep_conanfile = self._loader.load_conanfile(conanfile_path,
                                                    processed_profile,
                                                    ref=requirement.ref)
        if recipe_status == RECIPE_EDITABLE:
            dep_conanfile.in_local_cache = False
            dep_conanfile.develop = True

        if getattr(dep_conanfile, "alias", None):
            alias_ref = alias_ref or new_ref.copy_clear_rev()
            requirement.ref = ConanFileReference.loads(dep_conanfile.alias)
            dep_graph.aliased[alias_ref] = requirement.ref
            return self._create_new_node(current_node,
                                         dep_graph,
                                         requirement,
                                         name_req,
                                         check_updates,
                                         update,
                                         remote_name,
                                         processed_profile,
                                         alias_ref=alias_ref)

        logger.debug("GRAPH: new_node: %s" % str(new_ref))
        new_node = Node(new_ref, dep_conanfile)
        new_node.revision_pinned = requirement.ref.revision is not None
        new_node.recipe = recipe_status
        new_node.remote = remote
        new_node.ancestors = current_node.ancestors.copy()
        new_node.ancestors.add(current_node.name)
        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement.private,
                           requirement.build_require)
        return new_node
Example #14
0
    def _create_new_node(self, current_node, dep_graph, requirement, public_deps, name_req, aliased,
                         check_updates, update, remote_name, alias_ref=None):
        """ creates and adds a new node to the dependency graph
        """
        workspace_package = self._workspace[requirement.conan_reference] if self._workspace else None
        if workspace_package:
            conanfile_path = workspace_package.conanfile_path
            recipe_status = RECIPE_WORKSPACE
            remote = WORKSPACE_FILE
        else:
            result = self._proxy.get_recipe(requirement.conan_reference,
                                            check_updates, update, remote_name)
            conanfile_path, recipe_status, remote = result

        output = ScopedOutput(str(requirement.conan_reference), self._output)
        dep_conanfile = self._loader.load_conan(conanfile_path, output,
                                                reference=requirement.conan_reference)

        if workspace_package:
            workspace_package.conanfile = dep_conanfile
        if getattr(dep_conanfile, "alias", None):
            alias_reference = alias_ref or requirement.conan_reference
            requirement.conan_reference = ConanFileReference.loads(dep_conanfile.alias)
            aliased[alias_reference] = requirement.conan_reference
            return self._create_new_node(current_node, dep_graph, requirement, public_deps,
                                         name_req, aliased, check_updates, update,
                                         remote_name, alias_ref=alias_reference)

        new_node = Node(requirement.conan_reference, dep_conanfile)
        new_node.recipe = recipe_status
        new_node.remote = remote
        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement.private)
        if not requirement.private:
            public_deps[name_req] = new_node, None
        return new_node
Example #15
0
 def load_graph(self, conanfile, check_updates, update, remote_name):
     check_updates = check_updates or update
     dep_graph = DepsGraph()
     # compute the conanfile entry point for this dependency graph
     root_node = Node(None, conanfile)
     dep_graph.add_node(root_node)
     public_deps = {}  # {name: Node} dict with public nodes, so they are not added again
     aliased = {}
     # enter recursive computation
     t1 = time.time()
     loop_ancestors = []
     self._load_deps(root_node, Requirements(), dep_graph, public_deps, None, None,
                     loop_ancestors, aliased, check_updates, update, remote_name)
     logger.debug("Deps-builder: Time to load deps %s" % (time.time() - t1))
     t1 = time.time()
     dep_graph.compute_package_ids()
     logger.debug("Deps-builder: Propagate info %s" % (time.time() - t1))
     return dep_graph
Example #16
0
 def load_simple_graph(self, reference, profile, recorder):
     # Loads a graph without computing the binaries. It is necessary for
     # export-pkg command, not hitting the server
     # # https://github.com/conan-io/conan/issues/3432
     builder = DepsGraphBuilder(self._proxy,
                                self._output,
                                self._loader,
                                self._resolver,
                                workspace=None,
                                recorder=recorder)
     processed_profile = ProcessedProfile(profile, create_reference=None)
     conanfile = self._loader.load_virtual([reference], processed_profile)
     root_node = Node(None, conanfile, recipe=RECIPE_VIRTUAL)
     graph = builder.load_graph(root_node,
                                check_updates=False,
                                update=False,
                                remote_name=None,
                                processed_profile=processed_profile)
     return graph
Example #17
0
    def _create_new_node(self, current_node, dep_graph, requirement,
                         check_updates, update, remotes, profile_host,
                         profile_build, graph_lock, context_switch,
                         populate_settings_target):
        # If there is a context_switch, it is because it is a BR-build
        if context_switch:
            profile = profile_build
            context = CONTEXT_BUILD
        else:
            profile = profile_host if current_node.context == CONTEXT_HOST else profile_build
            context = current_node.context

        result = self._resolve_recipe(current_node, dep_graph, requirement,
                                      check_updates, update, remotes, profile,
                                      graph_lock)
        new_ref, dep_conanfile, recipe_status, remote, locked_id = result

        # Assign the profiles depending on the context
        if profile_build:  # Keep existing behavior (and conanfile members) if no profile_build
            dep_conanfile.settings_build = profile_build.processed_settings.copy(
            )
            if not context_switch:
                if populate_settings_target:
                    dep_conanfile.settings_target = current_node.conanfile.settings_target
                else:
                    dep_conanfile.settings_target = None
            else:
                if current_node.context == CONTEXT_HOST:
                    dep_conanfile.settings_target = profile_host.processed_settings.copy(
                    )
                else:
                    dep_conanfile.settings_target = profile_build.processed_settings.copy(
                    )

        logger.debug("GRAPH: new_node: %s" % str(new_ref))
        new_node = Node(new_ref, dep_conanfile, context=context)
        new_node.revision_pinned = requirement.ref.revision is not None
        new_node.recipe = recipe_status
        new_node.remote = remote
        # Ancestors are a copy of the parent, plus the parent itself
        new_node.ancestors.assign(current_node.ancestors)
        new_node.ancestors.add(current_node)

        if locked_id is not None:
            new_node.id = locked_id

        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement)
        return new_node
Example #18
0
    def _create_new_node(self, current_node, dep_graph, requirement,
                         check_updates, update, remotes, profile, graph_lock):

        result = self._resolve_recipe(current_node, dep_graph, requirement,
                                      check_updates, update, remotes, profile,
                                      graph_lock)
        new_ref, dep_conanfile, recipe_status, remote, locked_id = result

        logger.debug("GRAPH: new_node: %s" % str(new_ref))
        new_node = Node(new_ref, dep_conanfile)
        new_node.revision_pinned = requirement.ref.revision is not None
        new_node.recipe = recipe_status
        new_node.remote = remote
        # Ancestors are a copy of the parent, plus the parent itself
        new_node.ancestors = current_node.ancestors.copy()
        new_node.ancestors.add(current_node.name)

        if locked_id is not None:
            new_node.id = locked_id

        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement)
        return new_node
Example #19
0
    def load_graph(self, reference, create_reference, graph_info, build_mode, check_updates, update,
                   remote_name, recorder, apply_build_requires=True):

        def _inject_require(conanfile, ref):
            """ test_package functionality requires injecting the tested package as requirement
            before running the install
            """
            require = conanfile.requires.get(ref.name)
            if require:
                require.ref = require.range_ref = ref
            else:
                conanfile.requires(str(ref))
            conanfile._conan_user = ref.user
            conanfile._conan_channel = ref.channel

        # Computing the full dependency graph
        profile = graph_info.profile
        processed_profile = ProcessedProfile(profile, create_reference)
        ref = None
        if isinstance(reference, list):  # Install workspace with multiple root nodes
            conanfile = self._loader.load_virtual(reference, processed_profile,
                                                  scope_options=False)
            root_node = Node(ref, conanfile, recipe=RECIPE_VIRTUAL)
        elif isinstance(reference, ConanFileReference):
            if not self._cache.config.revisions_enabled and reference.revision is not None:
                raise ConanException("Revisions not enabled in the client, specify a "
                                     "reference without revision")
            # create without test_package and install <ref>
            conanfile = self._loader.load_virtual([reference], processed_profile)
            root_node = Node(ref, conanfile, recipe=RECIPE_VIRTUAL)
        else:
            path = reference
            if path.endswith(".py"):
                test = str(create_reference) if create_reference else None
                conanfile = self._loader.load_consumer(path, processed_profile, test=test,
                                                       name=graph_info.root.name,
                                                       version=graph_info.root.version,
                                                       user=graph_info.root.user,
                                                       channel=graph_info.root.channel)
                if create_reference:  # create with test_package
                    _inject_require(conanfile, create_reference)

                ref = ConanFileReference(conanfile.name, conanfile.version,
                                         conanfile._conan_user, conanfile._conan_channel,
                                         validate=False)
            else:
                conanfile = self._loader.load_conanfile_txt(path, processed_profile,
                                                            ref=graph_info.root)

            root_node = Node(ref, conanfile, recipe=RECIPE_CONSUMER)

        build_mode = BuildMode(build_mode, self._output)
        deps_graph = self._load_graph(root_node, check_updates, update,
                                      build_mode=build_mode, remote_name=remote_name,
                                      profile_build_requires=profile.build_requires,
                                      recorder=recorder,
                                      processed_profile=processed_profile,
                                      apply_build_requires=apply_build_requires)

        # THIS IS NECESSARY to store dependencies options in profile, for consumer
        # FIXME: This is a hack. Might dissapear if the graph for local commands is always recomputed
        graph_info.options = root_node.conanfile.options.values

        version_ranges_output = self._resolver.output
        if version_ranges_output:
            self._output.success("Version ranges solved")
            for msg in version_ranges_output:
                self._output.info("    %s" % msg)
            self._output.writeln("")

        build_mode.report_matches()
        return deps_graph, conanfile
Example #20
0
 def root(self, content, processed_profile):
     conan_path = os.path.join(self.folder, ".conan", "data", "root.py")
     save(conan_path, content)
     conanfile = self.loader.load_consumer(conan_path, processed_profile)
     return Node(None, conanfile, "rootpath")
Example #21
0
    def _create_new_node(self,
                         current_node,
                         dep_graph,
                         requirement,
                         name_req,
                         check_updates,
                         update,
                         remotes,
                         processed_profile,
                         graph_lock,
                         alias_ref=None):
        """ creates and adds a new node to the dependency graph
        """

        try:
            result = self._proxy.get_recipe(requirement.ref, check_updates,
                                            update, remotes, self._recorder)
        except ConanException as e:
            if current_node.ref:
                self._output.error(
                    "Failed requirement '%s' from '%s'" %
                    (requirement.ref, current_node.conanfile.display_name))
            raise e
        conanfile_path, recipe_status, remote, new_ref = result

        locked_id = requirement.locked_id
        lock_python_requires = graph_lock.python_requires(
            locked_id) if locked_id else None
        dep_conanfile = self._loader.load_conanfile(
            conanfile_path,
            processed_profile,
            ref=requirement.ref,
            lock_python_requires=lock_python_requires)
        if recipe_status == RECIPE_EDITABLE:
            dep_conanfile.in_local_cache = False
            dep_conanfile.develop = True

        if getattr(dep_conanfile, "alias", None):
            alias_ref = alias_ref or new_ref.copy_clear_rev()
            requirement.ref = ConanFileReference.loads(dep_conanfile.alias)
            dep_graph.aliased[alias_ref] = requirement.ref
            return self._create_new_node(current_node,
                                         dep_graph,
                                         requirement,
                                         name_req,
                                         check_updates,
                                         update,
                                         remotes,
                                         processed_profile,
                                         graph_lock,
                                         alias_ref=alias_ref)

        logger.debug("GRAPH: new_node: %s" % str(new_ref))
        new_node = Node(new_ref, dep_conanfile)
        new_node.revision_pinned = requirement.ref.revision is not None
        new_node.recipe = recipe_status
        new_node.remote = remote
        # Ancestors are a copy of the parent, plus the parent itself
        new_node.ancestors = current_node.ancestors.copy()
        new_node.ancestors.add(current_node.name)

        if locked_id:
            new_node.id = locked_id

        # build-requires and private affect transitively. If "node" is already
        # a build_require or a private one, its requirements will inherit that property
        # Or if the require specify that property, then it will get it too
        new_node.build_require = current_node.build_require or requirement.build_require
        new_node.private = current_node.private or requirement.private

        dep_graph.add_node(new_node)
        dep_graph.add_edge(current_node, new_node, requirement)
        return new_node
Example #22
0
    def load_graph(self, reference, create_reference, graph_info, build_mode,
                   check_updates, update, remote_name, recorder, workspace):
        def _inject_require(conanfile, reference):
            """ test_package functionality requires injecting the tested package as requirement
            before running the install
            """
            require = conanfile.requires.get(reference.name)
            if require:
                require.conan_reference = require.range_reference = reference
            else:
                conanfile.requires(str(reference))
            conanfile._conan_user = reference.user
            conanfile._conan_channel = reference.channel

        # Computing the full dependency graph
        profile = graph_info.profile
        cache_settings = profile.processed_settings
        processed_profile = ProcessedProfile(profile, create_reference)
        if isinstance(reference,
                      list):  # Install workspace with multiple root nodes
            conanfile = self._loader.load_virtual(reference, processed_profile)
        elif isinstance(reference, ConanFileReference):
            # create without test_package and install <ref>
            conanfile = self._loader.load_virtual([reference],
                                                  processed_profile)
        else:
            output = ScopedOutput("PROJECT", self._output)
            if reference.endswith(".py"):
                conanfile = self._loader.load_conanfile(reference,
                                                        output,
                                                        processed_profile,
                                                        consumer=True)
                if create_reference:  # create with test_package
                    _inject_require(conanfile, create_reference)
            else:
                conanfile = self._loader.load_conanfile_txt(
                    reference, output, processed_profile)

        build_mode = BuildMode(build_mode, self._output)
        root_node = Node(None, conanfile)
        deps_graph = self._load_graph(
            root_node,
            check_updates,
            update,
            build_mode=build_mode,
            remote_name=remote_name,
            profile_build_requires=profile.build_requires,
            recorder=recorder,
            workspace=workspace,
            processed_profile=processed_profile)

        # THIS IS NECESSARY to store dependencies options in profile, for consumer
        # FIXME: This is a hack. Might dissapear if the graph for local commands is always recomputed
        graph_info.options = root_node.conanfile.options.values

        version_ranges_output = self._resolver.output
        if version_ranges_output:
            self._output.success("Version ranges solved")
            for msg in version_ranges_output:
                self._output.info("    %s" % msg)
            self._output.writeln("")

        build_mode.report_matches()
        return deps_graph, conanfile, cache_settings
Example #23
0
    def _recurse_build_requires(self, graph, check_updates, update, build_mode,
                                remote_name, profile_build_requires, recorder,
                                workspace, processed_profile):
        for node in list(graph.nodes):
            # Virtual conanfiles doesn't have output, but conanfile.py and conanfile.txt do
            # FIXME: To be improved and build a explicit model for this
            if node.conanfile.output is None:
                continue
            if node.binary not in (BINARY_BUILD,
                                   BINARY_WORKSPACE) and node.conan_ref:
                continue
            package_build_requires = self._get_recipe_build_requires(
                node.conanfile)
            str_ref = str(node.conan_ref or "")
            new_profile_build_requires = OrderedDict()
            profile_build_requires = profile_build_requires or {}
            for pattern, build_requires in profile_build_requires.items():
                if ((not str_ref and pattern == "&")
                        or (str_ref and pattern == "&!")
                        or fnmatch.fnmatch(str_ref, pattern)):
                    for build_require in build_requires:
                        if build_require.name in package_build_requires:  # Override existing
                            package_build_requires[
                                build_require.name] = build_require
                        else:  # Profile one
                            new_profile_build_requires[
                                build_require.name] = build_require

            if package_build_requires:
                node.conanfile.build_requires_options.clear_unscoped_options()
                build_requires_options = node.conanfile.build_requires_options
                virtual = self._loader.load_virtual(
                    package_build_requires.values(),
                    scope_options=False,
                    build_requires_options=build_requires_options,
                    processed_profile=processed_profile)
                virtual_node = Node(None, virtual)
                build_requires_package_graph = self._load_graph(
                    virtual_node, check_updates, update, build_mode,
                    remote_name, profile_build_requires, recorder, workspace,
                    processed_profile)
                graph.add_graph(node,
                                build_requires_package_graph,
                                build_require=True)

            if new_profile_build_requires:
                node.conanfile.build_requires_options.clear_unscoped_options()
                build_requires_options = node.conanfile.build_requires_options
                virtual = self._loader.load_virtual(
                    new_profile_build_requires.values(),
                    scope_options=False,
                    build_requires_options=build_requires_options,
                    processed_profile=processed_profile)
                virtual_node = Node(None, virtual)
                build_requires_profile_graph = self._load_graph(
                    virtual_node, check_updates, update, build_mode,
                    remote_name, new_profile_build_requires, recorder,
                    workspace, processed_profile)
                graph.add_graph(node,
                                build_requires_profile_graph,
                                build_require=True)
Example #24
0
    def load_graph(self, reference, create_reference, graph_info, build_mode, check_updates, update,
                   remotes, recorder, apply_build_requires=True):

        def _inject_require(conanfile, ref):
            """ test_package functionality requires injecting the tested package as requirement
            before running the install
            """
            require = conanfile.requires.get(ref.name)
            if require:
                require.ref = require.range_ref = ref
            else:
                conanfile.requires.add_ref(ref)
            conanfile._conan_user = ref.user
            conanfile._conan_channel = ref.channel

        # Computing the full dependency graph
        profile = graph_info.profile
        processed_profile = profile
        processed_profile.dev_reference = create_reference
        ref = None
        graph_lock = graph_info.graph_lock
        if isinstance(reference, list):  # Install workspace with multiple root nodes
            conanfile = self._loader.load_virtual(reference, processed_profile,
                                                  scope_options=False)
            root_node = Node(ref, conanfile, recipe=RECIPE_VIRTUAL)
        elif isinstance(reference, ConanFileReference):
            if not self._cache.config.revisions_enabled and reference.revision is not None:
                raise ConanException("Revisions not enabled in the client, specify a "
                                     "reference without revision")
            # create without test_package and install <ref>
            conanfile = self._loader.load_virtual([reference], processed_profile)
            root_node = Node(ref, conanfile, recipe=RECIPE_VIRTUAL)
            if graph_lock:  # Find the Node ID in the lock of current root
                graph_lock.find_consumer_node(root_node, reference)
        else:
            path = reference
            if path.endswith(".py"):
                test = str(create_reference) if create_reference else None
                lock_python_requires = None
                # do not try apply lock_python_requires for test_package/conanfile.py consumer
                if graph_lock and not create_reference:
                    if graph_info.root.name is None:
                        # If the graph_info information is not there, better get what we can from
                        # the conanfile
                        conanfile = self._loader.load_class(path)
                        graph_info.root = ConanFileReference(graph_info.root.name or conanfile.name,
                                                             graph_info.root.version or conanfile.version,
                                                             graph_info.root.user,
                                                             graph_info.root.channel, validate=False)
                    node_id = graph_lock.get_node(graph_info.root)
                    lock_python_requires = graph_lock.python_requires(node_id)

                conanfile = self._loader.load_consumer(path, processed_profile, test=test,
                                                       name=graph_info.root.name,
                                                       version=graph_info.root.version,
                                                       user=graph_info.root.user,
                                                       channel=graph_info.root.channel,
                                                       lock_python_requires=lock_python_requires)
                if create_reference:  # create with test_package
                    _inject_require(conanfile, create_reference)

                ref = ConanFileReference(conanfile.name, conanfile.version,
                                         conanfile._conan_user, conanfile._conan_channel,
                                         validate=False)
            else:
                conanfile = self._loader.load_conanfile_txt(path, processed_profile,
                                                            ref=graph_info.root)

            root_node = Node(ref, conanfile, recipe=RECIPE_CONSUMER, path=path)

            if graph_lock:  # Find the Node ID in the lock of current root
                graph_lock.find_consumer_node(root_node, create_reference)

        build_mode = BuildMode(build_mode, self._output)
        deps_graph = self._load_graph(root_node, check_updates, update,
                                      build_mode=build_mode, remotes=remotes,
                                      profile_build_requires=profile.build_requires,
                                      recorder=recorder,
                                      processed_profile=processed_profile,
                                      apply_build_requires=apply_build_requires,
                                      graph_lock=graph_lock)

        # THIS IS NECESSARY to store dependencies options in profile, for consumer
        # FIXME: This is a hack. Might dissapear if graph for local commands is always recomputed
        graph_info.options = root_node.conanfile.options.values
        if ref:
            graph_info.root = ref
        if graph_info.graph_lock is None:
            graph_info.graph_lock = GraphLock(deps_graph)
        else:
            graph_info.graph_lock.update_check_graph(deps_graph, self._output)

        version_ranges_output = self._resolver.output
        if version_ranges_output:
            self._output.success("Version ranges solved")
            for msg in version_ranges_output:
                self._output.info("    %s" % msg)
            self._output.writeln("")

        build_mode.report_matches()
        return deps_graph, conanfile