统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口 完成项目 TypeScript/Prettier 与 Rust 全量格式化 修复 Pingora expected executable 门禁的空白敏感误报 同步开发运维文档与 AGC skill pack 格式化忽略规则
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import {spawnSync} from 'node:child_process';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
import path from 'node:path';
|
||||
|
||||
@@ -69,7 +69,9 @@ function run(command, args, label) {
|
||||
throw new Error(`${label} failed to start: ${result.error.message}`);
|
||||
}
|
||||
if ((result.status ?? 0) !== 0) {
|
||||
throw new Error(`${label} failed: ${(result.stderr || result.stdout).trim()}`);
|
||||
throw new Error(
|
||||
`${label} failed: ${(result.stderr || result.stdout).trim()}`,
|
||||
);
|
||||
}
|
||||
return result.stdout;
|
||||
}
|
||||
@@ -82,20 +84,47 @@ function assertIncludes(source, snippet, label) {
|
||||
|
||||
assertFile(androidArtifactPath, 'Android mobile shell APK', 1024 * 1024);
|
||||
assertZipHeader(androidArtifactPath, 'Android mobile shell APK');
|
||||
const androidListing = run('unzip', ['-l', androidArtifactPath], 'Android APK listing');
|
||||
assertIncludes(androidListing, 'AndroidManifest.xml', 'Android mobile shell APK');
|
||||
const androidListing = run(
|
||||
'unzip',
|
||||
['-l', androidArtifactPath],
|
||||
'Android APK listing',
|
||||
);
|
||||
assertIncludes(
|
||||
androidListing,
|
||||
'AndroidManifest.xml',
|
||||
'Android mobile shell APK',
|
||||
);
|
||||
assertIncludes(androidListing, 'classes.dex', 'Android mobile shell APK');
|
||||
assertIncludes(androidListing, 'assets/index.android.bundle', 'Android mobile shell APK');
|
||||
assertIncludes(
|
||||
androidListing,
|
||||
'assets/index.android.bundle',
|
||||
'Android mobile shell APK',
|
||||
);
|
||||
|
||||
assertFile(iosSimulatorArtifactPath, 'iOS simulator mobile shell archive', 1024 * 1024);
|
||||
assertGzipHeader(iosSimulatorArtifactPath, 'iOS simulator mobile shell archive');
|
||||
assertFile(
|
||||
iosSimulatorArtifactPath,
|
||||
'iOS simulator mobile shell archive',
|
||||
1024 * 1024,
|
||||
);
|
||||
assertGzipHeader(
|
||||
iosSimulatorArtifactPath,
|
||||
'iOS simulator mobile shell archive',
|
||||
);
|
||||
const iosListing = run(
|
||||
'tar',
|
||||
['-tzf', iosSimulatorArtifactPath],
|
||||
'iOS simulator archive listing',
|
||||
);
|
||||
assertIncludes(iosListing, '.app/Info.plist', 'iOS simulator mobile shell archive');
|
||||
assertIncludes(iosListing, '.app/Genarrative', 'iOS simulator mobile shell archive');
|
||||
assertIncludes(
|
||||
iosListing,
|
||||
'.app/Info.plist',
|
||||
'iOS simulator mobile shell archive',
|
||||
);
|
||||
assertIncludes(
|
||||
iosListing,
|
||||
'.app/Genarrative',
|
||||
'iOS simulator mobile shell archive',
|
||||
);
|
||||
assertIncludes(
|
||||
iosListing,
|
||||
'.app/main.jsbundle',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {spawnSync} from 'node:child_process';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const shellRoot = new URL('../', import.meta.url);
|
||||
@@ -31,24 +31,36 @@ assertObject(easConfig.cli, 'EAS cli config');
|
||||
assertObject(easConfig.build, 'EAS build config');
|
||||
|
||||
if (easConfig.cli.version !== '>= 20.3.0') {
|
||||
throw new Error('mobile shell EAS CLI version gate must stay pinned to the checked devDependency floor');
|
||||
throw new Error(
|
||||
'mobile shell EAS CLI version gate must stay pinned to the checked devDependency floor',
|
||||
);
|
||||
}
|
||||
|
||||
if (packageConfig.devDependencies?.['eas-cli'] !== '^20.3.0') {
|
||||
throw new Error('mobile shell package must declare the checked EAS CLI devDependency');
|
||||
throw new Error(
|
||||
'mobile shell package must declare the checked EAS CLI devDependency',
|
||||
);
|
||||
}
|
||||
|
||||
const easVersionResult = spawnSync(npmCommand, ['exec', 'eas', '--', '--version'], {
|
||||
cwd: shellRoot,
|
||||
encoding: 'utf8',
|
||||
});
|
||||
const easVersionResult = spawnSync(
|
||||
npmCommand,
|
||||
['exec', 'eas', '--', '--version'],
|
||||
{
|
||||
cwd: shellRoot,
|
||||
encoding: 'utf8',
|
||||
},
|
||||
);
|
||||
|
||||
if (easVersionResult.error) {
|
||||
throw new Error(`failed to start local EAS CLI version check: ${easVersionResult.error.message}`);
|
||||
throw new Error(
|
||||
`failed to start local EAS CLI version check: ${easVersionResult.error.message}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (easVersionResult.signal) {
|
||||
throw new Error(`local EAS CLI version check was terminated by signal ${easVersionResult.signal}`);
|
||||
throw new Error(
|
||||
`local EAS CLI version check was terminated by signal ${easVersionResult.signal}`,
|
||||
);
|
||||
}
|
||||
|
||||
if ((easVersionResult.status ?? 0) !== 0) {
|
||||
@@ -62,7 +74,9 @@ if (!(easVersionResult.stdout ?? '').trim().startsWith('eas-cli/20.3.0 ')) {
|
||||
}
|
||||
|
||||
if (easConfig.cli.appVersionSource !== 'local') {
|
||||
throw new Error('mobile shell EAS builds must use local app.json version fields');
|
||||
throw new Error(
|
||||
'mobile shell EAS builds must use local app.json version fields',
|
||||
);
|
||||
}
|
||||
|
||||
for (const scriptName of ['build:android', 'build:ios', 'build-config:smoke']) {
|
||||
@@ -90,14 +104,21 @@ for (const [label, outputPath, extension] of [
|
||||
['iOS simulator', iosSimulatorBuildOutputPath, '.tar.gz'],
|
||||
]) {
|
||||
if (!outputPath.startsWith('../../build/native/mobile/')) {
|
||||
throw new Error(`mobile shell ${label} local build output must stay under root build/native/mobile`);
|
||||
throw new Error(
|
||||
`mobile shell ${label} local build output must stay under root build/native/mobile`,
|
||||
);
|
||||
}
|
||||
if (!outputPath.endsWith(extension)) {
|
||||
throw new Error(`mobile shell ${label} local build output must end with ${extension}`);
|
||||
throw new Error(
|
||||
`mobile shell ${label} local build output must end with ${extension}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (packageConfig.scripts['build-config:smoke'] !== 'node scripts/check-eas-build-config.mjs') {
|
||||
if (
|
||||
packageConfig.scripts['build-config:smoke'] !==
|
||||
'node scripts/check-eas-build-config.mjs'
|
||||
) {
|
||||
throw new Error('mobile shell EAS config smoke script drifted');
|
||||
}
|
||||
|
||||
@@ -106,31 +127,46 @@ const productionSimulator = easConfig.build['production-simulator'];
|
||||
assertObject(production, 'EAS Android production profile');
|
||||
assertObject(productionSimulator, 'EAS iOS simulator production profile');
|
||||
|
||||
if (production.distribution !== 'internal' || production.channel !== 'production') {
|
||||
throw new Error('mobile shell Android production profile must build an internal production package');
|
||||
if (
|
||||
production.distribution !== 'internal' ||
|
||||
production.channel !== 'production'
|
||||
) {
|
||||
throw new Error(
|
||||
'mobile shell Android production profile must build an internal production package',
|
||||
);
|
||||
}
|
||||
|
||||
if (production.android?.buildType !== 'apk') {
|
||||
throw new Error('mobile shell Android production profile must produce an installable APK');
|
||||
throw new Error(
|
||||
'mobile shell Android production profile must produce an installable APK',
|
||||
);
|
||||
}
|
||||
|
||||
if (production.env?.EXPO_NO_DOTENV !== '1') {
|
||||
throw new Error('mobile shell Android production profile must ignore local dotenv files');
|
||||
throw new Error(
|
||||
'mobile shell Android production profile must ignore local dotenv files',
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
productionSimulator.distribution !== 'internal' ||
|
||||
productionSimulator.channel !== 'production'
|
||||
) {
|
||||
throw new Error('mobile shell iOS simulator production profile must stay internal production');
|
||||
throw new Error(
|
||||
'mobile shell iOS simulator production profile must stay internal production',
|
||||
);
|
||||
}
|
||||
|
||||
if (productionSimulator.ios?.simulator !== true) {
|
||||
throw new Error('mobile shell iOS production smoke profile must target simulator builds until signing is configured');
|
||||
throw new Error(
|
||||
'mobile shell iOS production smoke profile must target simulator builds until signing is configured',
|
||||
);
|
||||
}
|
||||
|
||||
if (productionSimulator.env?.EXPO_NO_DOTENV !== '1') {
|
||||
throw new Error('mobile shell iOS simulator production profile must ignore local dotenv files');
|
||||
throw new Error(
|
||||
'mobile shell iOS simulator production profile must ignore local dotenv files',
|
||||
);
|
||||
}
|
||||
|
||||
for (const [profileName, profile] of Object.entries(easConfig.build)) {
|
||||
@@ -149,7 +185,9 @@ for (const [profileName, profile] of Object.entries(easConfig.build)) {
|
||||
}
|
||||
|
||||
if ('submit' in easConfig) {
|
||||
throw new Error('mobile shell EAS config must not include store submit profiles yet');
|
||||
throw new Error(
|
||||
'mobile shell EAS config must not include store submit profiles yet',
|
||||
);
|
||||
}
|
||||
|
||||
console.log('[mobile-shell:eas-build-config] OK');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {spawnSync} from 'node:child_process';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import fs from 'node:fs';
|
||||
|
||||
const shellRoot = new URL('../', import.meta.url);
|
||||
@@ -106,12 +106,16 @@ function readMetadata(platform) {
|
||||
const fileMetadata = metadata.fileMetadata ?? {};
|
||||
const metadataPlatforms = Object.keys(fileMetadata);
|
||||
if (metadataPlatforms.length !== 1 || metadataPlatforms[0] !== platform) {
|
||||
throw new Error(`Expo ${platform} export metadata must only include its platform`);
|
||||
throw new Error(
|
||||
`Expo ${platform} export metadata must only include its platform`,
|
||||
);
|
||||
}
|
||||
|
||||
const platformMetadata = fileMetadata[platform];
|
||||
if (!Array.isArray(platformMetadata?.assets)) {
|
||||
throw new Error(`Expo ${platform} export metadata must include an assets array`);
|
||||
throw new Error(
|
||||
`Expo ${platform} export metadata must include an assets array`,
|
||||
);
|
||||
}
|
||||
|
||||
const bundlePath = platformMetadata?.bundle;
|
||||
@@ -164,7 +168,7 @@ function assertBundle(platform, bundlePath) {
|
||||
}
|
||||
}
|
||||
|
||||
fs.rmSync(outputRoot, {recursive: true, force: true});
|
||||
fs.rmSync(outputRoot, { recursive: true, force: true });
|
||||
|
||||
try {
|
||||
for (const platform of platforms) {
|
||||
@@ -174,5 +178,5 @@ try {
|
||||
|
||||
console.log('[mobile-shell:expo-export] OK');
|
||||
} finally {
|
||||
fs.rmSync(outputRoot, {recursive: true, force: true});
|
||||
fs.rmSync(outputRoot, { recursive: true, force: true });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user