Refactor: improve fileEqual impl
Some checks are pending
Build / Build (push) Waiting to run
Build / Diff output (push) Blocked by required conditions
Build / Deploy to Cloudflare Pages (push) Blocked by required conditions
Build / Deploy to GitHub and GitLab (push) Blocked by required conditions

This commit is contained in:
SukkaW 2025-03-06 00:01:15 +08:00
parent 5f96fd024e
commit e13cee4e46
2 changed files with 34 additions and 51 deletions

View File

@ -39,6 +39,12 @@ describe('fileEqual', () => {
false
));
it('comment less', () => test(
['# A', '# B', 'B'],
['# A', 'B'],
false
));
it('larger', () => test(
['A', 'B'],
['A', 'B', 'C'],
@ -51,9 +57,15 @@ describe('fileEqual', () => {
false
));
it('eol', () => test(
it('eol more', () => test(
['A', 'B'],
['A', 'B', ''],
true
false
));
it('eol less', () => test(
['A', 'B', ''],
['A', 'B'],
false
));
});

View File

@ -11,75 +11,46 @@ export async function fileEqual(linesA: string[], source: AsyncIterable<string>
return false;
}
const linesABound = linesA.length - 1;
const maxIndexA = linesA.length - 1;
let index = -1;
let aLen = 0;
let bLen = 0;
for await (const lineB of source) {
index++;
if (index > linesABound) {
return (index === linesA.length && lineB.length === 0);
if (index > maxIndexA) {
return false;
}
const lineA = linesA[index];
aLen = lineA.length;
bLen = lineB.length;
if (aLen === 0) {
if (bLen === 0) {
// both lines are empty, check next line
continue;
}
// lineA is empty but lineB is not
return false;
}
// now lineA can not be empty
if (bLen === 0) {
// lineB is empty but lineA is not
const lineAIsComment = isCommentLine(lineA);
const lineBIsComment = isCommentLine(lineB);
if (lineAIsComment !== lineBIsComment) {
return false;
}
// now both lines can not be empty
const firstCharA = lineA.charCodeAt(0);
const firstCharB = lineB.charCodeAt(0);
if (firstCharA !== firstCharB) {
return false;
}
// now firstCharA is equal to firstCharB, we only need to check the first char
if (firstCharA === 35 /* # */) {
// Now both line are either both comment or both not comment
// We only need to compare one of them
if (lineAIsComment) {
continue;
}
// adguard conf
if (firstCharA === 33 /* ! */) {
continue;
}
if (
firstCharA === 47 /* / */
&& lineA[1] === '/' && lineB[1] === '/'
&& lineA[3] === '#' && lineB[3] === '#'
) {
continue;
}
if (aLen !== bLen) {
return false;
}
if (lineA !== lineB) {
return false;
}
}
// The file becomes larger
return !(index < linesABound);
return index === maxIndexA;
}
export function isCommentLine(line: string): boolean {
const firstChar = line.charCodeAt(0);
return (
firstChar === 35 // #
|| firstChar === 33 // !
|| (firstChar === 47 && line[1] === '/' && line[3] === '#') // //##
);
}
export async function compareAndWriteFile(span: Span, linesA: string[], filePath: string) {