def lint_requirements_in_conda(tool_source, lint_ctx):
    """Check requirements of tool source against best practice Conda channels."""
    conda_targets = tool_source_conda_targets(tool_source)
    if not conda_targets:
        lint_ctx.warn(
            "No valid package requirement tags found to check against Conda.")
        return

    for conda_target in conda_targets:
        (best_hit, exact) = best_practice_search(conda_target)
        conda_target_str = conda_target.package
        if conda_target.version:
            conda_target_str += "@%s" % (conda_target.version)
        if best_hit and exact:
            template = "Requirement [%s] matches target in best practice Conda channel [%s]."
            message = template % (conda_target_str, best_hit.get("channel"))
            lint_ctx.info(message)
        elif best_hit:
            template = "Requirement [%s] doesn't exactly match available version [%s] in best practice Conda channel [%s]."
            message = template % (conda_target_str, best_hit['version'],
                                  best_hit.get("channel"))
            lint_ctx.warn(message)
        else:
            template = "Requirement [%s] doesn't match any recipe in a best practice conda channel [%s]."
            message = template % (conda_target_str, BEST_PRACTICE_CHANNELS)
            lint_ctx.warn(message)
def cli(ctx, paths, **kwds):
    """Register multi-requirement containers as needed.

    BioContainers publishes all Bioconda packages automatically as individual
    container images. These however are not enough for tools with multiple
    best-practice requirements. Such requirements should be recorded and published
    so that a container can be created and registered for these tools.
    """
    registry_target = RegistryTarget(ctx, **kwds)
    conda_context = build_conda_context(ctx, **kwds)

    combinations_added = 0
    conda_targets_list, tool_paths_list = collect_conda_target_lists_and_tool_paths(ctx, paths, recursive=kwds["recursive"])
    for conda_targets, tool_paths in zip(conda_targets_list, tool_paths_list):
        ctx.vlog("Handling conda_targets [%s]" % conda_targets)
        mulled_targets = conda_to_mulled_targets(conda_targets)
        mulled_targets_str = "- " + "\n- ".join(map(conda_build_target_str, mulled_targets))
        if len(mulled_targets) < 2:
            ctx.vlog("Skipping registeration, fewer than 2 targets discovered.")
            # Skip these for now, we will want to revisit this for conda-forge dependencies and such.
            continue

        best_practice_requirements = True
        for conda_target in conda_targets:
            best_hit, exact = best_practice_search(conda_target, conda_context=conda_context)
            if not best_hit or not exact:
                ctx.vlog("Target [%s] is not available in best practice channels - skipping" % conda_target)
                best_practice_requirements = False

        if not best_practice_requirements:
            continue

        name = v2_image_name(mulled_targets)
        tag = "0"
        name_and_tag = "%s-%s" % (name, tag)
        target_filename = os.path.join(registry_target.output_directory, "%s.tsv" % name_and_tag)
        ctx.vlog("Target filename for registeration is [%s]" % target_filename)
        if os.path.exists(target_filename):
            ctx.vlog("Target file already exists, skipping")
            continue

        namespace = kwds["mulled_namespace"]
        repo_data = quay_repository(namespace, name)
        if "tags" in repo_data:
            ctx.vlog("quay repository already exists, skipping")
            continue

        if registry_target.has_pull_request_for(name):
            ctx.vlog("Found matching open pull request for [%s], skipping" % name)
            continue

        registry_target.write_targets(ctx, target_filename, mulled_targets)
        tools_str = "\n".join(map(lambda p: "- " + os.path.basename(p), tool_paths))
        registry_target.handle_pull_request(ctx, name, target_filename, mulled_targets_str, tools_str, **kwds)
        combinations_added += 1
def lint_requirements_in_conda(tool_source, lint_ctx):
    """Check requirements of tool source against best practice Conda channels."""
    conda_targets = tool_source_conda_targets(tool_source)
    if not conda_targets:
        lint_ctx.warn("No valid package requirement tags found to check against Conda.")
        return

    for conda_target in conda_targets:
        (best_hit, exact) = best_practice_search(conda_target)
        conda_target_str = conda_target.package
        if conda_target.version:
            conda_target_str += "@%s" % (conda_target.version)
        if best_hit and exact:
            template = "Requirement [%s] matches target in best practice Conda channel [%s]."
            message = template % (conda_target_str, best_hit.get("channel"))
            lint_ctx.info(message)
        elif best_hit:
            template = "Requirement [%s] doesn't exactly match available version [%s] in best practice Conda channel [%s]."
            message = template % (conda_target_str, best_hit['version'], best_hit.get("channel"))
            lint_ctx.warn(message)
        else:
            template = "Requirement [%s] doesn't match any recipe in a best practice conda channel [%s]."
            message = template % (conda_target_str, BEST_PRACTICE_CHANNELS)
            lint_ctx.warn(message)
def cli(ctx, paths, **kwds):
    """Register multi-requirement containers as needed.

    BioContainers publishes all Bioconda packages automatically as individual
    container images. These however are not enough for tools with multiple
    best-practice requirements. Such requirements should be recorded and published
    so that a container can be created and registered for these tools.
    """
    registry_target = RegistryTarget(ctx, **kwds)
    conda_context = build_conda_context(ctx, **kwds)

    combinations_added = 0
    conda_targets_list, tool_paths_list = collect_conda_target_lists_and_tool_paths(
        ctx, paths, recursive=kwds["recursive"])
    for conda_targets, tool_paths in zip(conda_targets_list, tool_paths_list):
        ctx.vlog("Handling conda_targets [%s]" % conda_targets)
        mulled_targets = conda_to_mulled_targets(conda_targets)
        mulled_targets_str = "- " + "\n- ".join(
            map(conda_build_target_str, mulled_targets))
        best_practice_requirements = True
        for conda_target in conda_targets:
            best_hit, exact = best_practice_search(
                conda_target,
                conda_context=conda_context,
                platform=BIOCONTAINERS_PLATFORM)
            if not best_hit:
                ctx.log(
                    "Target [%s] is not available in best practice channels - skipping"
                    % conda_target)
                best_practice_requirements = False
            if not exact:
                ctx.log(
                    "Target version [%s] for package [%s] is not available in best practice channels - please specify the full version",
                    conda_target.version, conda_target.package)

        if not best_practice_requirements:
            continue

        base_image = DEFAULT_BASE_IMAGE
        for conda_target in conda_targets:
            base_image = base_image_for_targets([conda_target],
                                                conda_context=conda_context)
            if base_image != DEFAULT_BASE_IMAGE:
                ctx.log("%s requires '%s' as base image" %
                        (conda_target, base_image))
                break

        if len(mulled_targets) < 1:
            ctx.log("Skipping registration, no targets discovered.")
            continue

        name = v2_image_name(mulled_targets)
        tag = "0"
        name_and_tag = "%s-%s" % (name, tag)
        target_filename = os.path.join(registry_target.output_directory,
                                       "%s.tsv" % name_and_tag)
        if os.path.exists(target_filename):
            ctx.log("Target file '%s' already exists, skipping" %
                    target_filename)
            continue

        if targets_to_mulled_name(mulled_targets,
                                  hash_func='v2',
                                  namespace=kwds["mulled_namespace"]):
            ctx.vlog("quay repository already exists, skipping")
            continue

        if registry_target.has_pull_request_for(name):
            ctx.vlog("Found matching open pull request for [%s], skipping" %
                     name)
            continue

        registry_target.write_targets(ctx, target_filename, mulled_targets,
                                      tag, base_image)
        tools_str = "\n".join(
            map(lambda p: "- " + os.path.basename(p), tool_paths))
        registry_target.handle_pull_request(ctx, name, target_filename,
                                            mulled_targets_str, tools_str,
                                            base_image, **kwds)
        combinations_added += 1