auto-coder 0.1.313__py3-none-any.whl → 0.1.315__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.313.dist-info → auto_coder-0.1.315.dist-info}/METADATA +1 -1
- {auto_coder-0.1.313.dist-info → auto_coder-0.1.315.dist-info}/RECORD +13 -8
- autocoder/auto_coder_runner.py +22 -26
- autocoder/linters/__init__.py +0 -0
- autocoder/linters/base_linter.py +108 -0
- autocoder/linters/code_linter.py +588 -0
- autocoder/linters/linter_factory.py +243 -0
- autocoder/linters/python_linter.py +616 -0
- autocoder/version.py +1 -1
- {auto_coder-0.1.313.dist-info → auto_coder-0.1.315.dist-info}/LICENSE +0 -0
- {auto_coder-0.1.313.dist-info → auto_coder-0.1.315.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.313.dist-info → auto_coder-0.1.315.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.313.dist-info → auto_coder-0.1.315.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module providing a factory for creating language-specific linters.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from typing import Optional, Dict, Any, List
|
|
7
|
+
|
|
8
|
+
from autocoder.linters.base_linter import BaseLinter
|
|
9
|
+
from autocoder.linters.code_linter import FrontendLinter
|
|
10
|
+
from autocoder.linters.python_linter import PythonLinter
|
|
11
|
+
|
|
12
|
+
class LinterFactory:
|
|
13
|
+
"""
|
|
14
|
+
Factory class for creating appropriate linter instances based on file type or language.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
@classmethod
|
|
18
|
+
def create_linter(cls, language: Optional[str] = None, file_path: Optional[str] = None, verbose: bool = False) -> BaseLinter:
|
|
19
|
+
"""
|
|
20
|
+
Create and return an appropriate linter instance based on language or file path.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
language (Optional[str]): Language identifier ('python', 'javascript', 'typescript', etc.).
|
|
24
|
+
file_path (Optional[str]): Path to a file to infer the language from.
|
|
25
|
+
verbose (bool): Whether to enable verbose output in the linter.
|
|
26
|
+
|
|
27
|
+
Returns:
|
|
28
|
+
BaseLinter: An instance of a linter appropriate for the language.
|
|
29
|
+
|
|
30
|
+
Raises:
|
|
31
|
+
ValueError: If no language could be determined or if the language is not supported.
|
|
32
|
+
"""
|
|
33
|
+
if language is None and file_path is None:
|
|
34
|
+
raise ValueError("Either language or file_path must be provided")
|
|
35
|
+
|
|
36
|
+
# If language is not provided, try to infer from file path
|
|
37
|
+
if language is None and file_path is not None:
|
|
38
|
+
language = cls._detect_language_from_file(file_path)
|
|
39
|
+
|
|
40
|
+
# Map language to linter class
|
|
41
|
+
linter_map = {
|
|
42
|
+
'python': PythonLinter,
|
|
43
|
+
'javascript': FrontendLinter,
|
|
44
|
+
'typescript': FrontendLinter,
|
|
45
|
+
'js': FrontendLinter,
|
|
46
|
+
'ts': FrontendLinter,
|
|
47
|
+
'jsx': FrontendLinter,
|
|
48
|
+
'tsx': FrontendLinter,
|
|
49
|
+
'react': FrontendLinter,
|
|
50
|
+
'vue': FrontendLinter,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
linter_class = linter_map.get(language.lower() if language else None)
|
|
54
|
+
|
|
55
|
+
if linter_class is None:
|
|
56
|
+
raise ValueError(f"Unsupported language: {language}")
|
|
57
|
+
|
|
58
|
+
return linter_class(verbose=verbose)
|
|
59
|
+
|
|
60
|
+
@classmethod
|
|
61
|
+
def _detect_language_from_file(cls, file_path: str) -> str:
|
|
62
|
+
"""
|
|
63
|
+
Detect the programming language based on file extension.
|
|
64
|
+
|
|
65
|
+
Args:
|
|
66
|
+
file_path (str): Path to the file.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
str: Language identifier.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
ValueError: If the file extension is not recognized.
|
|
73
|
+
"""
|
|
74
|
+
if not os.path.exists(file_path):
|
|
75
|
+
raise ValueError(f"File does not exist: {file_path}")
|
|
76
|
+
|
|
77
|
+
_, ext = os.path.splitext(file_path)
|
|
78
|
+
ext = ext.lower()
|
|
79
|
+
|
|
80
|
+
# Map extensions to languages
|
|
81
|
+
extension_map = {
|
|
82
|
+
'.py': 'python',
|
|
83
|
+
'.js': 'javascript',
|
|
84
|
+
'.ts': 'typescript',
|
|
85
|
+
'.jsx': 'react',
|
|
86
|
+
'.tsx': 'react',
|
|
87
|
+
'.vue': 'vue',
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
language = extension_map.get(ext)
|
|
91
|
+
if language is None:
|
|
92
|
+
raise ValueError(f"Unsupported file extension: {ext}")
|
|
93
|
+
|
|
94
|
+
return language
|
|
95
|
+
|
|
96
|
+
@classmethod
|
|
97
|
+
def get_supported_languages(cls) -> List[str]:
|
|
98
|
+
"""
|
|
99
|
+
Get a list of supported programming languages.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
List[str]: List of supported language identifiers.
|
|
103
|
+
"""
|
|
104
|
+
return ['python', 'javascript', 'typescript', 'react', 'vue']
|
|
105
|
+
|
|
106
|
+
@classmethod
|
|
107
|
+
def lint_file(cls, file_path: str, fix: bool = False, verbose: bool = False) -> Dict[str, Any]:
|
|
108
|
+
"""
|
|
109
|
+
Lint a single file using the appropriate linter.
|
|
110
|
+
|
|
111
|
+
Args:
|
|
112
|
+
file_path (str): Path to the file to lint.
|
|
113
|
+
fix (bool): Whether to automatically fix fixable issues.
|
|
114
|
+
verbose (bool): Whether to enable verbose output.
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
Dict[str, Any]: Lint results.
|
|
118
|
+
"""
|
|
119
|
+
linter = cls.create_linter(file_path=file_path, verbose=verbose)
|
|
120
|
+
return linter.lint_file(file_path, fix=fix)
|
|
121
|
+
|
|
122
|
+
@classmethod
|
|
123
|
+
def lint_project(cls, project_path: str, language: Optional[str] = None, fix: bool = False, verbose: bool = False) -> Dict[str, Any]:
|
|
124
|
+
"""
|
|
125
|
+
Lint a project using the appropriate linter.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
project_path (str): Path to the project directory.
|
|
129
|
+
language (Optional[str]): Language identifier to specify which linter to use.
|
|
130
|
+
If not provided, will try to auto-detect.
|
|
131
|
+
fix (bool): Whether to automatically fix fixable issues.
|
|
132
|
+
verbose (bool): Whether to enable verbose output.
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
Dict[str, Any]: Lint results.
|
|
136
|
+
"""
|
|
137
|
+
# If language not specified, try to detect from project contents
|
|
138
|
+
if language is None:
|
|
139
|
+
# First check for package.json (JavaScript/TypeScript)
|
|
140
|
+
if os.path.exists(os.path.join(project_path, 'package.json')):
|
|
141
|
+
linter = cls.create_linter(language='javascript', verbose=verbose)
|
|
142
|
+
# Check for setup.py or requirements.txt (Python)
|
|
143
|
+
elif (os.path.exists(os.path.join(project_path, 'setup.py')) or
|
|
144
|
+
os.path.exists(os.path.join(project_path, 'requirements.txt'))):
|
|
145
|
+
linter = cls.create_linter(language='python', verbose=verbose)
|
|
146
|
+
else:
|
|
147
|
+
# Count file extensions to guess the dominant language
|
|
148
|
+
language_counts = {}
|
|
149
|
+
for root, _, files in os.walk(project_path):
|
|
150
|
+
for file in files:
|
|
151
|
+
_, ext = os.path.splitext(file)
|
|
152
|
+
ext = ext.lower()
|
|
153
|
+
language_counts[ext] = language_counts.get(ext, 0) + 1
|
|
154
|
+
|
|
155
|
+
# Find the most common relevant extension
|
|
156
|
+
relevant_extensions = {'.py', '.js', '.ts', '.jsx', '.tsx', '.vue'}
|
|
157
|
+
most_common = None
|
|
158
|
+
max_count = 0
|
|
159
|
+
|
|
160
|
+
for ext, count in language_counts.items():
|
|
161
|
+
if ext in relevant_extensions and count > max_count:
|
|
162
|
+
most_common = ext
|
|
163
|
+
max_count = count
|
|
164
|
+
|
|
165
|
+
if most_common is None:
|
|
166
|
+
raise ValueError(f"Could not detect project language in {project_path}")
|
|
167
|
+
|
|
168
|
+
language = cls._detect_language_from_file(f"dummy{most_common}")
|
|
169
|
+
linter = cls.create_linter(language=language, verbose=verbose)
|
|
170
|
+
else:
|
|
171
|
+
linter = cls.create_linter(language=language, verbose=verbose)
|
|
172
|
+
|
|
173
|
+
return linter.lint_project(project_path, fix=fix)
|
|
174
|
+
|
|
175
|
+
@classmethod
|
|
176
|
+
def format_lint_result(cls, lint_result: Dict[str, Any], language: Optional[str] = None) -> str:
|
|
177
|
+
"""
|
|
178
|
+
Format lint results into a human-readable string.
|
|
179
|
+
|
|
180
|
+
Args:
|
|
181
|
+
lint_result (Dict[str, Any]): The lint result dictionary.
|
|
182
|
+
language (Optional[str]): Language identifier to specify which formatter to use.
|
|
183
|
+
If not provided, will try to infer from lint_result.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
str: A formatted string representation of the lint results.
|
|
187
|
+
"""
|
|
188
|
+
# Try to infer language from lint_result
|
|
189
|
+
if language is None:
|
|
190
|
+
if 'language' in lint_result:
|
|
191
|
+
language = lint_result['language']
|
|
192
|
+
elif 'project_type' in lint_result:
|
|
193
|
+
language = lint_result['project_type']
|
|
194
|
+
elif 'file_type' in lint_result:
|
|
195
|
+
language = lint_result['file_type']
|
|
196
|
+
else:
|
|
197
|
+
# Default to Python as a fallback
|
|
198
|
+
language = 'python'
|
|
199
|
+
|
|
200
|
+
linter = cls.create_linter(language=language)
|
|
201
|
+
return linter.format_lint_result(lint_result)
|
|
202
|
+
|
|
203
|
+
def lint_file(file_path: str, fix: bool = False, verbose: bool = False) -> Dict[str, Any]:
|
|
204
|
+
"""
|
|
205
|
+
Utility function to lint a single file.
|
|
206
|
+
|
|
207
|
+
Args:
|
|
208
|
+
file_path (str): Path to the file to lint.
|
|
209
|
+
fix (bool): Whether to automatically fix fixable issues.
|
|
210
|
+
verbose (bool): Whether to display verbose output.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
Dict[str, Any]: A dictionary containing lint results.
|
|
214
|
+
"""
|
|
215
|
+
return LinterFactory.lint_file(file_path, fix=fix, verbose=verbose)
|
|
216
|
+
|
|
217
|
+
def lint_project(project_path: str, language: Optional[str] = None, fix: bool = False, verbose: bool = False) -> Dict[str, Any]:
|
|
218
|
+
"""
|
|
219
|
+
Utility function to lint a project.
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
project_path (str): Path to the project directory.
|
|
223
|
+
language (Optional[str]): Language identifier to specify which linter to use.
|
|
224
|
+
fix (bool): Whether to automatically fix fixable issues.
|
|
225
|
+
verbose (bool): Whether to display verbose output.
|
|
226
|
+
|
|
227
|
+
Returns:
|
|
228
|
+
Dict[str, Any]: A dictionary containing lint results.
|
|
229
|
+
"""
|
|
230
|
+
return LinterFactory.lint_project(project_path, language=language, fix=fix, verbose=verbose)
|
|
231
|
+
|
|
232
|
+
def format_lint_result(lint_result: Dict[str, Any], language: Optional[str] = None) -> str:
|
|
233
|
+
"""
|
|
234
|
+
Format lint results into a human-readable string.
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
lint_result (Dict): The lint result dictionary.
|
|
238
|
+
language (Optional[str]): Language identifier to specify which formatter to use.
|
|
239
|
+
|
|
240
|
+
Returns:
|
|
241
|
+
str: A formatted string representation of the lint results.
|
|
242
|
+
"""
|
|
243
|
+
return LinterFactory.format_lint_result(lint_result, language=language)
|