Пример #1
0
    def test_valid_params(self):
        build_mode = BuildMode(["outdated", "missing"], self.output)
        self.assertTrue(build_mode.outdated)
        self.assertTrue(build_mode.missing)
        self.assertFalse(build_mode.never)

        build_mode = BuildMode(["never"], self.output)
        self.assertFalse(build_mode.outdated)
        self.assertFalse(build_mode.missing)
        self.assertTrue(build_mode.never)
Пример #2
0
    def test_pattern_matching(self):
        build_mode = BuildMode(["Boost*"], self.output)
        reference = ConanFileReference.loads("Boost/1.69.0@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("Boost_Addons/1.0.0@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("MyBoost/1.0@user/stable")
        self.assertFalse(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/Boost@user/stable")
        self.assertFalse(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/1.0@Boost/stable")
        self.assertFalse(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/1.0@user/Boost")
        self.assertFalse(build_mode.forced(self.conanfile, reference))

        build_mode = BuildMode(["foo/*@user/stable"], self.output)
        reference = ConanFileReference.loads("foo/1.0.0@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/1.0@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/1.0.0-abcdefg@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))

        build_mode = BuildMode(["*@user/stable"], self.output)
        reference = ConanFileReference.loads("foo/1.0.0@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("bar/1.0@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/1.0.0-abcdefg@user/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("foo/1.0.0@NewUser/stable")
        self.assertFalse(build_mode.forced(self.conanfile, reference))

        build_mode = BuildMode(["*Tool"], self.output)
        reference = ConanFileReference.loads("Tool/0.1@lasote/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("PythonTool/0.1@lasote/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("SomeTool/1.2@user/channel")
        self.assertTrue(build_mode.forced(self.conanfile, reference))

        build_mode = BuildMode(["Tool/*"], self.output)
        reference = ConanFileReference.loads("Tool/0.1@lasote/stable")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("Tool/1.1@user/testing")
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        reference = ConanFileReference.loads("PythonTool/0.1@lasote/stable")
        self.assertFalse(build_mode.forced(self.conanfile, reference))

        build_mode.report_matches()
        self.assertEqual("", self.output)
Пример #3
0
    def _evaluate_node(self, node, build_mode, update, remotes):
        assert node.binary is None, "Node.binary should be None"
        assert node.package_id is not None, "Node.package_id shouldn't be None"
        assert node.package_id != PACKAGE_ID_UNKNOWN, "Node.package_id shouldn't be Unknown"
        assert node.prev is None, "Node.prev should be None"

        # If it has lock
        locked = node.graph_lock_node
        if locked and locked.package_id:  # if package_id = None, nothing to lock here
            # First we update the package_id, just in case there are differences or something
            locked.package_id = node.package_id  # necessary for PACKAGE_ID_UNKNOWN
            pref = PackageReference(locked.ref, locked.package_id,
                                    locked.prev)  # Keep locked PREV
            self._process_node(node, pref, build_mode, update, remotes)
            if node.binary == BINARY_MISSING and build_mode.allowed(
                    node.conanfile):
                node.binary = BINARY_BUILD
            if node.binary == BINARY_BUILD and locked.prev:
                raise ConanException(
                    "Cannot build '%s' because it is already locked in the input "
                    "lockfile" % repr(node.ref))
        else:
            assert node.prev is None, "Non locked node shouldn't have PREV in evaluate_node"
            assert node.binary is None, "Node.binary should be None if not locked"
            pref = PackageReference(node.ref, node.package_id)
            self._process_node(node, pref, build_mode, update, remotes)
            if node.binary == BINARY_MISSING:
                if node.conanfile.compatible_packages:
                    compatible_build_mode = BuildMode(None, self._out)
                    for compatible_package in node.conanfile.compatible_packages:
                        package_id = compatible_package.package_id()
                        if package_id == node.package_id:
                            node.conanfile.output.info(
                                "Compatible package ID %s equal to the "
                                "default package ID" % package_id)
                            continue
                        pref = PackageReference(node.ref, package_id)
                        node.binary = None  # Invalidate it
                        # NO Build mode
                        self._process_node(node, pref, compatible_build_mode,
                                           update, remotes)
                        assert node.binary is not None
                        if node.binary != BINARY_MISSING:
                            node.conanfile.output.info(
                                "Main binary package '%s' missing. Using "
                                "compatible package '%s'" %
                                (node.package_id, package_id))
                            # Modifying package id under the hood, FIXME
                            node._package_id = package_id
                            # So they are available in package_info() method
                            node.conanfile.settings.values = compatible_package.settings
                            node.conanfile.options.values = compatible_package.options
                            break
                if node.binary == BINARY_MISSING and build_mode.allowed(
                        node.conanfile):
                    node.binary = BINARY_BUILD

            if locked:
                locked.package_id = node.package_id
                locked.prev = node.prev
Пример #4
0
 def test_non_matching_full_reference_build_force(self):
     reference = ConanFileReference.loads("Bar/0.1@user/stable")
     build_mode = BuildMode(["Bar/0.1@user/testing"], self.output)
     self.assertFalse(build_mode.forced(self.conanfile, reference))
     build_mode.report_matches()
     self.assertIn("No package matching 'Bar/0.1@user/testing' pattern",
                   self.output)
Пример #5
0
    def install_workspace(self, profile, workspace, remote_name, build_modes,
                          update):
        loader = self.get_loader(profile)
        references = [
            ConanFileReference(v, "root", "project", "develop")
            for v in workspace.root
        ]
        conanfile = loader.load_virtual(references)
        remote_proxy = self.get_proxy(remote_name=remote_name)
        graph_builder = self._get_graph_builder(loader, remote_proxy)
        graph_builder._workspace = workspace
        deps_graph = graph_builder.load_graph(conanfile, False, update)

        output = ScopedOutput(str("Workspace"), self._user_io.out)
        output.highlight("Installing...")
        print_graph(deps_graph, self._user_io.out)

        build_mode = BuildMode(build_modes, self._user_io.out)
        build_requires = BuildRequires(loader, graph_builder, self._registry)
        installer = ConanInstaller(self._client_cache,
                                   output,
                                   remote_proxy,
                                   build_mode,
                                   build_requires,
                                   recorder=self._recorder)
        installer._workspace = workspace

        installer.install(deps_graph,
                          profile.build_requires,
                          keep_build=False,
                          update=update)
        build_mode.report_matches()
        workspace.generate()
Пример #6
0
    def _resolve_graph(self,
                       root_node,
                       profile_host,
                       profile_build,
                       graph_lock,
                       build_mode,
                       check_updates,
                       update,
                       remotes,
                       recorder,
                       apply_build_requires=True):
        build_mode = BuildMode(build_mode, self._output)
        deps_graph = self._load_graph(
            root_node,
            check_updates,
            update,
            build_mode=build_mode,
            remotes=remotes,
            recorder=recorder,
            profile_host=profile_host,
            profile_build=profile_build,
            apply_build_requires=apply_build_requires,
            graph_lock=graph_lock)

        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("")
            self._resolver.clear_output()

        build_mode.report_matches()
        return deps_graph
Пример #7
0
    def test_casing(self):
        reference = ConanFileReference.loads("Boost/1.69.0@user/stable")

        build_mode = BuildMode(["Boost"], self.output)
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        build_mode = BuildMode(["Bo*"], self.output)
        self.assertTrue(build_mode.forced(self.conanfile, reference))
        build_mode.report_matches()
        self.assertEqual("", self.output)

        build_mode = BuildMode(["boost"], self.output)
        self.assertFalse(build_mode.forced(self.conanfile, reference))
        build_mode = BuildMode(["bo*"], self.output)
        self.assertFalse(build_mode.forced(self.conanfile, reference))
        build_mode.report_matches()
        self.assertIn("ERROR: No package matching", self.output)        
Пример #8
0
 def build_consumer(self,
                    path,
                    profile_build_requires=None,
                    ref=None,
                    create_ref=None,
                    install=True):
     profile = Profile()
     if profile_build_requires:
         profile.build_requires = profile_build_requires
     profile.process_settings(self.cache)
     update = check_updates = False
     recorder = ActionRecorder()
     remotes = Remotes()
     build_mode = []  # Means build all
     ref = ref or ConanFileReference(None, None, None, None, validate=False)
     options = OptionsValues()
     graph_info = GraphInfo(profile, options, root_ref=ref)
     app = self._get_app()
     deps_graph = app.graph_manager.load_graph(path, create_ref, graph_info,
                                               build_mode, check_updates,
                                               update, remotes, recorder)
     if install:
         binary_installer = BinaryInstaller(app, recorder)
         build_mode = BuildMode(build_mode, app.out)
         binary_installer.install(deps_graph, None, build_mode, update,
                                  False, graph_info)
     return deps_graph
Пример #9
0
    def _resolve_graph(self, root_node, graph_info, build_mode, check_updates,
                       update, remotes, recorder, apply_build_requires=True):
        build_mode = BuildMode(build_mode, self._output)
        profile_host = graph_info.profile_host
        graph_lock = graph_info.graph_lock
        deps_graph = self._load_graph(root_node, check_updates, update,
                                      build_mode=build_mode, remotes=remotes,
                                      recorder=recorder,
                                      profile_host=profile_host,
                                      profile_build=graph_info.profile_build,
                                      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 root_node.ref:
            graph_info.root = root_node.ref

        if graph_info.graph_lock is None:
            graph_info.graph_lock = GraphLock(deps_graph, self._cache.config.revisions_enabled)

        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("")
            self._resolver.clear_output()

        build_mode.report_matches()
        return deps_graph
Пример #10
0
    def _build_graph(self, profile_host, profile_build, install=False):
        path = temp_folder()
        path = os.path.join(path, "conanfile.txt")
        save(path, textwrap.dedent("""
            [requires]
            app/testing@user/channel
        """))

        ref = ConanFileReference(None, None, None, None, validate=False)
        options = OptionsValues()
        graph_info = GraphInfo(profile_host=profile_host, profile_build=profile_build,
                               options=options, root_ref=ref)
        recorder = ActionRecorder()
        app = self._get_app()
        deps_graph = app.graph_manager.load_graph(path, create_reference=None, graph_info=graph_info,
                                                  build_mode=[], check_updates=False, update=False,
                                                  remotes=Remotes(), recorder=recorder)

        if install:
            build_mode = []  # Means build all
            binary_installer = BinaryInstaller(app, recorder)
            build_mode = BuildMode(build_mode, app.out)
            binary_installer.install(deps_graph, None, build_mode, update=False,
                                     profile_host=profile_host, profile_build=profile_build,
                                     graph_lock=None,
                                     keep_build=False)
        return deps_graph
Пример #11
0
 def _get_deps_graph(self, reference, profile, check_updates, update, build_mode,
                     remote_name):
     loader = self.get_loader(profile)
     conanfile = self._load_install_conanfile(loader, reference)
     graph_builder = self._get_graph_builder(loader, self._recorder)
     build_mode = BuildMode(build_mode, self._user_io.out)
     deps_graph = graph_builder.load_graph(conanfile, check_updates, update,
                                           build_mode=build_mode, remote_name=remote_name,
                                           profile_build_requires=profile.build_requires)
     return deps_graph, conanfile
Пример #12
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
Пример #13
0
 def info_nodes_to_build(self, reference, profile, build_modes, remote_name, check_updates):
     remote_proxy = self.get_proxy(remote_name=remote_name)
     deps_graph, _, conanfile = self._get_deps_graph(reference, profile, remote_proxy, update=False,
                                                     check_updates=check_updates)
     build_mode = BuildMode(build_modes, self._user_io.out)
     installer = ConanInstaller(self._client_cache, self._user_io.out, remote_proxy, build_mode,
                                None, recorder=self._recorder)
     nodes = installer.nodes_to_build(deps_graph)
     counter = Counter(ref.conan.name for ref, _ in nodes)
     ret = [ref if counter[ref.conan.name] > 1 else str(ref.conan) for ref, _ in nodes]
     return ret, self._get_project_reference(reference, conanfile)
Пример #14
0
    def _evaluate_node(self, node, build_mode, update, remotes):
        assert node.binary is None, "Node.binary should be None"
        assert node.package_id is not None, "Node.package_id shouldn't be None"
        assert node.package_id != PACKAGE_ID_UNKNOWN, "Node.package_id shouldn't be Unknown"
        assert node.prev is None, "Node.prev should be None"

        # If it has lock
        locked = node.graph_lock_node
        if locked and locked.pref.id == node.package_id:
            pref = locked.pref  # Keep the locked with PREV
            self._process_node(node, pref, build_mode, update, remotes)
            if node.binary == BINARY_MISSING and build_mode.allowed(
                    node.conanfile):
                node.binary = BINARY_BUILD
        else:
            assert node.prev is None, "Non locked node shouldn't have PREV in evaluate_node"
            pref = PackageReference(node.ref, node.package_id)
            self._process_node(node, pref, build_mode, update, remotes)
            if node.binary == BINARY_MISSING:
                if node.conanfile.compatible_packages:
                    compatible_build_mode = BuildMode(None, self._out)
                    for compatible_package in node.conanfile.compatible_packages:
                        package_id = compatible_package.package_id()
                        if package_id == node.package_id:
                            node.conanfile.output.info(
                                "Compatible package ID %s equal to the "
                                "default package ID" % package_id)
                            continue
                        pref = PackageReference(node.ref, package_id)
                        node.binary = None  # Invalidate it
                        # NO Build mode
                        self._process_node(node, pref, compatible_build_mode,
                                           update, remotes)
                        assert node.binary is not None
                        if node.binary != BINARY_MISSING:
                            node.conanfile.output.info(
                                "Main binary package '%s' missing. Using "
                                "compatible package '%s'" %
                                (node.package_id, package_id))
                            node._package_id = package_id
                            # So they are available in package_info() method
                            node.conanfile.settings.values = compatible_package.settings
                            node.conanfile.options.values = compatible_package.options
                            break
                if node.binary == BINARY_MISSING and build_mode.allowed(
                        node.conanfile):
                    node.binary = BINARY_BUILD
Пример #15
0
def deps_install(app, ref_or_path, install_folder, graph_info, remotes=None, build_modes=None,
                 update=False, manifest_folder=None, manifest_verify=False,
                 manifest_interactive=False, generators=None, no_imports=False,
                 create_reference=None, keep_build=False, use_lock=False, recorder=None):
    """ Fetch and build all dependencies for the given reference
    :param app: The ConanApp instance with all collaborators
    @param ref_or_path: ConanFileReference or path to user space conanfile
    @param install_folder: where the output files will be saved
    @param build_modes: List of build_modes specified
    @param update: Check for updated in the upstream remotes (and update)
    @param manifest_folder: Folder to install the manifests
    @param manifest_verify: Verify dependencies manifests against stored ones
    @param manifest_interactive: Install deps manifests in folder for later verify, asking user
    for confirmation
    @param generators: List of generators from command line. If False, no generator will be
    written
    @param no_imports: Install specified packages but avoid running imports

    """
    out, user_io, graph_manager, cache = app.out, app.user_io, app.graph_manager, app.cache
    remote_manager, hook_manager = app.remote_manager, app.hook_manager
    if generators is not False:
        generators = set(generators) if generators else set()
        generators.add("txt")  # Add txt generator by default

    out.info("Configuration:")
    out.writeln(graph_info.profile_host.dumps())
    deps_graph = graph_manager.load_graph(ref_or_path, create_reference, graph_info, build_modes,
                                          False, update, remotes, recorder)
    root_node = deps_graph.root
    conanfile = root_node.conanfile
    if root_node.recipe == RECIPE_VIRTUAL:
        out.highlight("Installing package: %s" % str(ref_or_path))
    else:
        conanfile.output.highlight("Installing package")
    print_graph(deps_graph, out)

    try:
        if cross_building(graph_info.profile_host.processed_settings):
            settings = get_cross_building_settings(graph_info.profile_host.processed_settings)
            message = "Cross-build from '%s:%s' to '%s:%s'" % settings
            out.writeln(message, Color.BRIGHT_MAGENTA)
    except ConanException:  # Setting os doesn't exist
        pass

    installer = BinaryInstaller(app, recorder=recorder)
    # TODO: Extract this from the GraphManager, reuse same object, check args earlier
    build_modes = BuildMode(build_modes, out)
    installer.install(deps_graph, remotes, build_modes, update, keep_build=keep_build,
                      graph_info=graph_info)
    # GraphLock always != None here (because of graph_manager.load_graph)
    graph_info.graph_lock.update_check_graph(deps_graph, out)

    if manifest_folder:
        manifest_manager = ManifestManager(manifest_folder, user_io=user_io, cache=cache)
        for node in deps_graph.nodes:
            if node.recipe in (RECIPE_CONSUMER, RECIPE_VIRTUAL):
                continue
            complete_recipe_sources(remote_manager, cache, node.conanfile, node.ref,
                                    remotes)
        manifest_manager.check_graph(deps_graph, verify=manifest_verify,
                                     interactive=manifest_interactive)
        manifest_manager.print_log()

    if install_folder:
        conanfile.install_folder = install_folder
        # Write generators
        output = conanfile.output if root_node.recipe != RECIPE_VIRTUAL else out
        if generators is not False:
            tmp = list(conanfile.generators)  # Add the command line specified generators
            tmp.extend([g for g in generators if g not in tmp])
            conanfile.generators = tmp
            write_generators(conanfile, install_folder, output)
        if not isinstance(ref_or_path, ConanFileReference) or use_lock:
            # Write conaninfo
            content = normalize(conanfile.info.dumps())
            save(os.path.join(install_folder, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            graph_info.save(install_folder)
            output.info("Generated graphinfo")
        if not no_imports:
            run_imports(conanfile, install_folder)
        call_system_requirements(conanfile, conanfile.output)

        if not create_reference and isinstance(ref_or_path, ConanFileReference):
            # The conanfile loaded is a virtual one. The one w deploy is the first level one
            neighbours = deps_graph.root.neighbors()
            deploy_conanfile = neighbours[0].conanfile
            if hasattr(deploy_conanfile, "deploy") and callable(deploy_conanfile.deploy):
                run_deploy(deploy_conanfile, install_folder)
Пример #16
0
 def test_multiple_builds(self):
     reference = ConanFileReference.loads("Bar/0.1@user/stable")
     build_mode = BuildMode(["Bar", "Foo"], self.output)
     self.assertTrue(build_mode.forced(self.conanfile, reference))
     build_mode.report_matches()
     self.assertIn("ERROR: No package matching", self.output)
Пример #17
0
    def test_allowed(self):
        build_mode = BuildMode(["outdated", "missing"], self.output)
        self.assertTrue(build_mode.allowed(self.conanfile))

        build_mode = BuildMode([], self.output)
        self.assertFalse(build_mode.allowed(self.conanfile))
Пример #18
0
 def test_invalid_configuration(self):
     with six.assertRaisesRegex(self, ConanException,
                                  "--build=never not compatible with other options"):
         BuildMode(["outdated", "missing", "never"], self.output)
Пример #19
0
 def test_full_reference_build_force(self):
     reference = ConanFileReference.loads("Bar/0.1@user/testing")
     build_mode = BuildMode(["Bar/0.1@user/testing"], self.output)
     self.assertTrue(build_mode.forced(self.conanfile, reference))
     build_mode.report_matches()
     self.assertEqual("", self.output)
Пример #20
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
Пример #21
0
def deps_install(app,
                 ref_or_path,
                 install_folder,
                 base_folder,
                 graph_info,
                 remotes=None,
                 build_modes=None,
                 update=False,
                 manifest_folder=None,
                 manifest_verify=False,
                 manifest_interactive=False,
                 generators=None,
                 no_imports=False,
                 create_reference=None,
                 keep_build=False,
                 recorder=None,
                 lockfile_node_id=None,
                 is_build_require=False,
                 add_txt_generator=True,
                 require_overrides=None,
                 conanfile_path=None,
                 test=None,
                 source_folder=None,
                 output_folder=None):
    """ Fetch and build all dependencies for the given reference
    @param app: The ConanApp instance with all collaborators
    @param ref_or_path: ConanFileReference or path to user space conanfile
    @param install_folder: where the output files will be saved
    @param build_modes: List of build_modes specified
    @param update: Check for updated in the upstream remotes (and update)
    @param manifest_folder: Folder to install the manifests
    @param manifest_verify: Verify dependencies manifests against stored ones
    @param manifest_interactive: Install deps manifests in folder for later verify, asking user
    for confirmation
    @param generators: List of generators from command line.
    @param no_imports: Install specified packages but avoid running imports
    @param add_txt_generator: Add the txt to the list of generators

    """

    out, user_io, graph_manager, cache = app.out, app.user_io, app.graph_manager, app.cache
    remote_manager, hook_manager = app.remote_manager, app.hook_manager

    profile_host, profile_build = graph_info.profile_host, graph_info.profile_build

    if profile_build:
        out.info("Configuration (profile_host):")
        out.writeln(profile_host.dumps())
        out.info("Configuration (profile_build):")
        out.writeln(profile_build.dumps())
    else:
        out.info("Configuration:")
        out.writeln(profile_host.dumps())

    deps_graph = graph_manager.load_graph(ref_or_path,
                                          create_reference,
                                          graph_info,
                                          build_modes,
                                          False,
                                          update,
                                          remotes,
                                          recorder,
                                          lockfile_node_id=lockfile_node_id,
                                          is_build_require=is_build_require,
                                          require_overrides=require_overrides)
    graph_lock = graph_info.graph_lock  # After the graph is loaded it is defined
    root_node = deps_graph.root
    conanfile = root_node.conanfile
    if root_node.recipe == RECIPE_VIRTUAL:
        out.highlight("Installing package: %s" % str(ref_or_path))
    else:
        conanfile.output.highlight("Installing package")
    print_graph(deps_graph, out)

    try:
        if cross_building(conanfile):
            settings = get_cross_building_settings(conanfile)
            message = "Cross-build from '%s:%s' to '%s:%s'" % settings
            out.writeln(message, Color.BRIGHT_MAGENTA)
    except ConanException:  # Setting os doesn't exist
        pass

    installer = BinaryInstaller(app, recorder=recorder)
    # TODO: Extract this from the GraphManager, reuse same object, check args earlier
    build_modes = BuildMode(build_modes, out)
    installer.install(deps_graph,
                      remotes,
                      build_modes,
                      update,
                      profile_host,
                      profile_build,
                      graph_lock,
                      keep_build=keep_build)

    graph_lock.complete_matching_prevs()

    if manifest_folder:
        manifest_manager = ManifestManager(manifest_folder,
                                           user_io=user_io,
                                           cache=cache)
        for node in deps_graph.nodes:
            if node.recipe in (RECIPE_CONSUMER, RECIPE_VIRTUAL):
                continue
            retrieve_exports_sources(remote_manager, cache, node.conanfile,
                                     node.ref, remotes)
        manifest_manager.check_graph(deps_graph,
                                     verify=manifest_verify,
                                     interactive=manifest_interactive)
        manifest_manager.print_log()

    if hasattr(conanfile, "layout") and not test:
        conanfile.folders.set_base_source(source_folder or conanfile_path)
        conanfile.folders.set_base_install(output_folder or conanfile_path)
        conanfile.folders.set_base_imports(output_folder or conanfile_path)
        conanfile.folders.set_base_generators(output_folder or conanfile_path)
    else:
        conanfile.folders.set_base_install(install_folder)
        conanfile.folders.set_base_imports(install_folder)
        conanfile.folders.set_base_generators(base_folder)

    output = conanfile.output if root_node.recipe != RECIPE_VIRTUAL else out

    if install_folder:
        # Write generators
        tmp = list(
            conanfile.generators)  # Add the command line specified generators
        generators = set(generators) if generators else set()
        tmp.extend([g for g in generators if g not in tmp])
        if add_txt_generator:
            tmp.append("txt")
        conanfile.generators = tmp
        app.generator_manager.write_generators(conanfile, install_folder,
                                               conanfile.generators_folder,
                                               output)
        write_toolchain(conanfile, conanfile.generators_folder, output)

        if not isinstance(ref_or_path, ConanFileReference):
            # Write conaninfo
            content = normalize(conanfile.info.dumps())
            save(os.path.join(install_folder, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            graph_info.save(install_folder)
            output.info("Generated graphinfo")
            graph_lock_file = GraphLockFile(profile_host, profile_build,
                                            graph_lock)
            graph_lock_file.save(os.path.join(install_folder, "conan.lock"))
        if not no_imports:
            run_imports(conanfile)
        if type(conanfile
                ).system_requirements != ConanFile.system_requirements:
            call_system_requirements(conanfile, conanfile.output)

        if not create_reference and isinstance(ref_or_path,
                                               ConanFileReference):
            # The conanfile loaded is a virtual one. The one w deploy is the first level one
            neighbours = deps_graph.root.neighbors()
            deploy_conanfile = neighbours[0].conanfile
            if hasattr(deploy_conanfile, "deploy") and callable(
                    deploy_conanfile.deploy):
                run_deploy(deploy_conanfile, install_folder)
Пример #22
0
 def test_no_user_channel_revision_included(self):
     reference = ConanFileReference.loads("Hello/0.1@#rrev1")
     build_mode = BuildMode(["Hello/0.1@#rrev1"], self.output)
     self.assertTrue(build_mode.forced(self.conanfile, reference))
     build_mode.report_matches()
     self.assertEqual("", self.output)
Пример #23
0
    def install(self, reference, install_folder, profile, remote_name=None, build_modes=None,
                update=False, manifest_folder=None, manifest_verify=False,
                manifest_interactive=False, generators=None, no_imports=False, inject_require=None,
                install_reference=False, keep_build=False):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param install_folder: where the output files will be saved
        @param remote: install only from that remote
        @param profile: Profile object with both the -s introduced options and profile read values
        @param build_modes: List of build_modes specified
        @param update: Check for updated in the upstream remotes (and update)
        @param manifest_folder: Folder to install the manifests
        @param manifest_verify: Verify dependencies manifests against stored ones
        @param manifest_interactive: Install deps manifests in folder for later verify, asking user
        for confirmation
        @param generators: List of generators from command line. If False, no generator will be
        written
        @param no_imports: Install specified packages but avoid running imports
        @param inject_require: Reference to add as a requirement to the conanfile
        """

        if generators is not False:
            generators = set(generators) if generators else set()
            generators.add("txt")  # Add txt generator by default

        manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io,
                                           client_cache=self._client_cache,
                                           verify=manifest_verify,
                                           interactive=manifest_interactive) if manifest_folder else None
        remote_proxy = self.get_proxy(remote_name=remote_name, manifest_manager=manifest_manager)

        loader = self.get_loader(profile)
        if not install_reference:
            if isinstance(reference, ConanFileReference):  # is a create
                loader.dev_reference = reference
            elif inject_require:
                loader.dev_reference = inject_require
        conanfile = self._load_install_conanfile(loader, reference)
        if inject_require:
            self._inject_require(conanfile, inject_require)
        graph_builder = self._get_graph_builder(loader, remote_proxy)
        deps_graph = graph_builder.load_graph(conanfile, False, update)

        if not isinstance(reference, ConanFileReference):
            output = ScopedOutput(("%s (test package)" % str(inject_require)) if inject_require else "PROJECT",
                                  self._user_io.out)
            output.highlight("Installing %s" % reference)
        else:
            output = ScopedOutput(str(reference), self._user_io.out)
            output.highlight("Installing package")
        Printer(self._user_io.out).print_graph(deps_graph, self._registry)

        try:
            if cross_building(loader._settings):
                b_os, b_arch, h_os, h_arch = get_cross_building_settings(loader._settings)
                message = "Cross-build from '%s:%s' to '%s:%s'" % (b_os, b_arch, h_os, h_arch)
                self._user_io.out.writeln(message, Color.BRIGHT_MAGENTA)
        except ConanException:  # Setting os doesn't exist
            pass

        build_mode = BuildMode(build_modes, self._user_io.out)
        build_requires = BuildRequires(loader, graph_builder, self._registry)
        installer = ConanInstaller(self._client_cache, output, remote_proxy, build_mode,
                                   build_requires, recorder=self._recorder)

        # Apply build_requires to consumer conanfile
        if not isinstance(reference, ConanFileReference):
            build_requires.install("", conanfile, installer, profile.build_requires, output, update)

        installer.install(deps_graph, profile.build_requires, keep_build, update=update)
        build_mode.report_matches()

        if install_folder:
            # Write generators
            if generators is not False:
                tmp = list(conanfile.generators)  # Add the command line specified generators
                tmp.extend([g for g in generators if g not in tmp])
                conanfile.generators = tmp
                write_generators(conanfile, install_folder, output)
            if not isinstance(reference, ConanFileReference):
                # Write conaninfo
                content = normalize(conanfile.info.dumps())
                save(os.path.join(install_folder, CONANINFO), content)
                output.info("Generated %s" % CONANINFO)
            if not no_imports:
                run_imports(conanfile, install_folder, output)
            call_system_requirements(conanfile, output)

            if install_reference:
                # The conanfile loaded is really a virtual one. The one with the deploy is the first level one
                deploy_conanfile = deps_graph.inverse_levels()[1][0].conanfile
                if hasattr(deploy_conanfile, "deploy") and callable(deploy_conanfile.deploy):
                    run_deploy(deploy_conanfile, install_folder, output)

        if manifest_manager:
            manifest_manager.print_log()
Пример #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
Пример #25
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
Пример #26
0
    def _evaluate_node(self, node, build_mode, update, remotes):
        assert node.binary is None, "Node.binary should be None"
        assert node.package_id is not None, "Node.package_id shouldn't be None"
        assert node.package_id != PACKAGE_ID_UNKNOWN, "Node.package_id shouldn't be Unknown"
        assert node.prev is None, "Node.prev should be None"

        # If it has lock
        locked = node.graph_lock_node
        if locked and locked.package_id and locked.package_id != PACKAGE_ID_UNKNOWN:
            pref = PackageReference(locked.ref, locked.package_id, locked.prev)  # Keep locked PREV
            self._process_node(node, pref, build_mode, update, remotes)
            if node.binary == BINARY_MISSING and build_mode.allowed(node.conanfile):
                node.binary = BINARY_BUILD
            if node.binary == BINARY_BUILD:
                locked.unlock_prev()

            if node.package_id != locked.package_id:  # It was a compatible package
                # https://github.com/conan-io/conan/issues/9002
                # We need to iterate to search the compatible combination
                for compatible_package in node.conanfile.compatible_packages:
                    comp_package_id = compatible_package.package_id()
                    if comp_package_id == locked.package_id:
                        node._package_id = locked.package_id  # FIXME: Ugly definition of private
                        node.conanfile.settings.values = compatible_package.settings
                        node.conanfile.options.values = compatible_package.options
                        break
                else:
                    raise ConanException("'%s' package-id '%s' doesn't match the locked one '%s'"
                                         % (repr(locked.ref), node.package_id, locked.package_id))
        else:
            assert node.prev is None, "Non locked node shouldn't have PREV in evaluate_node"
            assert node.binary is None, "Node.binary should be None if not locked"
            pref = PackageReference(node.ref, node.package_id)
            self._process_node(node, pref, build_mode, update, remotes)
            if node.binary in (BINARY_MISSING, BINARY_INVALID):
                if node.conanfile.compatible_packages:
                    compatible_build_mode = BuildMode(None, self._out)
                    for compatible_package in node.conanfile.compatible_packages:
                        package_id = compatible_package.package_id()
                        if package_id == node.package_id:
                            node.conanfile.output.info("Compatible package ID %s equal to the "
                                                       "default package ID" % package_id)
                            continue
                        pref = PackageReference(node.ref, package_id)
                        node.binary = None  # Invalidate it
                        # NO Build mode
                        self._process_node(node, pref, compatible_build_mode, update, remotes)
                        assert node.binary is not None
                        if node.binary not in (BINARY_MISSING, ):
                            node.conanfile.output.info("Main binary package '%s' missing. Using "
                                                       "compatible package '%s'"
                                                       % (node.package_id, package_id))

                            # Modifying package id under the hood, FIXME
                            node._package_id = package_id
                            # So they are available in package_info() method
                            node.conanfile.settings.values = compatible_package.settings
                            # TODO: Conan 2.0 clean this ugly
                            node.conanfile.options._package_options.values = compatible_package.options._package_values
                            break
                    if node.binary == BINARY_MISSING and node.package_id == PACKAGE_ID_INVALID:
                        node.binary = BINARY_INVALID
                if node.binary == BINARY_MISSING and build_mode.allowed(node.conanfile):
                    node.binary = BINARY_BUILD

            if locked:
                # package_id was not locked, this means a base lockfile that is being completed
                locked.complete_base_node(node.package_id, node.prev)