Skip to content

Commit 29b0d66

Browse files
author
Taois
committed
feat: 文件头工具调优
1 parent 5d10671 commit 29b0d66

File tree

3 files changed

+283
-47
lines changed

3 files changed

+283
-47
lines changed

drpy-node-bundle/libs/localDsCore.bundled.js

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -383618,6 +383618,14 @@ var FileHeaderManager = class {
383618383618
headerRegex: /@header\(([\s\S]*?)\)/,
383619383619
createComment: (content) => `"""\n${content}\n"""`,
383620383620
topCommentsRegex: /^(\s*(#[^\n]*\n|'''[\s\S]*?'''|"""[\s\S]*?""")\s*)+/
383621+
},
383622+
".php": {
383623+
start: "/*",
383624+
end: "*/",
383625+
regex: /(<\?php\s*)?(\s*\/\*[\s\S]*?\*\/)/,
383626+
headerRegex: /@header\(([\s\S]*?)\)/,
383627+
createComment: (content) => `/*\n${content}\n*/`,
383628+
topCommentsRegex: /(<\?php\s*)?(\s*(\/\/[^\n]*\n|\/\*[\s\S]*?\*\/)\s*)+/
383621383629
}
383622383630
};
383623383631
/**
@@ -383635,12 +383643,20 @@ var FileHeaderManager = class {
383635383643
let stringChar = "";
383636383644
let escape = false;
383637383645
let inLineComment = false;
383646+
let inBlockComment = false;
383638383647
for (; index < text.length; index++) {
383639383648
const char = text[index];
383640383649
if (inLineComment) {
383641383650
if (char === "\n") inLineComment = false;
383642383651
continue;
383643383652
}
383653+
if (inBlockComment) {
383654+
if (char === "*" && text[index + 1] === "/") {
383655+
inBlockComment = false;
383656+
index++;
383657+
}
383658+
continue;
383659+
}
383644383660
if (inString) {
383645383661
if (escape) escape = false;
383646383662
else if (char === "\\") escape = true;
@@ -383650,6 +383666,9 @@ var FileHeaderManager = class {
383650383666
if (char === "/" && text[index + 1] === "/") {
383651383667
inLineComment = true;
383652383668
index++;
383669+
} else if (char === "/" && text[index + 1] === "*") {
383670+
inBlockComment = true;
383671+
index++;
383653383672
} else if (ext === ".py" && char === "#") inLineComment = true;
383654383673
else if (char === "\"" || char === "'") {
383655383674
inString = true;
@@ -383667,19 +383686,18 @@ var FileHeaderManager = class {
383667383686
return null;
383668383687
}
383669383688
/**
383670-
* 解析JavaScript对象字面量(支持无引号属性名)
383689+
* 解析对象字符串
383671383690
* @param {string} str 对象字符串
383672383691
* @returns {Object} 解析后的对象
383673383692
*/
383674383693
static parseObjectLiteral(str) {
383675-
const normalized = str.replace(/([{,]\s*)([a-zA-Z_$][\w$]*)(\s*:)/g, "$1\"$2\"$3").replace(/'([^']+)'/g, "\"$1\"");
383676383694
try {
383677-
return JSON.parse(normalized);
383695+
return JSON5.parse(str);
383678383696
} catch (e) {
383679383697
try {
383680383698
return new Function(`return ${str}`)();
383681-
} catch {
383682-
throw new Error(`Invalid header object: ${str}`);
383699+
} catch (evalError) {
383700+
throw new Error(`Invalid header object: ${str}. Error: ${evalError.message}`);
383683383701
}
383684383702
}
383685383703
}
@@ -383753,34 +383771,51 @@ var FileHeaderManager = class {
383753383771
const ext = path.extname(filePath);
383754383772
const config = this.COMMENT_CONFIG[ext];
383755383773
if (!config) throw new Error(`Unsupported file type: ${ext}`);
383756-
const headerStr = `@header(${JSON.stringify(headerObj, null, 2).replace(/"([a-zA-Z_$][\w$]*)":/g, "$1:").replace(/"/g, "'")})`;
383774+
const headerStr = `@header(${JSON5.stringify(headerObj, null, 2)})`;
383757383775
const match = content.match(config.regex);
383758383776
let newContent;
383759383777
if (match) {
383760383778
const [fullComment] = match;
383761383779
const commentStartIndex = content.indexOf(fullComment);
383762383780
const commentEndIndex = commentStartIndex + fullComment.length;
383763-
if (content.substring(0, commentStartIndex).trim() !== "") newContent = config.createComment(headerStr) + "\n\n" + content;
383764-
else {
383781+
const beforeComment = content.substring(0, commentStartIndex);
383782+
if (!(beforeComment.trim() === "" || ext === ".php" && beforeComment.trim() === "<?php")) {
383783+
let newComment = config.createComment(headerStr) + "\n\n";
383784+
if (ext === ".php") if (content.trim().startsWith("<?php")) newContent = content.replace(/<\?php\s*/, `<?php\n\n${newComment.trim()}\n\n`);
383785+
else newContent = `<?php\n\n${newComment.trim()}\n\n` + content;
383786+
else newContent = newComment + content;
383787+
} else {
383765383788
const headerBlock = this.findHeaderBlock(fullComment, ext);
383766383789
if (headerBlock) {
383767383790
const updatedComment = fullComment.substring(0, headerBlock.start) + headerStr + fullComment.substring(headerBlock.end);
383768383791
newContent = content.substring(0, commentStartIndex) + updatedComment + content.substring(commentEndIndex);
383769383792
} else {
383770-
const updatedComment = fullComment.replace(config.end, "").trim() + `\n${headerStr}\n${config.end}`;
383793+
const trimmedComment = fullComment.trim();
383794+
let updatedComment;
383795+
if (ext === ".php" && trimmedComment.startsWith("<?php")) {
383796+
const endMarker = config.end;
383797+
const lastIndex = fullComment.lastIndexOf(endMarker);
383798+
if (lastIndex !== -1) updatedComment = fullComment.substring(0, lastIndex).trim() + `\n${headerStr}\n${endMarker}` + fullComment.substring(lastIndex + endMarker.length);
383799+
else updatedComment = fullComment + `\n${config.createComment(headerStr)}`;
383800+
} else updatedComment = fullComment.replace(config.end, "").trim() + `\n${headerStr}\n${config.end}`;
383771383801
newContent = content.substring(0, commentStartIndex) + updatedComment + content.substring(commentEndIndex);
383772383802
}
383773383803
}
383774-
} else newContent = config.createComment(headerStr) + "\n\n" + content;
383804+
} else {
383805+
let newComment = config.createComment(headerStr) + "\n\n";
383806+
if (ext === ".php") if (content.trim().startsWith("<?php")) newContent = content.replace(/<\?php\s*/, `<?php\n\n${newComment.trim()}\n\n`);
383807+
else newContent = `<?php\n\n${newComment.trim()}\n\n` + content;
383808+
else newContent = newComment + content;
383809+
}
383775383810
if (!newContent.replace(config.regex, "").trim()) throw new Error("写入失败:内容不能只包含文件头而无原始内容");
383776383811
if (!newContent || newContent.trim().length === 0) throw new Error("Generated content is empty, operation aborted");
383777383812
const originalCodeLines = originalContent.split("\n").filter((line) => {
383778383813
const trimmed = line.trim();
383779-
return trimmed && !trimmed.startsWith("//") && !trimmed.startsWith("/*") && !trimmed.startsWith("*") && !trimmed.startsWith("*/") && !trimmed.startsWith("#") && !trimmed.startsWith("\"\"\"") && !trimmed.startsWith("'''");
383814+
return trimmed && !trimmed.startsWith("//") && !trimmed.startsWith("/*") && !trimmed.startsWith("*") && !trimmed.startsWith("*/") && !trimmed.startsWith("#") && !trimmed.startsWith("\"\"\"") && !trimmed.startsWith("'''") && !trimmed.startsWith("<?php");
383780383815
});
383781383816
const newCodeLines = newContent.split("\n").filter((line) => {
383782383817
const trimmed = line.trim();
383783-
return trimmed && !trimmed.startsWith("//") && !trimmed.startsWith("/*") && !trimmed.startsWith("*") && !trimmed.startsWith("*/") && !trimmed.startsWith("#") && !trimmed.startsWith("\"\"\"") && !trimmed.startsWith("'''") && !trimmed.includes("@header(");
383818+
return trimmed && !trimmed.startsWith("//") && !trimmed.startsWith("/*") && !trimmed.startsWith("*") && !trimmed.startsWith("*/") && !trimmed.startsWith("#") && !trimmed.startsWith("\"\"\"") && !trimmed.startsWith("'''") && !trimmed.startsWith("<?php") && !trimmed.includes("@header(");
383784383819
});
383785383820
if (originalCodeLines.length > 5 && newCodeLines.length < originalCodeLines.length * .8) throw new Error("Content integrity check failed: significant code loss detected, operation aborted");
383786383821
let backupPath = null;
@@ -383840,11 +383875,18 @@ var FileHeaderManager = class {
383840383875
let [fullComment] = match;
383841383876
const headerBlock = this.findHeaderBlock(fullComment, ext);
383842383877
if (headerBlock) {
383843-
let cleanedInner = (fullComment.substring(0, headerBlock.start) + fullComment.substring(headerBlock.end)).replace(config.start, "").replace(config.end, "").split("\n").filter((line) => line.trim().length > 0).join("\n");
383844-
if (!cleanedInner.trim()) content = content.replace(fullComment, "");
383878+
let beforeHeader = fullComment.substring(0, headerBlock.start);
383879+
let afterHeader = fullComment.substring(headerBlock.end);
383880+
beforeHeader = beforeHeader.replace(config.start, "");
383881+
afterHeader = afterHeader.replace(config.end, "");
383882+
if (ext === ".php") beforeHeader = beforeHeader.replace(/<\?php\s*/, "");
383883+
let cleanedInner = (beforeHeader + "\n" + afterHeader).split("\n").map((line) => line.trim()).filter((line) => line.length > 0).join("\n");
383884+
if (!cleanedInner) if (ext === ".php" && fullComment.trim().startsWith("<?php")) content = content.replace(fullComment, "<?php\n");
383885+
else content = content.replace(fullComment, "");
383845383886
else {
383846-
const newComment = `${config.start}\n${cleanedInner}\n${config.end}`;
383847-
content = content.replace(fullComment, newComment);
383887+
let newComment = `${config.start}\n${cleanedInner}\n${config.end}`;
383888+
if (ext === ".php" && fullComment.trim().startsWith("<?php")) newComment = `<?php\n\n${newComment}`;
383889+
content = content.replace(fullComment, () => newComment);
383848383890
}
383849383891
}
383850383892
return content.trim();

scripts/test/test_cctv_header.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import fs from 'fs/promises';
2+
import path from 'path';
3+
import {fileURLToPath} from 'url';
4+
import FileHeaderManager from '../../utils/fileHeaderManager.js';
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
const __dirname = path.dirname(__filename);
8+
9+
// 源文件路径
10+
const sourceFile = path.resolve(__dirname, '../../spider/js/央视大全[官].js');
11+
// 测试文件路径
12+
const testFile = path.resolve(__dirname, 'test_cctv_header_temp.js');
13+
14+
async function runTest() {
15+
console.log('=== 开始测试文件头操作 ===');
16+
console.log(`源文件: ${sourceFile}`);
17+
console.log(`测试文件: ${testFile}`);
18+
19+
try {
20+
// 1. 复制文件
21+
console.log('\n[1/6] 正在复制源文件到测试文件...');
22+
try {
23+
await fs.copyFile(sourceFile, testFile);
24+
console.log('✅ 复制完成。');
25+
} catch (e) {
26+
console.error('❌ 复制失败:', e.message);
27+
return;
28+
}
29+
30+
// 2. 读取文件头
31+
console.log('\n[2/6] 正在读取文件头...');
32+
let header = await FileHeaderManager.readHeader(testFile);
33+
if (header) {
34+
console.log('✅ 读取到的文件头:', JSON.stringify(header, null, 2));
35+
} else {
36+
console.log('⚠️ 未找到文件头,将尝试创建新文件头。');
37+
header = {};
38+
}
39+
40+
// 3. 修改文件头
41+
console.log('\n[3/6] 正在修改并写入文件头...');
42+
const timestamp = Date.now();
43+
const originalTitle = header.title || 'Unknown';
44+
header.title = `${originalTitle}_TEST_${timestamp}`;
45+
header.test_timestamp = timestamp;
46+
47+
try {
48+
await FileHeaderManager.writeHeader(testFile, header);
49+
console.log('✅ 写入操作完成。');
50+
} catch (e) {
51+
console.error('❌ 写入失败:', e.message);
52+
throw e;
53+
}
54+
55+
// 4. 再次读取验证
56+
console.log('\n[4/6] 再次读取以验证写入...');
57+
const newHeader = await FileHeaderManager.readHeader(testFile);
58+
console.log('读取到的新文件头:', JSON.stringify(newHeader, null, 2));
59+
60+
if (newHeader && newHeader.test_timestamp === timestamp) {
61+
console.log('✅ 验证成功:新字段已存在且值正确。');
62+
} else {
63+
console.error('❌ 验证失败:新字段未找到或值不匹配。');
64+
throw new Error('Verification failed');
65+
}
66+
67+
// 5. 移除文件头
68+
console.log('\n[5/6] 正在移除文件头...');
69+
// 注意:removeHeader 返回处理后的内容字符串,不自动写入文件
70+
const contentWithoutHeader = await FileHeaderManager.removeHeader(testFile);
71+
72+
// 我们需要手动写入文件以验证
73+
await fs.writeFile(testFile, contentWithoutHeader);
74+
console.log('✅ 移除操作完成,已写回文件。');
75+
76+
// 6. 验证移除结果
77+
console.log('\n[6/6] 验证移除结果...');
78+
const headerAfterRemove = await FileHeaderManager.readHeader(testFile);
79+
if (!headerAfterRemove || Object.keys(headerAfterRemove).length === 0) {
80+
console.log('✅ 验证成功:文件头已移除。');
81+
} else {
82+
console.log('❌ 验证失败:文件头仍然存在:', headerAfterRemove);
83+
throw new Error('Removal verification failed');
84+
}
85+
86+
console.log('\n=== 测试全部通过 ===');
87+
88+
} catch (error) {
89+
console.error('\n❌ 测试过程中发生错误:', error);
90+
} finally {
91+
// 7. 清理
92+
console.log('\n[7/7] 清理测试文件...');
93+
try {
94+
await fs.unlink(testFile);
95+
console.log('✅ 测试文件已删除。');
96+
} catch (e) {
97+
console.error('⚠️ 删除测试文件失败 (可能文件不存在):', e.message);
98+
}
99+
}
100+
}
101+
102+
runTest();

0 commit comments

Comments
 (0)