"""Linter for CWL tools."""
from typing import TYPE_CHECKING
lint_tool_types = ["cwl"]
from galaxy.tool_util.cwl.schema import schema_loader
from galaxy.tool_util.lint import Linter
if TYPE_CHECKING:
from galaxy.tool_util.lint import LintContext
from galaxy.tool_util.parser import ToolSource
[docs]class CWLValid(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
raw_reference = schema_loader.raw_process_reference(tool_source.source_path)
try:
schema_loader.process_definition(raw_reference)
except Exception:
return
lint_ctx.info("CWL appears to be valid.")
[docs]class CWLInValid(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
raw_reference = schema_loader.raw_process_reference(tool_source.source_path)
try:
schema_loader.process_definition(raw_reference)
except Exception as e:
lint_ctx.error(f"Failed to valdiate CWL artifact: {e}")
[docs]class CWLVersionMissing(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
raw_reference = schema_loader.raw_process_reference(tool_source.source_path)
cwl_version = raw_reference.process_object.get("cwlVersion", None)
if cwl_version is None:
lint_ctx.error("CWL file does not contain a 'cwlVersion'")
[docs]class CWLVersionUnknown(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
raw_reference = schema_loader.raw_process_reference(tool_source.source_path)
cwl_version = raw_reference.process_object.get("cwlVersion", None)
if cwl_version not in ["v1.0"]:
lint_ctx.warn(f"CWL version [{cwl_version}] is unknown, we recommend the v1.0 the stable release.")
[docs]class CWLVersionGood(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
raw_reference = schema_loader.raw_process_reference(tool_source.source_path)
cwl_version = raw_reference.process_object.get("cwlVersion", None)
if cwl_version in ["v1.0"]:
lint_ctx.info(f"Modern CWL version [{cwl_version}].")
[docs]class CWLDockerMissing(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
_, containers, *_ = tool_source.parse_requirements_and_containers()
if len(containers) == 0:
lint_ctx.warn("Tool does not specify a DockerPull source.")
[docs]class CWLDockerGood(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
_, containers, *_ = tool_source.parse_requirements_and_containers()
if len(containers) > 0:
identifier = containers[0].identifier
lint_ctx.info(f"Tool will run in Docker image [{identifier}].")
[docs]class CWLDescriptionMissing(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
help = tool_source.parse_help()
if not help:
lint_ctx.warn("Description of tool is empty or absent.")
[docs]class CWLHelpTODO(Linter):
[docs] @classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
help = tool_source.parse_help()
if help and "TODO" in help:
lint_ctx.warn("Help contains TODO text.")