Skip to content
Open
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
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ norminette -d
norminette -dd
```

### Ignore file

You can create a `.normignore` file that works exactly like `.gitignore` but for norminette.

You can disable this feature by using the `--no-normignore` flag.

## Docker usage

```
Expand Down
16 changes: 16 additions & 0 deletions norminette/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import platform
import subprocess
import sys
import os
from importlib.metadata import version

from norminette.context import Context
Expand All @@ -13,6 +14,7 @@
from norminette.lexer import Lexer
from norminette.registry import Registry
from norminette.tools.colors import colors
from norminette.tools.normignore import NormIgnoreSpec

version_text = f"norminette {version('norminette')}"
version_text += f", Python {platform.python_version()}"
Expand Down Expand Up @@ -66,6 +68,11 @@ def main():
action="store_true",
help="Parse only source files not match to .gitignore",
)
parser.add_argument(
"--no-normignore",
action="store_true",
help="Ignore .normignore file",
)
parser.add_argument(
"-f",
"--format",
Expand Down Expand Up @@ -130,6 +137,15 @@ def main():
)
sys.exit(0)
files = tmp_targets

if not args.no_normignore:
spec = NormIgnoreSpec(os.getcwd())
tmp_targets = []
for target in files:
if not spec.is_ignored(target.path):
tmp_targets.append(target)
files = tmp_targets

for file in files:
try:
lexer = Lexer(file)
Expand Down
28 changes: 28 additions & 0 deletions norminette/tools/normignore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os
import pathspec


class NormIgnoreSpec:
def __init__(self, cwd):
self.spec = self._load(cwd)
self.filepath = os.path.join(os.getcwd(), ".normignore")

def _load(self, cwd):
try:
with open(os.path.join(cwd, ".normignore")) as f:
lines = f.read().splitlines()
except FileNotFoundError:
return None
except PermissionError:
print("Warning: unable to access normignore file")
return None

return pathspec.PathSpec.from_lines(
"gitignore",
lines
)

def is_ignored(self, target):
if not self.spec:
return False
return self.spec.match_file(target)
22 changes: 20 additions & 2 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ commands =
[tool.poetry.dependencies]
python = ">=3.10"
argparse = "^1.4.0"
pathspec = ">=1.0.4"

[tool.poetry.group.dev.dependencies]
pytest = "^7.3.2"
Expand Down
54 changes: 54 additions & 0 deletions tests/test_normignore.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from norminette.tools.normignore import NormIgnoreSpec
import pytest


def test_single_file(tmp_path):
normignore_file = tmp_path / ".normignore"
normignore_file.write_text("ignored.c\n")

file1 = tmp_path / "ignored.c"
file2 = tmp_path / "not_ignored.c"
file1.write_text("")
file2.write_text("")

ignore = NormIgnoreSpec(tmp_path)

files = [file1, file2]
filtered = [f for f in files if not ignore.is_ignored(f)]
assert file2 in filtered
assert file1 not in filtered


def test_directory(tmp_path):
normignore_file = tmp_path / ".normignore"
normignore_file.write_text("build/\n")

(tmp_path / "build").mkdir()
file1 = tmp_path / "build" / "file.c"
file1.write_text("")
file2 = tmp_path / "main.c"
file2.write_text("")

ignore = NormIgnoreSpec(tmp_path)
files = [file1, file2]
filtered = [f for f in files if not ignore.is_ignored(f)]

assert file2 in filtered
assert file1 not in filtered


@pytest.mark.parametrize("pattern, filename, ignored", [
("*.c", "main.c", True),
("*.c", "readme.md", False),
("build/", "build/file.c", True),
("build/", "src/file.c", False),
])
def test_multiple_patterns(tmp_path, pattern, filename, ignored):
(tmp_path / ".normignore").write_text(pattern + "\n")
file = tmp_path / filename
file.parent.mkdir(parents=True, exist_ok=True)
file.write_text("")

ignore = NormIgnoreSpec(tmp_path)
result = ignore.is_ignored(file)
assert result == ignored