Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default --no-markdown-linebreak-ext for trailing-whitespace #324

Merged
merged 1 commit into from
Oct 13, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ Add this to your `.pre-commit-config.yaml`
- `requirements-txt-fixer` - Sorts entries in requirements.txt and removes incorrect entry for `pkg-resources==0.0.0`
- `sort-simple-yaml` - Sorts simple YAML files which consist only of top-level keys, preserving comments and blocks.
- `trailing-whitespace` - Trims trailing whitespace.
- Markdown linebreak trailing spaces preserved for `.md` and`.markdown`;
use `args: ['--markdown-linebreak-ext=txt,text']` to add other extensions,
`args: ['--markdown-linebreak-ext=*']` to preserve them for all files,
or `args: ['--no-markdown-linebreak-ext']` to disable and always trim.
- To preserve Markdown [hard linebreaks](https://github.github.com/gfm/#hard-line-break)
use `args: [--markdown-linebreak-ext=md]` (or other extensions used
by your markdownfiles). If for some reason you want to treat all files
as markdown, use `--markdown-linebreak-ext=*`.

### As a standalone package

Expand Down
21 changes: 11 additions & 10 deletions pre_commit_hooks/trailing_whitespace_fixer.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,24 +35,25 @@ def main(argv=None):
parser = argparse.ArgumentParser()
parser.add_argument(
'--no-markdown-linebreak-ext',
action='store_const',
const=[],
default=argparse.SUPPRESS,
dest='markdown_linebreak_ext',
help='Do not preserve linebreak spaces in Markdown',
action='store_true',
help=argparse.SUPPRESS,
)
parser.add_argument(
'--markdown-linebreak-ext',
action='append',
const='',
default=['md,markdown'],
default=[],
metavar='*|EXT[,EXT,...]',
nargs='?',
help='Markdown extensions (or *) for linebreak spaces',
help=(
'Markdown extensions (or *) to not strip linebreak spaces. '
'default: %(default)s'
),
)
parser.add_argument('filenames', nargs='*', help='Filenames to fix')
args = parser.parse_args(argv)

if args.no_markdown_linebreak_ext:
print('--no-markdown-linebreak-ext now does nothing!')

md_args = args.markdown_linebreak_ext
if '' in md_args:
parser.error('--markdown-linebreak-ext requires a non-empty argument')
Expand All @@ -66,7 +67,7 @@ def main(argv=None):
for ext in md_exts:
if any(c in ext[1:] for c in r'./\:'):
parser.error(
"bad --markdown-linebreak-ext extension '{}' (has . / \\ :)\n"
"bad --markdown-linebreak-ext extension {!r} (has . / \\ :)\n"
" (probably filename; use '--markdown-linebreak-ext=EXT')"
.format(ext),
)
Expand Down
100 changes: 25 additions & 75 deletions tests/trailing_whitespace_fixer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
),
)
def test_fixes_trailing_whitespace(input_s, expected, tmpdir):
path = tmpdir.join('file.txt')
path = tmpdir.join('file.md')
path.write(input_s)
assert main((path.strpath,)) == 1
assert path.read() == expected
Expand All @@ -36,89 +36,39 @@ def test_ok_with_dos_line_endings(tmpdir):
assert ret == 0


def test_markdown_ok(tmpdir):
filename = tmpdir.join('foo.md')
filename.write_binary(b'foo \n')
ret = main((filename.strpath,))
assert filename.read_binary() == b'foo \n'
assert ret == 0


# filename, expected input, expected output
MD_TESTS_1 = (
('foo.md', 'foo \nbar \n ', 'foo \nbar\n'),
('bar.Markdown', 'bar \nbaz\t\n\t\n', 'bar \nbaz\n\n'),
('.md', 'baz \nquux \t\n\t\n', 'baz\nquux\n\n'),
('txt', 'foo \nbaz \n\t\n', 'foo\nbaz\n\n'),
)


@pytest.mark.parametrize(('filename', 'input_s', 'output'), MD_TESTS_1)
def test_fixes_trailing_markdown_whitespace(filename, input_s, output, tmpdir):
path = tmpdir.join(filename)
path.write(input_s)
ret = main([path.strpath])
@pytest.mark.parametrize('ext', ('md', 'Md', '.md', '*'))
def test_fixes_markdown_files(tmpdir, ext):
path = tmpdir.join('test.md')
path.write(
'foo \n' # leaves alone
'bar \n' # less than two so it is removed
'baz \n' # more than two so it becomes two spaces
'\t\n' # trailing tabs are stripped anyway
'\n ', # whitespace at the end of the file is removed
)
ret = main((path.strpath, '--markdown-linebreak-ext={}'.format(ext)))
assert ret == 1
assert path.read() == output
assert path.read() == (
'foo \n'
'bar\n'
'baz \n'
'\n'
'\n'
)


# filename, expected input, expected output
MD_TESTS_2 = (
('foo.txt', 'foo \nbar \n \n', 'foo \nbar\n\n'),
('bar.Markdown', 'bar \nbaz\t\n\t\n', 'bar \nbaz\n\n'),
('bar.MD', 'bar \nbaz\t \n\t\n', 'bar \nbaz \n\n'),
('.txt', 'baz \nquux \t\n\t\n', 'baz\nquux\n\n'),
('txt', 'foo \nbaz \n\t\n', 'foo\nbaz\n\n'),
)


@pytest.mark.parametrize(('filename', 'input_s', 'output'), MD_TESTS_2)
def test_markdown_linebreak_ext_opt(filename, input_s, output, tmpdir):
path = tmpdir.join(filename)
path.write(input_s)
ret = main(('--markdown-linebreak-ext=TxT', path.strpath))
assert ret == 1
assert path.read() == output


# filename, expected input, expected output
MD_TESTS_3 = (
('foo.baz', 'foo \nbar \n ', 'foo \nbar\n'),
('bar', 'bar \nbaz\t\n\t\n', 'bar \nbaz\n\n'),
)


@pytest.mark.parametrize(('filename', 'input_s', 'output'), MD_TESTS_3)
def test_markdown_linebreak_ext_opt_all(filename, input_s, output, tmpdir):
path = tmpdir.join(filename)
path.write(input_s)
# need to make sure filename is not treated as argument to option
ret = main(('--markdown-linebreak-ext=*', path.strpath))
assert ret == 1
assert path.read() == output


@pytest.mark.parametrize(('arg'), ('--', 'a.b', 'a/b'))
@pytest.mark.parametrize('arg', ('--', 'a.b', 'a/b', ''))
def test_markdown_linebreak_ext_badopt(arg):
with pytest.raises(SystemExit) as excinfo:
main(['--markdown-linebreak-ext', arg])
assert excinfo.value.code == 2


# filename, expected input, expected output
MD_TESTS_4 = (
('bar.md', 'bar \nbaz\t \n\t\n', 'bar\nbaz\n\n'),
('bar.markdown', 'baz \nquux \n', 'baz\nquux\n'),
)


@pytest.mark.parametrize(('filename', 'input_s', 'output'), MD_TESTS_4)
def test_no_markdown_linebreak_ext_opt(filename, input_s, output, tmpdir):
path = tmpdir.join(filename)
path.write(input_s)
ret = main(['--no-markdown-linebreak-ext', path.strpath])
assert ret == 1
assert path.read() == output
def test_prints_warning_with_no_markdown_ext(capsys, tmpdir):
f = tmpdir.join('f').ensure()
assert main((f.strpath, '--no-markdown-linebreak-ext')) == 0
out, _ = capsys.readouterr()
assert out == '--no-markdown-linebreak-ext now does nothing!\n'


def test_preserve_non_utf8_file(tmpdir):
Expand Down