Skip to content

Commit 8675957

Browse files
committed
fix(main): resolve missing return statement in determine_output_target
1 parent 8285177 commit 8675957

3 files changed

Lines changed: 45 additions & 6 deletions

File tree

codeconcat/main.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
4. **Logging**: Setting up rich-text logging for better developer experience.
1313
"""
1414

15+
import fnmatch
1516
import logging
1617
import sys
1718
from pathlib import Path
@@ -85,6 +86,22 @@ def determine_output_target(
8586
return None, True
8687

8788

89+
def convert_globs_to_regex(patterns: list[str]) -> list[str]:
90+
"""
91+
Converts a list of glob patterns to regex patterns using fnmatch.
92+
"""
93+
regex_patterns = []
94+
for p in patterns:
95+
try:
96+
# fnmatch.translate converts a glob to a regex.
97+
# It anchors the pattern to the end of the string (\Z).
98+
regex_patterns.append(fnmatch.translate(p))
99+
except Exception:
100+
# Fallback: if translation fails, keep original (might already be regex?)
101+
regex_patterns.append(p)
102+
return regex_patterns
103+
104+
88105
def main() -> None:
89106
"""
90107
Main execution entry point.
@@ -148,14 +165,19 @@ def main() -> None:
148165
# Merge lists unique
149166
base_excludes = base_config.get("exclude_patterns", [])
150167
override_excludes = config_overrides.get("exclude", []) or []
168+
# Convert user provided globs to regex
169+
override_excludes = convert_globs_to_regex(override_excludes)
151170
files_excludes = list(set(base_excludes + override_excludes)) # Unique
152171

153172
base_whitelist = base_config.get("whitelist_patterns", [])
154173
override_whitelist = config_overrides.get("whitelist", []) or []
174+
# Convert user provided globs to regex
175+
override_whitelist = convert_globs_to_regex(override_whitelist)
155176
files_whitelist = list(set(base_whitelist + override_whitelist)) # Unique
156177

157178
# Force patterns (Additive) - No config base yet, just overrides
158179
files_force = config_overrides.get("force_patterns", []) or []
180+
files_force = convert_globs_to_regex(files_force)
159181

160182
# --- Output Target Resolution ---
161183
# Apply Smart TTY Logic if not in Wizard mode (Wizard sets destination_file explicitly)

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
66

77
[project]
88
name = "codeconcat"
9-
version = "3.0.0" # Major UI/UX Upgrade
9+
version = "3.0.1" # Fix invalid regex crash
1010
authors = [
1111
{ name="Luis Guilherme", email="lgpelin92@gmail.com" },
1212
]

tests/test_main.py

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ def test_exclude_flag(tmp_path: Path):
9999
str(source_dir),
100100
str(output_file),
101101
"--exclude",
102-
r"exclude\.custom$",
102+
"exclude.custom",
103103
]
104104
with patch.object(sys, "argv", test_args):
105105
main()
@@ -135,7 +135,7 @@ def test_whitelist_flag(tmp_path: Path):
135135
str(source_dir),
136136
str(output_file),
137137
"--whitelist",
138-
r"\.py$",
138+
"*.py",
139139
]
140140
with patch.object(sys, "argv", test_args):
141141
main()
@@ -165,8 +165,6 @@ def test_no_gitignore_flag(tmp_path: Path):
165165
str(source_dir),
166166
str(output_file),
167167
"--no-gitignore",
168-
"--exclude",
169-
"",
170168
]
171169
with patch.object(sys, "argv", test_args):
172170
main()
@@ -187,7 +185,7 @@ def test_gitignore_default(tmp_path: Path):
187185
# Simulate command line: codeconcat ./src output.txt --exclude ''
188186
# ADDED --exclude '' to disable default config excludes for this test
189187
# This isolates the effect of ONLY the .gitignore file
190-
test_args = ["codeconcat", str(source_dir), str(output_file), "--exclude", ""]
188+
test_args = ["codeconcat", str(source_dir), str(output_file)]
191189
with patch.object(sys, "argv", test_args):
192190
main()
193191

@@ -317,3 +315,22 @@ def test_exclude_output_file_implicitly(tmp_path: Path):
317315
assert "print('hello')" in content
318316
assert "PRE_EXISTING_OUTPUT_CONTENT" not in content
319317
assert f"### File: `{output_file.name}`" not in content
318+
319+
320+
def test_glob_exclusion_translation(tmp_path: Path):
321+
"""Test that glob patterns (e.g. *.lock) are correctly translated and do not crash."""
322+
source_dir = tmp_path / "src"
323+
output_file = tmp_path / "output.txt"
324+
create_test_files(
325+
source_dir, {"keep.py": "keep", "ignore.lock": "ignore", "nested/ignore.lock": "ignore"}
326+
)
327+
328+
# Simulate --exclude "*.lock"
329+
test_args = ["codeconcat", str(source_dir), str(output_file), "--exclude", "*.lock"]
330+
with patch.object(sys, "argv", test_args):
331+
main()
332+
333+
assert output_file.exists()
334+
content = output_file.read_text()
335+
assert "keep.py" in content
336+
assert "ignore.lock" not in content

0 commit comments

Comments
 (0)