auto-coder 0.1.375__py3-none-any.whl → 0.1.377__py3-none-any.whl
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.
Potentially problematic release.
This version of auto-coder might be problematic. Click here for more details.
- {auto_coder-0.1.375.dist-info → auto_coder-0.1.377.dist-info}/METADATA +1 -1
- {auto_coder-0.1.375.dist-info → auto_coder-0.1.377.dist-info}/RECORD +18 -52
- autocoder/agent/base_agentic/base_agent.py +9 -8
- autocoder/auto_coder_rag.py +12 -0
- autocoder/models.py +2 -2
- autocoder/rag/agentic_rag.py +7 -20
- autocoder/rag/cache/local_duckdb_storage_cache.py +63 -33
- autocoder/rag/conversation_to_queries.py +37 -5
- autocoder/rag/long_context_rag.py +161 -41
- autocoder/rag/tools/recall_tool.py +2 -1
- autocoder/rag/tools/search_tool.py +2 -1
- autocoder/rag/types.py +36 -0
- autocoder/utils/_markitdown.py +59 -13
- autocoder/version.py +1 -1
- autocoder/agent/agentic_edit.py +0 -833
- autocoder/agent/agentic_edit_tools/__init__.py +0 -28
- autocoder/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +0 -32
- autocoder/agent/agentic_edit_tools/attempt_completion_tool_resolver.py +0 -29
- autocoder/agent/agentic_edit_tools/base_tool_resolver.py +0 -29
- autocoder/agent/agentic_edit_tools/execute_command_tool_resolver.py +0 -84
- autocoder/agent/agentic_edit_tools/list_code_definition_names_tool_resolver.py +0 -75
- autocoder/agent/agentic_edit_tools/list_files_tool_resolver.py +0 -62
- autocoder/agent/agentic_edit_tools/plan_mode_respond_tool_resolver.py +0 -30
- autocoder/agent/agentic_edit_tools/read_file_tool_resolver.py +0 -36
- autocoder/agent/agentic_edit_tools/replace_in_file_tool_resolver.py +0 -95
- autocoder/agent/agentic_edit_tools/search_files_tool_resolver.py +0 -70
- autocoder/agent/agentic_edit_tools/use_mcp_tool_resolver.py +0 -55
- autocoder/agent/agentic_edit_tools/write_to_file_tool_resolver.py +0 -98
- autocoder/agent/agentic_edit_types.py +0 -124
- autocoder/auto_coder_lang.py +0 -60
- autocoder/auto_coder_rag_client_mcp.py +0 -170
- autocoder/auto_coder_rag_mcp.py +0 -193
- autocoder/common/llm_rerank.py +0 -84
- autocoder/common/model_speed_test.py +0 -392
- autocoder/common/v2/agent/agentic_edit_conversation.py +0 -188
- autocoder/common/v2/agent/ignore_utils.py +0 -50
- autocoder/dispacher/actions/plugins/action_translate.py +0 -214
- autocoder/ignorefiles/__init__.py +0 -4
- autocoder/ignorefiles/ignore_file_utils.py +0 -63
- autocoder/ignorefiles/test_ignore_file_utils.py +0 -91
- autocoder/linters/code_linter.py +0 -588
- autocoder/rag/loaders/test_image_loader.py +0 -209
- autocoder/rag/raw_rag.py +0 -96
- autocoder/rag/simple_directory_reader.py +0 -646
- autocoder/rag/simple_rag.py +0 -404
- autocoder/regex_project/__init__.py +0 -162
- autocoder/utils/coder.py +0 -125
- autocoder/utils/tests.py +0 -37
- {auto_coder-0.1.375.dist-info → auto_coder-0.1.377.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.375.dist-info → auto_coder-0.1.377.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.375.dist-info → auto_coder-0.1.377.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.375.dist-info → auto_coder-0.1.377.dist-info}/top_level.txt +0 -0
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import os
|
|
3
|
-
from typing import Optional, List
|
|
4
|
-
import pathspec
|
|
5
|
-
|
|
6
|
-
DEFAULT_IGNORED_DIRS = ['.git', '.auto-coder', 'node_modules', '.mvn', '.idea', '__pycache__', '.venv', 'venv', 'dist', 'build', '.gradle']
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def load_ignore_spec(source_dir: str) -> Optional[pathspec.PathSpec]:
|
|
10
|
-
"""
|
|
11
|
-
Loads .autocoderignore file from the source_dir if it exists.
|
|
12
|
-
Returns a PathSpec object or None if no ignore file.
|
|
13
|
-
"""
|
|
14
|
-
ignore_file_path = os.path.join(source_dir, ".autocoderignore")
|
|
15
|
-
if not os.path.isfile(ignore_file_path):
|
|
16
|
-
return None
|
|
17
|
-
try:
|
|
18
|
-
with open(ignore_file_path, "r") as f:
|
|
19
|
-
ignore_patterns = f.read().splitlines()
|
|
20
|
-
spec = pathspec.PathSpec.from_lines("gitwildmatch", ignore_patterns)
|
|
21
|
-
return spec
|
|
22
|
-
except Exception:
|
|
23
|
-
return None
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def should_ignore(path: str, ignore_spec: Optional[pathspec.PathSpec], ignored_dirs: List[str], source_dir: str) -> bool:
|
|
27
|
-
"""
|
|
28
|
-
Determine if a given path should be ignored based on ignore_spec and ignored_dirs.
|
|
29
|
-
- path: absolute path
|
|
30
|
-
- ignore_spec: PathSpec object or None
|
|
31
|
-
- ignored_dirs: list of directory names to ignore
|
|
32
|
-
- source_dir: root source directory absolute path
|
|
33
|
-
"""
|
|
34
|
-
rel_path = os.path.relpath(path, source_dir)
|
|
35
|
-
parts = rel_path.split(os.sep)
|
|
36
|
-
|
|
37
|
-
# Always ignore if any part matches ignored_dirs
|
|
38
|
-
for part in parts:
|
|
39
|
-
if part in ignored_dirs:
|
|
40
|
-
return True
|
|
41
|
-
|
|
42
|
-
# If ignore_spec exists, use it to check
|
|
43
|
-
if ignore_spec:
|
|
44
|
-
# pathspec expects posix style paths
|
|
45
|
-
rel_path_posix = rel_path.replace(os.sep, "/")
|
|
46
|
-
# Check both file and dir ignoring
|
|
47
|
-
if ignore_spec.match_file(rel_path_posix):
|
|
48
|
-
return True
|
|
49
|
-
|
|
50
|
-
return False
|
|
@@ -1,214 +0,0 @@
|
|
|
1
|
-
from autocoder.common import (
|
|
2
|
-
AutoCoderArgs,
|
|
3
|
-
TranslateArgs,
|
|
4
|
-
TranslateReadme,
|
|
5
|
-
split_code_into_segments,
|
|
6
|
-
)
|
|
7
|
-
from autocoder.suffixproject import SuffixProject
|
|
8
|
-
from typing import Optional
|
|
9
|
-
import byzerllm
|
|
10
|
-
import os
|
|
11
|
-
import time
|
|
12
|
-
from loguru import logger
|
|
13
|
-
from prompt_toolkit import prompt
|
|
14
|
-
from prompt_toolkit.shortcuts import confirm, radiolist_dialog
|
|
15
|
-
from rich import print
|
|
16
|
-
from rich.table import Table
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
@byzerllm.prompt()
|
|
20
|
-
def translate_readme(content: str, lang: str, instruction: Optional[str] = None) -> str:
|
|
21
|
-
"""
|
|
22
|
-
你做翻译时,需要遵循如下要求:
|
|
23
|
-
|
|
24
|
-
{%- if instruction %}
|
|
25
|
-
{{ instruction }}
|
|
26
|
-
{%- endif %}
|
|
27
|
-
|
|
28
|
-
请将下面的内容翻译成{{ lang }}:
|
|
29
|
-
|
|
30
|
-
{{ content }}
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
def get_translate_part(content: str) -> str:
|
|
35
|
-
return content
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
def confirm_translation_parameters(translate_args: TranslateArgs) -> TranslateArgs:
|
|
39
|
-
while True:
|
|
40
|
-
table = Table(title="Translation Parameters")
|
|
41
|
-
table.add_column("Parameter", style="cyan")
|
|
42
|
-
table.add_column("Value", style="magenta")
|
|
43
|
-
table.add_row("Target Language", translate_args.target_lang)
|
|
44
|
-
table.add_row("File Suffixes", translate_args.file_suffix)
|
|
45
|
-
table.add_row("New File Mark", translate_args.new_file_mark)
|
|
46
|
-
table.add_row(
|
|
47
|
-
"Translate File Name", str(translate_args.should_translate_file_name)
|
|
48
|
-
)
|
|
49
|
-
table.add_row("File List", ", ".join(translate_args.file_list))
|
|
50
|
-
table.add_row("Output Directory", translate_args.output_dir)
|
|
51
|
-
print(table)
|
|
52
|
-
|
|
53
|
-
if confirm("Are the above parameters correct?"):
|
|
54
|
-
break
|
|
55
|
-
|
|
56
|
-
param_options = [
|
|
57
|
-
("1", "Target Language"),
|
|
58
|
-
("2", "File Suffixes"),
|
|
59
|
-
("3", "New File Mark"),
|
|
60
|
-
("4", "Translate File Name"),
|
|
61
|
-
("5", "File List"),
|
|
62
|
-
("6", "Output Directory"),
|
|
63
|
-
]
|
|
64
|
-
selected_param = radiolist_dialog(
|
|
65
|
-
title="Select parameter to modify",
|
|
66
|
-
text="Choose the parameter you want to change:",
|
|
67
|
-
values=param_options,
|
|
68
|
-
).run()
|
|
69
|
-
|
|
70
|
-
if selected_param == "1":
|
|
71
|
-
translate_args.target_lang = prompt("Enter the new target language: ")
|
|
72
|
-
elif selected_param == "2":
|
|
73
|
-
translate_args.file_suffix = prompt(
|
|
74
|
-
"Enter the new file suffixes (comma-separated): "
|
|
75
|
-
)
|
|
76
|
-
elif selected_param == "3":
|
|
77
|
-
translate_args.new_file_mark = prompt("Enter the new file mark: ")
|
|
78
|
-
elif selected_param == "4":
|
|
79
|
-
translate_args.should_translate_file_name = confirm("Translate file names?")
|
|
80
|
-
elif selected_param == "5":
|
|
81
|
-
translate_args.file_list = prompt(
|
|
82
|
-
"Enter the new file list (comma-separated): "
|
|
83
|
-
).split(",")
|
|
84
|
-
elif selected_param == "6":
|
|
85
|
-
translate_args.output_dir = prompt("Enter the new output directory: ")
|
|
86
|
-
|
|
87
|
-
return translate_args
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class ActionTranslate:
|
|
91
|
-
def __init__(
|
|
92
|
-
self, args: AutoCoderArgs, llm: Optional[byzerllm.ByzerLLM] = None
|
|
93
|
-
) -> None:
|
|
94
|
-
self.args = args
|
|
95
|
-
self.llm = llm
|
|
96
|
-
self.pp = None
|
|
97
|
-
|
|
98
|
-
def run(self):
|
|
99
|
-
args = self.args
|
|
100
|
-
if not args.project_type.startswith("translate"):
|
|
101
|
-
return False
|
|
102
|
-
|
|
103
|
-
if (
|
|
104
|
-
args.project_type == "translate"
|
|
105
|
-
and args.query is not None
|
|
106
|
-
and self.llm is not None
|
|
107
|
-
):
|
|
108
|
-
t = self.llm.chat_oai(
|
|
109
|
-
conversations=[{"role": "user", "content": args.query}],
|
|
110
|
-
response_class=TranslateArgs,
|
|
111
|
-
)
|
|
112
|
-
tranlate_args: TranslateArgs = t[0].value
|
|
113
|
-
if tranlate_args:
|
|
114
|
-
lang = tranlate_args.target_lang
|
|
115
|
-
suffixes = tranlate_args.file_suffix
|
|
116
|
-
new_file_mark = tranlate_args.new_file_mark
|
|
117
|
-
file_list = tranlate_args.file_list
|
|
118
|
-
output_dir = tranlate_args.output_dir
|
|
119
|
-
should_translate_file_name = tranlate_args.should_translate_file_name
|
|
120
|
-
else:
|
|
121
|
-
[
|
|
122
|
-
_,
|
|
123
|
-
lang,
|
|
124
|
-
suffixes,
|
|
125
|
-
new_file_mark,
|
|
126
|
-
file_list_str,
|
|
127
|
-
output_dir,
|
|
128
|
-
should_translate_file_name,
|
|
129
|
-
] = args.project_type.split("/")
|
|
130
|
-
file_list = file_list_str.split(",")
|
|
131
|
-
|
|
132
|
-
translate_args = TranslateArgs(
|
|
133
|
-
target_lang=lang,
|
|
134
|
-
file_suffix=suffixes,
|
|
135
|
-
new_file_mark=new_file_mark,
|
|
136
|
-
file_list=file_list,
|
|
137
|
-
output_dir=output_dir,
|
|
138
|
-
should_translate_file_name=should_translate_file_name,
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
translate_args = confirm_translation_parameters(translate_args)
|
|
142
|
-
|
|
143
|
-
def file_filter(file_path, suffixes):
|
|
144
|
-
for suffix in suffixes:
|
|
145
|
-
if suffix.startswith("."):
|
|
146
|
-
if file_path.endswith(f"-{translate_args.new_file_mark}{suffix}"):
|
|
147
|
-
return False
|
|
148
|
-
else:
|
|
149
|
-
if file_path.endswith(f"-{translate_args.new_file_mark}.{suffix}"):
|
|
150
|
-
return False
|
|
151
|
-
return True
|
|
152
|
-
|
|
153
|
-
args.project_type = translate_args.file_suffix
|
|
154
|
-
pp = SuffixProject(args=args, llm=self.llm, file_filter=file_filter)
|
|
155
|
-
self.pp = pp
|
|
156
|
-
pp.run()
|
|
157
|
-
for source in pp.sources:
|
|
158
|
-
if (
|
|
159
|
-
translate_args.file_list
|
|
160
|
-
and source.module_name not in translate_args.file_list
|
|
161
|
-
):
|
|
162
|
-
continue
|
|
163
|
-
logger.info(f"Translating {source.module_name}...")
|
|
164
|
-
max_tokens = self.args.model_max_length or 2000
|
|
165
|
-
segments = split_code_into_segments(
|
|
166
|
-
source_code=source.source_code, max_tokens=max_tokens
|
|
167
|
-
)
|
|
168
|
-
temp_result = []
|
|
169
|
-
segment_count = 0
|
|
170
|
-
for segment in segments:
|
|
171
|
-
content = translate_readme(
|
|
172
|
-
content=segment,
|
|
173
|
-
lang=translate_args.target_lang,
|
|
174
|
-
instruction=args.query,
|
|
175
|
-
)
|
|
176
|
-
t = self.llm.chat_oai(
|
|
177
|
-
conversations=[{"role": "user", "content": content}]
|
|
178
|
-
)
|
|
179
|
-
temp_result.append(get_translate_part(t[0].output))
|
|
180
|
-
time.sleep(args.anti_quota_limit)
|
|
181
|
-
segment_count += 1
|
|
182
|
-
print(
|
|
183
|
-
f"Translated {segment_count}({len(content)}) of {len(segments)} segments from {source.module_name}",
|
|
184
|
-
flush=True,
|
|
185
|
-
)
|
|
186
|
-
readme = TranslateReadme(
|
|
187
|
-
filename=source.module_name, content="".join(temp_result)
|
|
188
|
-
)
|
|
189
|
-
filename, extension = os.path.splitext(readme.filename)
|
|
190
|
-
file_short_name, _ = os.path.splitext(os.path.basename(filename))
|
|
191
|
-
|
|
192
|
-
if translate_args.new_file_mark:
|
|
193
|
-
new_file_mark = f"-{translate_args.new_file_mark}"
|
|
194
|
-
|
|
195
|
-
if translate_args.should_translate_file_name:
|
|
196
|
-
file_short_name = translate_readme.with_llm(self.llm).run(
|
|
197
|
-
content=file_short_name,
|
|
198
|
-
lang=translate_args.target_lang,
|
|
199
|
-
instruction=args.query,
|
|
200
|
-
)
|
|
201
|
-
file_short_name = file_short_name.replace(" ", "_")
|
|
202
|
-
|
|
203
|
-
if translate_args.output_dir:
|
|
204
|
-
new_filename = os.path.join(
|
|
205
|
-
translate_args.output_dir,
|
|
206
|
-
f"{file_short_name}{new_file_mark}{extension}",
|
|
207
|
-
)
|
|
208
|
-
else:
|
|
209
|
-
new_filename = f"{filename}{new_file_mark}{extension}"
|
|
210
|
-
|
|
211
|
-
logger.info(f"Writing to {new_filename}...")
|
|
212
|
-
with open(new_filename, "w",encoding="utf-8") as file:
|
|
213
|
-
file.write(readme.content)
|
|
214
|
-
return True
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import os
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from threading import Lock
|
|
5
|
-
import pathspec
|
|
6
|
-
|
|
7
|
-
DEFAULT_EXCLUDES = [
|
|
8
|
-
'.git', '.auto-coder', 'node_modules', '.mvn', '.idea',
|
|
9
|
-
'__pycache__', '.venv', 'venv', 'dist', 'build', '.gradle',".next"
|
|
10
|
-
]
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class IgnoreFileManager:
|
|
14
|
-
_instance = None
|
|
15
|
-
_lock = Lock()
|
|
16
|
-
|
|
17
|
-
def __new__(cls):
|
|
18
|
-
if not cls._instance:
|
|
19
|
-
with cls._lock:
|
|
20
|
-
if not cls._instance:
|
|
21
|
-
cls._instance = super(IgnoreFileManager, cls).__new__(cls)
|
|
22
|
-
cls._instance._initialized = False
|
|
23
|
-
return cls._instance
|
|
24
|
-
|
|
25
|
-
def __init__(self):
|
|
26
|
-
if self._initialized:
|
|
27
|
-
return
|
|
28
|
-
self._initialized = True
|
|
29
|
-
self._spec = None
|
|
30
|
-
self._load_ignore_spec()
|
|
31
|
-
|
|
32
|
-
def _load_ignore_spec(self):
|
|
33
|
-
ignore_patterns = []
|
|
34
|
-
project_root = Path(os.getcwd())
|
|
35
|
-
|
|
36
|
-
ignore_file_paths = [
|
|
37
|
-
project_root / '.autocoderignore',
|
|
38
|
-
project_root / '.auto-coder' / '.autocoderignore'
|
|
39
|
-
]
|
|
40
|
-
|
|
41
|
-
for ignore_file in ignore_file_paths:
|
|
42
|
-
if ignore_file.is_file():
|
|
43
|
-
with open(ignore_file, 'r', encoding='utf-8') as f:
|
|
44
|
-
ignore_patterns = f.read().splitlines()
|
|
45
|
-
break
|
|
46
|
-
|
|
47
|
-
# 添加默认排除目录
|
|
48
|
-
ignore_patterns.extend(DEFAULT_EXCLUDES)
|
|
49
|
-
|
|
50
|
-
self._spec = pathspec.PathSpec.from_lines('gitwildmatch', ignore_patterns)
|
|
51
|
-
|
|
52
|
-
def should_ignore(self, path: str) -> bool:
|
|
53
|
-
rel_path = os.path.relpath(path, os.getcwd())
|
|
54
|
-
# 标准化分隔符
|
|
55
|
-
rel_path = rel_path.replace(os.sep, '/')
|
|
56
|
-
return self._spec.match_file(rel_path)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
# 对外提供单例
|
|
60
|
-
_ignore_manager = IgnoreFileManager()
|
|
61
|
-
|
|
62
|
-
def should_ignore(path: str) -> bool:
|
|
63
|
-
return _ignore_manager.should_ignore(path)
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import os
|
|
3
|
-
import shutil
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
from src.autocoder.ignorefiles import ignore_file_utils
|
|
9
|
-
|
|
10
|
-
@pytest.fixture(autouse=True)
|
|
11
|
-
def cleanup_ignore_manager(monkeypatch):
|
|
12
|
-
"""
|
|
13
|
-
在每个测试前后清理 IgnoreFileManager 的单例状态,保证测试隔离
|
|
14
|
-
"""
|
|
15
|
-
# 备份原始实例
|
|
16
|
-
original_instance = ignore_file_utils._ignore_manager
|
|
17
|
-
# 强制重新加载忽略规则
|
|
18
|
-
def reset_ignore_manager():
|
|
19
|
-
ignore_file_utils.IgnoreFileManager._instance = None
|
|
20
|
-
return ignore_file_utils.IgnoreFileManager()
|
|
21
|
-
|
|
22
|
-
monkeypatch.setattr(ignore_file_utils, "_ignore_manager", reset_ignore_manager())
|
|
23
|
-
yield
|
|
24
|
-
# 恢复原始实例
|
|
25
|
-
ignore_file_utils._ignore_manager = original_instance
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def test_default_excludes(tmp_path, monkeypatch):
|
|
29
|
-
# 切换当前工作目录
|
|
30
|
-
monkeypatch.chdir(tmp_path)
|
|
31
|
-
|
|
32
|
-
# 不创建任何 .autocoderignore 文件,使用默认排除规则
|
|
33
|
-
# 创建默认排除目录
|
|
34
|
-
for dirname in ignore_file_utils.DEFAULT_EXCLUDES:
|
|
35
|
-
(tmp_path / dirname).mkdir(parents=True, exist_ok=True)
|
|
36
|
-
# 应该被忽略
|
|
37
|
-
assert ignore_file_utils.should_ignore(str(tmp_path / dirname)) is True
|
|
38
|
-
|
|
39
|
-
# 创建不会被忽略的文件
|
|
40
|
-
normal_file = tmp_path / "myfile.txt"
|
|
41
|
-
normal_file.write_text("hello")
|
|
42
|
-
assert ignore_file_utils.should_ignore(str(normal_file)) is False
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def test_custom_ignore_file(tmp_path, monkeypatch):
|
|
46
|
-
monkeypatch.chdir(tmp_path)
|
|
47
|
-
|
|
48
|
-
# 创建自定义忽略文件
|
|
49
|
-
ignore_file = tmp_path / ".autocoderignore"
|
|
50
|
-
ignore_file.write_text("data/**\nsecret.txt")
|
|
51
|
-
|
|
52
|
-
# 重新初始化忽略管理器以加载新规则
|
|
53
|
-
ignore_file_utils.IgnoreFileManager._instance = None
|
|
54
|
-
ignore_file_utils._ignore_manager = ignore_file_utils.IgnoreFileManager()
|
|
55
|
-
|
|
56
|
-
# 符合忽略规则的路径
|
|
57
|
-
ignored_dir = tmp_path / "data" / "subdir"
|
|
58
|
-
ignored_dir.mkdir(parents=True)
|
|
59
|
-
ignored_file = tmp_path / "secret.txt"
|
|
60
|
-
ignored_file.write_text("secret")
|
|
61
|
-
|
|
62
|
-
assert ignore_file_utils.should_ignore(str(ignored_dir)) is True
|
|
63
|
-
assert ignore_file_utils.should_ignore(str(ignored_file)) is True
|
|
64
|
-
|
|
65
|
-
# 不应被忽略的文件
|
|
66
|
-
normal_file = tmp_path / "keepme.txt"
|
|
67
|
-
normal_file.write_text("keep me")
|
|
68
|
-
assert ignore_file_utils.should_ignore(str(normal_file)) is False
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
def test_nested_ignore_file(tmp_path, monkeypatch):
|
|
72
|
-
monkeypatch.chdir(tmp_path)
|
|
73
|
-
|
|
74
|
-
# 没有根目录的.ignore,创建.auto-coder/.autocoderignore
|
|
75
|
-
nested_dir = tmp_path / ".auto-coder"
|
|
76
|
-
nested_dir.mkdir()
|
|
77
|
-
|
|
78
|
-
ignore_file = nested_dir / ".autocoderignore"
|
|
79
|
-
ignore_file.write_text("logs/**")
|
|
80
|
-
|
|
81
|
-
# 重新初始化忽略管理器以加载新规则
|
|
82
|
-
ignore_file_utils.IgnoreFileManager._instance = None
|
|
83
|
-
ignore_file_utils._ignore_manager = ignore_file_utils.IgnoreFileManager()
|
|
84
|
-
|
|
85
|
-
ignored_dir = tmp_path / "logs" / "2024"
|
|
86
|
-
ignored_dir.mkdir(parents=True)
|
|
87
|
-
assert ignore_file_utils.should_ignore(str(ignored_dir)) is True
|
|
88
|
-
|
|
89
|
-
normal_file = tmp_path / "main.py"
|
|
90
|
-
normal_file.write_text("# main")
|
|
91
|
-
assert ignore_file_utils.should_ignore(str(normal_file)) is False
|