Skip to content

Commit

Permalink
split help linters
Browse files Browse the repository at this point in the history
  • Loading branch information
bernt-matthias committed Nov 26, 2023
1 parent 6cbb4b9 commit 3305cef
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 45 deletions.
139 changes: 107 additions & 32 deletions lib/galaxy/tool_util/linters/help.py
Original file line number Diff line number Diff line change
@@ -1,43 +1,118 @@
"""This module contains a linting function for a tool's help."""
from typing import (
TYPE_CHECKING,
Union,
)

from typing import Union

from galaxy.tool_util.lint import Linter
from galaxy.util import (
rst_to_html,
unicodify,
)

if TYPE_CHECKING:
from galaxy.tool_util.lint import LintContext
from galaxy.tool_util.parser.interface import ToolSource


class HelpMultiple(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
helps = tool_xml.findall("./help")
print(helps)
if len(helps) > 1:
lint_ctx.error("More than one help section found, behavior undefined.", node=helps[1])


class HelpMissing(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
root = tool_xml.find("./help") or tool_xml.getroot()
help = tool_xml.find("./help")
if help is None:
lint_ctx.warn("No help section found, consider adding a help section to your tool.", node=root)


class HelpEmpty(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
help = tool_xml.find("./help")
if help is None:
return
help_text = help.text or ""
if not help_text.strip():
lint_ctx.warn("Help section appears to be empty.", node=help)


class HelpPresent(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
help = tool_xml.find("./help")
if help is None:
return
help_text = help.text or ""
if help_text.strip():
lint_ctx.valid("Tool contains help section.", node=help)


class HelpTODO(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
help = tool_xml.find("./help")
if help is None:
return
help_text = help.text or ""
if "TODO" in help_text:
lint_ctx.warn("Help contains TODO text.", node=help)


class HelpInvalidRST(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
help = tool_xml.find("./help")
if help is None:
return
help_text = help.text or ""
if not help_text.strip():
return
invalid_rst = rst_invalid(help_text)
if invalid_rst:
lint_ctx.warn(f"Invalid reStructuredText found in help - [{invalid_rst}].", node=help)


def lint_help(tool_xml, lint_ctx):
"""Ensure tool contains exactly one valid RST help block."""
# determine node to report for general problems with help
root = tool_xml.find("./help")
if root is None:
root = tool_xml.getroot()
helps = tool_xml.findall("./help")
if len(helps) > 1:
lint_ctx.error("More than one help section found, behavior undefined.", node=helps[1])
return

if len(helps) == 0:
lint_ctx.warn("No help section found, consider adding a help section to your tool.", node=root)
return

help_text = helps[0].text or ""
if not help_text.strip():
lint_ctx.warn("Help section appears to be empty.", node=helps[0])
return

lint_ctx.valid("Tool contains help section.", node=helps[0])

if "TODO" in help_text:
lint_ctx.warn("Help contains TODO text.", node=helps[0])

invalid_rst = rst_invalid(help_text)
if invalid_rst:
lint_ctx.warn(f"Invalid reStructuredText found in help - [{invalid_rst}].", node=helps[0])
else:
lint_ctx.valid("Help contains valid reStructuredText.", node=helps[0])
class HelpValidRST(Linter):
@classmethod
def lint(cls, tool_source: "ToolSource", lint_ctx: "LintContext"):
tool_xml = getattr(tool_source, "xml_tree", None)
if not tool_xml:
return
help = tool_xml.find("./help")
if help is None:
return
help_text = help.text or ""
if not help_text.strip():
return
invalid_rst = rst_invalid(help_text)
if not invalid_rst:
lint_ctx.valid("Help contains valid reStructuredText.", node=help)


def rst_invalid(text: str) -> Union[bool, str]:
Expand Down
25 changes: 12 additions & 13 deletions test/unit/tool_util/test_tool_linters.py
Original file line number Diff line number Diff line change
Expand Up @@ -1053,18 +1053,17 @@ def test_general_valid_new_profile_fmt(lint_ctx):


def test_help_multiple(lint_ctx):
tool_xml_tree = get_xml_tree(HELP_MULTIPLE)
run_lint_module(lint_ctx, help, tool_xml_tree)
assert "More than one help section found, behavior undefined." in lint_ctx.error_messages
tool_source = get_xml_tool_source(HELP_MULTIPLE)
run_lint_module(lint_ctx, help, tool_source)
assert not lint_ctx.info_messages
assert not lint_ctx.valid_messages
assert len(lint_ctx.valid_messages) == 2 # has help and valid rst
assert not lint_ctx.warn_messages
assert len(lint_ctx.error_messages) == 1
assert lint_ctx.error_messages == ["More than one help section found, behavior undefined."]


def test_help_absent(lint_ctx):
tool_xml_tree = get_xml_tree(HELP_ABSENT)
run_lint_module(lint_ctx, help, tool_xml_tree)
tool_source = get_xml_tool_source(HELP_ABSENT)
run_lint_module(lint_ctx, help, tool_source)
assert "No help section found, consider adding a help section to your tool." in lint_ctx.warn_messages
assert not lint_ctx.info_messages
assert not lint_ctx.valid_messages
Expand All @@ -1073,8 +1072,8 @@ def test_help_absent(lint_ctx):


def test_help_empty(lint_ctx):
tool_xml_tree = get_xml_tree(HELP_EMPTY)
run_lint_module(lint_ctx, help, tool_xml_tree)
tool_source = get_xml_tool_source(HELP_EMPTY)
run_lint_module(lint_ctx, help, tool_source)
assert "Help section appears to be empty." in lint_ctx.warn_messages
assert not lint_ctx.info_messages
assert not lint_ctx.valid_messages
Expand All @@ -1083,8 +1082,8 @@ def test_help_empty(lint_ctx):


def test_help_todo(lint_ctx):
tool_xml_tree = get_xml_tree(HELP_TODO)
run_lint_module(lint_ctx, help, tool_xml_tree)
tool_source = get_xml_tool_source(HELP_TODO)
run_lint_module(lint_ctx, help, tool_source)
assert "Tool contains help section." in lint_ctx.valid_messages
assert "Help contains valid reStructuredText." in lint_ctx.valid_messages
assert "Help contains TODO text." in lint_ctx.warn_messages
Expand All @@ -1095,8 +1094,8 @@ def test_help_todo(lint_ctx):


def test_help_invalid_rst(lint_ctx):
tool_xml_tree = get_xml_tree(HELP_INVALID_RST)
run_lint_module(lint_ctx, help, tool_xml_tree)
tool_source = get_xml_tool_source(HELP_INVALID_RST)
run_lint_module(lint_ctx, help, tool_source)
assert "Tool contains help section." in lint_ctx.valid_messages
assert (
"Invalid reStructuredText found in help - [<string>:2: (WARNING/2) Inline strong start-string without end-string.\n]."
Expand Down

0 comments on commit 3305cef

Please sign in to comment.