Skip to content

Commit 00e5446

Browse files
committed
Update version to 2.6.0 in package.json and enhance AAB parsing error messages with localized strings for better user feedback.
1 parent 22ccd73 commit 00e5446

File tree

4 files changed

+44
-24
lines changed

4 files changed

+44
-24
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-native-update-cli",
3-
"version": "2.5.0",
3+
"version": "2.6.0",
44
"description": "command line tool for react-native-update (remote updates for react native)",
55
"main": "index.js",
66
"bin": {

src/locales/en.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ export default {
22
addedToGitignore: 'Added {{line}} to .gitignore',
33
androidCrunchPngsWarning:
44
'The crunchPngs option of android seems not disabled (Please ignore this warning if already disabled), which may cause abnormal consumption of mobile network traffic. Please refer to https://cresc.dev/docs/getting-started#disable-crunchpngs-on-android \n',
5+
aabOpenApksFailed: 'Failed to open generated .apks file',
6+
aabReadUniversalApkFailed: 'Failed to read universal.apk',
7+
aabUniversalApkNotFound: 'universal.apk not found in generated .apks',
8+
aabManifestNotFound:
9+
"AndroidManifest.xml can't be found in AAB base/manifest/",
10+
aabParseResourcesWarning: '[Warning] Failed to parse resources.arsc: {{error}}',
11+
aabParseFailed: 'Failed to parse AAB: {{error}}',
12+
aabParseManifestError: 'Parse AndroidManifest.xml error: {{error}}',
13+
aabParseResourcesError: 'Parser resources.arsc error: {{error}}',
514
appId: 'App ID',
615
appIdMismatchApk:
716
'App ID mismatch! Current APK: {{appIdInPkg}}, current update.json: {{appId}}',

src/locales/zh.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@ export default {
22
addedToGitignore: '已将 {{line}} 添加到 .gitignore',
33
androidCrunchPngsWarning:
44
'android 的 crunchPngs 选项似乎尚未禁用(如已禁用则请忽略此提示),这可能导致热更包体积异常增大,具体请参考 https://pushy.reactnative.cn/docs/getting-started.html#%E7%A6%81%E7%94%A8-android-%E7%9A%84-crunch-%E4%BC%98%E5%8C%96 \n',
5+
aabOpenApksFailed: '无法打开生成的 .apks 文件',
6+
aabReadUniversalApkFailed: '无法读取 universal.apk',
7+
aabUniversalApkNotFound: '在生成的 .apks 中未找到 universal.apk',
8+
aabManifestNotFound: '在 AAB 的 base/manifest/ 中找不到 AndroidManifest.xml',
9+
aabParseResourcesWarning: '[警告] 解析 resources.arsc 失败:{{error}}',
10+
aabParseFailed: '解析 AAB 失败:{{error}}',
11+
aabParseManifestError: '解析 AndroidManifest.xml 出错:{{error}}',
12+
aabParseResourcesError: '解析 resources.arsc 出错:{{error}}',
513
appId: '应用 id',
614
appIdMismatchApk:
715
'appId不匹配!当前apk: {{appIdInPkg}}, 当前update.json: {{appId}}',

src/utils/app-info-parser/aab.ts

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import fs from 'fs-extra';
22
import path from 'path';
33
import os from 'os';
4-
import {
5-
open as openZipFile,
6-
} from 'yauzl';
4+
import { open as openZipFile } from 'yauzl';
75
import Zip from './zip';
6+
import { t } from '../i18n';
87

98
class AabParser extends Zip {
109
file: string | File;
@@ -14,13 +13,23 @@ class AabParser extends Zip {
1413
this.file = file;
1514
}
1615

17-
/**
18-
* 从 AAB 提取 APK(不依赖 bundletool)
19-
*/
20-
async extractApk(outputPath: string) {
16+
async extractApk(
17+
outputPath: string,
18+
{
19+
includeAllSplits = true,
20+
splits,
21+
}: { includeAllSplits?: boolean; splits?: string[] | null },
22+
) {
2123
const { exec } = require('child_process');
2224
const util = require('util');
2325
const execAsync = util.promisify(exec);
26+
const normalizedSplits = Array.isArray(splits)
27+
? splits.map((item) => item.trim()).filter(Boolean)
28+
: [];
29+
const modules = includeAllSplits
30+
? null
31+
: Array.from(new Set(['base', ...normalizedSplits]));
32+
const modulesArg = modules ? ` --modules="${modules.join(',')}"` : '';
2433

2534
// Create a temp file for the .apks output
2635
const tempDir = os.tmpdir();
@@ -32,21 +41,21 @@ class AabParser extends Zip {
3241
// User might need keystore to sign it properly but for simple extraction we stick to default debug key if possible or unsigned?
3342
// actually bundletool build-apks signs with debug key by default if no keystore provided.
3443

35-
let cmd = `bundletool build-apks --mode=universal --bundle="${this.file}" --output="${tempApksPath}" --overwrite`;
44+
let cmd = `bundletool build-apks --mode=universal --bundle="${this.file}" --output="${tempApksPath}" --overwrite${modulesArg}`;
3645
try {
3746
await execAsync(cmd);
3847
} catch (e) {
3948
// Fallback to npx node-bundletool if bundletool is not in PATH
4049
// We use -y to avoid interactive prompt for installation
41-
cmd = `npx -y node-bundletool build-apks --mode=universal --bundle="${this.file}" --output="${tempApksPath}" --overwrite`;
50+
cmd = `npx -y node-bundletool build-apks --mode=universal --bundle="${this.file}" --output="${tempApksPath}" --overwrite${modulesArg}`;
4251
await execAsync(cmd);
4352
}
4453

4554
// 2. Extract universal.apk from the .apks (zip) file
4655
await new Promise<void>((resolve, reject) => {
4756
openZipFile(tempApksPath, { lazyEntries: true }, (err, zipfile) => {
4857
if (err || !zipfile) {
49-
reject(err || new Error('Failed to open generated .apks file'));
58+
reject(err || new Error(t('aabOpenApksFailed')));
5059
return;
5160
}
5261

@@ -57,7 +66,7 @@ class AabParser extends Zip {
5766
found = true;
5867
zipfile.openReadStream(entry, (err, readStream) => {
5968
if (err || !readStream) {
60-
reject(err || new Error('Failed to read universal.apk'));
69+
reject(err || new Error(t('aabReadUniversalApkFailed')));
6170
return;
6271
}
6372
const writeStream = fs.createWriteStream(outputPath);
@@ -74,8 +83,7 @@ class AabParser extends Zip {
7483
});
7584

7685
zipfile.on('end', () => {
77-
if (!found)
78-
reject(new Error('universal.apk not found in generated .apks'));
86+
if (!found) reject(new Error(t('aabUniversalApkNotFound')));
7987
});
8088
zipfile.on('error', reject);
8189
});
@@ -102,9 +110,7 @@ class AabParser extends Zip {
102110
);
103111

104112
if (!manifestBuffer) {
105-
throw new Error(
106-
"AndroidManifest.xml can't be found in AAB base/manifest/",
107-
);
113+
throw new Error(t('aabManifestNotFound'));
108114
}
109115

110116
let apkInfo = this._parseManifest(manifestBuffer as Buffer);
@@ -117,15 +123,12 @@ class AabParser extends Zip {
117123
apkInfo = mapInfoResource(apkInfo, resourceMap);
118124
}
119125
} catch (e: any) {
120-
console.warn(
121-
'[Warning] Failed to parse resources.arsc:',
122-
e?.message ?? e,
123-
);
126+
console.warn(t('aabParseResourcesWarning', { error: e?.message ?? e }));
124127
}
125128

126129
return apkInfo;
127130
} catch (error: any) {
128-
throw new Error(`Failed to parse AAB: ${error.message ?? error}`);
131+
throw new Error(t('aabParseFailed', { error: error.message ?? error }));
129132
}
130133
}
131134
/**
@@ -146,7 +149,7 @@ class AabParser extends Zip {
146149
});
147150
return parser.parse();
148151
} catch (e: any) {
149-
throw new Error(`Parse AndroidManifest.xml error: ${e.message}`);
152+
throw new Error(t('aabParseManifestError', { error: e?.message ?? e }));
150153
}
151154
}
152155

@@ -159,7 +162,7 @@ class AabParser extends Zip {
159162
const ResourceFinder = require('./resource-finder');
160163
return new ResourceFinder().processResourceTable(buffer);
161164
} catch (e: any) {
162-
throw new Error(`Parser resources.arsc error: ${e.message}`);
165+
throw new Error(t('aabParseResourcesError', { error: e?.message ?? e }));
163166
}
164167
}
165168
}

0 commit comments

Comments
 (0)