Mercurial > repos > bcclaywell > argo_navis
diff venv/lib/python2.7/site-packages/planemo/shed_lint.py @ 0:d67268158946 draft
planemo upload commit a3f181f5f126803c654b3a66dd4e83a48f7e203b
author | bcclaywell |
---|---|
date | Mon, 12 Oct 2015 17:43:33 -0400 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/venv/lib/python2.7/site-packages/planemo/shed_lint.py Mon Oct 12 17:43:33 2015 -0400 @@ -0,0 +1,287 @@ +import os +import yaml +from galaxy.tools.lint import LintContext +from galaxy.tools.linters.help import rst_invalid +from planemo.lint import lint_xsd +from planemo.shed import ( + REPO_TYPE_UNRESTRICTED, + REPO_TYPE_TOOL_DEP, + REPO_TYPE_SUITE, + CURRENT_CATEGORIES, + validate_repo_owner, + validate_repo_name, +) +from planemo.tool_lint import ( + build_lint_args, + yield_tool_xmls, + handle_tool_load_error, +) +from planemo.shed2tap import base +from planemo.xml import XSDS_PATH + + +from planemo.io import info +from planemo.io import error + +from galaxy.tools.lint import lint_xml_with + +TOOL_DEPENDENCIES_XSD = os.path.join(XSDS_PATH, "tool_dependencies.xsd") +REPO_DEPENDENCIES_XSD = os.path.join(XSDS_PATH, "repository_dependencies.xsd") + + +VALID_REPOSITORY_TYPES = [ + REPO_TYPE_UNRESTRICTED, + REPO_TYPE_TOOL_DEP, + REPO_TYPE_SUITE, +] + +SHED_METADATA = [ + "description", + "long_description", + "remote_repository_url", + "homepage_url", + "categories", +] + + +def lint_repository(ctx, realized_repository, **kwds): + # TODO: this really needs to start working with realized path. + failed = False + path = realized_repository.real_path + info("Linting repository %s" % path) + lint_args = build_lint_args(ctx, **kwds) + lint_ctx = LintContext(lint_args["level"]) + lint_ctx.lint( + "lint_expansion", + lint_expansion, + realized_repository, + ) + lint_ctx.lint( + "lint_expected_files", + lint_expected_files, + realized_repository, + ) + lint_ctx.lint( + "lint_tool_dependencies_xsd", + lint_tool_dependencies_xsd, + path, + ) + lint_ctx.lint( + "lint_tool_dependencies_actions", + lint_tool_dependencies_actions, + path, + ) + lint_ctx.lint( + "lint_repository_dependencies", + lint_repository_dependencies, + path, + ) + lint_ctx.lint( + "lint_shed_yaml", + lint_shed_yaml, + realized_repository, + ) + lint_ctx.lint( + "lint_readme", + lint_readme, + path, + ) + if kwds["tools"]: + for (tool_path, tool_xml) in yield_tool_xmls(ctx, path, + recursive=True): + info("+Linting tool %s" % tool_path) + if handle_tool_load_error(tool_path, tool_xml): + failed = True + continue + lint_xml_with( + lint_ctx, + tool_xml, + extra_modules=lint_args["extra_modules"] + ) + if kwds["ensure_metadata"]: + lint_ctx.lint( + "lint_shed_metadata", + lint_shed_metadata, + realized_repository, + ) + if not failed: + failed = lint_ctx.failed(lint_args["fail_level"]) + if failed: + error("Failed linting") + return 1 if failed else 0 + + +def lint_expansion(realized_repository, lint_ctx): + missing = realized_repository.missing + if missing: + msg = "Failed to expand inclusions %s" % missing + lint_ctx.warn(msg) + else: + lint_ctx.info("Included files all found.") + + +def lint_shed_metadata(realized_repository, lint_ctx): + found_all = True + for key in SHED_METADATA: + if key not in realized_repository.config: + found_all = False + lint_ctx.warn( + "Missing shed metadata field [%s] for repository" % key + ) + if found_all: + lint_ctx.info( + "Found all shed metadata fields required for automated repository " + "creation and/or updates." + ) + + +def lint_readme(path, lint_ctx): + readme_rst = os.path.join(path, "README.rst") + readme = os.path.join(path, "README") + readme_txt = os.path.join(path, "README.txt") + + readme_found = False + for readme in [readme_rst, readme, readme_txt]: + if os.path.exists(readme): + readme_found = readme + + readme_md = os.path.join(path, "README.md") + if not readme_found and os.path.exists(readme_md): + lint_ctx.warn("Tool Shed doesn't render markdown, " + "README.md is invalid readme.") + return + + if not readme_found: + # TODO: filter on TYPE and make this a warning if + # unrestricted repository - need to update iuc standards + # first though. + lint_ctx.info("No README found skipping.") + return + + if readme_found.endswith(".rst"): + readme_text = open(readme_found, "r").read() + invalid_rst = rst_invalid(readme_text) + if invalid_rst: + template = "Invalid restructured text found in README [%s]." + msg = template % invalid_rst + lint_ctx.warn(msg) + return + lint_ctx.info("README found containing valid reStructuredText.") + else: + lint_ctx.info("README found containing plain text.") + + +def lint_tool_dependencies_xsd(path, lint_ctx): + tool_dependencies = os.path.join(path, "tool_dependencies.xml") + if not os.path.exists(tool_dependencies): + lint_ctx.info("No tool_dependencies.xml, skipping.") + return + lint_xsd(lint_ctx, TOOL_DEPENDENCIES_XSD, tool_dependencies) + + +def lint_tool_dependencies_actions(path, lint_ctx): + tool_dependencies = os.path.join(path, "tool_dependencies.xml") + if not os.path.exists(tool_dependencies): + lint_ctx.info("No tool_dependencies.xml, skipping.") + return + try: + base.Dependencies(tool_dependencies) + lint_ctx.info("Parsed tool dependencies.") + except Exception as e: + import sys + import traceback + exc_type, exc_value, exc_traceback = sys.exc_info() + traceback.print_tb(exc_traceback, limit=1, file=sys.stdout) + traceback.print_exc() + template = "Problem parsing tool_dependenies.xml [%s]" + msg = template % str(e) + lint_ctx.warn(msg) + return + + +def lint_expected_files(realized_repository, lint_ctx): + if realized_repository.is_package: + if not os.path.exists(realized_repository.tool_dependencies_path): + lint_ctx.warn("Package repository does not contain a " + "tool_dependencies.xml file.") + + if realized_repository.is_suite: + if not os.path.exists(realized_repository.repo_dependencies_path): + lint_ctx.warn("Suite repository does not contain a " + "repository_dependencies.xml file.") + + +def lint_repository_dependencies(path, lint_ctx): + repo_dependencies = os.path.join(path, "repository_dependencies.xml") + if not os.path.exists(repo_dependencies): + lint_ctx.info("No repository_dependencies.xml, skipping.") + return + lint_xsd(lint_ctx, REPO_DEPENDENCIES_XSD, repo_dependencies) + + +def lint_shed_yaml(realized_repository, lint_ctx): + path = realized_repository.real_path + shed_yaml = os.path.join(path, ".shed.yml") + if not os.path.exists(shed_yaml): + lint_ctx.info("No .shed.yml file found, skipping.") + return + try: + yaml.load(open(shed_yaml, "r")) + except Exception as e: + lint_ctx.warn("Failed to parse .shed.yml file [%s]" % str(e)) + return + lint_ctx.info(".shed.yml found and appears to be valid YAML.") + _lint_shed_contents(lint_ctx, realized_repository) + + +def _lint_shed_contents(lint_ctx, realized_repository): + config = realized_repository.config + + def _lint_if_present(key, func, *args): + value = config.get(key, None) + if value is not None: + msg = func(value, *args) + if msg: + lint_ctx.warn(msg) + + _lint_if_present("owner", validate_repo_owner) + _lint_if_present("name", validate_repo_name) + _lint_if_present("type", _validate_repo_type, config["name"]) + _lint_if_present("categories", _validate_categories, realized_repository) + + +def _validate_repo_type(repo_type, name): + if repo_type not in VALID_REPOSITORY_TYPES: + return "Invalid repository type specified [%s]" % repo_type + + is_dep = repo_type == "tool_dependency_definition" + is_suite = repo_type == "repository_suite_definition" + if is_dep and not name.startswith("package_"): + return ("Tool dependency definition repositories should have names " + "starting with package_") + if is_suite and not name.startswith("suite_"): + return ("Repository suite definition repositories should have names " + "starting with suite_") + if name.startswith("package_") or name.startswith("suite_"): + if repo_type == "unrestricted": + return ("Repository name indicated specialized repository type " + "but repository is listed as unrestricted.") + + +def _validate_categories(categories, realized_repository): + msg = None + if len(categories) == 0: + msg = "Repository should specify one or more categories." + else: + for category in categories: + unknown_categories = [] + if category not in CURRENT_CATEGORIES: + unknown_categories.append(category) + if unknown_categories: + msg = "Categories [%s] unknown." % unknown_categories + if realized_repository.is_package: + if "Tool Dependency Packages" not in categories: + msg = ("Packages should be placed and should only be placed " + "in the category 'Tool Dependency Packages'.") + + return msg