Skip to content

Commit

Permalink
Present a more user-friendly error if .gitignore is invalid
Browse files Browse the repository at this point in the history
Fixes #2359
  • Loading branch information
nipunn1313 committed Aug 7, 2021
1 parent b1d0601 commit b4402ea
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Expand Up @@ -6,6 +6,7 @@

- Add support for formatting Jupyter Notebook files (#2357)
- Move from `appdirs` dependency to `platformdirs` (#2375)
- Present a more user-friendly error if .gitignore is invalid (#2414)

## 21.7b0

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -77,7 +77,7 @@ def get_long_description() -> str:
"tomli>=0.2.6,<2.0.0",
"typed-ast>=1.4.2; python_version < '3.8'",
"regex>=2020.1.8",
"pathspec>=0.8.1, <1",
"pathspec>=0.9.0, <1",
"dataclasses>=0.6; python_version < '3.7'",
"typing_extensions>=3.10.0.0; python_version < '3.10'",
"mypy_extensions>=0.4.3",
Expand Down
2 changes: 2 additions & 0 deletions src/black/__init__.py
Expand Up @@ -495,6 +495,8 @@ def get_sources(
if exclude is None:
exclude = re_compile_maybe_verbose(DEFAULT_EXCLUDES)
gitignore = get_gitignore(root)
if gitignore is None:
ctx.exit(1)
else:
gitignore = None

Expand Down
7 changes: 6 additions & 1 deletion src/black/files.py
Expand Up @@ -18,6 +18,7 @@
)

from pathspec import PathSpec
from pathspec.patterns.gitwildmatch import GitWildMatchPatternError
import tomli

from black.output import err
Expand Down Expand Up @@ -122,7 +123,11 @@ def get_gitignore(root: Path) -> PathSpec:
if gitignore.is_file():
with gitignore.open(encoding="utf-8") as gf:
lines = gf.readlines()
return PathSpec.from_lines("gitwildmatch", lines)
try:
return PathSpec.from_lines("gitwildmatch", lines)
except GitWildMatchPatternError as e:
err(f"Could not parse {gitignore}: {e}")
return None


def normalize_path_maybe_ignore(
Expand Down
1 change: 1 addition & 0 deletions tests/data/invalid_gitignore_tests/.gitignore
@@ -0,0 +1 @@
!
Empty file.
1 change: 1 addition & 0 deletions tests/data/invalid_gitignore_tests/pyproject.toml
@@ -0,0 +1 @@
# Empty configuration file; used in tests to avoid interference from Black's own config.
12 changes: 12 additions & 0 deletions tests/test_black.py
Expand Up @@ -1727,6 +1727,18 @@ def test_nested_gitignore(self) -> None:
)
self.assertEqual(sorted(expected), sorted(sources))

def test_invalid_gitignore(self) -> None:
path = THIS_DIR / "data" / "invalid_gitignore_tests"
empty_config = THIS_DIR / "data" / "invalid_gitignore_tests" / "pyproject.toml"
result = BlackRunner().invoke(
black.main, ["--verbose", "--config", str(empty_config), str(path)]
)
assert result.exit_code == 1
assert result.stderr_bytes is not None

gitignore = path / ".gitignore"
assert f"Could not parse {gitignore}" in result.stderr_bytes.decode()

def test_empty_include(self) -> None:
path = THIS_DIR / "data" / "include_exclude_tests"
report = black.Report()
Expand Down

0 comments on commit b4402ea

Please sign in to comment.