nat-n / poethepoet

A task runner that works well with poetry.
https://poethepoet.natn.io/
MIT License
1.39k stars 56 forks source link

Unable to define a command which spans multiple lines #224

Closed snejus closed 2 months ago

snejus commented 2 months ago

Hi, I noticed the documentation mentions that it's possible to define a command across multiple lines with comments and thus I was to configure the following command

[tool.poe.tasks.test-with-coverage]
help = "Run tests and record coverage"
cmd = """
pytest
    --cov=package                           # record coverage in package
    --cov-report=xml:.reports/coverage.xml  # save xml for coverage upload
    --cov-report=html:.reports/html         # save html files for local dev use
    --cov-branch                            # record coverage across logical branches
    --cov-context=test                      # show which tests cover specific lines in the code (available in HTML)
"""

However poe does not seem to be happy about it and throws me the following error:

Error: Invalid cmd task 'test-with-coverage' includes multiple command lines

Then, I tried configuring the example given in the docs

[tool.poe.tasks]
clean = """
rm -rf ./**/*.pyc
       ./**/__pycache__    # this will match all __pycache__ dirs in the project
"""

However this resulted in an exception

$ poe clean
Traceback (most recent call last):
  File "/media/pipx-3.8/bin/poe", line 8, in <module>
    sys.exit(main())
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/__init__.py", line 35, in main
    result = app(cli_args=sys.argv[1:])
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/app.py", line 126, in __call__
    return self.run_task(task) or 0
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/app.py", line 174, in run_task
    return task.run(context=context)
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/task/base.py", line 479, in run
    return self._handle_run(context, task_env)
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/task/cmd.py", line 56, in _handle_run
    cmd = (*self._resolve_commandline(context, env), *extra_args)
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/task/cmd.py", line 87, in _resolve_commandline
    for cmd_token, has_glob in resolve_command_tokens(
  File "/media/pipx-3.8/venvs/poethepoet/lib/python3.8/site-packages/poethepoet/helpers/command/__init__.py", line 59, in resolve_command_tokens
    for segment in word:
TypeError: 'Comment' object is not iterable

Is there something missing in my configuration in the above examples?

snejus commented 2 months ago

I started looking into this and added failing tests for simplified equivalents of the two cases above: https://github.com/nat-n/poethepoet/pull/225.

Interestingly, the Comment exception seems to be thrown if there's a single comment in the last line. If there is more than one comment, then I see the invalid cmd task/multiline error.

nat-n commented 2 months ago

Hi @snejus, thanks for looking into this!

I'll look into this as soon as I have some time. This must have been introduced as an untracked breaking change in 0.23.0. Not enough tests :(

Now... without spending more time than I have at this moment to think about it; this exception makes me unsure if it's the docs or the code that should be fixed.

One approach to recover the previous behavior would be to parse lines, strip comments, then merge the lines.

nat-n commented 2 months ago

This issue is fixed in 0.27.0 🚀