undersort 0.1.4__tar.gz → 0.1.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {undersort-0.1.4 → undersort-0.1.5}/PKG-INFO +12 -2
- {undersort-0.1.4 → undersort-0.1.5}/README.md +11 -1
- {undersort-0.1.4 → undersort-0.1.5}/pyproject.toml +5 -1
- {undersort-0.1.4 → undersort-0.1.5}/tests/test_config.py +43 -7
- {undersort-0.1.4 → undersort-0.1.5}/tests/test_main.py +72 -0
- {undersort-0.1.4 → undersort-0.1.5}/undersort/config.py +9 -1
- {undersort-0.1.4 → undersort-0.1.5}/undersort/main.py +52 -3
- {undersort-0.1.4 → undersort-0.1.5}/uv.lock +1 -1
- {undersort-0.1.4 → undersort-0.1.5}/.github/workflows/ci.yml +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/.gitignore +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/.pre-commit-config.yaml +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/.pre-commit-hooks.yaml +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/.python-version +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/.vscode/settings.json +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/LICENSE +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/Makefile +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/tests/__init__.py +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/tests/test_nosort.py +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/tests/test_sorter.py +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/undersort/__init__.py +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/undersort/logger.py +0 -0
- {undersort-0.1.4 → undersort-0.1.5}/undersort/sorter.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: undersort
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: A tool to sort class methods by visibility (public, protected, private)
|
|
5
5
|
Project-URL: Homepage, https://github.com/kivicode/undersort
|
|
6
6
|
Project-URL: Repository, https://github.com/kivicode/undersort
|
|
@@ -68,6 +68,10 @@ order = ["public", "protected", "private"]
|
|
|
68
68
|
# Options: "class" (classmethod), "static" (staticmethod), "instance" (regular methods)
|
|
69
69
|
# Default: ["instance", "class", "static"]
|
|
70
70
|
method_type_order = ["instance", "class", "static"]
|
|
71
|
+
|
|
72
|
+
# Exclude files/directories matching these patterns (optional)
|
|
73
|
+
# Patterns support glob syntax (e.g., "tests/*", "migrations/*.py", "**/generated/*")
|
|
74
|
+
# exclude = ["tests/*", "migrations/*.py"]
|
|
71
75
|
```
|
|
72
76
|
|
|
73
77
|
### Method Visibility Rules
|
|
@@ -185,9 +189,15 @@ undersort --diff example.py
|
|
|
185
189
|
|
|
186
190
|
# Combine flags
|
|
187
191
|
undersort --check --diff src/
|
|
192
|
+
|
|
193
|
+
# Exclude specific files or directories
|
|
194
|
+
undersort --exclude "tests/*" --exclude "migrations/*.py" src/
|
|
195
|
+
|
|
196
|
+
# Multiple exclude patterns (can be combined with config file patterns)
|
|
197
|
+
undersort --exclude "test_*.py" --exclude "*/legacy/*" .
|
|
188
198
|
```
|
|
189
199
|
|
|
190
|
-
**Note**: By default, undersort excludes all dot-prefixed directories (e.g., `.venv`, `.git`, `.pytest_cache`) and common build directories (`venv`, `__pycache__`, `node_modules`) when scanning directories recursively.
|
|
200
|
+
**Note**: By default, undersort excludes all dot-prefixed directories (e.g., `.venv`, `.git`, `.pytest_cache`) and common build directories (`venv`, `__pycache__`, `node_modules`) when scanning directories recursively. You can add custom exclusions via CLI flags or the config file.
|
|
191
201
|
|
|
192
202
|
### Pre-commit Integration
|
|
193
203
|
|
|
@@ -41,6 +41,10 @@ order = ["public", "protected", "private"]
|
|
|
41
41
|
# Options: "class" (classmethod), "static" (staticmethod), "instance" (regular methods)
|
|
42
42
|
# Default: ["instance", "class", "static"]
|
|
43
43
|
method_type_order = ["instance", "class", "static"]
|
|
44
|
+
|
|
45
|
+
# Exclude files/directories matching these patterns (optional)
|
|
46
|
+
# Patterns support glob syntax (e.g., "tests/*", "migrations/*.py", "**/generated/*")
|
|
47
|
+
# exclude = ["tests/*", "migrations/*.py"]
|
|
44
48
|
```
|
|
45
49
|
|
|
46
50
|
### Method Visibility Rules
|
|
@@ -158,9 +162,15 @@ undersort --diff example.py
|
|
|
158
162
|
|
|
159
163
|
# Combine flags
|
|
160
164
|
undersort --check --diff src/
|
|
165
|
+
|
|
166
|
+
# Exclude specific files or directories
|
|
167
|
+
undersort --exclude "tests/*" --exclude "migrations/*.py" src/
|
|
168
|
+
|
|
169
|
+
# Multiple exclude patterns (can be combined with config file patterns)
|
|
170
|
+
undersort --exclude "test_*.py" --exclude "*/legacy/*" .
|
|
161
171
|
```
|
|
162
172
|
|
|
163
|
-
**Note**: By default, undersort excludes all dot-prefixed directories (e.g., `.venv`, `.git`, `.pytest_cache`) and common build directories (`venv`, `__pycache__`, `node_modules`) when scanning directories recursively.
|
|
173
|
+
**Note**: By default, undersort excludes all dot-prefixed directories (e.g., `.venv`, `.git`, `.pytest_cache`) and common build directories (`venv`, `__pycache__`, `node_modules`) when scanning directories recursively. You can add custom exclusions via CLI flags or the config file.
|
|
164
174
|
|
|
165
175
|
### Pre-commit Integration
|
|
166
176
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "undersort"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.5"
|
|
8
8
|
description = "A tool to sort class methods by visibility (public, protected, private)"
|
|
9
9
|
authors = [{ name = "KiviCode", email = "kivicode.dev@gmail.com" }]
|
|
10
10
|
readme = "README.md"
|
|
@@ -50,6 +50,10 @@ order = ["public", "protected", "private"]
|
|
|
50
50
|
# Default order if not specified: ["instance", "class", "static"]
|
|
51
51
|
method_type_order = ["instance", "class", "static"]
|
|
52
52
|
|
|
53
|
+
# Exclude files/directories matching these patterns (optional)
|
|
54
|
+
# Patterns support glob syntax (e.g., "tests/*", "migrations/*.py", "**/generated/*")
|
|
55
|
+
# exclude = ["tests/*", "migrations/*.py"]
|
|
56
|
+
|
|
53
57
|
[tool.ruff]
|
|
54
58
|
unsafe-fixes = true
|
|
55
59
|
exclude = [".venv"]
|
|
@@ -14,7 +14,7 @@ class TestConfigLoading:
|
|
|
14
14
|
"""Test that default config is returned when no pyproject.toml exists."""
|
|
15
15
|
monkeypatch.chdir(tmp_path)
|
|
16
16
|
config = load_config()
|
|
17
|
-
assert config == {"order": ["public", "protected", "private"], "method_type_order": None}
|
|
17
|
+
assert config == {"order": ["public", "protected", "private"], "method_type_order": None, "exclude": None}
|
|
18
18
|
|
|
19
19
|
def test_load_custom_order(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
20
20
|
"""Test loading custom order from pyproject.toml."""
|
|
@@ -27,7 +27,7 @@ order = ["private", "protected", "public"]
|
|
|
27
27
|
|
|
28
28
|
monkeypatch.chdir(tmp_path)
|
|
29
29
|
config = load_config()
|
|
30
|
-
assert config == {"order": ["private", "protected", "public"], "method_type_order": None}
|
|
30
|
+
assert config == {"order": ["private", "protected", "public"], "method_type_order": None, "exclude": None}
|
|
31
31
|
|
|
32
32
|
def test_invalid_order_values(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
33
33
|
"""Test that invalid order values fall back to default."""
|
|
@@ -40,7 +40,7 @@ order = ["public", "invalid", "private"]
|
|
|
40
40
|
|
|
41
41
|
monkeypatch.chdir(tmp_path)
|
|
42
42
|
config = load_config()
|
|
43
|
-
assert config == {"order": ["public", "protected", "private"], "method_type_order": None}
|
|
43
|
+
assert config == {"order": ["public", "protected", "private"], "method_type_order": None, "exclude": None}
|
|
44
44
|
|
|
45
45
|
def test_missing_order_key(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
46
46
|
"""Test that missing order key returns default."""
|
|
@@ -53,7 +53,7 @@ some_other_key = "value"
|
|
|
53
53
|
|
|
54
54
|
monkeypatch.chdir(tmp_path)
|
|
55
55
|
config = load_config()
|
|
56
|
-
assert config == {"order": ["public", "protected", "private"], "method_type_order": None}
|
|
56
|
+
assert config == {"order": ["public", "protected", "private"], "method_type_order": None, "exclude": None}
|
|
57
57
|
|
|
58
58
|
def test_missing_tool_section(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
59
59
|
"""Test that missing tool.undersort section returns default."""
|
|
@@ -66,7 +66,7 @@ name = "test"
|
|
|
66
66
|
|
|
67
67
|
monkeypatch.chdir(tmp_path)
|
|
68
68
|
config = load_config()
|
|
69
|
-
assert config == {"order": ["public", "protected", "private"], "method_type_order": None}
|
|
69
|
+
assert config == {"order": ["public", "protected", "private"], "method_type_order": None, "exclude": None}
|
|
70
70
|
|
|
71
71
|
def test_find_pyproject_in_parent(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
72
72
|
"""Test that pyproject.toml is found in parent directories."""
|
|
@@ -84,7 +84,7 @@ order = ["private", "public", "protected"]
|
|
|
84
84
|
monkeypatch.chdir(subdir)
|
|
85
85
|
|
|
86
86
|
config = load_config()
|
|
87
|
-
assert config == {"order": ["private", "public", "protected"], "method_type_order": None}
|
|
87
|
+
assert config == {"order": ["private", "public", "protected"], "method_type_order": None, "exclude": None}
|
|
88
88
|
|
|
89
89
|
def test_corrupted_toml(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
90
90
|
"""Test that corrupted TOML file falls back to default."""
|
|
@@ -97,7 +97,7 @@ order = ["public" # Invalid TOML
|
|
|
97
97
|
|
|
98
98
|
monkeypatch.chdir(tmp_path)
|
|
99
99
|
config = load_config()
|
|
100
|
-
assert config == {"order": ["public", "protected", "private"], "method_type_order": None}
|
|
100
|
+
assert config == {"order": ["public", "protected", "private"], "method_type_order": None, "exclude": None}
|
|
101
101
|
|
|
102
102
|
def test_find_pyproject_toml_not_found(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
103
103
|
"""Test _find_pyproject_toml returns None when not found."""
|
|
@@ -113,3 +113,39 @@ order = ["public" # Invalid TOML
|
|
|
113
113
|
monkeypatch.chdir(tmp_path)
|
|
114
114
|
result = _find_pyproject_toml()
|
|
115
115
|
assert result == pyproject_path
|
|
116
|
+
|
|
117
|
+
def test_load_exclude_patterns(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
118
|
+
"""Test loading exclude patterns from pyproject.toml."""
|
|
119
|
+
pyproject_content = """
|
|
120
|
+
[tool.undersort]
|
|
121
|
+
order = ["public", "protected", "private"]
|
|
122
|
+
exclude = ["tests/*", "migrations/*.py"]
|
|
123
|
+
"""
|
|
124
|
+
pyproject_path = tmp_path / "pyproject.toml"
|
|
125
|
+
pyproject_path.write_text(pyproject_content)
|
|
126
|
+
|
|
127
|
+
monkeypatch.chdir(tmp_path)
|
|
128
|
+
config = load_config()
|
|
129
|
+
assert config == {
|
|
130
|
+
"order": ["public", "protected", "private"],
|
|
131
|
+
"method_type_order": None,
|
|
132
|
+
"exclude": ["tests/*", "migrations/*.py"],
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
def test_invalid_exclude_type(self, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
136
|
+
"""Test that invalid exclude type falls back to None."""
|
|
137
|
+
pyproject_content = """
|
|
138
|
+
[tool.undersort]
|
|
139
|
+
order = ["public", "protected", "private"]
|
|
140
|
+
exclude = "invalid"
|
|
141
|
+
"""
|
|
142
|
+
pyproject_path = tmp_path / "pyproject.toml"
|
|
143
|
+
pyproject_path.write_text(pyproject_content)
|
|
144
|
+
|
|
145
|
+
monkeypatch.chdir(tmp_path)
|
|
146
|
+
config = load_config()
|
|
147
|
+
assert config == {
|
|
148
|
+
"order": ["public", "protected", "private"],
|
|
149
|
+
"method_type_order": None,
|
|
150
|
+
"exclude": None,
|
|
151
|
+
}
|
|
@@ -107,3 +107,75 @@ class TestCollectPythonFiles:
|
|
|
107
107
|
assert result[0].name == "a.py"
|
|
108
108
|
assert result[1].name == "b.py"
|
|
109
109
|
assert result[2].name == "c.py"
|
|
110
|
+
|
|
111
|
+
def test_exclude_patterns_simple(self, tmp_path: Path) -> None:
|
|
112
|
+
"""Test excluding files by simple pattern."""
|
|
113
|
+
(tmp_path / "main.py").write_text("# main")
|
|
114
|
+
(tmp_path / "test.py").write_text("# test")
|
|
115
|
+
(tmp_path / "setup.py").write_text("# setup")
|
|
116
|
+
|
|
117
|
+
result = collect_python_files(tmp_path, recursive=False, exclude_patterns=["test.py"])
|
|
118
|
+
|
|
119
|
+
assert len(result) == 2
|
|
120
|
+
assert any(f.name == "main.py" for f in result)
|
|
121
|
+
assert any(f.name == "setup.py" for f in result)
|
|
122
|
+
assert not any(f.name == "test.py" for f in result)
|
|
123
|
+
|
|
124
|
+
def test_exclude_patterns_wildcard(self, tmp_path: Path) -> None:
|
|
125
|
+
"""Test excluding files by wildcard pattern."""
|
|
126
|
+
(tmp_path / "main.py").write_text("# main")
|
|
127
|
+
(tmp_path / "test_one.py").write_text("# test")
|
|
128
|
+
(tmp_path / "test_two.py").write_text("# test")
|
|
129
|
+
|
|
130
|
+
result = collect_python_files(tmp_path, recursive=False, exclude_patterns=["test_*.py"])
|
|
131
|
+
|
|
132
|
+
assert len(result) == 1
|
|
133
|
+
assert result[0].name == "main.py"
|
|
134
|
+
|
|
135
|
+
def test_exclude_patterns_directory(self, tmp_path: Path) -> None:
|
|
136
|
+
"""Test excluding entire directories."""
|
|
137
|
+
(tmp_path / "main.py").write_text("# main")
|
|
138
|
+
(tmp_path / "tests").mkdir()
|
|
139
|
+
(tmp_path / "tests" / "test_one.py").write_text("# test")
|
|
140
|
+
(tmp_path / "tests" / "test_two.py").write_text("# test")
|
|
141
|
+
(tmp_path / "src").mkdir()
|
|
142
|
+
(tmp_path / "src" / "app.py").write_text("# app")
|
|
143
|
+
|
|
144
|
+
result = collect_python_files(tmp_path, recursive=True, exclude_patterns=["tests/*"])
|
|
145
|
+
|
|
146
|
+
assert len(result) == 2
|
|
147
|
+
assert any(f.name == "main.py" for f in result)
|
|
148
|
+
assert any(f.name == "app.py" for f in result)
|
|
149
|
+
assert not any("test" in f.name for f in result)
|
|
150
|
+
|
|
151
|
+
def test_exclude_patterns_multiple(self, tmp_path: Path) -> None:
|
|
152
|
+
"""Test excluding with multiple patterns."""
|
|
153
|
+
(tmp_path / "main.py").write_text("# main")
|
|
154
|
+
(tmp_path / "test.py").write_text("# test")
|
|
155
|
+
(tmp_path / "migrations").mkdir()
|
|
156
|
+
(tmp_path / "migrations" / "001.py").write_text("# migration")
|
|
157
|
+
(tmp_path / "src").mkdir()
|
|
158
|
+
(tmp_path / "src" / "app.py").write_text("# app")
|
|
159
|
+
|
|
160
|
+
result = collect_python_files(tmp_path, recursive=True, exclude_patterns=["test.py", "migrations/*"])
|
|
161
|
+
|
|
162
|
+
assert len(result) == 2
|
|
163
|
+
assert any(f.name == "main.py" for f in result)
|
|
164
|
+
assert any(f.name == "app.py" for f in result)
|
|
165
|
+
assert not any(f.name == "test.py" for f in result)
|
|
166
|
+
assert not any("001.py" in str(f) for f in result)
|
|
167
|
+
|
|
168
|
+
def test_exclude_patterns_nested_directories(self, tmp_path: Path) -> None:
|
|
169
|
+
"""Test excluding nested directories."""
|
|
170
|
+
(tmp_path / "main.py").write_text("# main")
|
|
171
|
+
(tmp_path / "tests").mkdir()
|
|
172
|
+
(tmp_path / "tests" / "unit").mkdir()
|
|
173
|
+
(tmp_path / "tests" / "unit" / "test_one.py").write_text("# test")
|
|
174
|
+
(tmp_path / "src").mkdir()
|
|
175
|
+
(tmp_path / "src" / "app.py").write_text("# app")
|
|
176
|
+
|
|
177
|
+
result = collect_python_files(tmp_path, recursive=True, exclude_patterns=["tests/*"])
|
|
178
|
+
|
|
179
|
+
assert len(result) == 2
|
|
180
|
+
assert any(f.name == "main.py" for f in result)
|
|
181
|
+
assert any(f.name == "app.py" for f in result)
|
|
@@ -10,11 +10,12 @@ def load_config() -> dict[str, list[str] | None]:
|
|
|
10
10
|
"""Load configuration from pyproject.toml.
|
|
11
11
|
|
|
12
12
|
Returns:
|
|
13
|
-
Dictionary with 'order' and '
|
|
13
|
+
Dictionary with 'order', 'method_type_order', and 'exclude' keys.
|
|
14
14
|
"""
|
|
15
15
|
default_config: dict[str, list[str] | None] = {
|
|
16
16
|
"order": ["public", "protected", "private"],
|
|
17
17
|
"method_type_order": None,
|
|
18
|
+
"exclude": None,
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
pyproject_path = _find_pyproject_toml()
|
|
@@ -50,6 +51,13 @@ def load_config() -> dict[str, list[str] | None]:
|
|
|
50
51
|
else:
|
|
51
52
|
result["method_type_order"] = method_type_order
|
|
52
53
|
|
|
54
|
+
if "exclude" in config:
|
|
55
|
+
exclude = config["exclude"]
|
|
56
|
+
if isinstance(exclude, list):
|
|
57
|
+
result["exclude"] = exclude
|
|
58
|
+
else:
|
|
59
|
+
logger.warning(f"Invalid exclude value in {pyproject_path}. Must be a list.")
|
|
60
|
+
|
|
53
61
|
return result
|
|
54
62
|
|
|
55
63
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Main entry point for undersort CLI."""
|
|
2
2
|
|
|
3
3
|
import argparse
|
|
4
|
+
import fnmatch
|
|
4
5
|
import sys
|
|
5
6
|
from pathlib import Path
|
|
6
7
|
|
|
@@ -9,12 +10,13 @@ from undersort.config import load_config
|
|
|
9
10
|
from undersort.sorter import sort_file
|
|
10
11
|
|
|
11
12
|
|
|
12
|
-
def collect_python_files(path: Path, recursive: bool = True) -> list[Path]:
|
|
13
|
+
def collect_python_files(path: Path, recursive: bool = True, exclude_patterns: list[str] | None = None) -> list[Path]:
|
|
13
14
|
"""Collect Python files from a path (file or directory).
|
|
14
15
|
|
|
15
16
|
Args:
|
|
16
17
|
path: File or directory path
|
|
17
18
|
recursive: If True, recursively search directories
|
|
19
|
+
exclude_patterns: List of glob patterns to exclude (e.g., ["tests/*", "migrations/*.py"])
|
|
18
20
|
|
|
19
21
|
Returns:
|
|
20
22
|
List of Python file paths
|
|
@@ -37,12 +39,47 @@ def collect_python_files(path: Path, recursive: bool = True) -> list[Path]:
|
|
|
37
39
|
if not any(part in exclude_dirs or (part.startswith(".") and part != ".") for part in f.parts)
|
|
38
40
|
]
|
|
39
41
|
|
|
42
|
+
if exclude_patterns:
|
|
43
|
+
filtered_files = [f for f in filtered_files if not _matches_any_pattern(f, exclude_patterns)]
|
|
44
|
+
|
|
40
45
|
return sorted(filtered_files)
|
|
41
46
|
|
|
42
47
|
return []
|
|
43
48
|
|
|
44
49
|
|
|
45
|
-
def
|
|
50
|
+
def _matches_any_pattern(file_path: Path, patterns: list[str]) -> bool:
|
|
51
|
+
"""Check if a file matches any of the exclusion patterns.
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
file_path: Path to check
|
|
55
|
+
patterns: List of glob patterns
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
True if file matches any pattern, False otherwise
|
|
59
|
+
"""
|
|
60
|
+
path_str = str(file_path)
|
|
61
|
+
|
|
62
|
+
for pattern in patterns:
|
|
63
|
+
if fnmatch.fnmatch(path_str, pattern):
|
|
64
|
+
return True
|
|
65
|
+
|
|
66
|
+
if "/" not in pattern:
|
|
67
|
+
if fnmatch.fnmatch(file_path.name, pattern):
|
|
68
|
+
return True
|
|
69
|
+
continue
|
|
70
|
+
|
|
71
|
+
if fnmatch.fnmatch(path_str, f"*/{pattern}"):
|
|
72
|
+
return True
|
|
73
|
+
|
|
74
|
+
for part_idx in range(len(file_path.parts)):
|
|
75
|
+
subpath = str(Path(*file_path.parts[part_idx:]))
|
|
76
|
+
if fnmatch.fnmatch(subpath, pattern):
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def main() -> int: # noqa: PLR0912
|
|
46
83
|
"""Main entry point for undersort."""
|
|
47
84
|
parser = argparse.ArgumentParser(description="Sort class methods by visibility (public, protected, private)")
|
|
48
85
|
parser.add_argument(
|
|
@@ -68,18 +105,30 @@ def main() -> int:
|
|
|
68
105
|
default=True,
|
|
69
106
|
help="Don't recursively search directories",
|
|
70
107
|
)
|
|
108
|
+
parser.add_argument(
|
|
109
|
+
"--exclude",
|
|
110
|
+
action="append",
|
|
111
|
+
help="Exclude files/directories matching pattern (can be used multiple times)",
|
|
112
|
+
)
|
|
71
113
|
|
|
72
114
|
args = parser.parse_args()
|
|
73
115
|
|
|
74
116
|
config = load_config()
|
|
75
117
|
|
|
118
|
+
exclude_patterns: list[str] = []
|
|
119
|
+
config_exclude = config.get("exclude")
|
|
120
|
+
if config_exclude:
|
|
121
|
+
exclude_patterns.extend(config_exclude)
|
|
122
|
+
if args.exclude:
|
|
123
|
+
exclude_patterns.extend(args.exclude)
|
|
124
|
+
|
|
76
125
|
all_files: list[Path] = []
|
|
77
126
|
for path in args.paths:
|
|
78
127
|
if not path.exists():
|
|
79
128
|
logger.error(f"Path not found: {path}")
|
|
80
129
|
continue
|
|
81
130
|
|
|
82
|
-
python_files = collect_python_files(path, args.recursive)
|
|
131
|
+
python_files = collect_python_files(path, args.recursive, exclude_patterns or None)
|
|
83
132
|
all_files.extend(python_files)
|
|
84
133
|
|
|
85
134
|
if not all_files:
|
|
@@ -905,7 +905,7 @@ wheels = [
|
|
|
905
905
|
|
|
906
906
|
[[package]]
|
|
907
907
|
name = "undersort"
|
|
908
|
-
version = "0.1.
|
|
908
|
+
version = "0.1.5"
|
|
909
909
|
source = { editable = "." }
|
|
910
910
|
dependencies = [
|
|
911
911
|
{ name = "libcst", version = "1.1.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.9'" },
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|