From 707407dd49bf556dfaaf7553fe0c16f8408d1acc Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Sat, 19 Oct 2019 12:29:46 -0700 Subject: [PATCH] Normalize paths on windows to forward slashes --- pre_commit/commands/run.py | 6 ++++++ tests/commands/run_test.py | 20 +++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/pre_commit/commands/run.py b/pre_commit/commands/run.py index dd30c7e5..0b1f7b7e 100644 --- a/pre_commit/commands/run.py +++ b/pre_commit/commands/run.py @@ -34,6 +34,12 @@ def filter_by_include_exclude(names, include, exclude): class Classifier(object): def __init__(self, filenames): + # on windows we normalize all filenames to use forward slashes + # this makes it easier to filter using the `files:` regex + # this also makes improperly quoted shell-based hooks work better + # see #1173 + if os.altsep == '/' and os.sep == '\\': + filenames = (f.replace(os.sep, os.altsep) for f in filenames) self.filenames = [f for f in filenames if os.path.lexists(f)] self._types_cache = {} diff --git a/tests/commands/run_test.py b/tests/commands/run_test.py index f6d5c93f..4221134b 100644 --- a/tests/commands/run_test.py +++ b/tests/commands/run_test.py @@ -7,6 +7,7 @@ import pipes import subprocess import sys +import mock import pytest import pre_commit.constants as C @@ -782,7 +783,7 @@ def test_files_running_subdir(repo_with_passing_hook, tempdir_factory): '--files', 'foo.py', tempdir_factory=tempdir_factory, ) - assert 'subdir/foo.py'.replace('/', os.sep) in stdout + assert 'subdir/foo.py' in stdout @pytest.mark.parametrize( @@ -826,6 +827,23 @@ def test_classifier_removes_dne(): assert classifier.filenames == [] +def test_classifier_normalizes_filenames_on_windows_to_forward_slashes(tmpdir): + with tmpdir.as_cwd(): + tmpdir.join('a/b/c').ensure() + with mock.patch.object(os, 'altsep', '/'): + with mock.patch.object(os, 'sep', '\\'): + classifier = Classifier((r'a\b\c',)) + assert classifier.filenames == ['a/b/c'] + + +def test_classifier_does_not_normalize_backslashes_non_windows(tmpdir): + with mock.patch.object(os.path, 'lexists', return_value=True): + with mock.patch.object(os, 'altsep', None): + with mock.patch.object(os, 'sep', '/'): + classifier = Classifier((r'a/b\c',)) + assert classifier.filenames == [r'a/b\c'] + + @pytest.fixture def some_filenames(): return (