def cli(ctx, paths, **kwds): """Install conda packages for tool requirements.""" conda_context = build_conda_context(ctx, **kwds) if not conda_context.is_conda_installed(): auto_init = kwds.get("conda_auto_init", False) failed = True if auto_init: if conda_context.can_install_conda(): if conda_util.install_conda(conda_context): error("Attempted to install conda and failed.") else: failed = False else: error("Cannot install conda, failing conda_install.") else: error("Conda not configured - run planemo conda_init' or pass --conda_auto_init to continue.") if failed: raise ExitCodeException(EXIT_CODE_FAILED_DEPENDENCIES) return_codes = [] for conda_target in collect_conda_targets(ctx, paths): ctx.log("Install conda target %s" % conda_target) return_code = conda_util.install_conda_target( conda_target, conda_context=conda_context ) return_codes.append(return_code) return coalesce_return_codes(return_codes, assert_at_least_one=True)
def cli(ctx, **kwds): """Download and install conda. This will download conda for managing dependencies for your platform using the appropriate Miniconda installer. By running this command, you are agreeing to the terms of the conda license a 3-clause BSD 3 license. Please review full license at http://docs.continuum.io/anaconda/eula. Planemo will print a warning and terminate with an exit code of 7 if Conda is already installed. """ conda_context = build_conda_context(ctx, **kwds) if conda_context.is_conda_installed(): warn(MESSAGE_ERROR_ALREADY_EXISTS % conda_context.conda_exec) exit = EXIT_CODE_ALREADY_EXISTS else: exit = conda_util.install_conda(conda_context=conda_context, force_conda_build=True) if exit: warn(MESSAGE_ERROR_FAILED % conda_context.conda_exec) else: info(MESSAGE_INSTALL_OKAY % conda_context.conda_exec) ctx.exit(exit)
def cli(ctx, paths, **kwds): """Perform conda build with Planemo's conda.""" # Force conda_use_local for building... kwds["conda_use_local"] = True conda_context = build_conda_context(ctx, handle_auto_init=True, **kwds) build_args = list(paths) conda_context.exec_command("build", build_args)
def cli(ctx, paths, **kwds): """Install conda packages for tool requirements.""" conda_context = build_conda_context(ctx, **kwds) if not conda_context.is_conda_installed(): auto_init = kwds.get("conda_auto_init", False) failed = True if auto_init: if conda_context.can_install_conda(): if conda_util.install_conda(conda_context): error("Attempted to install conda and failed.") else: failed = False else: error("Cannot install conda, failing conda_install.") else: error( "Conda not configured - run planemo conda_init' or pass --conda_auto_init to continue." ) if failed: raise ExitCodeException(EXIT_CODE_FAILED_DEPENDENCIES) return_codes = [] for conda_target in collect_conda_targets(ctx, paths): ctx.log("Install conda target %s" % conda_target) return_code = conda_util.install_conda_target( conda_target, conda_context=conda_context) return_codes.append(return_code) return coalesce_return_codes(return_codes, assert_at_least_one=True)
def cli(ctx, path, **kwds): """Source output to activate a conda environment for this tool. % . <(planemo conda_env bowtie2.xml) % which bowtie2 TODO_PLACE_PATH_HERE """ conda_context = build_conda_context(use_planemo_shell_exec=False, **kwds) conda_targets = collect_conda_targets( path, conda_context=conda_context ) installed_conda_targets = conda_util.filter_installed_targets( conda_targets, conda_context=conda_context ) env_name, exit_code = conda_util.build_isolated_environment( installed_conda_targets, conda_context=conda_context ) if exit_code: error("Failed to build environmnt for request.") return 1 ps1 = ps1_for_path(path, base="PRE_CONDA_PS1") remove_env = "%s env remove -y --name '%s'" % ( conda_context.conda_exec, env_name ) deactivate = conda_context.deactivate activate = conda_context.activate command = SOURCE_COMMAND % ( activate, env_name, ps1, deactivate, remove_env ) print(command)
def cli(ctx, path, **kwds): """Activate a conda environment for tool. Source the output of this command to activate a conda environment for this tool. \b $ . <(planemo conda_env seqtk_seq.xml) Deactivate environment with conda_env_deactivate (seqtk_seq_v6) $ which seqtk /home/planemo/miniconda2/envs/jobdepsDkzcjjfecc6d406196737781ff4456ec60975c137e04884e4f4b05dc68192f7cec4656/bin/seqtk (seqtk_seq_v6) $ conda_env_deactivate $ """ conda_context = build_conda_context(ctx, use_planemo_shell_exec=False, **kwds) conda_targets = collect_conda_targets(ctx, [path]) installed_conda_targets = conda_util.filter_installed_targets( conda_targets, conda_context=conda_context) env_name, exit_code = conda_util.build_isolated_environment( installed_conda_targets, conda_context=conda_context, quiet=True) if exit_code: error("Failed to build environment for request.") return 1 ps1 = ps1_for_path(path, base="PRE_CONDA_PS1") remove_env = "%s env remove -y --name '%s'" % (conda_context.conda_exec, env_name) deactivate = conda_context.deactivate activate = conda_context.activate command = SOURCE_COMMAND % (activate, env_name, ps1, deactivate, remove_env) print(command)
def _handle_dependency_resolution(ctx, config_directory, kwds): _validate_dependency_resolution_options(kwds) always_specify_attribute = object() dependency_attribute_kwds = { 'conda_prefix': None, 'conda_exec': None, 'conda_debug': False, 'conda_copy_dependencies': False, 'conda_auto_init': always_specify_attribute, 'conda_auto_install': always_specify_attribute, 'conda_ensure_channels': '', } attributes = [] def add_attribute(key, value): attributes.append('%s="%s"' % (key, value)) conda_prefix_specified = False for key, default_value in iteritems(dependency_attribute_kwds): value = kwds.get(key, default_value) if value != default_value: conda_prefix_specified = conda_prefix_specified or (key == "conda_prefix") # Strip leading prefix (conda_) off attributes attribute_key = "_".join(key.split("_")[1:]) add_attribute(attribute_key, value) conda_context = build_conda_context(ctx, **kwds) if not conda_prefix_specified: add_attribute("prefix", conda_context.conda_prefix) add_attribute("condarc_override", conda_context.condarc_override) attribute_str = " ".join(attributes) if kwds.get("dependency_resolvers_config_file", None): resolution_type = "__explicit__" else: resolution_type = "default_dependency_resolution" for key in STOCK_DEPENDENCY_RESOLUTION_STRATEGIES: if kwds.get(key): resolution_type = key if resolution_type != "__explicit__": # Planemo manages the dependency resolve conf file. resolvers_conf = os.path.join( config_directory, "resolvers_conf.xml" ) template_str = STOCK_DEPENDENCY_RESOLUTION_STRATEGIES[resolution_type] conf_contents = Template(template_str).safe_substitute({ 'attributes': attribute_str }) open(resolvers_conf, "w").write(conf_contents) ctx.vlog( "Writing dependency_resolvers_config_file to path %s with contents [%s]", resolvers_conf, conf_contents, ) kwds["dependency_resolvers_config_file"] = resolvers_conf
def _handle_dependency_resolution(config_directory, kwds): resolutions_strategies = [ "brew_dependency_resolution", "dependency_resolvers_config_file", "shed_dependency_resolution", "conda_dependency_resolution", ] selected_strategies = 0 for key in resolutions_strategies: if kwds.get(key): selected_strategies += 1 if selected_strategies > 1: message = "At most one option from [%s] may be specified" raise click.UsageError(message % resolutions_strategies) dependency_attribute_kwds = { 'conda_prefix': None, 'conda_exec': None, 'conda_debug': False, 'conda_copy_dependencies': False, 'conda_auto_init': False, 'conda_auto_install': False, 'conda_ensure_channels': '', } attributes = [] def add_attribute(key, value): attributes.append('%s="%s"' % (key, value)) for key, default_value in iteritems(dependency_attribute_kwds): value = kwds.get(key, default_value) if value != default_value: # Strip leading prefix (conda_) off attributes attribute_key = "_".join(key.split("_")[1:]) add_attribute(attribute_key, value) if not [attribute for attribute in attributes if "prefix" in attribute]: conda_context = build_conda_context(**kwds) add_attribute("prefix", conda_context.conda_prefix) attribute_str = " ".join(attributes) for key in STOCK_DEPENDENCY_RESOLUTION_STRATEGIES: if kwds.get(key): resolvers_conf = os.path.join( config_directory, "resolvers_conf.xml" ) template_str = STOCK_DEPENDENCY_RESOLUTION_STRATEGIES[key] conf_contents = Template(template_str).safe_substitute({ 'attributes': attribute_str }) open(resolvers_conf, "w").write(conf_contents) kwds["dependency_resolvers_config_file"] = resolvers_conf
def _handle_dependency_resolution(ctx, config_directory, kwds): _validate_dependency_resolution_options(kwds) always_specify_attribute = object() dependency_attribute_kwds = { 'conda_prefix': None, 'conda_exec': None, 'conda_debug': False, 'conda_copy_dependencies': False, 'conda_auto_init': always_specify_attribute, 'conda_auto_install': always_specify_attribute, 'conda_ensure_channels': '', } attributes = [] def add_attribute(key, value): attributes.append('%s="%s"' % (key, value)) conda_prefix_specified = False for key, default_value in iteritems(dependency_attribute_kwds): value = kwds.get(key, default_value) if value != default_value: conda_prefix_specified = conda_prefix_specified or ( key == "conda_prefix") # Strip leading prefix (conda_) off attributes attribute_key = "_".join(key.split("_")[1:]) add_attribute(attribute_key, value) conda_context = build_conda_context(ctx, **kwds) if not conda_prefix_specified: add_attribute("prefix", conda_context.conda_prefix) add_attribute("condarc_override", conda_context.condarc_override) attribute_str = " ".join(attributes) if kwds.get("dependency_resolvers_config_file", None): resolution_type = "__explicit__" else: resolution_type = "default_dependency_resolution" for key in STOCK_DEPENDENCY_RESOLUTION_STRATEGIES: if kwds.get(key): resolution_type = key if resolution_type != "__explicit__": # Planemo manages the dependency resolve conf file. resolvers_conf = os.path.join(config_directory, "resolvers_conf.xml") template_str = STOCK_DEPENDENCY_RESOLUTION_STRATEGIES[resolution_type] conf_contents = Template(template_str).safe_substitute( {'attributes': attribute_str}) open(resolvers_conf, "w").write(conf_contents) ctx.vlog( "Writing dependency_resolvers_config_file to path %s with contents [%s]", resolvers_conf, conf_contents, ) kwds["dependency_resolvers_config_file"] = resolvers_conf
def cli(ctx, path, **kwds): """Install conda packages for tool requirements.""" conda_context = build_conda_context(**kwds) return_codes = [] for conda_target in collect_conda_targets(path): ctx.log("Install conda target %s" % conda_target) return_code = conda_util.install_conda_target( conda_target, conda_context=conda_context) return_codes.append(return_code) return coalesce_return_codes(return_codes, assert_at_least_one=True)
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 cli(ctx, paths, **kwds): """Install conda packages for tool requirements.""" conda_context = build_conda_context(ctx, handle_auto_init=True, **kwds) return_codes = [] for conda_target in collect_conda_targets(ctx, paths, recursive=kwds["recursive"]): ctx.log("Install conda target %s" % conda_target) return_code = conda_util.install_conda_target( conda_target, conda_context=conda_context, skip_environment=kwds.get("global", False) ) return_codes.append(return_code) return coalesce_return_codes(return_codes, assert_at_least_one=True)
def cli(ctx, path, **kwds): """Install conda packages for tool requirements.""" conda_context = build_conda_context(**kwds) return_codes = [] for conda_target in collect_conda_targets(path): ctx.log("Install conda target %s" % conda_target) return_code = conda_util.install_conda_target( conda_target, conda_context=conda_context ) return_codes.append(return_code) return coalesce_return_codes(return_codes, assert_at_least_one=True)
def cli(ctx, term, **kwds): """Perform conda search with Planemo's conda. Implicitly adds channels Planemo is configured with. """ conda_context = build_conda_context(ctx, handle_auto_init=True, **kwds) # Handle CLI interface change for conda search in 4.5. # xref: https://github.com/conda/conda/pull/5597/files if conda_context.conda_version >= VERSION_4_DOT_4: term = "*%s*" % term args = conda_context._override_channels_args + [term] conda_context.exec_command("search", args)
def cli(ctx, **kwds): """Download and install conda. This will download conda for managing dependencies for your platform using the appropriate Miniconda installer. By running this command, you are agreeing to the terms of the conda license a 3-clause BSD 3 license. Please review full license at http://docs.continuum.io/anaconda/eula. """ conda_context = build_conda_context(**kwds) return conda_util.install_conda(conda_context=conda_context)
def _handle_dependency_resolution(config_directory, kwds): resolutions_strategies = [ "brew_dependency_resolution", "dependency_resolvers_config_file", "shed_dependency_resolution", "conda_dependency_resolution", ] selected_strategies = 0 for key in resolutions_strategies: if kwds.get(key): selected_strategies += 1 if selected_strategies > 1: message = "At most one option from [%s] may be specified" raise click.UsageError(message % resolutions_strategies) dependency_attribute_kwds = { 'conda_prefix': None, 'conda_exec': None, 'conda_debug': False, 'conda_copy_dependencies': False, 'conda_auto_init': False, 'conda_auto_install': False, 'conda_ensure_channels': '', } attributes = [] def add_attribute(key, value): attributes.append('%s="%s"' % (key, value)) for key, default_value in iteritems(dependency_attribute_kwds): value = kwds.get(key, default_value) if value != default_value: # Strip leading prefix (conda_) off attributes attribute_key = "_".join(key.split("_")[1:]) add_attribute(attribute_key, value) if not [attribute for attribute in attributes if "prefix" in attribute]: conda_context = build_conda_context(**kwds) add_attribute("prefix", conda_context.conda_prefix) attribute_str = " ".join(attributes) for key in STOCK_DEPENDENCY_RESOLUTION_STRATEGIES: if kwds.get(key): resolvers_conf = os.path.join(config_directory, "resolvers_conf.xml") template_str = STOCK_DEPENDENCY_RESOLUTION_STRATEGIES[key] conf_contents = Template(template_str).safe_substitute( {'attributes': attribute_str}) open(resolvers_conf, "w").write(conf_contents) kwds["dependency_resolvers_config_file"] = resolvers_conf
def cli(ctx, paths, **kwds): """Install conda packages for tool requirements.""" conda_context = build_conda_context(ctx, handle_auto_init=True, **kwds) return_codes = [] for conda_target in collect_conda_targets(ctx, paths, recursive=kwds["recursive"]): ctx.log("Install conda target %s" % conda_target) return_code = conda_util.install_conda_target( conda_target, conda_context=conda_context, skip_environment=kwds.get("global", False)) return_codes.append(return_code) return coalesce_return_codes(return_codes, assert_at_least_one=True)
def cli(ctx, path, **kwds): """Activate a conda environment for tool. Source the output of this command to activate a conda environment for this tool. \b $ . <(planemo conda_env seqtk_seq.xml) Deactivate environment with conda_env_deactivate (seqtk_seq_v6) $ which seqtk /home/planemo/miniconda2/envs/jobdepsDkzcjjfecc6d406196737781ff4456ec60975c137e04884e4f4b05dc68192f7cec4656/bin/seqtk (seqtk_seq_v6) $ conda_env_deactivate $ """ conda_context = build_conda_context(ctx, use_planemo_shell_exec=False, **kwds) conda_targets = collect_conda_targets( ctx, [path], conda_context=conda_context ) installed_conda_targets = conda_util.filter_installed_targets( conda_targets, conda_context=conda_context ) env_name, exit_code = conda_util.build_isolated_environment( installed_conda_targets, conda_context=conda_context, quiet=True ) if exit_code: error("Failed to build environmnt for request.") return 1 ps1 = ps1_for_path(path, base="PRE_CONDA_PS1") remove_env = "%s env remove -y --name '%s'" % ( conda_context.conda_exec, env_name ) deactivate = conda_context.deactivate activate = conda_context.activate command = SOURCE_COMMAND % ( activate, env_name, ps1, deactivate, remove_env ) print(command)
def ensure_dependency_resolvers_conf_configured(ctx, kwds, resolvers_conf=None): """Use supplied CLI options (kwds) to find or build a dependency resolvers file. Set new path in kwds if needed. """ _validate_dependency_resolution_options(kwds) always_specify_attribute = object() dependency_attribute_kwds = { 'conda_prefix': None, 'conda_exec': None, 'conda_debug': False, 'conda_copy_dependencies': False, 'conda_auto_init': always_specify_attribute, 'conda_auto_install': always_specify_attribute, 'conda_ensure_channels': '', 'conda_use_local': False, } attributes = [] def add_attribute(key, value): attributes.append('%s="%s"' % (key, value)) conda_prefix_specified = False for key, default_value in iteritems(dependency_attribute_kwds): value = kwds.get(key, default_value) if value != default_value: conda_prefix_specified = conda_prefix_specified or (key == "conda_prefix") # Strip leading prefix (conda_) off attributes attribute_key = "_".join(key.split("_")[1:]) add_attribute(attribute_key, value) conda_context = build_conda_context(ctx, **kwds) if not conda_prefix_specified: add_attribute("prefix", conda_context.conda_prefix) add_attribute("condarc_override", conda_context.condarc_override) attribute_str = " ".join(attributes) if kwds.get("dependency_resolvers_config_file", None): resolution_type = "__explicit__" else: resolution_type = "default_dependency_resolution" for key in STOCK_DEPENDENCY_RESOLUTION_STRATEGIES: if kwds.get(key): resolution_type = key if resolution_type != "__explicit__": # Planemo manages the dependency resolve conf file. template_str = STOCK_DEPENDENCY_RESOLUTION_STRATEGIES[resolution_type] conf_contents = Template(template_str).safe_substitute({ 'attributes': attribute_str }) if resolvers_conf is None: resolvers_conf = tempfile.NamedTemporaryFile(delete=False).name open(resolvers_conf, "w").write(conf_contents) ctx.vlog( "Writing dependency_resolvers_config_file to path %s with contents [%s]", resolvers_conf, conf_contents, ) kwds["dependency_resolvers_config_file"] = resolvers_conf
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
def ensure_dependency_resolvers_conf_configured(ctx, kwds, resolvers_conf=None): """Use supplied CLI options (kwds) to find or build a dependency resolvers file. Set new path in kwds if needed. """ _validate_dependency_resolution_options(kwds) always_specify_attribute = object() dependency_attribute_kwds = { 'conda_prefix': None, 'conda_exec': None, 'conda_debug': False, 'conda_copy_dependencies': False, 'conda_auto_init': always_specify_attribute, 'conda_auto_install': always_specify_attribute, 'conda_ensure_channels': '', 'conda_use_local': False, } attributes = [] def add_attribute(key, value): attributes.append('%s="%s"' % (key, value)) conda_prefix_specified = False for key, default_value in iteritems(dependency_attribute_kwds): value = kwds.get(key, default_value) if value != default_value: conda_prefix_specified = conda_prefix_specified or ( key == "conda_prefix") # Strip leading prefix (conda_) off attributes attribute_key = "_".join(key.split("_")[1:]) add_attribute(attribute_key, value) conda_context = build_conda_context(ctx, **kwds) if not conda_prefix_specified: add_attribute("prefix", conda_context.conda_prefix) add_attribute("condarc_override", conda_context.condarc_override) attribute_str = " ".join(attributes) if kwds.get("dependency_resolvers_config_file", None): resolution_type = "__explicit__" else: resolution_type = "default_dependency_resolution" for key in STOCK_DEPENDENCY_RESOLUTION_STRATEGIES: if kwds.get(key): resolution_type = key if resolution_type != "__explicit__": # Planemo manages the dependency resolve conf file. template_str = STOCK_DEPENDENCY_RESOLUTION_STRATEGIES[resolution_type] conf_contents = Template(template_str).safe_substitute( {'attributes': attribute_str}) if resolvers_conf is None: resolvers_conf = tempfile.NamedTemporaryFile(delete=False).name with open(resolvers_conf, "w") as fh: fh.write(conf_contents) ctx.vlog( "Writing dependency_resolvers_config_file to path %s with contents [%s]", resolvers_conf, conf_contents, ) kwds["dependency_resolvers_config_file"] = resolvers_conf