chore: format all common files (#431)

This commit is contained in:
tecvan
2025-07-31 21:46:47 +08:00
committed by GitHub
parent 8136ddd82d
commit 40088b0a05
60 changed files with 658 additions and 288 deletions

View File

@@ -1,10 +1,26 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
SourceFile,
ChineseComment,
ParsedComment,
FileWithComments,
CommentType,
MultiLineContext
MultiLineContext,
} from '../types/index';
import { getCommentPatterns } from '../utils/language';
import { containsChinese, cleanCommentText } from '../utils/chinese';
@@ -69,15 +85,17 @@ const parseSingleLineComments = (
let matchCount = 0;
const maxMatches = 100; // Limit each line to a maximum of 100 matches
let lastIndex = 0;
while ((match = pattern.exec(line)) !== null) {
// Multiple protections against infinite loops
matchCount++;
if (matchCount > maxMatches) {
console.warn(`⚠️ 单行匹配次数过多,中断处理: ${line.substring(0, 50)}...`);
console.warn(
`⚠️ 单行匹配次数过多,中断处理: ${line.substring(0, 50)}...`,
);
break;
}
// Check if lastIndex is advancing to prevent an infinite loop
if (pattern.global) {
if (pattern.lastIndex <= lastIndex) {
@@ -89,7 +107,7 @@ const parseSingleLineComments = (
}
lastIndex = pattern.lastIndex;
}
if (match[1]) {
const commentContent = match[1];
let commentStartIndex = match.index!;
@@ -246,7 +264,6 @@ const parseMultiLineComments = (
const commentContent = line.substring(0, endMatch.index!);
commentLines.push(commentContent);
comments.push({
content: commentLines.join('\n'),
startLine: commentStart!.line,
@@ -298,11 +315,14 @@ export const filterChineseComments = (
language?: string,
): ChineseComment[] => {
const result: ChineseComment[] = [];
for (const comment of comments) {
if (comment.type === 'multi-line' && comment.content.includes('\n')) {
// Multi-line comments: line-by-line processing
const multiLineResults = processMultiLineCommentForChinese(comment, language);
const multiLineResults = processMultiLineCommentForChinese(
comment,
language,
);
result.push(...multiLineResults);
} else if (containsChinese(comment.content)) {
// Single-line comments or single-line multi-line comments
@@ -316,7 +336,7 @@ export const filterChineseComments = (
});
}
}
return result;
};
@@ -329,14 +349,14 @@ const processMultiLineCommentForChinese = (
): ChineseComment[] => {
const lines = comment.content.split('\n');
const result: ChineseComment[] = [];
lines.forEach((line, lineIndex) => {
const cleanedLine = cleanCommentText(line, 'multi-line', language);
if (containsChinese(cleanedLine)) {
// Calculate the position of this line in the original file
const actualLineNumber = comment.startLine + lineIndex;
// Create a comment object representing this line
const lineComment: ChineseComment = {
content: cleanedLine,
@@ -350,14 +370,14 @@ const processMultiLineCommentForChinese = (
isPartOfMultiLine: true,
originalComment: comment,
lineIndexInComment: lineIndex,
totalLinesInComment: lines.length
}
totalLinesInComment: lines.length,
},
};
result.push(lineComment);
}
});
return result;
};
@@ -393,7 +413,9 @@ export const detectChineseInFile = (file: SourceFile): ChineseComment[] => {
/**
* Batch detection of Chinese comments in multiple files
*/
export const detectChineseInFiles = (files: SourceFile[]): FileWithComments[] => {
export const detectChineseInFiles = (
files: SourceFile[],
): FileWithComments[] => {
const results: FileWithComments[] = [];
for (let i = 0; i < files.length; i++) {
@@ -428,7 +450,9 @@ export const detectChineseInFiles = (files: SourceFile[]): FileWithComments[] =>
/**
* Get annotation statistics
*/
export const getCommentStats = (files: SourceFile[]): {
export const getCommentStats = (
files: SourceFile[],
): {
totalFiles: number;
filesWithComments: number;
totalComments: number;
@@ -441,12 +465,15 @@ export const getCommentStats = (files: SourceFile[]): {
const commentsByType: Record<CommentType, number> = {
'single-line': 0,
'multi-line': 0,
'documentation': 0
documentation: 0,
};
files.forEach(file => {
const allComments = parseComments(file);
const chineseCommentsInFile = filterChineseComments(allComments, file.language);
const chineseCommentsInFile = filterChineseComments(
allComments,
file.language,
);
if (chineseCommentsInFile.length > 0) {
filesWithComments++;
@@ -465,6 +492,6 @@ export const getCommentStats = (files: SourceFile[]): {
filesWithComments,
totalComments,
chineseComments,
commentsByType
commentsByType,
};
};

View File

@@ -1,13 +1,35 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { promises as fs } from 'fs';
import { SourceFile, FileScanConfig, Result } from '../types/index';
import { detectLanguage, filterFilesByExtensions, isTextFile } from '../utils/language';
import {
detectLanguage,
filterFilesByExtensions,
isTextFile,
} from '../utils/language';
import { getGitTrackedFiles, getAllGitFiles } from '../utils/git';
import { tryCatch } from '../utils/fp';
/**
* Read the file contents and create a SourceFile object
*/
export const readSourceFile = async (filePath: string): Promise<Result<SourceFile>> => {
export const readSourceFile = async (
filePath: string,
): Promise<Result<SourceFile>> => {
return tryCatch(async () => {
const content = await fs.readFile(filePath, 'utf-8');
const language = detectLanguage(filePath);
@@ -15,7 +37,7 @@ export const readSourceFile = async (filePath: string): Promise<Result<SourceFil
return {
path: filePath,
content,
language
language,
};
});
};
@@ -23,14 +45,17 @@ export const readSourceFile = async (filePath: string): Promise<Result<SourceFil
/**
* Batch reading of source files
*/
export const readSourceFiles = async (filePaths: string[]): Promise<SourceFile[]> => {
export const readSourceFiles = async (
filePaths: string[],
): Promise<SourceFile[]> => {
const results = await Promise.allSettled(
filePaths.map(path => readSourceFile(path))
filePaths.map(path => readSourceFile(path)),
);
return results
.filter((result): result is PromiseFulfilledResult<Result<SourceFile>> =>
result.status === 'fulfilled' && result.value.success
.filter(
(result): result is PromiseFulfilledResult<Result<SourceFile>> =>
result.status === 'fulfilled' && result.value.success,
)
.map(result => (result.value as { success: true; data: SourceFile }).data);
};
@@ -38,7 +63,9 @@ export const readSourceFiles = async (filePaths: string[]): Promise<SourceFile[]
/**
* Get the source code file in the Git repository
*/
export const getSourceFiles = async (config: FileScanConfig): Promise<Result<string[]>> => {
export const getSourceFiles = async (
config: FileScanConfig,
): Promise<Result<string[]>> => {
const { root, extensions, includeUntracked } = config;
return tryCatch(async () => {
@@ -66,7 +93,9 @@ export const getSourceFiles = async (config: FileScanConfig): Promise<Result<str
/**
* Scan and read all source code files
*/
export const scanSourceFiles = async (config: FileScanConfig): Promise<Result<SourceFile[]>> => {
export const scanSourceFiles = async (
config: FileScanConfig,
): Promise<Result<SourceFile[]>> => {
return tryCatch(async () => {
const filesResult = await getSourceFiles(config);
@@ -94,28 +123,32 @@ export const isFileAccessible = async (filePath: string): Promise<boolean> => {
/**
* Get file statistics
*/
export const getFileStats = async (filePaths: string[]): Promise<{
export const getFileStats = async (
filePaths: string[],
): Promise<{
total: number;
accessible: number;
textFiles: number;
supportedFiles: number;
}> => {
const accessibilityResults = await Promise.allSettled(
filePaths.map(isFileAccessible)
filePaths.map(isFileAccessible),
);
const accessible = accessibilityResults.filter(
(result): result is PromiseFulfilledResult<boolean> =>
result.status === 'fulfilled' && result.value
result.status === 'fulfilled' && result.value,
).length;
const textFiles = filePaths.filter(isTextFile).length;
const supportedFiles = filePaths.filter(path => detectLanguage(path) !== 'other').length;
const supportedFiles = filePaths.filter(
path => detectLanguage(path) !== 'other',
).length;
return {
total: filePaths.length,
accessible,
textFiles,
supportedFiles
supportedFiles,
};
};

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ProcessingReport,
ProcessingStats,
@@ -198,18 +214,22 @@ export const generateMarkdownReport = (report: ProcessingReport): string => {
detail.status === 'success'
? '✅'
: detail.status === 'error'
? '❌'
: detail.status === 'skipped'
? '⏭️'
: '🔄';
? '❌'
: detail.status === 'skipped'
? '⏭️'
: '🔄';
markdown += `| ${detail.file} | ${status} | ${detail.commentCount} | ${duration} | ${detail.errorMessage || '-'} |\n`;
markdown += `| ${detail.file} | ${status} | ${
detail.commentCount
} | ${duration} | ${detail.errorMessage || '-'} |\n`;
});
if (stats.errors.length > 0) {
markdown += '\n## ❌ 错误详情\n\n';
stats.errors.forEach((error, index) => {
markdown += `${index + 1}. **${error.file}**\n \`\`\`\n ${error.error}\n \`\`\`\n\n`;
markdown += `${index + 1}. **${error.file}**\n \`\`\`\n ${
error.error
}\n \`\`\`\n\n`;
});
}
@@ -276,7 +296,9 @@ export class ProgressDisplay {
const speed = current / elapsed;
const eta = speed > 0 ? (this.total - current) / speed : 0;
let line = `进度: ${current}/${this.total} (${percentage}%) | 耗时: ${elapsed.toFixed(1)}s`;
let line = `进度: ${current}/${
this.total
} (${percentage}%) | 耗时: ${elapsed.toFixed(1)}s`;
if (eta > 0) {
line += ` | 预计剩余: ${eta.toFixed(1)}s`;

View File

@@ -1,3 +1,19 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
TranslationResult,
TranslationContext,
@@ -7,7 +23,10 @@ import {
import { TranslationConfig } from '../types/config';
import { retry, chunk } from '../utils/fp';
import { isValidTranslation } from '../utils/chinese';
import { translate as volcTranslate, TranslateConfig as VolcTranslateConfig } from '../volc/translate';
import {
translate as volcTranslate,
TranslateConfig as VolcTranslateConfig,
} from '../volc/translate';
/**
* Translation services
@@ -59,7 +78,7 @@ export class TranslationService {
private async callVolcTranslate(texts: string[]): Promise<string[]> {
const volcConfig = this.toVolcConfig();
const response = await volcTranslate(texts, volcConfig);
return response.TranslationList.map(item => item.Translation);
}
@@ -101,7 +120,9 @@ export class TranslationService {
return result;
} catch (error) {
throw new TranslationError(
`Translation failed: ${error instanceof Error ? error.message : String(error)}`,
`Translation failed: ${
error instanceof Error ? error.message : String(error)
}`,
comment,
);
}
@@ -146,7 +167,7 @@ export class TranslationService {
// Batch translation of uncached comments
const chunks = chunk(uncachedComments, concurrency);
for (const chunkItems of chunks) {
try {
const textsToTranslate = chunkItems.map(item => item.comment.content);
@@ -163,13 +184,16 @@ export class TranslationService {
const result: TranslationResult = {
original: item.comment.content,
translated,
confidence: this.calculateConfidence(translated, item.comment.content),
confidence: this.calculateConfidence(
translated,
item.comment.content,
),
};
// cache results
const cacheKey = this.getCacheKey(item.comment.content);
this.cache.set(cacheKey, result);
results[item.index] = result;
} else {
// If the translation fails, an error result is created
@@ -189,8 +213,12 @@ export class TranslationService {
confidence: 0,
};
});
console.warn(`批量翻译失败: ${error instanceof Error ? error.message : String(error)}`);
console.warn(
`批量翻译失败: ${
error instanceof Error ? error.message : String(error)
}`,
);
}
}