Example #1
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
Example #2
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
def workspace_install(self,
                      path,
                      settings=None,
                      options=None,
                      env=None,
                      remote_name=None,
                      build=None,
                      profile_name=None,
                      update=False,
                      cwd=None,
                      install_folder=None):
    cwd = cwd or get_cwd()
    abs_path = os.path.normpath(os.path.join(cwd, path))

    remotes = self.app.load_remotes(remote_name=remote_name, update=update)
    # remotes = self.app.cache.registry.load_remotes()
    # remotes.select(remote_name)
    # self.app.python_requires.enable_remotes(update=update, remotes=remotes)

    workspace = Workspace(abs_path, self.app.cache)
    graph_info = get_graph_info(profile_name, settings, options, env, cwd,
                                None, self.app.cache, self.app.out)

    self.app.out.info("Configuration:")
    self.app.out.writeln(graph_info.profile_host.dumps())

    self.app.cache.editable_packages.override(workspace.get_editable_dict())

    recorder = ActionRecorder()
    deps_graph = self.app.graph_manager.load_graph(workspace.root, None,
                                                   graph_info, build, False,
                                                   update, remotes, recorder)

    print_graph(deps_graph, self.app.out)

    # Inject the generators before installing
    for node in deps_graph.nodes:
        if node.recipe == RECIPE_EDITABLE:
            generators = workspace[node.ref].generators
            if generators is not None:
                tmp = list(node.conanfile.generators)
                tmp.extend([g for g in generators if g not in tmp])
                node.conanfile.generators = tmp

    installer = BinaryInstaller(self.app, recorder)
    installer.install(deps_graph,
                      remotes,
                      build,
                      update,
                      keep_build=False,
                      graph_info=graph_info)

    install_folder = install_folder or cwd
    workspace.generate(install_folder, deps_graph, self.app.out)

    workspace.build(install_folder, deps_graph, self.app.out, self.app)
 def setUp(self):
     self.output = TestBufferConanOutput()
     cache_folder = temp_folder()
     cache = ClientCache(cache_folder, self.output)
     self.cache = cache
     self.remote_manager = MockRemoteManager()
     self.resolver = RangeResolver(cache, self.remote_manager)
     proxy = ConanProxy(cache, self.output, self.remote_manager)
     self.loader = ConanFileLoader(None, self.output, ConanPythonRequire(None, None))
     self.manager = GraphManager(self.output, cache, self.remote_manager, self.loader, proxy,
                                 self.resolver)
     hook_manager = Mock()
     recorder = Mock()
     self.binary_installer = BinaryInstaller(cache, self.output, self.remote_manager, recorder,
                                             hook_manager)
Example #5
0
    def install_workspace(self, graph_info, workspace, remote_name,
                          build_modes, update):
        refs = [
            ConanFileReference(v, "root", "project", "develop")
            for v in workspace.root
        ]
        deps_graph, _ = self._graph_manager.load_graph(refs, None, graph_info,
                                                       build_modes, False,
                                                       update, remote_name,
                                                       self._recorder,
                                                       workspace)

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

        installer = BinaryInstaller(self._cache,
                                    output,
                                    self._remote_manager,
                                    recorder=self._recorder,
                                    workspace=workspace,
                                    hook_manager=self._hook_manager)
        installer.install(deps_graph, keep_build=False, graph_info=graph_info)
        workspace.generate()
Example #6
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)
Example #7
0
    def install(self, 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):
        """ Fetch and build all dependencies for the given reference
        @param ref_or_path: ConanFileReference or path to user space conanfile
        @param install_folder: where the output files will be saved
        @param remote_name: 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
        """

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

        self._user_io.out.info("Configuration:")
        self._user_io.out.writeln(graph_info.profile.dumps())
        result = self._graph_manager.load_graph(ref_or_path, create_reference, graph_info,
                                                build_modes, False, update, remotes,
                                                self._recorder)
        deps_graph, conanfile = result

        if conanfile.display_name == "virtual":
            self._user_io.out.highlight("Installing package: %s" % str(ref_or_path))
        else:
            conanfile.output.highlight("Installing package")
        print_graph(deps_graph, self._user_io.out)

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

        installer = BinaryInstaller(self._cache, self._user_io.out, self._remote_manager,
                                    recorder=self._recorder,
                                    hook_manager=self._hook_manager)
        installer.install(deps_graph, remotes, keep_build=keep_build, graph_info=graph_info)

        if manifest_folder:
            manifest_manager = ManifestManager(manifest_folder, user_io=self._user_io,
                                               cache=self._cache)
            for node in deps_graph.nodes:
                if node.recipe in (RECIPE_CONSUMER, RECIPE_VIRTUAL):
                    continue
                complete_recipe_sources(self._remote_manager, self._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:
            # Write generators
            output = conanfile.output if conanfile.display_name != "virtual" else self._user_io.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):
                # 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)
class GraphManagerTest(unittest.TestCase):

    def setUp(self):
        self.output = TestBufferConanOutput()
        cache_folder = temp_folder()
        cache = ClientCache(cache_folder, self.output)
        self.cache = cache
        self.remote_manager = MockRemoteManager()
        self.resolver = RangeResolver(cache, self.remote_manager)
        proxy = ConanProxy(cache, self.output, self.remote_manager)
        self.loader = ConanFileLoader(None, self.output, ConanPythonRequire(None, None))
        self.manager = GraphManager(self.output, cache, self.remote_manager, self.loader, proxy,
                                    self.resolver)
        hook_manager = Mock()
        recorder = Mock()
        self.binary_installer = BinaryInstaller(cache, self.output, self.remote_manager, recorder,
                                                hook_manager)

    def _cache_recipe(self, reference, test_conanfile, revision=None):
        if isinstance(test_conanfile, TestConanFile):
            test_conanfile.info = True
        ref = ConanFileReference.loads(reference)
        save(self.cache.package_layout(ref).conanfile(), str(test_conanfile))
        with self.cache.package_layout(ref).update_metadata() as metadata:
            metadata.recipe.revision = revision or "123"
        manifest = FileTreeManifest.create(self.cache.package_layout(ref).export())
        manifest.save(self.cache.package_layout(ref).export())

    def build_graph(self, content, profile_build_requires=None, ref=None, create_ref=None):
        path = temp_folder()
        path = os.path.join(path, "conanfile.py")
        save(path, str(content))
        self.loader.cached_conanfiles = {}

        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 = []
        ref = ref or ConanFileReference(None, None, None, None, validate=False)
        options = OptionsValues()
        graph_info = GraphInfo(profile, options, root_ref=ref)
        deps_graph, _ = self.manager.load_graph(path, create_ref, graph_info,
                                                build_mode, check_updates, update,
                                                remotes, recorder)
        self.binary_installer.install(deps_graph, False, graph_info)
        return deps_graph

    def _check_node(self, node, ref, deps, build_deps, dependents, closure):
        conanfile = node.conanfile
        ref = ConanFileReference.loads(str(ref))
        self.assertEqual(node.ref.full_repr(), ref.full_repr())
        self.assertEqual(conanfile.name, ref.name)
        self.assertEqual(len(node.dependencies), len(deps) + len(build_deps))

        dependants = node.inverse_neighbors()
        self.assertEqual(len(dependants), len(dependents))
        for d in dependents:
            self.assertIn(d, dependants)

        # The recipe requires is resolved to the reference WITH revision!
        self.assertEqual(len(deps), len(conanfile.requires))
        for dep in deps:
            self.assertEqual(conanfile.requires[dep.name].ref,
                             dep.ref)

        self.assertEqual(closure, node.public_closure)
        libs = []
        envs = []
        for n in closure:
            libs.append("mylib%s%slib" % (n.ref.name, n.ref.version))
            envs.append("myenv%s%senv" % (n.ref.name, n.ref.version))
        self.assertEqual(conanfile.deps_cpp_info.libs, libs)
        env = {"MYENV": envs} if envs else {}
        self.assertEqual(conanfile.deps_env_info.vars, env)
Example #9
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)