Skip to content

Commit 062ad6d

Browse files
KyleKinghukkin
andauthored
add: --no-validate option to skip AST safety check (#496)
* fix(#50): add --no-validate * refactor: use `dest=validate` Co-authored-by: Taneli Hukkinen <[email protected]> * refactor: finish renaming the stored value to validate * test: add patch to unit test * docs: add 'validate' to documentation * docs: re-generate help on Python 3.13.1 * test: add valid configuration test * fix: allow override * Apply suggestions from code review Co-authored-by: Taneli Hukkinen <[email protected]> * ci: apply formatting --------- Co-authored-by: Taneli Hukkinen <[email protected]>
1 parent 52f3c06 commit 062ad6d

File tree

6 files changed

+68
-14
lines changed

6 files changed

+68
-14
lines changed

README.md

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,10 @@ If a file is not properly formatted, the exit code will be non-zero.
9393

9494
```console
9595
foo@bar:~$ mdformat --help
96-
usage: mdformat [-h] [--check] [--version] [--number] [--wrap {keep,no,INTEGER}]
97-
[--end-of-line {lf,crlf,keep}] [--exclude PATTERN]
98-
[--extensions EXTENSION] [--codeformatters LANGUAGE]
96+
usage: mdformat [-h] [--check] [--no-validate] [--version] [--number]
97+
[--wrap {keep,no,INTEGER}] [--end-of-line {lf,crlf,keep}]
98+
[--exclude PATTERN] [--extensions EXTENSION]
99+
[--codeformatters LANGUAGE]
99100
[paths ...]
100101

101102
CommonMark compliant Markdown formatter
@@ -106,19 +107,23 @@ positional arguments:
106107
options:
107108
-h, --help show this help message and exit
108109
--check do not apply changes to files
110+
--no-validate do not validate that the rendered HTML is consistent
109111
--version show program's version number and exit
110112
--number apply consecutive numbering to ordered lists
111113
--wrap {keep,no,INTEGER}
112114
paragraph word wrap mode (default: keep)
113115
--end-of-line {lf,crlf,keep}
114116
output file line ending mode (default: lf)
115-
--exclude PATTERN exclude files that match the Unix-style glob pattern (multiple allowed)
117+
--exclude PATTERN exclude files that match the Unix-style glob pattern
118+
(multiple allowed)
116119
--extensions EXTENSION
117-
require and enable an extension plugin (multiple allowed) (use
118-
`--no-extensions` to disable) (default: all enabled)
120+
require and enable an extension plugin (multiple
121+
allowed) (use `--no-extensions` to disable) (default:
122+
all enabled)
119123
--codeformatters LANGUAGE
120-
require and enable a code formatter plugin (multiple allowed)
121-
(use `--no-codeformatters` to disable) (default: all enabled)
124+
require and enable a code formatter plugin (multiple
125+
allowed) (use `--no-codeformatters` to disable)
126+
(default: all enabled)
122127
```
123128

124129
The `--exclude` option is only available on Python 3.13+.

docs/users/configuration_file.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ Command line interface arguments take precedence over the configuration file.
2020
wrap = "keep" # options: {"keep", "no", INTEGER}
2121
number = false # options: {false, true}
2222
end_of_line = "lf" # options: {"lf", "crlf", "keep"}
23+
validate = true # options: {false, true}
2324
# extensions = [ # options: a list of enabled extensions (default: all installed are enabled)
2425
# "gfm",
2526
# "toc",

src/mdformat/_cli.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,16 @@ def run(cli_args: Sequence[str]) -> int: # noqa: C901
142142
getattr(plugin, "CHANGES_AST", False)
143143
for plugin in enabled_parserplugins.values()
144144
)
145-
if not changes_ast and not is_md_equal(
146-
original_str,
147-
formatted_str,
148-
options=opts,
149-
extensions=enabled_parserplugins,
150-
codeformatters=enabled_codeformatters,
145+
if (
146+
opts["validate"]
147+
and not changes_ast
148+
and not is_md_equal(
149+
original_str,
150+
formatted_str,
151+
options=opts,
152+
extensions=enabled_parserplugins,
153+
codeformatters=enabled_codeformatters,
154+
)
151155
):
152156
print_error(
153157
f'Could not format "{path_str}".',
@@ -197,6 +201,13 @@ def make_arg_parser(
197201
parser.add_argument(
198202
"--check", action="store_true", help="do not apply changes to files"
199203
)
204+
parser.add_argument(
205+
"--no-validate",
206+
action="store_const",
207+
const=False,
208+
dest="validate",
209+
help="do not validate that the rendered HTML is consistent",
210+
)
200211
version_str = f"mdformat {mdformat.__version__}"
201212
plugin_version_str = get_plugin_version_str(
202213
{**parser_extension_dists, **codeformatter_dists}

src/mdformat/_conf.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"wrap": "keep",
1111
"number": False,
1212
"end_of_line": "lf",
13+
"validate": True,
1314
"exclude": [],
1415
"plugin": {},
1516
"extensions": None,
@@ -59,6 +60,9 @@ def _validate_values(opts: Mapping, conf_path: Path) -> None: # noqa: C901
5960
if "end_of_line" in opts:
6061
if opts["end_of_line"] not in {"crlf", "lf", "keep"}:
6162
raise InvalidConfError(f"Invalid 'end_of_line' value in {conf_path}")
63+
if "validate" in opts:
64+
if not isinstance(opts["validate"], bool):
65+
raise InvalidConfError(f"Invalid 'validate' value in {conf_path}")
6266
if "number" in opts:
6367
if not isinstance(opts["number"], bool):
6468
raise InvalidConfError(f"Invalid 'number' value in {conf_path}")

tests/test_cli.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,19 @@ def test_eol__check_keep_crlf(tmp_path):
345345
assert run((str(file_path), "--check", "--end-of-line=keep")) == 1
346346

347347

348+
def test_cli_no_validate(tmp_path):
349+
file_path = tmp_path / "test.md"
350+
content = "1. ordered"
351+
file_path.write_text(content)
352+
353+
with patch("mdformat.renderer._context.get_list_marker_type", return_value="?"):
354+
assert run((str(file_path),)) == 1
355+
assert file_path.read_text() == content
356+
357+
assert run((str(file_path), "--no-validate")) == 0
358+
assert file_path.read_text() == "1? ordered\n"
359+
360+
348361
def test_get_plugin_info_str():
349362
info = get_plugin_info_str(
350363
{"mdformat-tables": ("0.1.0", ["tables"])},

tests/test_config_file.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ def test_invalid_toml(tmp_path, capsys):
6464
[
6565
("wrap", "wrap = -3"),
6666
("end_of_line", "end_of_line = 'lol'"),
67+
("validate", "validate = 'off'"),
6768
("number", "number = 0"),
6869
("exclude", "exclude = '**'"),
6970
("exclude", "exclude = ['1',3]"),
@@ -149,3 +150,22 @@ def test_empty_exclude(tmp_path, capsys):
149150

150151
assert run((str(tmp_path),)) == 0
151152
assert file1_path.read_text() == FORMATTED_MARKDOWN
153+
154+
155+
def test_conf_no_validate(tmp_path):
156+
file_path = tmp_path / "file.md"
157+
content = "1. ordered"
158+
file_path.write_text(content)
159+
160+
with mock.patch(
161+
"mdformat.renderer._context.get_list_marker_type",
162+
return_value="?",
163+
):
164+
assert run_with_clear_cache((str(file_path),)) == 1
165+
assert file_path.read_text() == content
166+
167+
config_path = tmp_path / ".mdformat.toml"
168+
config_path.write_text("validate = false")
169+
170+
assert run_with_clear_cache((str(file_path),)) == 0
171+
assert file_path.read_text() == "1? ordered\n"

0 commit comments

Comments
 (0)