Esempio n. 1
0
    def package_available(self, package_ref, package_folder, check_outdated):
        """
        Returns True if there is a local or remote package available (and up to date if check_outdated).
        It wont download the package, just check its hash
        """

        output = ScopedOutput(str(package_ref.conan), self._out)
        remote_info = None
        # No package in local cache
        if not os.path.exists(package_folder):
            try:
                # NOTE This call can associate a recently exported recipe, with anything
                # to a remote containing the recipe reference
                remote_info = self._get_package_info(package_ref)
            except (NotFoundException, NoRemoteAvailable):  # 404 or no remote
                return False

        # Maybe we have the package (locally or in remote) but it's outdated
        if check_outdated:
            if remote_info:
                package_hash = remote_info.recipe_hash
            else:
                package_hash = self._client_cache.read_package_recipe_hash(
                    package_folder)
            local_recipe_hash = self._client_cache.load_manifest(
                package_ref.conan).summary_hash
            up_to_date = local_recipe_hash == package_hash
            if not up_to_date:
                output.info("Outdated package!")
            else:
                output.info("Package is up to date")
            return up_to_date

        return True
Esempio n. 2
0
    def get_recipe(self, conan_reference):
        output = ScopedOutput(str(conan_reference), self._out)

        def _refresh():
            export_path = self._client_cache.export(conan_reference)
            rmdir(export_path)
            # It might need to remove shortpath
            rm_conandir(self._client_cache.source(conan_reference))
            current_remote, _ = self._get_remote(conan_reference)
            output.info("Retrieving from remote '%s'..." % current_remote.name)
            self._remote_manager.get_recipe(conan_reference, export_path, current_remote)
            if self._update:
                output.info("Updated!")
            else:
                output.info("Installed!")

        # check if it is in disk
        conanfile_path = self._client_cache.conanfile(conan_reference)

        if os.path.exists(conanfile_path):
            log_recipe_got_from_local_cache(conan_reference)
            if self._check_updates:
                ret = self.update_available(conan_reference)
                if ret != 0:  # Found and not equal
                    remote, ref_remote = self._get_remote(conan_reference)
                    if ret == 1:
                        if not self._update:
                            if remote != ref_remote:  # Forced new remote
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u -r %s' to update it."
                                            % (remote.name, remote.name))
                            else:
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u' to update it."
                                            % remote.name)
                            output.warn("Refused to install!")
                        else:
                            if remote != ref_remote:
                                # Delete packages, could be non coherent with new remote
                                DiskRemover(self._client_cache).remove_packages(conan_reference)
                            _refresh()
                    elif ret == -1:
                        if not self._update:
                            output.info("Current conanfile is newer "
                                        "than %s's one" % remote.name)
                        else:
                            output.error("Current conanfile is newer than %s's one. "
                                         "Run 'conan remove %s' and run install again "
                                         "to replace it." % (remote.name, conan_reference))

        else:
            self._retrieve_recipe(conan_reference, output)

        if self._manifest_manager:
            # Just make sure that the recipe sources are there to check
            self.get_recipe_sources(conan_reference)
            remote = self._registry.get_ref(conan_reference)
            self._manifest_manager.check_recipe(conan_reference, remote)

        return conanfile_path
Esempio n. 3
0
    def get_recipe(self, conan_reference):
        output = ScopedOutput(str(conan_reference), self._out)

        def _refresh():
            export_path = self._client_cache.export(conan_reference)
            rmdir(export_path)
            # It might need to remove shortpath
            rm_conandir(self._client_cache.source(conan_reference))
            current_remote, _ = self._get_remote(conan_reference)
            output.info("Retrieving from remote '%s'..." % current_remote.name)
            self._remote_manager.get_recipe(conan_reference, export_path, current_remote)
            if self._update:
                output.info("Updated!")
            else:
                output.info("Installed!")

        # check if it is in disk
        conanfile_path = self._client_cache.conanfile(conan_reference)

        if os.path.exists(conanfile_path):
            log_recipe_got_from_local_cache(conan_reference)
            if self._check_updates:
                ret = self.update_available(conan_reference)
                if ret != 0:  # Found and not equal
                    remote, ref_remote = self._get_remote(conan_reference)
                    if ret == 1:
                        if not self._update:
                            if remote != ref_remote:  # Forced new remote
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u -r %s' to update it."
                                            % (remote.name, remote.name))
                            else:
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u' to update it."
                                            % remote.name)
                            output.warn("Refused to install!")
                        else:
                            if remote != ref_remote:
                                # Delete packages, could be non coherent with new remote
                                DiskRemover(self._client_cache).remove_packages(conan_reference)
                            _refresh()
                    elif ret == -1:
                        if not self._update:
                            output.info("Current conanfile is newer "
                                        "than %s's one" % remote.name)
                        else:
                            output.error("Current conanfile is newer than %s's one. "
                                         "Run 'conan remove %s' and run install again "
                                         "to replace it." % (remote.name, conan_reference))

        else:
            self._retrieve_recipe(conan_reference, output)

        if self._manifest_manager:
            # Just make sure that the recipe sources are there to check
            self.get_recipe_sources(conan_reference)
            remote = self._registry.get_ref(conan_reference)
            self._manifest_manager.check_recipe(conan_reference, remote)

        return conanfile_path
Esempio n. 4
0
File: proxy.py Progetto: antmd/conan
    def package_available(self, package_ref, short_paths, check_outdated):
        """
        Returns True if there is a local or remote package available (and up to date if check_outdated).
        It wont download the package, just check its hash
        """

        output = ScopedOutput(str(package_ref.conan), self._out)
        package_folder = self._client_cache.package(package_ref,
                                                    short_paths=short_paths)

        remote_info = None
        # No package in local cache
        if not os.path.exists(package_folder):
            try:
                remote_info = self.get_package_info(package_ref)
            except ConanException:
                return False  # Not local nor remote

        # Maybe we have the package (locally or in remote) but it's outdated
        if check_outdated:
            if remote_info:
                package_hash = remote_info.recipe_hash
            else:
                package_hash = self._client_cache.read_package_recipe_hash(
                    package_folder)
            local_recipe_hash = self._client_cache.load_manifest(
                package_ref.conan).summary_hash
            up_to_date = local_recipe_hash == package_hash
            if not up_to_date:
                output.info("Outdated package!")
            else:
                output.info("Package is up to date")
            return up_to_date

        return True
Esempio n. 5
0
    def get_package(self, package_ref, short_paths):
        """ obtain a package, either from disk or retrieve from remotes if necessary
        and not necessary to build
        """
        output = ScopedOutput(str(package_ref.conan), self._out)
        package_folder = self._client_cache.package(package_ref, short_paths=short_paths)

        # Check current package status
        if os.path.exists(package_folder):
            if self._check_updates:
                read_manifest = self._client_cache.load_package_manifest(package_ref)
                try:  # get_conan_digest can fail, not in server
                    upstream_manifest = self.get_package_digest(package_ref)
                    if upstream_manifest.file_sums != read_manifest.file_sums:
                        if upstream_manifest.time > read_manifest.time:
                            output.warn("Current package is older than remote upstream one")
                            if self._update:
                                output.warn("Removing it to retrieve or build an updated one")
                                rmdir(package_folder)
                        else:
                            output.warn("Current package is newer than remote upstream one")
                except ConanException:
                    pass

        installed = False
        local_package = os.path.exists(package_folder)
        if local_package:
            output.info('Already installed!')
            installed = True
            log_package_got_from_local_cache(package_ref)
        else:
            installed = self._retrieve_remote_package(package_ref, package_folder,
                                                      output)
        self.handle_package_manifest(package_ref, installed)
        return installed
Esempio n. 6
0
def download(reference, package_ids, remote_name, recipe, remote_manager,
             client_cache, out, recorder, loader, hook_manager):

    assert(isinstance(reference, ConanFileReference))
    output = ScopedOutput(str(reference), out)
    registry = client_cache.registry
    remote = registry.remotes.get(remote_name) if remote_name else registry.remotes.default

    hook_manager.execute("pre_download", reference=reference, remote=remote)
    # First of all download package recipe
    try:
        remote_manager.get_recipe(reference, remote)
    except NotFoundException:
        raise NotFoundException("'%s' not found in remote '%s'" % (str(reference), remote.name))
    registry.refs.set(reference, remote.name)
    conan_file_path = client_cache.conanfile(reference)
    conanfile = loader.load_class(conan_file_path)

    if not recipe:  # Not only the recipe
        # Download the sources too, don't be lazy
        complete_recipe_sources(remote_manager, client_cache, conanfile, reference)

        if not package_ids:  # User didnt specify a specific package binary
            output.info("Getting the complete package list from '%s'..." % str(reference))
            packages_props = remote_manager.search_packages(remote, reference, None)
            package_ids = list(packages_props.keys())
            if not package_ids:
                output.warn("No remote binary packages found in remote")

        _download_binaries(conanfile, reference, package_ids, client_cache, remote_manager,
                           remote, output, recorder)
    hook_manager.execute("post_download", conanfile_path=conan_file_path, reference=reference,
                         remote=remote)
Esempio n. 7
0
def download(ref, package_ids, remote, recipe, remote_manager, cache, out,
             recorder, loader, hook_manager, remotes):

    assert (isinstance(ref, ConanFileReference))
    output = ScopedOutput(str(ref), out)

    hook_manager.execute("pre_download", reference=ref, remote=remote)

    ref = remote_manager.get_recipe(ref, remote)
    with cache.package_layout(ref).update_metadata() as metadata:
        metadata.recipe.remote = remote.name

    conan_file_path = cache.package_layout(ref).conanfile()
    conanfile = loader.load_class(conan_file_path)

    # Download the sources too, don't be lazy
    complete_recipe_sources(remote_manager, cache, conanfile, ref, remotes)

    if not recipe:  # Not only the recipe
        if not package_ids:  # User didn't specify a specific package binary
            output.info("Getting the complete package list from '%s'..." %
                        ref.full_repr())
            packages_props = remote_manager.search_packages(remote, ref, None)
            package_ids = list(packages_props.keys())
            if not package_ids:
                output.warn("No remote binary packages found in remote")

        _download_binaries(conanfile, ref, package_ids, cache, remote_manager,
                           remote, output, recorder)
    hook_manager.execute("post_download",
                         conanfile_path=conan_file_path,
                         reference=ref,
                         remote=remote)
Esempio n. 8
0
def download(app, ref, package_ids, remote, recipe, recorder, remotes):
    out, remote_manager, cache, loader = app.out, app.remote_manager, app.cache, app.loader
    hook_manager = app.hook_manager
    assert (isinstance(ref, ConanFileReference))
    output = ScopedOutput(str(ref), out)

    hook_manager.execute("pre_download", reference=ref, remote=remote)

    try:
        ref = remote_manager.get_recipe(ref, remote)
    except NotFoundException:
        raise RecipeNotFoundException(ref)

    conan_file_path = cache.package_layout(ref).conanfile()
    conanfile = loader.load_basic(conan_file_path)

    # Download the sources too, don't be lazy
    retrieve_exports_sources(remote_manager, cache, conanfile, ref, remotes)

    if not recipe:  # Not only the recipe
        if not package_ids:  # User didn't specify a specific package binary
            output.info("Getting the complete package list from '%s'..." %
                        ref.full_str())
            packages_props = remote_manager.search_packages(remote, ref, None)
            package_ids = list(packages_props.keys())
            if not package_ids:
                output.warn("No remote binary packages found in remote")

        parallel = cache.config.parallel_download
        _download_binaries(conanfile, ref, package_ids, cache, remote_manager,
                           remote, output, recorder, parallel)
    hook_manager.execute("post_download",
                         conanfile_path=conan_file_path,
                         reference=ref,
                         remote=remote)
Esempio n. 9
0
def export_recipe(conanfile, origin_folder, destination_folder):
    if isinstance(conanfile.exports, str):
        conanfile.exports = (conanfile.exports, )

    output = conanfile.output
    package_output = ScopedOutput("%s exports" % output.scope, output)

    if os.path.exists(os.path.join(origin_folder, DATA_YML)):
        package_output.info(
            "File '{}' found. Exporting it...".format(DATA_YML))
        tmp = [DATA_YML]
        if conanfile.exports:
            tmp.extend(conanfile.exports
                       )  # conanfile.exports could be a tuple (immutable)
        conanfile.exports = tmp

    included_exports, excluded_exports = _classify_patterns(conanfile.exports)

    try:
        os.unlink(os.path.join(origin_folder, CONANFILE + 'c'))
    except OSError:
        pass

    copier = FileCopier([origin_folder], destination_folder)
    for pattern in included_exports:
        copier(pattern, links=True, excludes=excluded_exports)

    copier.report(package_output)
Esempio n. 10
0
    def package_available(self, package_ref, package_folder, check_outdated):
        """
        Returns True if there is a local or remote package available (and up to date if check_outdated).
        It wont download the package, just check its hash
        """

        output = ScopedOutput(str(package_ref.conan), self._out)
        remote_info = None
        # No package in local cache
        if not os.path.exists(package_folder):
            try:
                remote_info = self.get_package_info(package_ref)
            except (NotFoundException, NoRemoteAvailable):  # 404 or no remote
                return False

        # Maybe we have the package (locally or in remote) but it's outdated
        if check_outdated:
            if remote_info:
                package_hash = remote_info.recipe_hash
            else:
                package_hash = self._client_cache.read_package_recipe_hash(package_folder)
            local_recipe_hash = self._client_cache.load_manifest(package_ref.conan).summary_hash
            up_to_date = local_recipe_hash == package_hash
            if not up_to_date:
                output.info("Outdated package!")
            else:
                output.info("Package is up to date")
            return up_to_date

        return True
Esempio n. 11
0
    def package(self, reference, package_id):
        # Package paths
        conan_file_path = self._client_cache.conanfile(reference)
        if not os.path.exists(conan_file_path):
            raise ConanException("Package recipe '%s' does not exist" % str(reference))

        if not package_id:
            packages = [PackageReference(reference, packid)
                        for packid in self._client_cache.conan_builds(reference)]
            if not packages:
                raise NotFoundException("%s: Package recipe has not been built locally\n"
                                        "Please read the 'conan package' command help\n"
                                        "Use 'conan install' or 'conan test_package' to build and "
                                        "create binaries" % str(reference))
        else:
            packages = [PackageReference(reference, package_id)]

        for package_reference in packages:
            build_folder = self._client_cache.build(package_reference, short_paths=None)
            if not os.path.exists(build_folder):
                raise NotFoundException("%s: Package binary '%s' folder doesn't exist\n"
                                        "Please read the 'conan package' command help\n"
                                        "Use 'conan install' or 'conan test_package' to build and "
                                        "create binaries"
                                        % (str(reference), package_reference.package_id))
            # The package already exist, we can use short_paths if they were defined
            package_folder = self._client_cache.package(package_reference, short_paths=None)
            # Will read current conaninfo with specified options and load conanfile with them
            output = ScopedOutput(str(reference), self._user_io.out)
            output.info("Re-packaging %s" % package_reference.package_id)
            loader = self._loader(build_folder)
            conanfile = loader.load_conan(conan_file_path, self._user_io.out)
            self._load_deps_info(build_folder, conanfile, output)
            rmdir(package_folder)
            packager.create_package(conanfile, build_folder, package_folder, output)
Esempio n. 12
0
    def get_package(self, package_ref, short_paths):
        """ obtain a package, either from disk or retrieve from remotes if necessary
        and not necessary to build
        """
        output = ScopedOutput(str(package_ref.conan), self._out)
        package_folder = self._client_cache.package(package_ref, short_paths=short_paths)

        # Check current package status
        if os.path.exists(package_folder):
            if self._check_updates:
                read_manifest = self._client_cache.load_package_manifest(package_ref)
                try:  # get_conan_digest can fail, not in server
                    upstream_manifest = self.get_package_digest(package_ref)
                    if upstream_manifest != read_manifest:
                        if upstream_manifest.time > read_manifest.time:
                            output.warn("Current package is older than remote upstream one")
                            if self._update:
                                output.warn("Removing it to retrieve or build an updated one")
                                rmdir(package_folder)
                        else:
                            output.warn("Current package is newer than remote upstream one")
                except ConanException:
                    pass

        installed = False
        local_package = os.path.exists(package_folder)
        if local_package:
            output.info('Already installed!')
            installed = True
            log_package_got_from_local_cache(package_ref)
        else:
            installed = self._retrieve_remote_package(package_ref, package_folder,
                                                      output)
        self.handle_package_manifest(package_ref, installed)
        return installed
Esempio n. 13
0
    def _handle_node_workspace(self, node, workspace_package, inverse_levels,
                               deps_graph):
        conan_ref, conan_file = node.conan_ref, node.conanfile
        output = ScopedOutput("Workspace %s" % conan_ref.name, self._out)
        include_dirs = workspace_package.includedirs
        lib_dirs = workspace_package.libdirs
        self._call_package_info(conan_file, workspace_package.package_folder)
        if include_dirs:
            conan_file.cpp_info.includedirs = include_dirs
        if lib_dirs:
            conan_file.cpp_info.libdirs = lib_dirs
            # Make sure the folders exists, otherwise they will be filtered out
            lib_paths = [
                os.path.join(conan_file.cpp_info.rootpath, p)
                if not os.path.isabs(p) else p for p in lib_dirs
            ]
            for p in lib_paths:
                mkdir(p)

        self._propagate_info(node, inverse_levels, deps_graph, output)

        build_folder = workspace_package.build_folder
        write_generators(conan_file, build_folder, output)
        save(os.path.join(build_folder, CONANINFO), conan_file.info.dumps())
        output.info("Generated %s" % CONANINFO)
        save(os.path.join(build_folder, BUILD_INFO),
             TXTGenerator(conan_file).content)
        output.info("Generated %s" % BUILD_INFO)
        # Build step might need DLLs, binaries as protoc to generate source files
        # So execute imports() before build, storing the list of copied_files
        from conans.client.importer import run_imports
        copied_files = run_imports(conan_file, build_folder, output)
        report_copied_files(copied_files, output)
Esempio n. 14
0
    def _get_recipe(self, reference, check_updates, update, remote_name):
        output = ScopedOutput(str(reference), self._out)
        # check if it is in disk
        conanfile_path = self._client_cache.conanfile(reference)

        # NOT in disk, must be retrieved from remotes
        if not os.path.exists(conanfile_path):
            ref_remote = self._download_recipe(reference, output, remote_name)
            status = RECIPE_DOWNLOADED
            return conanfile_path, status, ref_remote

        ref_remote = self._registry.get_ref(reference)
        check_updates = check_updates or update
        # Recipe exists in disk, but no need to check updates
        if not check_updates:
            status = RECIPE_INCACHE
            log_recipe_got_from_local_cache(reference)
            self._recorder.recipe_fetched_from_cache(reference)
            return conanfile_path, status, ref_remote

        named_remote = self._registry.remote(
            remote_name) if remote_name else None
        update_remote = named_remote or ref_remote
        if not update_remote:
            status = RECIPE_NO_REMOTE
            log_recipe_got_from_local_cache(reference)
            self._recorder.recipe_fetched_from_cache(reference)
            return conanfile_path, status, None

        try:  # get_conan_manifest can fail, not in server
            upstream_manifest = self._remote_manager.get_conan_manifest(
                reference, update_remote)
        except NotFoundException:
            status = RECIPE_NOT_IN_REMOTE
            log_recipe_got_from_local_cache(reference)
            self._recorder.recipe_fetched_from_cache(reference)
            return conanfile_path, status, update_remote

        export = self._client_cache.export(reference)
        read_manifest = FileTreeManifest.load(export)
        if upstream_manifest != read_manifest:
            if upstream_manifest.time > read_manifest.time:
                if update:
                    DiskRemover(self._client_cache).remove_recipe(reference)
                    output.info("Retrieving from remote '%s'..." %
                                update_remote.name)
                    self._remote_manager.get_recipe(reference, update_remote)
                    self._registry.set_ref(reference, update_remote)
                    status = RECIPE_UPDATED
                else:
                    status = RECIPE_UPDATEABLE
            else:
                status = RECIPE_NEWER
        else:
            status = RECIPE_INCACHE

        log_recipe_got_from_local_cache(reference)
        self._recorder.recipe_fetched_from_cache(reference)
        return conanfile_path, status, update_remote
Esempio n. 15
0
    def get_conanfile(self, conan_reference):
        output = ScopedOutput(str(conan_reference), self._out)

        def _refresh():
            conan_dir_path = self._paths.export(conan_reference)
            rmdir(conan_dir_path)
            rmdir(self._paths.source(conan_reference), True)  # It might need to remove shortpath
            current_remote, _ = self._get_remote(conan_reference)
            output.info("Retrieving from remote '%s'..." % current_remote.name)
            self._remote_manager.get_conanfile(conan_reference, current_remote)
            if self._update:
                output.info("Updated!")
            else:
                output.info("Installed!")

        # check if it is in disk
        conanfile_path = self._paths.conanfile(conan_reference)

        path_exist = path_exists(conanfile_path, self._paths.store)

        if path_exist:
            if self._check_integrity:  # Check if package is corrupted
                read_manifest, expected_manifest = self._paths.conan_manifests(conan_reference)
                if read_manifest.file_sums != expected_manifest.file_sums:
                    output.warn("Bad conanfile detected! Removing export directory... ")
                    _refresh()
            else:  # Check for updates
                if self._check_updates:
                    ret = self.update_available(conan_reference)
                    if ret != 0:  # Found and not equal
                        remote, ref_remote = self._get_remote(conan_reference)
                        if ret == 1:
                            if not self._update:
                                if remote != ref_remote:  # Forced new remote
                                    output.warn("There is a new conanfile in '%s' remote. "
                                                "Execute 'install -u -r %s' to update it."
                                                % (remote.name, remote.name))
                                else:
                                    output.warn("There is a new conanfile in '%s' remote. "
                                                "Execute 'install -u' to update it."
                                                % remote.name)
                                output.warn("Refused to install!")
                            else:
                                if remote != ref_remote:
                                    # Delete packages, could be non coherent with new remote
                                    rmdir(self._paths.packages(conan_reference))
                                _refresh()
                        elif ret == -1:
                            if not self._update:
                                output.info("Current conanfile is newer "
                                            "than %s's one" % remote.name)
                            else:
                                output.error("Current conanfile is newer than %s's one. "
                                             "Run 'conan remove %s' and run install again "
                                             "to replace it." % (remote.name, conan_reference))

        else:
            self._retrieve_conanfile(conan_reference, output)
        return conanfile_path
Esempio n. 16
0
    def package(self, reference, package_id):
        # Package paths
        conan_file_path = self._client_cache.conanfile(reference)
        if not os.path.exists(conan_file_path):
            raise ConanException("Package recipe '%s' does not exist" %
                                 str(reference))

        conanfile = load_conanfile_class(conan_file_path)
        if hasattr(conanfile, "build_id"):
            raise ConanException(
                "package command does not support recipes with 'build_id'\n"
                "To repackage them use 'conan install'")

        if not package_id:
            packages = [
                PackageReference(reference, packid)
                for packid in self._client_cache.conan_builds(reference)
            ]
            if not packages:
                raise NotFoundException(
                    "%s: Package recipe has not been built locally\n"
                    "Please read the 'conan package' command help\n"
                    "Use 'conan install' or 'conan test_package' to build and "
                    "create binaries" % str(reference))
        else:
            packages = [PackageReference(reference, package_id)]

        package_source_folder = self._client_cache.source(
            reference, conanfile.short_paths)
        for package_reference in packages:
            build_folder = self._client_cache.build(package_reference,
                                                    short_paths=None)
            if not os.path.exists(build_folder):
                raise NotFoundException(
                    "%s: Package binary '%s' folder doesn't exist\n"
                    "Please read the 'conan package' command help\n"
                    "Use 'conan install' or 'conan test_package' to build and "
                    "create binaries" %
                    (str(reference), package_reference.package_id))
            # The package already exist, we can use short_paths if they were defined
            package_folder = self._client_cache.package(package_reference,
                                                        short_paths=None)
            # Will read current conaninfo with specified options and load conanfile with them
            output = ScopedOutput(str(reference), self._user_io.out)
            output.info("Re-packaging %s" % package_reference.package_id)
            conanfile = load_consumer_conanfile(conan_file_path,
                                                build_folder,
                                                self._client_cache.settings,
                                                self._runner,
                                                output,
                                                reference=reference)
            rmdir(package_folder)
            if getattr(conanfile, 'no_copy_source', False):
                source_folder = package_source_folder
            else:
                source_folder = build_folder
            with environment_append(conanfile.env):
                packager.create_package(conanfile, source_folder, build_folder,
                                        package_folder, output)
Esempio n. 17
0
 def allowed(self, conan_file, reference):
     if self.missing or self.outdated:
         return True
     if conan_file.build_policy_missing:
         out = ScopedOutput(str(reference), self._out)
         out.info(
             "Building package from source as defined by build_policy='missing'"
         )
         return True
     return False
Esempio n. 18
0
    def install(self, reference, current_path, remote=None, options=None, settings=None,
                build_mode=False, filename=None, update=False, check_updates=False,
                integrity=False, scopes=None, generators=None):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param current_path: where the output files will be saved
        @param remote: install only from that remote
        @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...]
        @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...]
        """
        generators = generators or []
        objects = self._get_graph(reference, current_path, remote, options, settings, filename,
                                  update, check_updates, integrity, scopes)
        (_, deps_graph, _, registry, conanfile, remote_proxy, loader) = objects

        Printer(self._user_io.out).print_graph(deps_graph, registry)
        # Warn if os doesn't match
        try:
            if detected_os() != loader._settings.os:
                message = '''You are building this package with settings.os='%s' on a '%s' system.
If this is your intention, you can ignore this message.
If not:
     - Check the passed settings (-s)
     - Check your global settings in ~/.conan/conan.conf
     - Remove conaninfo.txt to avoid bad cached settings
''' % (loader._settings.os, detected_os())
                self._user_io.out.warn(message)
        except ConanException:  # Setting os doesn't exist
            pass

        installer = ConanInstaller(self._paths, self._user_io, remote_proxy)
        installer.install(deps_graph, build_mode)

        scope_prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference)
        output = ScopedOutput(scope_prefix, self._user_io.out)

        # Write generators
        tmp = list(conanfile.generators)  # Add the command line specified generators
        tmp.extend(generators)
        conanfile.generators = tmp
        write_generators(conanfile, current_path, output)

        if not isinstance(reference, ConanFileReference):
            content = normalize(conanfile.info.dumps())
            save(os.path.join(current_path, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            local_installer = FileImporter(deps_graph, self._paths, current_path)
            conanfile.copy = local_installer
            conanfile.imports()
            copied_files = local_installer.execute()
            import_output = ScopedOutput("%s imports()" % output.scope, output)
            report_copied_files(copied_files, import_output)
Esempio n. 19
0
    def forced(self, reference, conanfile):
        if self.all:
            return True

        if conanfile.build_policy_always:
            out = ScopedOutput(str(reference), self._out)
            out.info("Building package from source as defined by build_policy='always'")
            return True

        ref = reference.name
        # Patterns to match, if package matches pattern, build is forced
        force_build = any([fnmatch.fnmatch(ref, pattern) for pattern in self.patterns])
        return force_build
Esempio n. 20
0
    def forced(self, reference, conanfile):
        if self.all:
            return True

        if conanfile.build_policy_always:
            out = ScopedOutput(str(reference), self._out)
            out.info("Building package from source as defined by build_policy='always'")
            return True

        ref = reference.name
        # Patterns to match, if package matches pattern, build is forced
        force_build = any([fnmatch.fnmatch(ref, pattern) for pattern in self.patterns])
        return force_build
Esempio n. 21
0
File: proxy.py Progetto: tru/conan
    def get_package(self, package_reference, force_build):
        """ obtain a package, either from disk or retrieve from remotes if necessary
        and not necessary to build
        """
        output = ScopedOutput(str(package_reference.conan), self._out)
        package_folder = self._paths.package(package_reference)

        # Check current package status
        if path_exists(package_folder, self._paths.store):
            if self._check_integrity or self._check_updates:
                read_manifest, expected_manifest = self._paths.package_manifests(
                    package_reference)

            if self._check_integrity:  # Check if package is corrupted
                if read_manifest.file_sums != expected_manifest.file_sums:
                    # If not valid package, ensure empty folder
                    output.warn("Bad package '%s' detected! Removing "
                                "package directory... " %
                                str(package_reference.package_id))
                    rmdir(package_folder)

            if self._check_updates:
                try:  # get_conan_digest can fail, not in server
                    upstream_manifest = self.get_package_digest(
                        package_reference)
                    if upstream_manifest.file_sums != read_manifest.file_sums:
                        if upstream_manifest.time > read_manifest.time:
                            output.warn(
                                "Current package is older than remote upstream one"
                            )
                            if self._update:
                                output.warn(
                                    "Removing it to retrieve or build an updated one"
                                )
                                rmdir(package_folder)
                        else:
                            output.warn(
                                "Current package is newer than remote upstream one"
                            )
                except ConanException:
                    pass

        if not force_build:
            local_package = os.path.exists(package_folder)
            if local_package:
                output = ScopedOutput(str(package_reference.conan), self._out)
                output.info('Already installed!')
                return True
            return self._retrieve_remote_package(package_reference, output)

        return False
Esempio n. 22
0
    def _build_node(self, conan_ref, conan_file, build_mode):
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._paths.package(package_reference)
        build_folder = self._paths.build(package_reference,
                                         conan_file.short_paths)
        src_folder = self._paths.source(conan_ref, conan_file.short_paths)
        export_folder = self._paths.export(conan_ref)

        # If already exists do not dirt the output, the common situation
        # is that package is already installed and OK. If don't, the proxy
        # will print some other message about it
        if not os.path.exists(package_folder):
            output.info("Installing package %s" % package_id)

        self._handle_system_requirements(conan_ref, package_reference,
                                         conan_file, output)

        force_build = self._build_forced(conan_ref, build_mode, conan_file)
        if self._remote_proxy.get_package(package_reference, force_build):
            return

        # we need and can build? Only if we are forced or build_mode missing and package not exists
        build = force_build or build_mode is True or conan_file.build_policy_missing

        if build:
            if not force_build and not build_mode:
                output.info(
                    "Building package from source as defined by build_policy='missing'"
                )
            try:
                rmdir(build_folder, conan_file.short_paths)
                rmdir(package_folder)
            except Exception as e:
                raise ConanException(
                    "%s\n\nCouldn't remove folder, might be busy or open\n"
                    "Close any app using it, and retry" % str(e))
            if force_build:
                output.warn('Forced build from source')

            self._build_package(export_folder, src_folder, build_folder,
                                package_folder, conan_file, output)

            # Creating ***info.txt files
            save(os.path.join(build_folder, CONANINFO),
                 conan_file.info.dumps())
            output.info("Generated %s" % CONANINFO)
            save(os.path.join(build_folder, BUILD_INFO),
                 TXTGenerator(conan_file).content)
            output.info("Generated %s" % BUILD_INFO)

            os.chdir(build_folder)
            create_package(conan_file, build_folder, package_folder, output)
        else:
            self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 23
0
    def _build_forced(self, conan_ref, build_mode, conan_file):
        if conan_file.build_policy_always:
            out = ScopedOutput(str(conan_ref), self._out)
            out.info("Building package from source as defined by build_policy='always'")
            return True

        if build_mode is False:  # "never" option, default
            return False

        if build_mode is True:  # Build missing (just if needed), not force
            return False

        # Patterns to match, if package matches pattern, build is forced
        force_build = any([fnmatch.fnmatch(str(conan_ref), pattern)
                           for pattern in build_mode])
        return force_build
Esempio n. 24
0
    def _build_forced(self, conan_ref, build_mode, conan_file):
        if conan_file.build_policy_always:
            out = ScopedOutput(str(conan_ref), self._out)
            out.info("Building package from source as defined by build_policy='always'")
            return True

        if build_mode is False:  # "never" option, default
            return False

        if build_mode is True:  # Build missing (just if needed), not force
            return False

        # Patterns to match, if package matches pattern, build is forced
        force_build = any([fnmatch.fnmatch(str(conan_ref), pattern)
                           for pattern in build_mode])
        return force_build
Esempio n. 25
0
 def source(self, conanfile_path, source_folder, info_folder):
     """
     :param conanfile_path: Absolute path to a conanfile
     :param source_folder: Absolute path where to put the files
     :param info_folder: Absolute path where to read the info files
     :param package_folder: Absolute path to the package_folder, only to have the var present
     :return:
     """
     output = ScopedOutput("PROJECT", self._user_io.out)
     # only infos if exist
     conanfile = self._load_consumer_conanfile(conanfile_path, info_folder, output)
     conanfile_folder = os.path.dirname(conanfile_path)
     if conanfile_folder != source_folder:
         output.info("Executing exports to: %s" % source_folder)
         _execute_export(conanfile_path, conanfile, source_folder, source_folder, output)
     config_source_local(source_folder, conanfile, conanfile_folder, output)
Esempio n. 26
0
    def package(self, reference, package_id):
        # Package paths
        conan_file_path = self._client_cache.conanfile(reference)
        if not os.path.exists(conan_file_path):
            raise ConanException("Package recipe '%s' does not exist" % str(reference))

        conanfile = load_conanfile_class(conan_file_path)
        if hasattr(conanfile, "build_id"):
            raise ConanException("package command does not support recipes with 'build_id'\n"
                                 "To repackage them use 'conan install'")

        if not package_id:
            packages = [PackageReference(reference, packid)
                        for packid in self._client_cache.conan_builds(reference)]
            if not packages:
                raise NotFoundException("%s: Package recipe has not been built locally\n"
                                        "Please read the 'conan package' command help\n"
                                        "Use 'conan install' or 'conan test_package' to build and "
                                        "create binaries" % str(reference))
        else:
            packages = [PackageReference(reference, package_id)]

        package_source_folder = self._client_cache.source(reference, conanfile.short_paths)
        for package_reference in packages:
            build_folder = self._client_cache.build(package_reference, short_paths=None)
            if not os.path.exists(build_folder):
                raise NotFoundException("%s: Package binary '%s' folder doesn't exist\n"
                                        "Please read the 'conan package' command help\n"
                                        "Use 'conan install' or 'conan test_package' to build and "
                                        "create binaries"
                                        % (str(reference), package_reference.package_id))
            # The package already exist, we can use short_paths if they were defined
            package_folder = self._client_cache.package(package_reference, short_paths=None)
            # Will read current conaninfo with specified options and load conanfile with them
            output = ScopedOutput(str(reference), self._user_io.out)
            output.info("Re-packaging %s" % package_reference.package_id)
            conanfile = load_consumer_conanfile(conan_file_path, build_folder,
                                                self._client_cache.settings,
                                                self._runner, output, reference)
            rmdir(package_folder)
            if getattr(conanfile, 'no_copy_source', False):
                source_folder = package_source_folder
            else:
                source_folder = build_folder
            with environment_append(conanfile.env):
                packager.create_package(conanfile, source_folder, build_folder, package_folder,
                                        output)
Esempio n. 27
0
 def source(self, conanfile_path, source_folder, info_folder):
     """
     :param conanfile_path: Absolute path to a conanfile
     :param source_folder: Absolute path where to put the files
     :param info_folder: Absolute path where to read the info files
     :param package_folder: Absolute path to the package_folder, only to have the var present
     :return:
     """
     output = ScopedOutput("PROJECT", self._user_io.out)
     # only infos if exist
     conanfile = self._load_consumer_conanfile(conanfile_path, info_folder, output)
     conanfile_folder = os.path.dirname(conanfile_path)
     if conanfile_folder != source_folder:
         output.info("Executing exports to: %s" % source_folder)
         _execute_export(conanfile_path, conanfile, source_folder,
                         source_folder, output)
     config_source_local(source_folder, conanfile, output)
Esempio n. 28
0
    def retrieve_conanfile(self, conan_reference, consumer=False):
        """ returns the requested conanfile object, retrieving it from
        remotes if necessary. Can raise NotFoundException
        """
        output = ScopedOutput(str(conan_reference), self._out)
        conanfile_path = self._paths.conanfile(conan_reference)

        if not self._paths.valid_conan_digest(conan_reference):
            conan_dir_path = self._paths.export(conan_reference)
            if path_exists(conan_dir_path, self._paths.store):
                # If not valid conanfile, ensure empty folder
                output.warn("Bad conanfile detected! Removing export directory... ")
                rmdir(conan_dir_path)
            output.info("Conanfile not found, retrieving from server")
            # If not in localhost, download it. Will raise if not found
            self._remote_manager.get_conanfile(conan_reference, self._remote)
        conanfile = self._loader.load_conan(conanfile_path, output, consumer)
        return conanfile
Esempio n. 29
0
    def _build_node(self, conan_ref, conan_file, build_mode):
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._paths.package(package_reference, conan_file.short_paths)
        build_folder = self._paths.build(package_reference, conan_file.short_paths)
        src_folder = self._paths.source(conan_ref, conan_file.short_paths)
        export_folder = self._paths.export(conan_ref)

        # If already exists do not dirt the output, the common situation
        # is that package is already installed and OK. If don't, the proxy
        # will print some other message about it
        if not package_exists(package_folder):
            output.info("Installing package %s" % package_id)

        self._handle_system_requirements(conan_ref, package_reference, conan_file, output)

        force_build = self._build_forced(conan_ref, build_mode, conan_file)
        if self._remote_proxy.get_package(package_reference, force_build,
                                          short_paths=conan_file.short_paths):
            return

        # we need and can build? Only if we are forced or build_mode missing and package not exists
        build = force_build or build_mode is True or conan_file.build_policy_missing

        if build:
            if not force_build and not build_mode:
                output.info("Building package from source as defined by build_policy='missing'")
            try:
                rmdir(build_folder, conan_file.short_paths)
                rmdir(package_folder)
            except Exception as e:
                raise ConanException("%s\n\nCouldn't remove folder, might be busy or open\n"
                                     "Close any app using it, and retry" % str(e))
            if force_build:
                output.warn('Forced build from source')

            self._build_package(export_folder, src_folder, build_folder, package_folder,
                                conan_file, output)

            # Creating ***info.txt files
            save(os.path.join(build_folder, CONANINFO), conan_file.info.dumps())
            output.info("Generated %s" % CONANINFO)
            save(os.path.join(build_folder, BUILD_INFO), TXTGenerator(conan_file).content)
            output.info("Generated %s" % BUILD_INFO)

            os.chdir(build_folder)
            create_package(conan_file, build_folder, package_folder, output)
            self._remote_proxy.handle_package_manifest(package_reference, installed=True)
        else:
            self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 30
0
    def download(self, reference, package_ids, remote_name, recipe):
        """ Download conanfile and specified packages to local repository
        @param reference: ConanFileReference
        @param package_ids: Package ids or empty for download all
        @param remote: install only from that remote
        @param only_recipe: download only the recipe
        """
        assert (isinstance(reference, ConanFileReference))
        output = ScopedOutput(str(reference), self._user_io.out)
        remote = self._registry.remote(
            remote_name) if remote_name else self._registry.default_remote
        package = self._remote_manager.search_recipes(remote, reference, None)
        if not package:  # Search the reference first, and raise if it doesn't exist
            raise ConanException("'%s' not found in remote" % str(reference))

        # First of all download package recipe
        self._remote_manager.get_recipe(reference, remote)
        self._registry.set_ref(reference, remote)

        if recipe:
            return

        # Download the sources too, don't be lazy
        conan_file_path = self._client_cache.conanfile(reference)
        conanfile = load_conanfile_class(conan_file_path)
        complete_recipe_sources(self._remote_manager, self._client_cache,
                                self._registry, conanfile, reference)

        if package_ids:
            download_binaries(reference, package_ids, self._client_cache,
                              self._remote_manager, remote, output,
                              self._recorder)
        else:
            output.info("Getting the complete package list "
                        "from '%s'..." % str(reference))
            packages_props = self._remote_manager.search_packages(
                remote, reference, None)
            if not packages_props:
                output = ScopedOutput(str(reference), self._user_io.out)
                output.warn("No remote binary packages found in remote")
            else:
                download_binaries(reference, list(packages_props.keys()),
                                  self._client_cache, self._remote_manager,
                                  remote, output, self._recorder)
Esempio n. 31
0
def download(reference, package_ids, remote_name, recipe, registry,
             remote_manager, client_cache, out, recorder, loader,
             hook_manager):

    assert (isinstance(reference, ConanFileReference))
    output = ScopedOutput(str(reference), out)
    remote = registry.remotes.get(
        remote_name) if remote_name else registry.remotes.default
    package = remote_manager.search_recipes(remote, reference, None)
    if not package:  # Search the reference first, and raise if it doesn't exist
        raise ConanException("'%s' not found in remote" % str(reference))

    hook_manager.execute("pre_download", reference=reference, remote=remote)
    # First of all download package recipe
    remote_manager.get_recipe(reference, remote)
    registry.refs.set(reference, remote.name)
    conan_file_path = client_cache.conanfile(reference)
    conanfile = loader.load_class(conan_file_path)

    if not recipe:
        # Download the sources too, don't be lazy
        complete_recipe_sources(remote_manager, client_cache, registry,
                                conanfile, reference)

        if package_ids:
            _download_binaries(reference, package_ids, client_cache,
                               remote_manager, remote, output, recorder,
                               loader)
        else:
            output.info("Getting the complete package list "
                        "from '%s'..." % str(reference))
            packages_props = remote_manager.search_packages(
                remote, reference, None)
            if not packages_props:
                output = ScopedOutput(str(reference), out)
                output.warn("No remote binary packages found in remote")
            else:
                _download_binaries(reference, list(packages_props.keys()),
                                   client_cache, remote_manager, remote,
                                   output, recorder, loader)
    hook_manager.execute("post_download",
                         conanfile_path=conan_file_path,
                         reference=reference,
                         remote=remote)
Esempio n. 32
0
    def get_package(self, package_reference, force_build):
        """ obtain a package, either from disk or retrieve from remotes if necessary
        and not necessary to build
        """
        output = ScopedOutput(str(package_reference.conan), self._out)
        package_folder = self._paths.package(package_reference)

        # Check current package status
        if path_exists(package_folder, self._paths.store):
            if self._check_integrity or self._check_updates:
                read_manifest, expected_manifest = self._paths.package_manifests(package_reference)

            if self._check_integrity:  # Check if package is corrupted
                if read_manifest.file_sums != expected_manifest.file_sums:
                    # If not valid package, ensure empty folder
                    output.warn("Bad package '%s' detected! Removing "
                                "package directory... " % str(package_reference.package_id))
                    rmdir(package_folder)

            if self._check_updates:
                try:  # get_conan_digest can fail, not in server
                    upstream_manifest = self.get_package_digest(package_reference)
                    if upstream_manifest.file_sums != read_manifest.file_sums:
                        if upstream_manifest.time > read_manifest.time:
                            output.warn("Current package is older than remote upstream one")
                            if self._update:
                                output.warn("Removing it to retrieve or build an updated one")
                                rmdir(package_folder)
                        else:
                            output.warn("Current package is newer than remote upstream one")
                except ConanException:
                    pass

        if not force_build:
            local_package = os.path.exists(package_folder)
            if local_package:
                output = ScopedOutput(str(package_reference.conan), self._out)
                output.info('Already installed!')
                return True
            return self._retrieve_remote_package(package_reference, output)

        return False
Esempio n. 33
0
    def _get_package(self, conan_ref, conan_file):
        '''Get remote package. It won't check if it's outdated'''
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._client_cache.package(package_reference, conan_file.short_paths)

        # If already exists do not dirt the output, the common situation
        # is that package is already installed and OK. If don't, the proxy
        # will print some other message about it
        if not os.path.exists(package_folder):
            output.info("Retrieving package %s" % package_id)

        if self._remote_proxy.get_package(package_reference, short_paths=conan_file.short_paths):
            self._handle_system_requirements(conan_ref, package_reference, conan_file, output)
            return True

        self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 34
0
    def _get_package(self, conan_ref, conan_file):
        '''Get remote package. It won't check if it's outdated'''
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._client_cache.package(package_reference, conan_file.short_paths)

        # If already exists do not dirt the output, the common situation
        # is that package is already installed and OK. If don't, the proxy
        # will print some other message about it
        if not os.path.exists(package_folder):
            output.info("Installing package %s" % package_id)

        if self._remote_proxy.get_package(package_reference, short_paths=conan_file.short_paths):
            self._handle_system_requirements(conan_ref, package_reference, conan_file, output)
            return True

        self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 35
0
    def forced(self, conan_file, reference):
        if self.never:
            return False
        if self.all:
            return True

        if conan_file.build_policy_always:
            out = ScopedOutput(str(reference), self._out)
            out.info(
                "Building package from source as defined by build_policy='always'"
            )
            return True

        ref = reference.name
        # Patterns to match, if package matches pattern, build is forced
        for pattern in self.patterns:
            if fnmatch.fnmatch(ref, pattern):
                try:
                    self._unused_patterns.remove(pattern)
                except ValueError:
                    pass
                return True
        return False
Esempio n. 36
0
 def _compute_private_nodes(self, deps_graph, build_mode):
     """ computes a list of nodes that are not required to be built, as they are
     private requirements of already available shared libraries as binaries
     """
     private_closure = deps_graph.private_nodes()
     skippable_nodes = []
     for private_node, private_requirers in private_closure:
         for private_requirer in private_requirers:
             conan_ref, conan_file = private_requirer
             if conan_ref is None:
                 continue
             package_id = conan_file.info.package_id()
             package_reference = PackageReference(conan_ref, package_id)
             package_folder = self._paths.package(package_reference)
             if not path_exists(package_folder, self._paths.store):
                 if not self._force_build(conan_ref, build_mode):  # Not download package
                     output = ScopedOutput(str(conan_ref), self._out)
                     output.info("Package not installed")
                     if not self._retrieve_remote_package(package_reference, output):
                         break
         else:
             skippable_nodes.append(private_node)
     return skippable_nodes
Esempio n. 37
0
    def package(self, reference, package_id):
        assert(isinstance(reference, ConanFileReference))

        # Package paths
        conan_file_path = self._client_cache.conanfile(reference)
        if not os.path.exists(conan_file_path):
            raise ConanException("Package recipe '%s' does not exist" % str(reference))

        if not package_id:
            packages = [PackageReference(reference, packid)
                        for packid in self._client_cache.conan_builds(reference)]
            if not packages:
                raise NotFoundException("%s: Package recipe has not been built locally\n"
                                        "Please read the 'conan package' command help\n"
                                        "Use 'conan install' or 'conan test_package' to build and "
                                        "create binaries" % str(reference))
        else:
            packages = [PackageReference(reference, package_id)]

        for package_reference in packages:
            build_folder = self._client_cache.build(package_reference, short_paths=None)
            if not build_exists(build_folder):
                raise NotFoundException("%s: Package binary '%s' folder doesn't exist\n"
                                        "Please read the 'conan package' command help\n"
                                        "Use 'conan install' or 'conan test_package' to build and "
                                        "create binaries"
                                        % (str(reference), package_reference.package_id))
            # The package already exist, we can use short_paths if they were defined
            package_folder = self._client_cache.package(package_reference, short_paths=None)
            # Will read current conaninfo with specified options and load conanfile with them
            output = ScopedOutput(str(reference), self._user_io.out)
            output.info("Re-packaging %s" % package_reference.package_id)
            loader = self._loader(build_folder)
            conanfile = loader.load_conan(conan_file_path, self._user_io.out)
            rmdir(package_folder)
            packager.create_package(conanfile, build_folder, package_folder, output)
Esempio n. 38
0
    def _get_recipe(self, conan_reference, check_updates, update):
        output = ScopedOutput(str(conan_reference), self._out)
        check_updates = check_updates or update
        # check if it is in disk
        conanfile_path = self._client_cache.conanfile(conan_reference)

        if os.path.exists(conanfile_path):
            if check_updates:
                ret = self.update_available(conan_reference)
                if ret != 0:  # Found and not equal
                    remote, ref_remote = self._get_remote(conan_reference)
                    if ret == 1:
                        if not update:
                            if remote != ref_remote:  # Forced new remote
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u -r %s' to update it."
                                            % (remote.name, remote.name))
                            else:
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u' to update it."
                                            % remote.name)
                            output.warn("Refused to install!")
                        else:
                            DiskRemover(self._client_cache).remove(conan_reference)
                            output.info("Retrieving from remote '%s'..." % remote.name)
                            self._remote_manager.get_recipe(conan_reference, remote)

                            output.info("Updated!")
                    elif ret == -1:
                        if not update:
                            output.info("Current conanfile is newer than %s's one" % remote.name)
                        else:
                            output.error("Current conanfile is newer than %s's one. "
                                         "Run 'conan remove %s' and run install again "
                                         "to replace it." % (remote.name, conan_reference))

            log_recipe_got_from_local_cache(conan_reference)
            self._recorder.recipe_fetched_from_cache(conan_reference)

        else:
            self._retrieve_recipe(conan_reference, output)

        if self._manifest_manager:
            # Just make sure that the recipe sources are there to check
            conanfile = load_conanfile_class(conanfile_path)
            complete_recipe_sources(self._remote_manager, self._client_cache, self._registry,
                                    conanfile, conan_reference)

            remote = self._registry.get_ref(conan_reference)
            self._manifest_manager.check_recipe(conan_reference, remote)

        return conanfile_path
Esempio n. 39
0
    def _build_node(self, conan_ref, conan_file, build_mode):
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._paths.package(package_reference)
        build_folder = self._paths.build(package_reference)
        src_folder = self._paths.source(conan_ref)
        export_folder = self._paths.export(conan_ref)

        # If already exists do not dirt the output, the common situation
        # is that package is already installed and OK. If don't, the proxy
        # will print some other message about it
        if not os.path.exists(package_folder):
            output.info("Installing package %s" % package_id)

        self._handle_system_requirements(conan_ref, package_reference,
                                         conan_file, output)

        force_build = self._force_build(conan_ref, build_mode)
        if self._remote_proxy.get_package(package_reference, force_build):
            return

        # Can we build? Only if we are forced or build_mode missing and package not exists
        build_allowed = force_build or build_mode is True

        if build_allowed:
            rmdir(build_folder)
            rmdir(package_folder)
            if force_build:
                output.warn('Forced build from source')

            self._build_package(export_folder, src_folder, build_folder,
                                conan_file, output)

            # Creating ***info.txt files
            save(os.path.join(build_folder, CONANINFO),
                 conan_file.info.dumps())
            output.info("Generated %s" % CONANINFO)
            save(
                os.path.join(build_folder, BUILD_INFO),
                TXTGenerator(conan_file.deps_cpp_info,
                             conan_file.cpp_info).content)
            output.info("Generated %s" % BUILD_INFO)

            os.chdir(build_folder)
            create_package(conan_file, build_folder, package_folder, output)
        else:
            self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 40
0
    def _build_node(self, conan_ref, conan_file, build_mode):
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._paths.package(package_reference)
        build_folder = self._paths.build(package_reference)
        src_folder = self._paths.source(conan_ref)
        export_folder = self._paths.export(conan_ref)

        # If already exists do not dirt the output, the common situation
        # is that package is already installed and OK. If don't, the proxy
        # will print some other message about it
        if not os.path.exists(package_folder):
            output.info("Installing package %s" % package_id)

        self._handle_system_requirements(conan_ref, package_reference, conan_file, output)

        force_build = self._force_build(conan_ref, build_mode)
        if self._remote_proxy.get_package(package_reference, force_build):
            return

        # Can we build? Only if we are forced or build_mode missing and package not exists
        build_allowed = force_build or build_mode is True

        if build_allowed:
            rmdir(build_folder)
            rmdir(package_folder)
            if force_build:
                output.warn('Forced build from source')

            self._build_package(export_folder, src_folder, build_folder, conan_file, output)

            # Creating ***info.txt files
            save(os.path.join(build_folder, CONANINFO), conan_file.info.dumps())
            output.info("Generated %s" % CONANINFO)
            save(os.path.join(build_folder, BUILD_INFO), TXTGenerator(conan_file.deps_cpp_info,
                                                                      conan_file.cpp_info).content)
            output.info("Generated %s" % BUILD_INFO)

            os.chdir(build_folder)
            create_package(conan_file, build_folder, package_folder, output)
        else:
            self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 41
0
    def _get_recipe(self, conan_reference, check_updates, update):
        output = ScopedOutput(str(conan_reference), self._out)
        check_updates = check_updates or update
        # check if it is in disk
        conanfile_path = self._client_cache.conanfile(conan_reference)

        remote = None
        if os.path.exists(conanfile_path):
            if check_updates:
                ret = self.update_available(conan_reference)
                if ret != 0:  # Found and not equal
                    remote, ref_remote = self._get_remote(conan_reference)
                    if ret == 1:
                        if not update:
                            if remote != ref_remote:  # Forced new remote
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u -r %s' to update it."
                                            % (remote.name, remote.name))
                            else:
                                output.warn("There is a new conanfile in '%s' remote. "
                                            "Execute 'install -u' to update it."
                                            % remote.name)
                            output.warn("Refused to install!")
                        else:
                            DiskRemover(self._client_cache).remove(conan_reference)
                            output.info("Retrieving from remote '%s'..." % remote.name)
                            self._remote_manager.get_recipe(conan_reference, remote)
                            self._registry.set_ref(conan_reference, remote)
                            output.info("Updated!")
                    elif ret == -1:
                        if not update:
                            output.info("Current conanfile is newer than %s's one" % remote.name)
                        else:
                            output.error("Current conanfile is newer than %s's one. "
                                         "Run 'conan remove %s' and run install again "
                                         "to replace it." % (remote.name, conan_reference))

            log_recipe_got_from_local_cache(conan_reference)
            self._recorder.recipe_fetched_from_cache(conan_reference)
        else:
            remote = self._retrieve_recipe(conan_reference, output)

        if not remote:
            remote = self._registry.get_ref(conan_reference)
        return conanfile_path, remote
Esempio n. 42
0
    def get_package(self, package_reference, force_build, short_paths, check_outdated):
        """ obtain a package, either from disk or retrieve from remotes if necessary
        and not necessary to build
        """
        output = ScopedOutput(str(package_reference.conan), self._out)
        package_folder = self._client_cache.package(package_reference, short_paths=short_paths)

        # Check current package status
        if os.path.exists(package_folder):
            if self._check_updates:
                read_manifest = self._client_cache.load_package_manifest(package_reference)
                try:  # get_conan_digest can fail, not in server
                    upstream_manifest = self.get_package_digest(package_reference)
                    if upstream_manifest.file_sums != read_manifest.file_sums:
                        if upstream_manifest.time > read_manifest.time:
                            output.warn("Current package is older than remote upstream one")
                            if self._update:
                                output.warn("Removing it to retrieve or build an updated one")
                                rmdir(package_folder)
                        else:
                            output.warn("Current package is newer than remote upstream one")
                except ConanException:
                    pass

        installed = False
        if not force_build:
            local_package = os.path.exists(package_folder)
            if local_package:
                output.info('Already installed!')
                installed = True
            else:
                installed = self._retrieve_remote_package(package_reference, package_folder,
                                                          output)
        # Check if the package is outdated
        if check_outdated and os.path.exists(package_folder):
            if self._package_outdated(package_reference, package_folder):
                output.info("Outdated package!")
                installed = False
            else:
                output.info("Package is up to date")

        self.handle_package_manifest(package_reference, installed)
        return installed
Esempio n. 43
0
    def install(self, reference, current_path, remote=None, options=None, settings=None,
                build_mode=False, filename=None, update=False, check_updates=False,
                manifest_folder=None, manifest_verify=False, manifest_interactive=False,
                scopes=None, generators=None, profile_name=None, package_settings=None,
                env=None, package_env=None, no_imports=False):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param current_path: where the output files will be saved
        @param remote: install only from that remote
        @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...]
        @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...]
        @param package_settings: dict name=> settings: {"zlib": [(settingname, settingvalue), ...]}
        @param profile: name of the profile to use
        @param env: list of tuples for environment vars: [(var, value), (var2, value2)...]
        @param package_env: package dict of list of tuples: {"package_name": [(var, value), (var2, value2)...]}
        """
        generators = generators or []

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

        profile = self.read_profile(profile_name, current_path)

        # Mix Settings, Env vars and scopes between profile and command line
        if profile:
            profile.update_settings(settings)
            profile.update_package_settings(package_settings)
            settings = profile.settings
            package_settings = profile.package_settings

            profile.update_env(env)
            profile.update_packages_env(package_env)
            env = profile.env
            package_env = profile.package_env

            profile.update_scopes(scopes)
            scopes = profile.scopes

        objects = self._get_graph(reference, current_path, remote, options, settings, filename,
                                  update, check_updates, manifest_manager, scopes, package_settings,
                                  env, package_env)
        (_, deps_graph, _, registry, conanfile, remote_proxy, loader) = objects

        Printer(self._user_io.out).print_graph(deps_graph, registry)
        # Warn if os doesn't match
        try:
            if detected_os() != loader._settings.os:
                message = '''You are building this package with settings.os='%s' on a '%s' system.
If this is your intention, you can ignore this message.
If not:
     - Check the passed settings (-s)
     - Check your global settings in ~/.conan/conan.conf
     - Remove conaninfo.txt to avoid bad cached settings
''' % (loader._settings.os, detected_os())
                self._user_io.out.warn(message)
        except ConanException:  # Setting os doesn't exist
            pass

        installer = ConanInstaller(self._client_cache, self._user_io, remote_proxy)
        installer.install(deps_graph, build_mode)

        prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference)
        output = ScopedOutput(prefix, self._user_io.out)

        # Write generators
        tmp = list(conanfile.generators)  # Add the command line specified generators
        tmp.extend(generators)
        conanfile.generators = tmp
        write_generators(conanfile, current_path, output)

        if not isinstance(reference, ConanFileReference):
            content = normalize(conanfile.info.dumps())
            save(os.path.join(current_path, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            if not no_imports:
                run_imports(conanfile, current_path, output)

        if manifest_manager:
            manifest_manager.print_log()
Esempio n. 44
0
    def install(self,
                reference,
                current_path,
                profile,
                remote=None,
                build_modes=None,
                filename=None,
                update=False,
                manifest_folder=None,
                manifest_verify=False,
                manifest_interactive=False,
                generators=None,
                no_imports=False,
                inject_require=None):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param current_path: 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 readed values
        @param build_modes: List of build_modes specified
        @param filename: Optional filename of the conanfile
        @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
        """
        generators = generators or []
        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 = ConanProxy(self._client_cache,
                                  self._user_io,
                                  self._remote_manager,
                                  remote,
                                  update=update,
                                  check_updates=False,
                                  manifest_manager=manifest_manager)

        loader = ConanFileLoader(self._runner, self._client_cache.settings,
                                 self._profile_with_defaults(profile))
        conanfile = self._get_conanfile_object(loader, reference, filename,
                                               current_path)
        if inject_require:
            self._inject_require(conanfile, inject_require)
        graph_builder = self._get_graph_builder(loader, update, remote_proxy)
        deps_graph = graph_builder.load(conanfile)

        # This line is so the conaninfo stores the correct complete info
        conanfile.info.scope = profile.scopes

        registry = RemoteRegistry(self._client_cache.registry,
                                  self._user_io.out)

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

        try:
            if loader._settings.os and detected_os() != loader._settings.os:
                message = "Cross-platform from '%s' to '%s'" % (
                    detected_os(), loader._settings.os)
                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, registry, output,
                                       profile.build_requires)
        installer = ConanInstaller(self._client_cache, output, remote_proxy,
                                   build_mode, build_requires)

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

        installer.install(deps_graph, current_path)
        build_mode.report_matches()

        # Write generators
        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, current_path, output)

        if not isinstance(reference, ConanFileReference):
            content = normalize(conanfile.info.dumps())
            save(os.path.join(current_path, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            if not no_imports:
                run_imports(conanfile, current_path, output)
            installer.call_system_requirements(conanfile, output)

        if manifest_manager:
            manifest_manager.print_log()
Esempio n. 45
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()
Esempio n. 46
0
    def _build_node(self, conan_ref, conan_file, build_mode):
        # Compute conan_file package from local (already compiled) or from remote
        output = ScopedOutput(str(conan_ref), self._out)
        package_id = conan_file.info.package_id()
        self._out.writeln("")
        output.info("Installing package %s" % package_id)
        package_reference = PackageReference(conan_ref, package_id)

        conan_ref = package_reference.conan
        package_folder = self._paths.package(package_reference)
        build_folder = self._paths.build(package_reference)
        src_folder = self._paths.source(conan_ref)
        export_folder = self._paths.export(conan_ref)

        self._handle_system_requirements(conan_ref, package_reference, conan_file, output)

        # Check if package is corrupted
        valid_package_digest = self._paths.valid_package_digest(package_reference)
        if os.path.exists(package_folder) and not valid_package_digest:
            # If not valid package, ensure empty folder
            output.warn("Bad package '%s' detected! Removing " "package directory... " % str(package_id))
            rmdir(package_folder)

        # Check if any only_source pattern matches with package
        force_build = self._force_build(conan_ref, build_mode)

        if not force_build:
            local_package = os.path.exists(package_folder)
            if local_package:
                output.info("Package installed in %s" % package_folder)
                return

            output.info("Package not installed")
            remote_package = self._retrieve_remote_package(package_reference, output)
            if remote_package:
                return

        # Can we build? Only if we are forced or build_mode missing and package not exists
        build_allowed = force_build or build_mode is True

        if build_allowed:
            rmdir(build_folder)
            rmdir(package_folder)
            if force_build:
                output.warn("Forced build from source")

            self._build_package(export_folder, src_folder, build_folder, conan_file, output)

            # Creating ***info.txt files
            save(os.path.join(build_folder, CONANINFO), conan_file.info.dumps())
            output.info("Generated %s" % CONANINFO)
            save(
                os.path.join(build_folder, BUILD_INFO),
                TXTGenerator(conan_file.deps_cpp_info, conan_file.cpp_info).content,
            )
            output.info("Generated %s" % BUILD_INFO)

            os.chdir(build_folder)
            create_package(conan_file, build_folder, package_folder, output)
        else:
            self._raise_package_not_found_error(conan_ref, conan_file)
Esempio n. 47
0
    def _build(self, nodes_by_level, skip_private_nodes, deps_graph, profile_build_requires):
        """ The build assumes an input of conans ordered by degree, first level
        should be independent from each other, the next-second level should have
        dependencies only to first level conans.
        param nodes_by_level: list of lists [[nodeA, nodeB], [nodeC], [nodeD, ...], ...]

        build_mode => ["*"] if user wrote "--build"
                   => ["hello*", "bye*"] if user wrote "--build hello --build bye"
                   => False if user wrote "never"
                   => True if user wrote "missing"
                   => "outdated" if user wrote "--build outdated"

        """

        inverse = deps_graph.inverse_levels()
        flat = []

        for level in inverse:
            level = sorted(level, key=lambda x: x.conan_ref)
            flat.extend(n for n in level if n not in skip_private_nodes)

        # Get the nodes in order and if we have to build them
        nodes_to_process = self._get_nodes(nodes_by_level, skip_private_nodes)

        for conan_ref, package_id, conan_file, build_needed in nodes_to_process:
            output = ScopedOutput(str(conan_ref), self._out)

            if build_needed and (conan_ref, package_id) not in self._built_packages:
                package_ref = PackageReference(conan_ref, package_id)
                build_allowed = self._build_mode.allowed(conan_file, conan_ref)
                if not build_allowed:
                    _raise_package_not_found_error(conan_file, conan_ref, output)

                if conan_file.build_policy_missing:
                    output.info("Building package from source as defined by build_policy='missing'")
                elif self._build_mode.forced(conan_file, conan_ref):
                    output.warn('Forced build from source')

                self._build_requires.install(conan_ref, conan_file, self, profile_build_requires, output)

                t1 = time.time()
                # Assign to node the propagated info
                self._propagate_info(conan_file, conan_ref, flat, deps_graph)
                builder = _ConanPackageBuilder(conan_file, package_ref, self._client_cache, output)
                with self._client_cache.conanfile_write_lock(conan_ref):
                    self._remote_proxy.get_recipe_sources(conan_ref, conan_file.short_paths)
                    builder.prepare_build()

                with self._client_cache.conanfile_read_lock(conan_ref):
                    with self._client_cache.package_lock(builder.build_reference):
                        builder.build()
                        builder.package()

                        self._remote_proxy.handle_package_manifest(package_ref, installed=True)
                        package_folder = self._client_cache.package(package_ref, conan_file.short_paths)
                        # Call the info method
                        call_package_info(conan_file, package_folder)

                        # Log build
                        self._log_built_package(conan_file, package_ref, time.time() - t1)
                        self._built_packages.add((conan_ref, package_id))
            else:
                # Get the package, we have a not outdated remote package
                package_ref = None
                if conan_ref:
                    package_ref = PackageReference(conan_ref, package_id)
                    with self._client_cache.package_lock(package_ref):
                        self._get_remote_package(conan_file, package_ref, output)

                # Assign to the node the propagated info
                # (conan_ref could be None if user project, but of course assign the info
                self._propagate_info(conan_file, conan_ref, flat, deps_graph)

                if package_ref:
                    # Call the info method
                    package_folder = self._client_cache.package(package_ref, conan_file.short_paths)
                    call_package_info(conan_file, package_folder)
Esempio n. 48
0
    def install(self, reference, current_path, profile, remote=None,
                build_modes=None, filename=None, update=False,
                manifest_folder=None, manifest_verify=False, manifest_interactive=False,
                generators=None, no_imports=False):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param current_path: 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 readed values
        @param build_modes: List of build_modes specified
        @param filename: Optional filename of the conanfile
        @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
        """
        generators = generators or []
        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 = ConanProxy(self._client_cache, self._user_io, self._remote_manager, remote,
                                  update=update, check_updates=False, manifest_manager=manifest_manager)
        loader = ConanFileLoader(self._runner, self._client_cache.settings, profile)
        conanfile = self._get_conanfile_object(loader, reference, filename, current_path)
        graph_builder = self._get_graph_builder(loader, update, remote_proxy)
        deps_graph = graph_builder.load(conanfile)

        # This line is so the conaninfo stores the correct complete info
        conanfile.info.scope = profile.scopes

        registry = RemoteRegistry(self._client_cache.registry, self._user_io.out)

        Printer(self._user_io.out).print_graph(deps_graph, registry)

        try:
            if detected_os() != loader._settings.os:
                message = "Cross-platform from '%s' to '%s'" % (detected_os(), loader._settings.os)
                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, remote_proxy, self._user_io.out, self._client_cache,
                                       self._search_manager, profile.build_requires, current_path,
                                       build_mode)

        # Apply build_requires to consumer conanfile
        build_requires.install("", conanfile)
        installer = ConanInstaller(self._client_cache, self._user_io.out, remote_proxy,
                                   build_requires)

        installer.install(deps_graph, build_mode, current_path)
        build_mode.report_matches()

        prefix = "PROJECT" if not isinstance(reference, ConanFileReference) else str(reference)
        output = ScopedOutput(prefix, self._user_io.out)

        # Write generators
        tmp = list(conanfile.generators)  # Add the command line specified generators
        tmp.extend(generators)
        conanfile.generators = tmp
        write_generators(conanfile, current_path, output)

        if not isinstance(reference, ConanFileReference):
            content = normalize(conanfile.info.dumps())
            save(os.path.join(current_path, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            if not no_imports:
                run_imports(conanfile, current_path, output)
            installer.call_system_requirements(conanfile, output)

        if manifest_manager:
            manifest_manager.print_log()
Esempio n. 49
0
    def install(self, reference, current_path, remote=None, options=None, settings=None,
                build_mode=False, info=None, filename=None, update=False):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param current_path: where the output files will be saved
        @param remote: install only from that remote
        @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...]
        @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...]
        """
        reference_given = True
        if not isinstance(reference, ConanFileReference):
            conanfile_path = reference
            reference_given = False
            reference = None

        loader = self._loader(current_path, settings, options)
        # Not check for updates for info command, it'll be checked when dep graph is built
        check_updates = not info
        remote_proxy = ConanProxy(self._paths, self._user_io, self._remote_manager,
                                  remote, update, check_updates)

        if reference_given:
            project_reference = None
            conanfile_path = remote_proxy.get_conanfile(reference)
            output = ScopedOutput(str(reference), self._user_io.out)
            conanfile = loader.load_conan(conanfile_path, output, consumer=True)
        else:
            project_reference = "PROJECT"
            output = ScopedOutput(project_reference, self._user_io.out)
            try:
                if filename and filename.endswith(".txt"):
                    raise NotFoundException("")
                conan_file_path = os.path.join(conanfile_path, filename or CONANFILE)
                conanfile = loader.load_conan(conan_file_path, output, consumer=True)
                is_txt = False

                if conanfile.name is not None and conanfile.version is not None:
                    project_reference = "%s/%s@" % (conanfile.name, conanfile.version)
                    project_reference += "PROJECT"
            except NotFoundException:  # Load requirements.txt
                conan_path = os.path.join(conanfile_path, filename or CONANFILE_TXT)
                conanfile = loader.load_conan_txt(conan_path, output)
                is_txt = True

        # build deps graph and install it
        builder = DepsBuilder(remote_proxy, self._user_io.out, loader)
        deps_graph = builder.load(reference, conanfile)
        registry = RemoteRegistry(self._paths.registry, self._user_io.out)
        if info:
            graph_updates_info = builder.get_graph_updates_info(deps_graph)
            Printer(self._user_io.out).print_info(deps_graph, project_reference,
                                                  info, registry, graph_updates_info,
                                                  remote)
            return
        Printer(self._user_io.out).print_graph(deps_graph, registry)

        installer = ConanInstaller(self._paths, self._user_io, remote_proxy)
        installer.install(deps_graph, build_mode)

        if not reference_given:
            if is_txt:
                conanfile.info.settings = loader._settings.values
            # Just in case the current package is header only, we still store the full settings
            # for reference and compiler checks
            conanfile.info.full_settings = loader._settings.values
            content = normalize(conanfile.info.dumps())
            save(os.path.join(current_path, CONANINFO), content)
            output.info("Generated %s" % CONANINFO)
            write_generators(conanfile, current_path, output)
            local_installer = FileImporter(deps_graph, self._paths, current_path)
            conanfile.copy = local_installer
            conanfile.imports()
            copied_files = local_installer.execute()
            import_output = ScopedOutput("%s imports()" % output.scope, output)
            report_copied_files(copied_files, import_output)
Esempio n. 50
0
    def _get_recipe(self, ref, check_updates, update, remotes, recorder):
        output = ScopedOutput(str(ref), self._out)
        # check if it is in disk
        conanfile_path = self._cache.package_layout(ref).conanfile()

        # NOT in disk, must be retrieved from remotes
        if not os.path.exists(conanfile_path):
            remote, new_ref = self._download_recipe(ref, output, remotes,
                                                    remotes.selected, recorder)
            status = RECIPE_DOWNLOADED
            return conanfile_path, status, remote, new_ref

        metadata = self._cache.package_layout(ref).load_metadata()
        cur_revision = metadata.recipe.revision
        cur_remote = metadata.recipe.remote
        cur_remote = remotes[cur_remote] if cur_remote else None
        selected_remote = remotes.selected or cur_remote

        check_updates = check_updates or update
        # Recipe exists in disk, but no need to check updates
        requested_different_revision = (
            ref.revision is not None) and cur_revision != ref.revision
        if requested_different_revision and not check_updates:
            raise NotFoundException(
                "The recipe in the local cache doesn't match the specified "
                "revision. Use '--update' to check in the remote.")

        if not requested_different_revision:
            if not check_updates:
                status = RECIPE_INCACHE
                ref = ref.copy_with_rev(cur_revision)
                return conanfile_path, status, cur_remote, ref

            if not selected_remote:
                status = RECIPE_NO_REMOTE
                ref = ref.copy_with_rev(cur_revision)
                return conanfile_path, status, None, ref
        else:  # Requested different revision and with --update
            remote, new_ref = self._download_recipe(ref, output, remotes,
                                                    selected_remote, recorder)
            status = RECIPE_DOWNLOADED
            return conanfile_path, status, remote, new_ref

        try:  # get_recipe_manifest can fail, not in server
            upstream_manifest, ref = self._remote_manager.get_recipe_manifest(
                ref, selected_remote)
        except NotFoundException:
            status = RECIPE_NOT_IN_REMOTE
            ref = ref.copy_with_rev(cur_revision)
            return conanfile_path, status, selected_remote, ref

        export = self._cache.package_layout(ref).export()
        read_manifest = FileTreeManifest.load(export)
        if upstream_manifest != read_manifest:
            if upstream_manifest.time > read_manifest.time:
                if update:
                    DiskRemover().remove_recipe(
                        self._cache.package_layout(ref), output=output)
                    output.info("Retrieving from remote '%s'..." %
                                selected_remote.name)
                    self._download_recipe(ref, output, remotes,
                                          selected_remote, recorder)
                    with self._cache.package_layout(
                            ref).update_metadata() as metadata:
                        metadata.recipe.remote = selected_remote.name
                    status = RECIPE_UPDATED
                    return conanfile_path, status, selected_remote, ref
                else:
                    status = RECIPE_UPDATEABLE
            else:
                status = RECIPE_NEWER
        else:
            status = RECIPE_INCACHE

        ref = ref.copy_with_rev(cur_revision)
        return conanfile_path, status, selected_remote, ref
Esempio n. 51
0
    def install(self, reference, current_path, remote=None, options=None, settings=None,
                build_mode=False, info=None, filename=None):
        """ Fetch and build all dependencies for the given reference
        @param reference: ConanFileReference or path to user space conanfile
        @param current_path: where the output files will be saved
        @param remote: install only from that remote
        @param options: written in JSON, e.g. {"compiler": "Visual Studio 12", ...}
        """
        reference_given = True
        if not isinstance(reference, ConanFileReference):
            conanfile_path = reference
            reference_given = False
            reference = None

        loader = self._loader(current_path, settings, options)
        installer = ConanInstaller(self._paths, self._user_io, loader, self.remote_manager, remote)

        if reference_given:
            project_reference = None
            conanfile = installer.retrieve_conanfile(reference, consumer=True)
        else:
            project_reference = "PROJECT"
            output = ScopedOutput(project_reference, self._user_io.out)
            try:
                if filename and filename.endswith(".txt"):
                    raise NotFoundException()
                conan_file_path = os.path.join(conanfile_path, filename or CONANFILE)
                conanfile = loader.load_conan(conan_file_path, output, consumer=True)
                is_txt = False

                if conanfile.name is not None and conanfile.version is not None:
                    project_reference = "%s/%s@" % (conanfile.name, conanfile.version)
                    # Calculate a placeholder conan file reference for the project
                    current_user = self._localdb.get_username()
                    if current_user:
                        project_reference += "%s/" % current_user
                    project_reference += "PROJECT"
            except NotFoundException:  # Load requirements.txt
                conan_path = os.path.join(conanfile_path, filename or CONANFILE_TXT)
                conanfile = loader.load_conan_txt(conan_path, output)
                is_txt = True

        # build deps graph and install it
        builder = DepsBuilder(installer, self._user_io.out)
        deps_graph = builder.load(reference, conanfile)
        if info:
            Printer(self._user_io.out).print_info(deps_graph, project_reference, info)
            return
        Printer(self._user_io.out).print_graph(deps_graph)
        installer.install(deps_graph, build_mode)

        if not reference_given:
            if is_txt:
                conanfile.info.settings = loader._settings.values
            # Just in case the current package is header only, we still store the full settings
            # for reference and compiler checks
            conanfile.info.full_settings = loader._settings.values
            content = normalize(conanfile.info.dumps())
            save(os.path.join(current_path, CONANINFO), content)
            self._user_io.out.writeln("")
            output.info("Generated %s" % CONANINFO)
            write_generators(conanfile, current_path, output)
            local_installer = FileImporter(deps_graph, self._paths, current_path)
            conanfile.copy = local_installer
            conanfile.imports()
            local_installer.execute()
Esempio n. 52
0
    def _build(self, nodes_by_level, skip_private_nodes, build_mode):
        """ The build assumes an input of conans ordered by degree, first level
        should be independent from each other, the next-second level should have
        dependencies only to first level conans.
        param nodes_by_level: list of lists [[nodeA, nodeB], [nodeC], [nodeD, ...], ...]

        build_mode => ["*"] if user wrote "--build"
                   => ["hello*", "bye*"] if user wrote "--build hello --build bye"
                   => False if user wrote "never"
                   => True if user wrote "missing"
                   => "outdated" if user wrote "--build outdated"

        """

        inverse = self._deps_graph.inverse_levels()
        flat = []

        for level in inverse:
            level = sorted(level, key=lambda x: x.conan_ref)
            flat.extend(level)

        # Get the nodes in order and if we have to build them
        nodes_to_process = self._get_nodes(nodes_by_level, skip_private_nodes, build_mode)

        for conan_ref, package_id, conan_file, build_needed in nodes_to_process:

            if build_needed:
                build_allowed = build_mode.allowed(conan_ref, conan_file)
                if not build_allowed:
                    self._raise_package_not_found_error(conan_ref, conan_file)

                output = ScopedOutput(str(conan_ref), self._out)
                package_ref = PackageReference(conan_ref, package_id)
                package_folder = self._client_cache.package(package_ref, conan_file.short_paths)
                if conan_file.build_policy_missing:
                    output.info("Building package from source as defined by build_policy='missing'")
                elif build_mode.forced(conan_ref, conan_file):
                    output.warn('Forced build from source')

                self._build_requires.install(conan_ref, conan_file)

                t1 = time.time()
                # Assign to node the propagated info
                self._propagate_info(conan_ref, conan_file, flat)

                self._remote_proxy.get_recipe_sources(conan_ref)
                # Call the conanfile's build method
                build_folder = self._build_conanfile(conan_ref, conan_file, package_ref,
                                                     package_folder, output)

                # Call the conanfile's package method
                self._package_conanfile(conan_ref, conan_file, package_ref, build_folder,
                                        package_folder, output)

                # Call the info method
                self._package_info_conanfile(conan_ref, conan_file)

                duration = time.time() - t1
                log_file = os.path.join(build_folder, RUN_LOG_NAME)
                log_file = log_file if os.path.exists(log_file) else None
                log_package_built(package_ref, duration, log_file)
            else:
                # Get the package, we have a not outdated remote package
                if conan_ref:
                    self._get_package(conan_ref, conan_file)

                # Assign to the node the propagated info
                # (conan_ref could be None if user project, but of course assign the info
                self._propagate_info(conan_ref, conan_file, flat)

                # Call the info method
                self._package_info_conanfile(conan_ref, conan_file)
Esempio n. 53
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()