Skip to content

Commit 1b5adf9

Browse files
committed
fix: update output file name
1 parent 0f31d0a commit 1b5adf9

File tree

4 files changed

+94
-36
lines changed

4 files changed

+94
-36
lines changed

.mergeignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,4 +209,4 @@ __marimo__/
209209
# Exclude this tool's output
210210
merged_code_context.txt
211211
.git
212-
212+
flatcode_context.txt

src/flatcode/config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@
1414
".DS_Store",
1515
"*.log",
1616
"logs/",
17+
"*_context.txt",
1718
]

src/flatcode/core/ignore.py

Lines changed: 53 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,63 +6,82 @@
66
from flatcode.config import DEFAULT_IGNORE_PATTERNS
77

88
def bootstrap_mergeignore(root_dir: Path, output_filename: str) -> Path:
9-
"""Checks for .mergeignore; creates one if it doesn't exist."""
9+
"""
10+
Checks for .mergeignore.
11+
1. If missing, create it with defaults + output_filename.
12+
2. If exists, check if output_filename is ignored. If not, append it.
13+
"""
1014
mergeignore_file = root_dir / ".mergeignore"
11-
if mergeignore_file.exists():
12-
print(f"Found existing: {mergeignore_file.name}")
13-
return mergeignore_file
14-
15-
print(f"'{mergeignore_file.name}' not found. Initializing...")
16-
gitignore_file = root_dir / ".gitignore"
1715

18-
try:
19-
patterns_to_write = []
20-
if gitignore_file.exists():
21-
# In a real app, dependency injection for input() is better
22-
choice = input(f"> Found .gitignore. Copy rules to .mergeignore? (Y/n): ").strip().lower()
23-
if choice != 'n':
24-
with open(gitignore_file, "r", encoding="utf-8") as f_git:
25-
patterns_to_write.extend(f_git.read().splitlines())
26-
print(f"Copied rules from .gitignore.")
16+
# --- Case 1: Create new .mergeignore ---
17+
if not mergeignore_file.exists():
18+
print(f"'{mergeignore_file.name}' not found. Initializing...")
19+
gitignore_file = root_dir / ".gitignore"
2720

28-
if not patterns_to_write:
29-
patterns_to_write = DEFAULT_IGNORE_PATTERNS
30-
31-
# Ensure the output file itself is always ignored
32-
if output_filename not in patterns_to_write:
33-
patterns_to_write.append(f"\n# Exclude this tool's output\n{output_filename}")
21+
try:
22+
patterns_to_write = []
23+
if gitignore_file.exists():
24+
# Side-effect: input() for interactive mode
25+
choice = input(f"> Found .gitignore. Copy rules to .mergeignore? (Y/n): ").strip().lower()
26+
if choice != 'n':
27+
with open(gitignore_file, "r", encoding="utf-8") as f_git:
28+
patterns_to_write.extend(f_git.read().splitlines())
29+
print(f"Copied rules from .gitignore.")
30+
31+
if not patterns_to_write:
32+
patterns_to_write = list(DEFAULT_IGNORE_PATTERNS) # Copy list
33+
34+
# Add the output file explicitly
35+
if output_filename not in patterns_to_write:
36+
patterns_to_write.append(f"\n# Exclude this tool's output\n{output_filename}")
37+
38+
with open(mergeignore_file, "w", encoding="utf-8") as f:
39+
f.write("\n".join(patterns_to_write))
40+
41+
print(f"Successfully created: {mergeignore_file.name}")
42+
return mergeignore_file
43+
44+
except Exception as e:
45+
print(f"Error creating .mergeignore: {e}", file=sys.stderr)
46+
sys.exit(1)
3447

35-
with open(mergeignore_file, "w", encoding="utf-8") as f:
36-
f.write("\n".join(patterns_to_write))
48+
# --- Case 2: Update existing .mergeignore ---
49+
else:
50+
try:
51+
# Check if the current output filename is already ignored by existing rules
52+
with open(mergeignore_file, "r", encoding="utf-8") as f:
53+
lines = f.readlines()
54+
55+
spec = pathspec.PathSpec.from_lines("gitwildmatch", lines)
56+
57+
# If the output file is NOT ignored by current rules, append it.
58+
if not spec.match_file(output_filename):
59+
print(f"Updating .mergeignore: Adding '{output_filename}' to ignore list.")
60+
with open(mergeignore_file, "a", encoding="utf-8") as f:
61+
f.write(f"\n# Auto-added output file\n{output_filename}\n")
62+
63+
except Exception as e:
64+
print(f"Warning: Could not update .mergeignore: {e}", file=sys.stderr)
3765

38-
print(f"Successfully created: {mergeignore_file.name}")
3966
return mergeignore_file
4067

41-
except Exception as e:
42-
print(f"Error creating .mergeignore: {e}", file=sys.stderr)
43-
sys.exit(1)
44-
4568
def load_ignore_spec(mergeignore_file: Path, extra_patterns: Optional[List[str]] = None) -> pathspec.PathSpec:
4669
"""
4770
Loads rules from .mergeignore and creates a PathSpec object.
48-
Includes any extra patterns (like the output filename).
71+
Includes any extra patterns (like the output filename) for runtime safety.
4972
"""
5073
lines = []
5174

52-
# 1. Read file if exists
5375
if mergeignore_file.exists():
5476
with open(mergeignore_file, "r", encoding="utf-8") as f:
5577
lines = f.readlines()
5678

57-
# 2. Add extra patterns (e.g., output file)
5879
if extra_patterns:
5980
lines.extend(extra_patterns)
6081

61-
# 3. Create spec using GitWildMatch (standard git behavior)
6282
try:
6383
spec = pathspec.PathSpec.from_lines("gitwildmatch", lines)
6484
return spec
6585
except Exception as e:
6686
print(f"Error parsing ignore rules: {e}", file=sys.stderr)
67-
# Return an empty spec on failure to prevent crash, though risky
6887
return pathspec.PathSpec.from_lines("gitwildmatch", [])

tests/test_refactored.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,4 +147,42 @@ def test_cli_dynamic_naming(complex_project, monkeypatch):
147147
main()
148148

149149
assert expected_file_path.exists()
150-
print(f"Successfully generated dynamic file: {expected_file_path.name}")
150+
print(f"Successfully generated dynamic file: {expected_file_path.name}")
151+
152+
def test_mergeignore_auto_append(tmp_path):
153+
"""
154+
[New] 验证如果 .mergeignore 存在但缺少当前输出文件,会自动追加。
155+
"""
156+
# 1. 创建现有的 .mergeignore,只包含 *.log
157+
ignore_file = tmp_path / ".mergeignore"
158+
ignore_file.write_text("*.log\n", encoding="utf-8")
159+
160+
# 2. 模拟运行 flatcode,输出文件为 custom_context.txt
161+
from flatcode.core.ignore import bootstrap_mergeignore
162+
output_name = "custom_context.txt"
163+
164+
bootstrap_mergeignore(tmp_path, output_name)
165+
166+
# 3. 验证文件内容被修改
167+
content = ignore_file.read_text(encoding="utf-8")
168+
assert "custom_context.txt" in content
169+
assert "# Auto-added output file" in content
170+
171+
def test_mergeignore_no_duplication(tmp_path):
172+
"""
173+
[New] 验证如果文件已经被忽略(例如通过通配符),则不会重复追加。
174+
"""
175+
# 1. 规则包含 *_context.txt
176+
ignore_file = tmp_path / ".mergeignore"
177+
ignore_file.write_text("*_context.txt\n", encoding="utf-8")
178+
179+
# 2. 运行,输出 my_project_context.txt (符合通配符)
180+
from flatcode.core.ignore import bootstrap_mergeignore
181+
output_name = "my_project_context.txt"
182+
183+
bootstrap_mergeignore(tmp_path, output_name)
184+
185+
# 3. 验证没有重复添加
186+
content = ignore_file.read_text(encoding="utf-8")
187+
# 应该只出现一次(即原有的规则),不会有具体的 my_project_context.txt
188+
assert "my_project_context.txt" not in content

0 commit comments

Comments
 (0)