executablebooks / mdformat

CommonMark compliant Markdown formatter
https://mdformat.rtfd.io
MIT License
447 stars 46 forks source link

Non standard output between core and plugins? #435

Open pawamoy opened 7 months ago

pawamoy commented 7 months ago

Describe the bug

context When I format files, I get output lines that sometimes start with "Failed", sometimes "Warning:", and sometimes "error:". It can be a bit confusing.

expectation I would expect all warnings to start with "warning:", and errors associated to these warnings be appended at the end of the warnings, since these errors do not cause the program to stop (also see #434).

bug I'm actually not sure which lines come from plugin, from core, or why they differ.

Example:

% make format
Warning: Failed formatting content of a yaml code block (line 214 before formatting). Filename: /media/data/dev/website/docs/posts/save-pytest-logs-as-artifact-gitlab-ci.md
Failed formatting content of a yaml code block (line 177 before formatting). Filename: /media/data/dev/website/docs/posts/save-pytest-logs-as-artifact-gitlab-ci.md
error: Failed to parse at 1:1: Unexpected token Indent
Warning: Failed formatting content of a python code block (line 276 before formatting). Filename: /media/data/dev/website/docs/posts/unify-logging-for-a-gunicorn-uvicorn-app.md
error: Failed to parse at 1:1: Unexpected token Indent
Warning: Failed formatting content of a python code block (line 306 before formatting). Filename: /media/data/dev/website/docs/posts/unify-logging-for-a-gunicorn-uvicorn-app.md
error: Failed to parse at 1:1: Unexpected token Indent
Warning: Failed formatting content of a python code block (line 319 before formatting). Filename: /media/data/dev/website/docs/posts/unify-logging-for-a-gunicorn-uvicorn-app.md
error: Failed to parse at 1:1: Unexpected token Indent
Failed formatting content of a python code block (line 248 before formatting). Filename: /media/data/dev/website/docs/posts/unify-logging-for-a-gunicorn-uvicorn-app.md
error: Failed to parse at 1:1: Unexpected token Indent
Failed formatting content of a python code block (line 272 before formatting). Filename: /media/data/dev/website/docs/posts/unify-logging-for-a-gunicorn-uvicorn-app.md
error: Failed to parse at 1:1: Unexpected token Indent
Failed formatting content of a python code block (line 282 before formatting). Filename: /media/data/dev/website/docs/posts/unify-logging-for-a-gunicorn-uvicorn-app.md
error: Failed to parse at 4:6: Unexpected token '%'
Warning: Failed formatting content of a python code block (line 276 before formatting). Filename: /media/data/dev/website/docs/posts/how-to-deal-with-jinja2-spacing.md
error: Failed to parse at 6:6: Unexpected token '%'
Warning: Failed formatting content of a python code block (line 292 before formatting). Filename: /media/data/dev/website/docs/posts/how-to-deal-with-jinja2-spacing.md
error: Failed to parse at 4:6: Unexpected token '%'
Failed formatting content of a python code block (line 269 before formatting). Filename: /media/data/dev/website/docs/posts/how-to-deal-with-jinja2-spacing.md
error: Failed to parse at 6:6: Unexpected token '%'
Failed formatting content of a python code block (line 285 before formatting). Filename: /media/data/dev/website/docs/posts/how-to-deal-with-jinja2-spacing.md
Warning: Failed formatting content of a toml code block (line 157 before formatting). Filename: /media/data/dev/website/docs/posts/docker-compose-django-postgres-nginx.md
Warning: Failed formatting content of a toml code block (line 383 before formatting). Filename: /media/data/dev/website/docs/posts/docker-compose-django-postgres-nginx.md
Failed formatting content of a toml code block (line 124 before formatting). Filename: /media/data/dev/website/docs/posts/docker-compose-django-postgres-nginx.md
Failed formatting content of a toml code block (line 329 before formatting). Filename: /media/data/dev/website/docs/posts/docker-compose-django-postgres-nginx.md
error: Failed to parse at 1:1: Unexpected token Indent
Failed formatting content of a python code block (line 151 before formatting). Filename: /media/data/dev/website/docs/posts/adding-links-to-formatted-and-syntax-highlighted-code.md
error: Failed to parse at 4:5: Unexpected token 'entry_points'
Warning: Failed formatting content of a python code block (line 42 before formatting). Filename: /media/data/dev/website/docs/posts/write-and-use-a-tox-plugin-from-inside-your-package.md
error: Failed to parse at 4:5: Unexpected token 'entry_points'
Failed formatting content of a python code block (line 39 before formatting). Filename: /media/data/dev/website/docs/posts/write-and-use-a-tox-plugin-from-inside-your-package.md
Warning: Failed formatting content of a yaml code block (line 124 before formatting). Filename: /media/data/dev/website/docs/posts/add-alembic-migrations-to-existing-fastapi-ormar-project.md
Failed formatting content of a yaml code block (line 126 before formatting). Filename: /media/data/dev/website/docs/posts/add-alembic-migrations-to-existing-fastapi-ormar-project.md

problem I think we could gain at standardizing error messages a bit :slightly_smiling_face: Typically, adding the plugin name would make it clear to which repository/project we should report an issue when something doesn't work as expected.

Reproduce the bug

git clone https://github.com/pawamoy/website --depth=1 /tmp/repro
cd /tmp/repro
python -m venv .venv
. .venv/bin/activate
python -m pip install mdformat-mkdocs[recommended]
python -m mdformat docs/posts --ignore-missing-references

List your environment

% python -V
Python 3.11.5
% mdformat --version
mdformat 0.7.17 (mdformat_tables: 0.4.1, mdformat_wikilink: 0.2.0, mdformat_admon: 2.0.2, mdformat_gfm: 0.3.6, mdformat_footnote: 0.1.1, mdformat_frontmatter: 2.0.8, mdformat_simple_breaks:
0.0.1, mdformat_mkdocs: 2.0.8, mdformat_config: 0.1.3, mdformat_ruff: 0.1.3, mdformat_web: 0.1.0, mdformat_beautysh: 0.1.1)
% uname -r
6.8.5-arch1-1
hukkin commented 3 weeks ago

Thanks for the issue!

Yes, there should be lots of room for improvement here.

One issue is plugins that invoke a code formatter in a subprocess. I think they should pretty much always send the subprocess's stderr to subprocess.DEVNULL as is done here, to not mix it up with mdformat's stderr, but I don't think there's any way mdformat can (or should) enforce that.

pawamoy commented 3 weeks ago

Apart from capturing everything at the file-descriptor level, using for example failprint, yep, no way to enforce that. I wouldn't particularly recommend using failprint as it's a potential can of worm for cross-platform compatibility :slightly_smiling_face:

Even if it's not enforced, it shouldn't be hard to convince plugin authors to update their code (or to send PRs, which I could do too) if there's documentation that goes in this direction.

Anyway, happy to help any way I can here!