Skip to content

Commit

Permalink
Allow help text with line breaks (#240)
Browse files Browse the repository at this point in the history
Improve formatting logic for help text spanning multiple lines and remove the faulty rule that prevented running tasks with multi-line help.

---------

Co-authored-by: Nat Noordanus <n@natn.me>
  • Loading branch information
taconi and nat-n authored Sep 23, 2024
1 parent de19a42 commit 62c6061
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 8 deletions.
4 changes: 0 additions & 4 deletions poethepoet/task/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,6 @@ def validate(self):
"""
Validation rules that don't require any extra context go here.
"""
if self.help and "\n" in self.help:
raise ConfigValidationError(
"Help messages must not contain line breaks"
)

class TaskSpec:
name: str
Expand Down
17 changes: 14 additions & 3 deletions poethepoet/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ def print_help(
if task.startswith("_"):
continue
tasks_section.append(
f" <em>{self._padr(task, col_width)}</em> {help_text}"
f" <em>{self._padr(task, col_width)}</em> "
f"{self._align(help_text, col_width)}"
)
for options, arg_help_text, default in args_help:
formatted_options = ", ".join(str(opt) for opt in options)
Expand All @@ -274,9 +275,14 @@ def print_help(
f"<em3>{self._padr(formatted_options, col_width-1)}</em3>",
]
if arg_help_text:
task_arg_help.append(arg_help_text)
task_arg_help.append(self._align(arg_help_text, col_width))
if default:
task_arg_help.append(default)
if "\n" in (arg_help_text or ""):
task_arg_help.append(
self._align(f"\n{default}", col_width, strip=False)
)
else:
task_arg_help.append(default)
tasks_section.append(" ".join(task_arg_help))

result.append(tasks_section)
Expand All @@ -298,6 +304,11 @@ def print_help(
+ ("\n" if verbosity >= 0 else "")
)

@staticmethod
def _align(text: str, width: int, *, strip: bool = True) -> str:
text = text.replace("\n", "\n" + " " * (width + 4))
return text.strip() if strip else text

@staticmethod
def _padr(text: str, width: int):
if len(text) >= width:
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def projects():
).groups()[0]: path
for project_key, project_path in projects.items()
for path in project_path.glob("**/*.toml")
if "site-packages" not in str(path)
}
)
return projects
Expand Down
41 changes: 41 additions & 0 deletions tests/fixtures/scripts_project/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,47 @@ async-task.args = ["a","b"]
multiple = true
required = true

[tool.poe.tasks.multiple-lines-help]
script = "pkg:echo_script(first, second, widgets=widgets, engines=engines)"
help = """
Multilines
Creating multi-line documentation for greater detail and inclusion of examples
"""

[[tool.poe.tasks.multiple-lines-help.args]]
name = "first"
positional = true
help = """
First positional arg
documentation multiline
"""

[[tool.poe.tasks.multiple-lines-help.args]]
name = "second"
positional = true
multiple = true
type = "integer"
help = """
Multiple positional arg
documentation multiline
"""

[[tool.poe.tasks.multiple-lines-help.args]]
name = "widgets"
multiple = 2
help = """
Multiple arg
documentation multiline
"""

[[tool.poe.tasks.multiple-lines-help.args]]
name = "engines"
default = "true"
help = """
Default arg
documentation multiline
"""


[build-system]
requires = ["poetry>=0.12"]
Expand Down
26 changes: 25 additions & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,30 @@ def test_documentation_of_task_named_args(run_poe):
r" greet-strict \s+All arguments are required\n"
r" --greeting"
r" \s+this one is required \[default: \$\{DOES\}n't \$\{STUFF\}\]\n"
r" --name \s+and this one is required\n",
r" --name"
r" \s+and this one is required\n"
r" greet-positional \s+\n"
r" greeting"
r" \s+this one is required \[default: \$\{DEFAULT_GREETING\}\]\n"
r" user"
r" \s+and this one is required\n"
r" --upper \s+\n"
r" multiple-value-args \s+\n"
r" first \s+\n"
r" second \s+\n"
r" --widgets \s+\n"
r" --engines \s+\n"
r" multiple-lines-help \s+Multilines\n"
r" \s+Creating multi-line documentation for greater"
" detail and inclusion of examples\n"
r" first \s+First positional arg\n"
r" \s+documentation multiline\n"
r" second \s+Multiple positional arg\n"
r" \s+documentation multiline\n"
r" --widgets \s+Multiple arg\n"
r" \s+documentation multiline\n"
r" --engines \s+Default arg\n"
r" \s+documentation multiline\s+\n"
r" \s+\[default: true\]\n",
result.capture,
)

0 comments on commit 62c6061

Please sign in to comment.