Skip to content

Commit 0a4c99a

Browse files
committed
Refactor/Chore: prepare build infra for further optimization
1 parent 78afa59 commit 0a4c99a

21 files changed

+282
-201
lines changed

Build/build-anti-bogus-domain.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ const { fetchRemoteTextAndCreateReadlineInterface, readFileByLine } = require('.
66
const { processLine } = require('./lib/process-line');
77
const { runner } = require('./lib/trace-runner');
88

9-
runner(__filename, async () => {
9+
const buildAntiBogusDomain = async () => {
1010
/** @type {string[]} */
1111
const res = [];
1212
for await (const line of await fetchRemoteTextAndCreateReadlineInterface('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf')) {
@@ -56,4 +56,10 @@ runner(__filename, async () => {
5656
path.resolve(__dirname, '../List/ip/reject.conf'),
5757
path.resolve(__dirname, '../Clash/ip/reject.txt')
5858
));
59-
});
59+
};
60+
61+
module.exports.buildAntiBogusDomain = buildAntiBogusDomain;
62+
63+
if (require.main === module) {
64+
runner(__filename, buildAntiBogusDomain);
65+
}

Build/build-apple-cdn.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const { createRuleset } = require('./lib/create-file');
33
const { parseFelixDnsmasq } = require('./lib/parse-dnsmasq');
44
const { runner } = require('./lib/trace-runner');
55

6-
runner(__filename, async () => {
6+
const buildAppleCdn = async () => {
77
const res = await parseFelixDnsmasq('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/apple.china.conf');
88

99
const description = [
@@ -40,4 +40,10 @@ runner(__filename, async () => {
4040
path.resolve(__dirname, '../Clash/domainset/apple_cdn.txt')
4141
)
4242
]);
43-
});
43+
};
44+
45+
module.exports.buildAppleCdn = buildAppleCdn;
46+
47+
if (require.main === module) {
48+
runner(__filename, buildAppleCdn);
49+
}

Build/build-cdn-conf.js

+13-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// @ts-check
22
const path = require('path');
33
const { createRuleset } = require('./lib/create-file');
4-
const { minifyRules } = require('./lib/minify-rules');
54
const { fetchRemoteTextAndCreateReadlineInterface, readFileByLine } = require('./lib/fetch-remote-text-by-line');
65
const Trie = require('./lib/trie');
76
const { runner } = require('./lib/trace-runner');
87
const fs = require('fs');
8+
const { processLine } = require('./lib/process-line');
99

1010
const publicSuffixPath = path.resolve(__dirname, '../node_modules/.cache/public_suffix-list_dat.txt');
1111

12-
runner(__filename, async () => {
12+
const buildCdnConf = async () => {
1313
const trie = new Trie();
1414

1515
if (fs.existsSync(publicSuffixPath)) {
@@ -42,10 +42,11 @@ runner(__filename, async () => {
4242

4343
/** @type {string[]} */
4444
const cdnDomainsList = [];
45-
for await (const line of readFileByLine(path.resolve(__dirname, '../Source/non_ip/cdn.conf'))) {
45+
for await (const l of readFileByLine(path.resolve(__dirname, '../Source/non_ip/cdn.conf'))) {
46+
const line = processLine(l);
4647
if (line === '# --- [AWS S3 Replace Me] ---') {
4748
S3OSSDomains.forEach(domain => cdnDomainsList.push(`DOMAIN-SUFFIX,${domain}`));
48-
} else {
49+
} else if (line) {
4950
cdnDomainsList.push(line);
5051
}
5152
}
@@ -57,15 +58,20 @@ runner(__filename, async () => {
5758
'',
5859
'This file contains object storage and static assets CDN domains.'
5960
];
60-
const ruleset = minifyRules(cdnDomainsList);
6161

6262
return Promise.all(createRuleset(
6363
'Sukka\'s Ruleset - CDN Domains',
6464
description,
6565
new Date(),
66-
ruleset,
66+
cdnDomainsList,
6767
'ruleset',
6868
path.resolve(__dirname, '../List/non_ip/cdn.conf'),
6969
path.resolve(__dirname, '../Clash/non_ip/cdn.txt')
7070
));
71-
});
71+
};
72+
73+
module.exports.buildCdnConf = buildCdnConf;
74+
75+
if (require.main === module) {
76+
runner(__filename, buildCdnConf);
77+
}

Build/build-chn-cidr.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ const EXCLUDE_CIDRS = [
1212
'223.120.0.0/15'
1313
];
1414

15-
runner(__filename, async () => {
15+
const buildChnCidr = async () => {
1616
const { exclude: excludeCidrs } = await import('cidr-tools-wasm');
1717

1818
/** @type {string[]} */
@@ -56,4 +56,10 @@ runner(__filename, async () => {
5656
pathResolve(__dirname, '../Clash/ip/china_ip.txt')
5757
)
5858
]);
59-
});
59+
};
60+
61+
module.exports.buildChnCidr = buildChnCidr;
62+
63+
if (require.main === module) {
64+
runner(__filename, buildChnCidr);
65+
}

Build/build-common.js

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// @ts-check
2+
3+
const path = require('path');
4+
const { PathScurry } = require('path-scurry');
5+
const { readFileByLine } = require('./lib/fetch-remote-text-by-line');
6+
const { processLine } = require('./lib/process-line');
7+
const { createRuleset } = require('./lib/create-file');
8+
const { domainDeduper } = require('./lib/domain-deduper');
9+
const { runner } = require('./lib/trace-runner');
10+
11+
const MAGIC_COMMAND_SKIP = '# $ custom_build_script';
12+
const MAGIC_COMMAND_TITLE = '# $ meta_title ';
13+
const MAGIC_COMMAND_DESCRIPTION = '# $ meta_description ';
14+
15+
const sourceDir = path.resolve(__dirname, '../Source');
16+
const outputSurgeDir = path.resolve(__dirname, '../List');
17+
const outputClashDir = path.resolve(__dirname, '../Clash');
18+
19+
const buildCommon = async () => {
20+
/** @type {Promise<void>[]} */
21+
const promises = [];
22+
23+
const pw = new PathScurry(sourceDir);
24+
for await (const entry of pw) {
25+
if (entry.isFile()) {
26+
if (path.extname(entry.name) === '.js') {
27+
continue;
28+
}
29+
30+
const relativePath = entry.relative();
31+
if (relativePath.startsWith('domainset/')) {
32+
promises.push(transformDomainset(entry.fullpath(), relativePath));
33+
continue;
34+
}
35+
if (
36+
relativePath.startsWith('ip/')
37+
|| relativePath.startsWith('non_ip/')
38+
) {
39+
promises.push(transformRuleset(entry.fullpath(), relativePath));
40+
continue;
41+
}
42+
}
43+
}
44+
45+
return Promise.all(promises);
46+
};
47+
48+
module.exports.buildCommon = buildCommon;
49+
50+
if (require.main === module) {
51+
runner(__filename, buildCommon);
52+
}
53+
54+
/**
55+
* @param {string} sourcePath
56+
*/
57+
const processFile = async (sourcePath) => {
58+
/** @type {string[]} */
59+
const lines = [];
60+
61+
let title = '';
62+
/** @type {string[]} */
63+
const descriptions = [];
64+
65+
for await (const line of readFileByLine(sourcePath)) {
66+
if (line === MAGIC_COMMAND_SKIP) {
67+
return;
68+
}
69+
70+
if (line.startsWith(MAGIC_COMMAND_TITLE)) {
71+
title = line.slice(MAGIC_COMMAND_TITLE.length).trim();
72+
continue;
73+
}
74+
75+
if (line.startsWith(MAGIC_COMMAND_DESCRIPTION)) {
76+
descriptions.push(line.slice(MAGIC_COMMAND_DESCRIPTION.length).trim());
77+
continue;
78+
}
79+
80+
const l = processLine(line);
81+
if (l) {
82+
lines.push(l);
83+
}
84+
}
85+
86+
return /** @type {const} */ ([title, descriptions, lines]);
87+
};
88+
89+
/**
90+
* @param {string} sourcePath
91+
* @param {string} relativePath
92+
*/
93+
async function transformDomainset(sourcePath, relativePath) {
94+
const res = await processFile(sourcePath);
95+
if (!res) return;
96+
const [title, descriptions, lines] = res;
97+
98+
const deduped = domainDeduper(lines);
99+
const description = [
100+
'License: AGPL 3.0',
101+
'Homepage: https://ruleset.skk.moe',
102+
'GitHub: https://github.com/SukkaW/Surge',
103+
...(
104+
descriptions.length
105+
? ['', ...descriptions]
106+
: []
107+
)
108+
];
109+
110+
await Promise.all(createRuleset(
111+
title,
112+
description,
113+
new Date(),
114+
deduped,
115+
'domainset',
116+
path.resolve(outputSurgeDir, relativePath),
117+
path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`)
118+
));
119+
}
120+
121+
/**
122+
* Output Surge RULE-SET and Clash classical text format
123+
*
124+
* @param {string} sourcePath
125+
* @param {string} relativePath
126+
*/
127+
async function transformRuleset(sourcePath, relativePath) {
128+
const res = await processFile(sourcePath);
129+
if (!res) return;
130+
const [title, descriptions, lines] = res;
131+
132+
const description = [
133+
'License: AGPL 3.0',
134+
'Homepage: https://ruleset.skk.moe',
135+
'GitHub: https://github.com/SukkaW/Surge',
136+
...(
137+
descriptions.length
138+
? ['', ...descriptions]
139+
: []
140+
)
141+
];
142+
143+
await Promise.all(createRuleset(
144+
title,
145+
description,
146+
new Date(),
147+
lines,
148+
'ruleset',
149+
path.resolve(outputSurgeDir, relativePath),
150+
path.resolve(outputClashDir, `${relativePath.slice(0, -path.extname(relativePath).length)}.txt`)
151+
));
152+
}

Build/build-domestic-ruleset.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const { compareAndWriteFile, createRuleset } = require('./lib/create-file');
77
const domainSorter = require('./lib/stable-sort-domain');
88
const { runner } = require('./lib/trace-runner');
99

10-
runner(__filename, async () => {
10+
const buildDomesticRuleset = async () => {
1111
const rl = readFileByLine(path.resolve(__dirname, '../Source/non_ip/domestic.conf'));
1212
const results = [];
1313
for await (const l of rl) {
@@ -67,4 +67,10 @@ runner(__filename, async () => {
6767
path.resolve(__dirname, '../Modules/sukka_local_dns_mapping.sgmodule')
6868
)
6969
]);
70-
});
70+
};
71+
72+
module.exports.buildDomesticRuleset = buildDomesticRuleset;
73+
74+
if (require.main === module) {
75+
runner(__filename, buildDomesticRuleset);
76+
}

Build/build-internal-cdn-rules.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const escapeRegExp = (string) => {
1515
return string.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
1616
};
1717

18-
runner(__filename, async () => {
18+
const buildInternalCDNDomains = async () => {
1919
const set = new Set();
2020
const keywords = new Set();
2121

@@ -87,4 +87,10 @@ runner(__filename, async () => {
8787
],
8888
path.resolve(__dirname, '../List/internal/cdn.txt')
8989
);
90-
});
90+
};
91+
92+
module.exports.buildInternalCDNDomains = buildInternalCDNDomains;
93+
94+
if (require.main === module) {
95+
runner(__filename, buildInternalCDNDomains);
96+
}

Build/build-internal-chn-domains.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const { parseFelixDnsmasq } = require('./lib/parse-dnsmasq');
55
const { runner } = require('./lib/trace-runner');
66
const { compareAndWriteFile } = require('./lib/create-file');
77

8-
runner(__filename, async () => {
8+
const buildInternalChnDomains = async () => {
99
const [result] = await Promise.all([
1010
parseFelixDnsmasq('https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf'),
1111
fse.ensureDir(path.resolve(__dirname, '../List/internal'))
@@ -15,4 +15,10 @@ runner(__filename, async () => {
1515
result.map(line => `SUFFIX,${line}`),
1616
path.resolve(__dirname, '../List/internal/accelerated-china-domains.txt')
1717
);
18-
});
18+
};
19+
20+
module.exports.buildInternalChnDomains = buildInternalChnDomains;
21+
22+
if (require.main === module) {
23+
runner(__filename, buildInternalChnDomains);
24+
}

Build/build-internal-reverse-chn-cidr.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const RESERVED_IPV4_CIDR = [
2424
'240.0.0.0/4'
2525
];
2626

27-
runner(__filename, async () => {
27+
const buildInternalReverseChnCIDR = async () => {
2828
const { exclude } = await import('cidr-tools-wasm');
2929

3030
/** @type {string[]} */
@@ -47,4 +47,10 @@ runner(__filename, async () => {
4747
path.resolve(__dirname, '../List/internal/reversed-chn-cidr.txt'),
4848
`${reversedCidr.join('\n')}\n`
4949
);
50-
});
50+
};
51+
52+
module.exports.buildInternalReverseChnCIDR = buildInternalReverseChnCIDR;
53+
54+
if (require.main === module) {
55+
runner(__filename, buildInternalReverseChnCIDR);
56+
}

Build/build-phishing-domainset.js

+8-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const BLACK_TLD = new Set([
6060
'com.cn'
6161
]);
6262

63-
runner(__filename, async () => {
63+
const buildPhishingDomainSet = async () => {
6464
const domainSet = Array.from((await processFilterRules('https://curbengh.github.io/phishing-filter/phishing-filter-agh.txt')).black);
6565
const domainCountMap = {};
6666

@@ -151,4 +151,10 @@ runner(__filename, async () => {
151151
path.resolve(__dirname, '../List/domainset/reject_phishing.conf'),
152152
path.resolve(__dirname, '../Clash/domainset/reject_phishing.txt')
153153
));
154-
});
154+
};
155+
156+
module.exports.buildPhishingDomainSet = buildPhishingDomainSet;
157+
158+
if (require.main === module) {
159+
runner(__filename, buildPhishingDomainSet);
160+
}

0 commit comments

Comments
 (0)