Skip to content

Commit f2915d1

Browse files
committed
Add check for illegal Widnows names
Fixes #589
1 parent b73acb1 commit f2915d1

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

.pre-commit-hooks.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@
4040
language: python
4141
types: [text, executable]
4242
stages: [commit, push, manual]
43+
- id: check-illegal-windows-names
44+
name: check illegal windows names
45+
entry: Illegal windows filenames detected
46+
language: fail
47+
files: '(?i)(^|/)(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.|/|$)'
4348
- id: check-json
4449
name: check json
4550
description: checks json files for parseable syntax.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ Checks for a common error of placing code before the docstring.
5151
#### `check-executables-have-shebangs`
5252
Checks that non-binary executables have a proper shebang.
5353

54+
#### `check-illegal-windows-names`
55+
Check for files that cannot be created on Windows.
56+
5457
#### `check-json`
5558
Attempts to load all json files to verify syntax.
5659

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from __future__ import annotations
2+
3+
import re
4+
from pathlib import Path
5+
from subprocess import check_output
6+
from typing import Any
7+
8+
import pytest
9+
import ruamel.yaml
10+
11+
yaml = ruamel.yaml.YAML(typ='safe')
12+
13+
14+
@pytest.fixture(scope='module')
15+
def hook_definition():
16+
project_root = Path(
17+
check_output(
18+
['git', 'rev-parse', '--show-toplevel'],
19+
text=True,
20+
).strip(),
21+
)
22+
hook_file_path = project_root / '.pre-commit-hooks.yaml'
23+
hook_defs = yaml.load(hook_file_path)
24+
hits = [
25+
hook_def
26+
for hook_def in hook_defs
27+
if hook_def['id'] == 'check-illegal-windows-names'
28+
]
29+
assert len(hits) == 1
30+
yield hits[0]
31+
32+
33+
@pytest.mark.parametrize(
34+
('filename', 'legal'),
35+
[
36+
pytest.param('README.md', True, id='standard file'),
37+
pytest.param('aux.txt', False, id='with ext'),
38+
pytest.param('aux', False, id='without ext'),
39+
pytest.param('AuX.tXt', False, id='capitals'),
40+
pytest.param('foo.aux', True, id='as ext'),
41+
pytest.param('com7.dat', False, id='com with digit'),
42+
pytest.param('com.dat', True, id='com without digit'),
43+
],
44+
)
45+
def test_check_illegal_windows_names(
46+
filename: str,
47+
legal: bool,
48+
hook_definition: dict[str, Any],
49+
) -> None:
50+
match = re.search(hook_definition['files'], filename)
51+
assert (match is None) == legal

0 commit comments

Comments
 (0)