feat: Add extensive language support for code splitting, scanning, and vulnerability detection by expanding file extensions, Tree-sitter node types, vulnerability patterns, and exclusion rules.
This commit is contained in:
parent
969d899476
commit
f743357bd7
|
|
@ -553,14 +553,16 @@ class QwenEmbedding(EmbeddingProvider):
|
||||||
payload = {
|
payload = {
|
||||||
"model": self.model,
|
"model": self.model,
|
||||||
"input": truncated_texts,
|
"input": truncated_texts,
|
||||||
"encoding_format": "float",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
url = f"{self.base_url.rstrip('/')}/embeddings"
|
url = f"{self.base_url.rstrip('/')}/embeddings"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient(timeout=60) as client:
|
async with httpx.AsyncClient(timeout=60.0) as client:
|
||||||
response = await client.post(url, headers=headers, json=payload)
|
response = await client.post(
|
||||||
|
url,
|
||||||
|
headers=headers,
|
||||||
|
json=payload,
|
||||||
|
)
|
||||||
response.raise_for_status()
|
response.raise_for_status()
|
||||||
data = response.json()
|
data = response.json()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,24 +30,63 @@ INDEX_VERSION = "2.0"
|
||||||
|
|
||||||
# 支持的文本文件扩展名
|
# 支持的文本文件扩展名
|
||||||
TEXT_EXTENSIONS = {
|
TEXT_EXTENSIONS = {
|
||||||
|
# 核心语言
|
||||||
".py", ".js", ".ts", ".tsx", ".jsx", ".java", ".go", ".rs",
|
".py", ".js", ".ts", ".tsx", ".jsx", ".java", ".go", ".rs",
|
||||||
".cpp", ".c", ".h", ".cc", ".hh", ".cs", ".php", ".rb",
|
".cpp", ".c", ".h", ".cc", ".hh", ".hpp", ".hxx", ".cs", ".php", ".rb",
|
||||||
".kt", ".swift", ".sql", ".sh", ".json", ".yml", ".yaml",
|
".kt", ".swift", ".dart", ".scala", ".sc", ".groovy", ".ktm", ".kts",
|
||||||
".xml", ".html", ".css", ".vue", ".svelte", ".md",
|
# .NET
|
||||||
|
".cshtml", ".vb", ".fs", ".fsi", ".fsx", ".sln", ".csproj", ".vbproj",
|
||||||
|
".fsproj", ".config", ".asax", ".master", ".ascx", ".asmx", ".svc",
|
||||||
|
# 数据与配置
|
||||||
|
".json", ".yml", ".yaml", ".toml", ".xml", ".properties", ".conf", ".ini",
|
||||||
|
# 脚本与命令
|
||||||
|
".sh", ".bash", ".zsh", ".fish", ".ps1", ".bat", ".cmd", ".sql", ".pl", ".pm", ".t",
|
||||||
|
# Web
|
||||||
|
".html", ".css", ".vue", ".svelte", ".md", ".proto", ".graphql", ".gql",
|
||||||
|
".prisma", ".sol", ".dockerfile", ".tf", ".hcl", ".tfvars",
|
||||||
|
# 其他
|
||||||
|
".lua", ".hs", ".lhs", ".clj", ".cljs", ".cljc", ".edn", ".ex", ".exs",
|
||||||
|
".erl", ".hrl", ".m", ".mm", ".r", ".rmd", ".properties"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 排除的目录
|
# 排除的目录
|
||||||
EXCLUDE_DIRS = {
|
EXCLUDE_DIRS = {
|
||||||
"node_modules", "vendor", "dist", "build", ".git",
|
# 构建与依赖
|
||||||
"__pycache__", ".pytest_cache", "coverage", ".nyc_output",
|
"node_modules", "vendor", "dist", "build", "target", "out", "bin", "obj",
|
||||||
".vscode", ".idea", ".vs", "target", "out", "bin", "obj",
|
"bower_components", "packages", "pkg", "Pods", ".gradle", ".m2",
|
||||||
"__MACOSX", ".next", ".nuxt", "venv", "env", ".env",
|
"vendor/bundle", ".bundle", "jspm_packages", "typings",
|
||||||
|
# 虚拟环境
|
||||||
|
"venv", "env", ".env", "virtualenv", ".venv",
|
||||||
|
# IDE 与元数据
|
||||||
|
".git", ".svn", ".hg", ".vscode", ".idea", ".vs", "TestResults",
|
||||||
|
"_ReSharper.*", ".settings", ".project", ".classpath", ".metadata",
|
||||||
|
# 缓存与日志
|
||||||
|
"__pycache__", ".pytest_cache", "coverage", "htmlcov", ".nyc_output",
|
||||||
|
".cache", ".next", ".nuxt", ".dart_tool", "htmlcov", "logs", "ipch",
|
||||||
|
# 云与基础设施
|
||||||
|
".aws-sam", ".serverless", ".terraform", ".terraform.d", "_site",
|
||||||
|
# 其他
|
||||||
|
"__MACOSX", "extern", "externals", "third-party", "3rdparty"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 排除的文件
|
# 排除的文件
|
||||||
EXCLUDE_FILES = {
|
EXCLUDE_FILES = {
|
||||||
".DS_Store", "package-lock.json", "yarn.lock", "pnpm-lock.yaml",
|
# 锁文件 (通常不索引,因为内容太长且无语义)
|
||||||
"Cargo.lock", "poetry.lock", "composer.lock", "Gemfile.lock",
|
"package-lock.json", "yarn.lock", "pnpm-lock.yaml", "Cargo.lock",
|
||||||
|
"poetry.lock", "composer.lock", "Gemfile.lock", "gradle.lockfile",
|
||||||
|
"mix.lock", "pnpm-workspace.yaml", "shrinkwrap.yaml",
|
||||||
|
# 静态资源与二进制
|
||||||
|
"*.min.js", "*.min.css", "jquery.js", "jquery.min.js", "*.map",
|
||||||
|
"*.pyc", "*.pyo", "*.pyd", "*.so", "*.dll", "*.exe", "*.o", "*.obj",
|
||||||
|
"*.a", "*.lib", "*.jar", "*.war", "*.ear", "*.class",
|
||||||
|
"*.svg", "*.ico", "*.woff*", "*.png", "*.jpg", "*.jpeg", "*.gif",
|
||||||
|
# 系统与秘密
|
||||||
|
".DS_Store", "thumbs.db", "desktop.ini", "*.pem", "*.crt", "*.key",
|
||||||
|
# 临时与日志
|
||||||
|
"*.log", "*.bak", "*.swp", "*.tmp", "tags",
|
||||||
|
# IDRE 与特定配置
|
||||||
|
"*.suo", "*.user", "*.sln.docstates", "*.vshost.*", "*.pdb",
|
||||||
|
".ruby-version", ".nvmrc"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -949,7 +988,7 @@ class CodeIndexer:
|
||||||
logger.info(f"📁 发现 {len(files)} 个文件待索引")
|
logger.info(f"📁 发现 {len(files)} 个文件待索引")
|
||||||
yield progress
|
yield progress
|
||||||
|
|
||||||
semaphore = asyncio.Semaphore(20) # 控制文件处理并发
|
semaphore = asyncio.Semaphore(10) # 降低并行度以平衡 CPU 和内存
|
||||||
file_hashes: Dict[str, str] = {}
|
file_hashes: Dict[str, str] = {}
|
||||||
|
|
||||||
async def process_file(file_path: str):
|
async def process_file(file_path: str):
|
||||||
|
|
@ -1083,7 +1122,7 @@ class CodeIndexer:
|
||||||
progress_callback(progress)
|
progress_callback(progress)
|
||||||
yield progress
|
yield progress
|
||||||
|
|
||||||
semaphore = asyncio.Semaphore(20)
|
semaphore = asyncio.Semaphore(10)
|
||||||
file_hashes: Dict[str, str] = dict(indexed_file_hashes)
|
file_hashes: Dict[str, str] = dict(indexed_file_hashes)
|
||||||
|
|
||||||
async def process_incremental_file(relative_path: str):
|
async def process_incremental_file(relative_path: str):
|
||||||
|
|
@ -1363,11 +1402,35 @@ class CodeIndexer:
|
||||||
if ext not in TEXT_EXTENSIONS:
|
if ext not in TEXT_EXTENSIONS:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# 检查排除文件
|
# 检查排除文件 (支持通配符)
|
||||||
if filename in EXCLUDE_FILES:
|
should_skip_file = False
|
||||||
|
for pattern in EXCLUDE_FILES:
|
||||||
|
if fnmatch.fnmatch(filename, pattern):
|
||||||
|
should_skip_file = True
|
||||||
|
break
|
||||||
|
if should_skip_file:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
# 排除疑似压缩过的文件 (通过行长度和内容分析)
|
||||||
file_path = os.path.join(root, filename)
|
file_path = os.path.join(root, filename)
|
||||||
|
try:
|
||||||
|
if os.path.getsize(file_path) > 50000: # > 50KB
|
||||||
|
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
|
||||||
|
# 检查前 5 行,防止第一行是版权注释的情况
|
||||||
|
is_minified = False
|
||||||
|
for _ in range(5):
|
||||||
|
line = f.readline()
|
||||||
|
if not line: break
|
||||||
|
if len(line) > 1000:
|
||||||
|
is_minified = True
|
||||||
|
break
|
||||||
|
|
||||||
|
if is_minified:
|
||||||
|
logger.info(f"⏩ 跳过疑似压缩或非代码文件: {filename}")
|
||||||
|
continue
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
relative_path = os.path.relpath(file_path, directory)
|
relative_path = os.path.relpath(file_path, directory)
|
||||||
|
|
||||||
# 检查排除模式
|
# 检查排除模式
|
||||||
|
|
|
||||||
|
|
@ -155,11 +155,29 @@ class TreeSitterParser:
|
||||||
".c": "c",
|
".c": "c",
|
||||||
".h": "c",
|
".h": "c",
|
||||||
".hpp": "cpp",
|
".hpp": "cpp",
|
||||||
|
".hxx": "cpp",
|
||||||
".cs": "csharp",
|
".cs": "csharp",
|
||||||
".php": "php",
|
".php": "php",
|
||||||
".rb": "ruby",
|
".rb": "ruby",
|
||||||
".kt": "kotlin",
|
".kt": "kotlin",
|
||||||
|
".ktm": "kotlin",
|
||||||
|
".kts": "kotlin",
|
||||||
".swift": "swift",
|
".swift": "swift",
|
||||||
|
".dart": "dart",
|
||||||
|
".scala": "scala",
|
||||||
|
".sc": "scala",
|
||||||
|
".groovy": "groovy",
|
||||||
|
".lua": "lua",
|
||||||
|
".hs": "haskell",
|
||||||
|
".clj": "clojure",
|
||||||
|
".ex": "elixir",
|
||||||
|
".erl": "erlang",
|
||||||
|
".m": "objective-c",
|
||||||
|
".mm": "objective-c",
|
||||||
|
".sh": "bash",
|
||||||
|
".bash": "bash",
|
||||||
|
".zsh": "bash",
|
||||||
|
".sql": "sql",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 各语言的函数/类节点类型
|
# 各语言的函数/类节点类型
|
||||||
|
|
@ -182,24 +200,55 @@ class TreeSitterParser:
|
||||||
"import": ["import_statement"],
|
"import": ["import_statement"],
|
||||||
},
|
},
|
||||||
"java": {
|
"java": {
|
||||||
"class": ["class_declaration"],
|
"class": ["class_declaration", "enum_declaration", "record_declaration"],
|
||||||
"method": ["method_declaration", "constructor_declaration"],
|
"method": ["method_declaration", "constructor_declaration"],
|
||||||
"interface": ["interface_declaration"],
|
"interface": ["interface_declaration", "annotation_type_declaration"],
|
||||||
"import": ["import_declaration"],
|
"import": ["import_declaration"],
|
||||||
},
|
},
|
||||||
|
"csharp": {
|
||||||
|
"class": ["class_declaration", "record_declaration", "struct_declaration", "enum_declaration"],
|
||||||
|
"method": ["method_declaration", "constructor_declaration", "destructor_declaration"],
|
||||||
|
"interface": ["interface_declaration"],
|
||||||
|
"import": ["using_directive"],
|
||||||
|
},
|
||||||
|
"cpp": {
|
||||||
|
"class": ["class_specifier", "struct_specifier", "enum_specifier"],
|
||||||
|
"function": ["function_definition"],
|
||||||
|
},
|
||||||
"go": {
|
"go": {
|
||||||
"struct": ["type_declaration"],
|
"struct": ["type_declaration"],
|
||||||
"function": ["function_declaration", "method_declaration"],
|
"function": ["function_declaration", "method_declaration"],
|
||||||
"interface": ["type_declaration"],
|
"interface": ["type_declaration"],
|
||||||
"import": ["import_declaration"],
|
"import": ["import_declaration"],
|
||||||
},
|
},
|
||||||
|
"rust": {
|
||||||
|
"struct": ["struct_item", "union_item"],
|
||||||
|
"enum": ["enum_item"],
|
||||||
|
"function": ["function_item"],
|
||||||
|
"class": ["impl_item", "trait_item"],
|
||||||
|
},
|
||||||
|
"php": {
|
||||||
|
"class": ["class_declaration"],
|
||||||
|
"function": ["function_definition", "method_definition"],
|
||||||
|
"interface": ["interface_declaration"],
|
||||||
|
},
|
||||||
|
"ruby": {
|
||||||
|
"class": ["class", "module"],
|
||||||
|
"function": ["method"],
|
||||||
|
},
|
||||||
|
"swift": {
|
||||||
|
"class": ["class_declaration", "struct_declaration", "enum_declaration"],
|
||||||
|
"function": ["function_declaration"],
|
||||||
|
"interface": ["protocol_declaration"],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# tree-sitter-languages 支持的语言列表
|
# tree-sitter-languages 支持的语言列表
|
||||||
SUPPORTED_LANGUAGES = {
|
SUPPORTED_LANGUAGES = {
|
||||||
"python", "javascript", "typescript", "tsx", "java", "go", "rust",
|
"python", "javascript", "typescript", "tsx", "java", "go", "rust",
|
||||||
"c", "cpp", "csharp", "php", "ruby", "kotlin", "swift", "bash",
|
"c", "cpp", "csharp", "php", "ruby", "kotlin", "swift", "bash",
|
||||||
"json", "yaml", "html", "css", "sql", "markdown",
|
"json", "yaml", "html", "css", "sql", "markdown", "dart", "scala",
|
||||||
|
"lua", "haskell", "clojure", "elixir", "erlang", "objective-c"
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
@ -384,6 +433,26 @@ class CodeSplitter:
|
||||||
(r"\$_POST\[", "post_input"),
|
(r"\$_POST\[", "post_input"),
|
||||||
(r"\$_REQUEST\[", "request_input"),
|
(r"\$_REQUEST\[", "request_input"),
|
||||||
],
|
],
|
||||||
|
"csharp": [
|
||||||
|
(r"Process\.Start\s*\(", "process_start"),
|
||||||
|
(r"SqlCommand\s*\(.*\+", "sql_concat"),
|
||||||
|
(r"Deserialize\s*\(", "deserialization"),
|
||||||
|
(r"AllowHtml\s*=", "unsafe_html"),
|
||||||
|
(r"password\s*=", "password_assign"),
|
||||||
|
],
|
||||||
|
"cpp": [
|
||||||
|
(r"\bsystem\s*\(", "system_call"),
|
||||||
|
(r"\bpopen\s*\(", "popen"),
|
||||||
|
(r"\bstrcpy\s*\(", "unsafe_string_copy"),
|
||||||
|
(r"\bsprintf\s*\(", "unsafe_string_format"),
|
||||||
|
(r"\bmalloc\s*\(", "memory_allocation"),
|
||||||
|
],
|
||||||
|
"ruby": [
|
||||||
|
(r"\beval\s*\(", "eval"),
|
||||||
|
(r"`.*`", "shell_execution"),
|
||||||
|
(r"system\s*\(", "system_call"),
|
||||||
|
(r"send\s*\(", "dynamic_method_call"),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
|
|
@ -585,6 +654,25 @@ class CodeSplitter:
|
||||||
(r"^(\s*)interface\s+(\w+)", ChunkType.INTERFACE),
|
(r"^(\s*)interface\s+(\w+)", ChunkType.INTERFACE),
|
||||||
(r"^(\s*)(?:public|private|protected)?\s*(?:static\s+)?function\s+(\w+)", ChunkType.FUNCTION),
|
(r"^(\s*)(?:public|private|protected)?\s*(?:static\s+)?function\s+(\w+)", ChunkType.FUNCTION),
|
||||||
],
|
],
|
||||||
|
"csharp": [
|
||||||
|
(r"^(\s*)(?:public|private|protected|internal)?\s*(?:static\s+)?(?:partial\s+)?(?:class|record|struct|enum)\s+(\w+)", ChunkType.CLASS),
|
||||||
|
(r"^(\s*)(?:public|private|protected|internal)?\s*interface\s+(\w+)", ChunkType.INTERFACE),
|
||||||
|
(r"^(\s*)(?:public|private|protected|internal)?\s*(?:async\s+)?(?:static\s+)?[\w<>\[\],\s]+\s+(\w+)\s*\([^)]*\)", ChunkType.METHOD),
|
||||||
|
],
|
||||||
|
"cpp": [
|
||||||
|
(r"^(\s*)(?:class|struct)\s+(\w+)", ChunkType.CLASS),
|
||||||
|
(r"^(\s*)[\w<>:]+\s+(\w+)\s*\([^)]*\)\s*\{", ChunkType.FUNCTION),
|
||||||
|
],
|
||||||
|
"ruby": [
|
||||||
|
(r"^(\s*)(?:class|module)\s+(\w+)", ChunkType.CLASS),
|
||||||
|
(r"^(\s*)def\s+(\w+)", ChunkType.FUNCTION),
|
||||||
|
],
|
||||||
|
"rust": [
|
||||||
|
(r"^(\s*)(?:pub\s+)?(?:struct|enum|union)\s+(\w+)", ChunkType.CLASS),
|
||||||
|
(r"^(\s*)(?:pub\s+)?(?:async\s+)?fn\s+(\w+)", ChunkType.FUNCTION),
|
||||||
|
(r"^(\s*)(?:pub\s+)?impl", ChunkType.CLASS),
|
||||||
|
(r"^(\s*)(?:pub\s+)?trait\s+(\w+)", ChunkType.INTERFACE),
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
lang_patterns = patterns.get(language, [])
|
lang_patterns = patterns.get(language, [])
|
||||||
|
|
@ -788,9 +876,23 @@ class CodeSplitter:
|
||||||
"java": [
|
"java": [
|
||||||
r"^import\s+([\w.]+);",
|
r"^import\s+([\w.]+);",
|
||||||
],
|
],
|
||||||
|
"csharp": [
|
||||||
|
r"^using\s+([\w.]+);",
|
||||||
|
],
|
||||||
"go": [
|
"go": [
|
||||||
r"['\"]([^'\"]+)['\"]",
|
r"['\"]([^'\"]+)['\"]",
|
||||||
],
|
],
|
||||||
|
"cpp": [
|
||||||
|
r'^#include\s+["<]([^">]+)[">]',
|
||||||
|
],
|
||||||
|
"php": [
|
||||||
|
r"^use\s+([\w\\]+);",
|
||||||
|
r"require(?:_once)?\s*\(['\"]([^'\"]+)['\"]\)",
|
||||||
|
],
|
||||||
|
"ruby": [
|
||||||
|
r"require\s+['\"]([^'\"]+)['\"]",
|
||||||
|
r"require_relative\s+['\"]([^'\"]+)['\"]",
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
for pattern in patterns.get(language, []):
|
for pattern in patterns.get(language, []):
|
||||||
|
|
@ -835,10 +937,21 @@ class CodeSplitter:
|
||||||
r"class\s+(\w+)",
|
r"class\s+(\w+)",
|
||||||
r"(\w+)\s*=\s*",
|
r"(\w+)\s*=\s*",
|
||||||
],
|
],
|
||||||
"javascript": [
|
"java": [
|
||||||
r"function\s+(\w+)",
|
r"(?:public|private|protected)?\s*(?:static\s+)?(?:final\s+)?(?:class|interface|enum|record)\s+(\w+)",
|
||||||
r"(?:const|let|var)\s+(\w+)",
|
r"(?:public|private|protected)?\s*(?:static\s+)?[\w<>\[\],\s]+\s+(\w+)\s*\([^)]*\)",
|
||||||
r"class\s+(\w+)",
|
],
|
||||||
|
"csharp": [
|
||||||
|
r"(?:class|record|struct|enum|interface)\s+(\w+)",
|
||||||
|
r"[\w<>\[\],\s]+\s+(\w+)\s*\([^)]*\)",
|
||||||
|
],
|
||||||
|
"cpp": [
|
||||||
|
r"(?:class|struct)\s+(\w+)",
|
||||||
|
r"(?:[\w<>:]+)\s+(\w+)\s*\([^)]*\)\s*\{",
|
||||||
|
],
|
||||||
|
"rust": [
|
||||||
|
r"(?:struct|enum|union|trait)\s+(\w+)",
|
||||||
|
r"fn\s+(\w+)",
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,18 +37,32 @@ def get_analysis_config(user_config: Optional[Dict[str, Any]] = None) -> Dict[st
|
||||||
|
|
||||||
# 支持的文本文件扩展名
|
# 支持的文本文件扩展名
|
||||||
TEXT_EXTENSIONS = [
|
TEXT_EXTENSIONS = [
|
||||||
".js", ".ts", ".tsx", ".jsx", ".py", ".java", ".go", ".rs",
|
".py", ".js", ".ts", ".tsx", ".jsx", ".java", ".go", ".rs",
|
||||||
".cpp", ".c", ".h", ".cc", ".hh", ".cs", ".php", ".rb",
|
".cpp", ".c", ".h", ".cc", ".hh", ".hpp", ".hxx", ".cs", ".php", ".rb",
|
||||||
".kt", ".swift", ".sql", ".sh", ".json", ".yml", ".yaml"
|
".kt", ".swift", ".dart", ".scala", ".sc", ".groovy", ".ktm", ".kts",
|
||||||
|
".cshtml", ".vb", ".fs", ".fsi", ".fsx", ".sln", ".csproj", ".vbproj",
|
||||||
|
".fsproj", ".config", ".asax", ".master", ".ascx", ".asmx", ".svc",
|
||||||
|
".json", ".yml", ".yaml", ".toml", ".xml", ".properties", ".conf", ".ini",
|
||||||
|
".sh", ".bash", ".zsh", ".fish", ".ps1", ".bat", ".cmd", ".sql", ".pl", ".pm", ".t",
|
||||||
|
".html", ".css", ".vue", ".svelte", ".md", ".proto", ".graphql", ".gql",
|
||||||
|
".prisma", ".sol", ".dockerfile", ".tf", ".hcl", ".tfvars",
|
||||||
|
".lua", ".hs", ".lhs", ".clj", ".cljs", ".cljc", ".edn", ".ex", ".exs",
|
||||||
|
".erl", ".hrl", ".m", ".mm", ".r", ".rmd"
|
||||||
]
|
]
|
||||||
|
|
||||||
# 排除的目录和文件模式
|
# 排除的目录和文件模式
|
||||||
EXCLUDE_PATTERNS = [
|
EXCLUDE_PATTERNS = [
|
||||||
"node_modules/", "vendor/", "dist/", "build/", ".git/",
|
# 常用目录
|
||||||
"__pycache__/", ".pytest_cache/", "coverage/", ".nyc_output/",
|
"node_modules/", "vendor/", "dist/", "build/", "target/", "out/", "bin/", "obj/",
|
||||||
".vscode/", ".idea/", ".vs/", "target/", "out/",
|
".git/", ".svn/", ".hg/", ".vscode/", ".idea/", ".vs/", ".settings/",
|
||||||
"__MACOSX/", ".DS_Store", "package-lock.json", "yarn.lock",
|
".gradle/", ".m2/", "venv/", "env/", ".env/", "__pycache__/",
|
||||||
"pnpm-lock.yaml", ".min.js", ".min.css", ".map"
|
".pytest_cache/", "coverage/", ".nyc_output/", "bower_components/",
|
||||||
|
"packages/", "pkg/", "Pods/", "TestResults/", "_ReSharper.*",
|
||||||
|
# 常见锁文件与二进制
|
||||||
|
"package-lock.json", "yarn.lock", "pnpm-lock.yaml", "Cargo.lock",
|
||||||
|
"poetry.lock", "composer.lock", "Gemfile.lock", "gradle.lockfile",
|
||||||
|
".min.js", ".min.css", ".map", ".DS_Store", "*.pdb", "*.dll", "*.exe",
|
||||||
|
"*.o", "*.obj", "*.a", "*.lib", "*.jar", "*.war", "*.class"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -67,13 +81,26 @@ def get_language_from_path(path: str) -> str:
|
||||||
"""从文件路径获取语言类型"""
|
"""从文件路径获取语言类型"""
|
||||||
ext = path.split('.')[-1].lower() if '.' in path else ''
|
ext = path.split('.')[-1].lower() if '.' in path else ''
|
||||||
language_map = {
|
language_map = {
|
||||||
|
'py': 'python',
|
||||||
'js': 'javascript', 'jsx': 'javascript',
|
'js': 'javascript', 'jsx': 'javascript',
|
||||||
'ts': 'typescript', 'tsx': 'typescript',
|
'ts': 'typescript', 'tsx': 'typescript',
|
||||||
'py': 'python', 'java': 'java', 'go': 'go',
|
'java': 'java', 'go': 'go', 'rs': 'rust',
|
||||||
'rs': 'rust', 'cpp': 'cpp', 'c': 'cpp',
|
'cpp': 'cpp', 'c': 'c', 'cc': 'cpp', 'h': 'c', 'hh': 'cpp',
|
||||||
'cc': 'cpp', 'h': 'cpp', 'hh': 'cpp',
|
'hpp': 'cpp', 'hxx': 'cpp',
|
||||||
'cs': 'csharp', 'php': 'php', 'rb': 'ruby',
|
'cs': 'csharp', 'php': 'php', 'rb': 'ruby',
|
||||||
'kt': 'kotlin', 'swift': 'swift'
|
'kt': 'kotlin', 'ktm': 'kotlin', 'kts': 'kotlin',
|
||||||
|
'swift': 'swift', 'dart': 'dart',
|
||||||
|
'scala': 'scala', 'sc': 'scala',
|
||||||
|
'groovy': 'groovy', 'gsh': 'groovy', 'gvy': 'groovy', 'gy': 'groovy',
|
||||||
|
'sql': 'sql', 'sh': 'bash', 'bash': 'bash', 'zsh': 'bash',
|
||||||
|
'pl': 'perl', 'pm': 'perl', 't': 'perl',
|
||||||
|
'lua': 'lua', 'hs': 'haskell', 'lhs': 'haskell',
|
||||||
|
'clj': 'clojure', 'cljs': 'clojure', 'cljc': 'clojure', 'edn': 'clojure',
|
||||||
|
'ex': 'elixir', 'exs': 'elixir', 'erl': 'erlang', 'hrl': 'erlang',
|
||||||
|
'm': 'objective-c', 'mm': 'objective-c',
|
||||||
|
'r': 'r', 'rmd': 'r',
|
||||||
|
'vb': 'visual-basic', 'fs': 'fsharp', 'fsi': 'fsharp', 'fsx': 'fsharp',
|
||||||
|
'tf': 'hcl', 'hcl': 'hcl', 'dockerfile': 'dockerfile'
|
||||||
}
|
}
|
||||||
return language_map.get(ext, 'text')
|
return language_map.get(ext, 'text')
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue