禁止壳生产代码保留临时替身
移动壳配置检查扫描生产源码脚手架词 桌面壳配置检查扫描生产源码脚手架词 保留测试文件使用 mock 的边界 更新原生壳方案和团队决策记录
This commit is contained in:
@@ -19,6 +19,24 @@ const packagePath = new URL('../package.json', import.meta.url);
|
||||
const packageConfig = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
||||
const iconPath = new URL('../assets/icon.png', import.meta.url);
|
||||
const icon = PNG.sync.read(fs.readFileSync(iconPath));
|
||||
const productionSourceRoots = [
|
||||
new URL('../App.tsx', import.meta.url),
|
||||
new URL('../app.json', import.meta.url),
|
||||
new URL('../package.json', import.meta.url),
|
||||
new URL('../src/', import.meta.url),
|
||||
];
|
||||
const productionFileExtensions = new Set(['.json', '.mjs', '.ts', '.tsx']);
|
||||
const devScaffoldTerms = [
|
||||
'mo' + 'ck',
|
||||
'fa' + 'ke',
|
||||
'place' + 'holder',
|
||||
'st' + 'ub',
|
||||
'TO' + 'DO',
|
||||
'FIX' + 'ME',
|
||||
'占' + '位',
|
||||
'模' + '拟',
|
||||
'伪' + '造',
|
||||
];
|
||||
|
||||
function extractStringArrayExport(source, exportName) {
|
||||
const match = source.match(
|
||||
@@ -41,6 +59,58 @@ function extractStringArrayExport(source, exportName) {
|
||||
return entries;
|
||||
}
|
||||
|
||||
function collectProductionSourceFiles(entry) {
|
||||
const stats = fs.statSync(entry);
|
||||
if (stats.isDirectory()) {
|
||||
const directory = entry.href.endsWith('/') ? entry : new URL(`${entry.href}/`);
|
||||
return fs
|
||||
.readdirSync(entry, { withFileTypes: true })
|
||||
.flatMap((child) =>
|
||||
collectProductionSourceFiles(
|
||||
new URL(`${child.name}${child.isDirectory() ? '/' : ''}`, directory),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
const path = entry.pathname;
|
||||
const extension = path.match(/\.[^.]+$/)?.[0] ?? '';
|
||||
if (!productionFileExtensions.has(extension)) {
|
||||
return [];
|
||||
}
|
||||
if (path.includes('.test.') || path.endsWith('/scripts/check-config.mjs')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [entry];
|
||||
}
|
||||
|
||||
function assertNoDevScaffoldTerms(files) {
|
||||
for (const file of files) {
|
||||
const source = fs.readFileSync(file, 'utf8');
|
||||
const lineStarts = [0];
|
||||
for (let index = 0; index < source.length; index += 1) {
|
||||
if (source[index] === '\n') {
|
||||
lineStarts.push(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (const term of devScaffoldTerms) {
|
||||
const matchIndex = source.toLowerCase().indexOf(term.toLowerCase());
|
||||
if (matchIndex === -1) {
|
||||
continue;
|
||||
}
|
||||
const line = lineStarts.filter((start) => start <= matchIndex).length;
|
||||
throw new Error(
|
||||
`mobile shell production source must not include ${term}: ${file.pathname}:${line}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
assertNoDevScaffoldTerms(
|
||||
productionSourceRoots.flatMap((root) => collectProductionSourceFiles(root)),
|
||||
);
|
||||
|
||||
const sharedCapabilities = extractStringArrayExport(
|
||||
sharedContractSource,
|
||||
'HOST_BRIDGE_CAPABILITIES',
|
||||
|
||||
Reference in New Issue
Block a user