Skip to content

Commit 01f5e0a

Browse files
author
yangchao
committed
fix(builder): compare dotted versions correctly for Xcode and iOS checks
1 parent a6ff5e5 commit 01f5e0a

5 files changed

Lines changed: 44 additions & 46 deletions

File tree

src/core/base/test/parse.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { compareVersion } from '../utils/parse';
2+
3+
describe('parse.compareVersion', () => {
4+
it('compares versions segment by segment', () => {
5+
expect(compareVersion('1.0.10', '1.0.2')).toBeGreaterThan(0);
6+
expect(compareVersion('14.10', '14.3')).toBeGreaterThan(0);
7+
expect(compareVersion('1.0.0.2', '1.0.0.3')).toBeLessThan(0);
8+
expect(compareVersion('14.3', '14.3.0')).toBe(0);
9+
});
10+
11+
it('throws when params are not strings', () => {
12+
expect(() => compareVersion(null as unknown as string, '1.0.0')).toThrow('invalid param');
13+
});
14+
});

src/core/base/utils/parse.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,31 @@
11
'use strict';
22

33
/**
4-
* return result of versionMax > versionMin,其中仅支持纯数字版本,最高支持三位数版本号:333.666.345
5-
* @example (3.6.2, 3.7.0) => false; (3.9.0, 3.8.0) => true; (3.8.0, 3.8.0) => false;
6-
* @param versionMax
7-
* @param versionMin
4+
* Compare dotted numeric versions segment by segment.
5+
* @example compareVersion('3.6.2', '3.7.0') => -1
6+
* @example compareVersion('3.9.0', '3.8.0') => 1
7+
* @example compareVersion('3.8.0', '3.8.0') => 0
8+
* @param versionLeft
9+
* @param versionRight
810
* @param split
911
*/
10-
export function compareVersion(versionMax: string, versionMin: string, split = '.') {
11-
if (typeof versionMax !== 'string' || typeof versionMin !== 'string') {
12-
throw new Error(`invalid param: ${versionMax}, ${versionMin}`);
12+
export function compareVersion(versionLeft: string, versionRight: string, split = '.') {
13+
if (typeof versionLeft !== 'string' || typeof versionRight !== 'string') {
14+
throw new Error(`invalid param: ${versionLeft}, ${versionRight}`);
1315
}
14-
versionMax = versionMax.replace(split, '').padStart(3, '0');
15-
versionMin = versionMin.replace(split, '').padStart(3, '0');
16-
return Number(versionMax) > Number(versionMin);
16+
17+
const leftParts = versionLeft.split(split).map((part) => Number.parseInt(part, 10) || 0);
18+
const rightParts = versionRight.split(split).map((part) => Number.parseInt(part, 10) || 0);
19+
const maxLength = Math.max(leftParts.length, rightParts.length);
20+
21+
for (let i = 0; i < maxLength; i++) {
22+
const leftValue = leftParts[i] ?? 0;
23+
const rightValue = rightParts[i] ?? 0;
24+
25+
if (leftValue !== rightValue) {
26+
return leftValue - rightValue;
27+
}
28+
}
29+
30+
return 0;
1731
}

src/core/builder/platforms/ios/src/utils.ts

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ITaskOption } from '../../native-common/type';
77
import { IOptions } from './type'
88
import { BuildCheckResult } from '../../../@types/protected';
99
import i18n from '../../../../base/i18n';
10+
import { compareVersion } from '../../../../base/utils/parse';
1011

1112
/**
1213
* 修改 ios 的包名
@@ -218,11 +219,11 @@ export function verificationFunc(key: keyof IOptions, value: any, options: ITask
218219
}
219220
if (options.packages.native.JobSystem === 'taskFlow') {
220221
minVersion = '12.0';
221-
if (!compareVersion(value, minVersion)) {
222+
if (compareVersion(value, minVersion) < 0) {
222223
setError('i18n:ios.tips.targetVersionErrorWithTaskFlow', minVersion);
223224
}
224225
}
225-
if (res.valid && !compareVersion(value, minVersion)) {
226+
if (res.valid && compareVersion(value, minVersion) < 0) {
226227
setError('i18n:ios.tips.targetVersionError', minVersion);
227228
}
228229
}
@@ -262,19 +263,3 @@ export function verificationFunc(key: keyof IOptions, value: any, options: ITask
262263
}
263264
return res;
264265
}
265-
266-
/**
267-
* return result of versionMax > versionMin
268-
* @param versionOne
269-
* @param versionTwo
270-
* @param split
271-
*/
272-
export function compareVersion(versionMax: string, versionMin: string, split = '.') {
273-
if (typeof versionMax !== 'string' || typeof versionMin !== 'string') {
274-
return true;
275-
}
276-
const padNum = Math.max(versionMax.length, versionMin.length);
277-
versionMax = versionMax.replace(split, '').padStart(padNum, '0');
278-
versionMin = versionMin.replace(split, '').padStart(padNum, '0');
279-
return Number(versionMax) > Number(versionMin) || Number(versionMax) === Number(versionMin);
280-
}

src/core/builder/platforms/native-common/pack-tool/platforms/mac-os.ts

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as os from 'os';
44
import { execSync } from "child_process";
55
import NativePackTool, { CocosParams } from '../base/default';
66
import { cchelper, toolHelper } from "../utils";
7+
import { compareVersion } from '../../../../../base/utils/parse';
78

89
export interface IOrientation {
910
landscapeLeft: boolean;
@@ -51,22 +52,6 @@ export abstract class MacOSPackTool extends NativePackTool {
5152
return /Apple/.test(model) && process.platform === 'darwin';
5253
}
5354

54-
protected compareVersion(a: string, b: string): number {
55-
const aParts = a.split('.').map((part) => Number.parseInt(part, 10) || 0);
56-
const bParts = b.split('.').map((part) => Number.parseInt(part, 10) || 0);
57-
const maxLength = Math.max(aParts.length, bParts.length);
58-
59-
for (let i = 0; i < maxLength; i++) {
60-
const aValue = aParts[i] ?? 0;
61-
const bValue = bParts[i] ?? 0;
62-
if (aValue !== bValue) {
63-
return aValue - bValue;
64-
}
65-
}
66-
67-
return 0;
68-
}
69-
7055
protected getXcodeVersion(): string {
7156
try {
7257
const output = execSync('xcrun xcodebuild -version').toString('utf8');
@@ -90,7 +75,7 @@ export abstract class MacOSPackTool extends NativePackTool {
9075

9176
protected getIosSimulatorArch(): 'arm64' | 'x86_64' {
9277
// Xcode 14.3+ no longer supports running iOS Simulator under Rosetta on Apple Silicon.
93-
if (this.isAppleSilicon() && this.compareVersion(this.getXcodeVersion(), '14.3') >= 0) {
78+
if (this.isAppleSilicon() && compareVersion(this.getXcodeVersion(), '14.3') >= 0) {
9479
return 'arm64';
9580
}
9681
return 'x86_64';

src/core/builder/worker/builder/manager/build-template.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class BuildTemplate implements IBuildTemplate {
6262
}
6363
this._versionUser = this._versionUser || '1.0.0';
6464
// 用户构建模板版本小于默认构建模板版本,警告建议更新
65-
if (utils.Parse.compareVersion(this.config.version, this._versionUser)) {
65+
if (utils.Parse.compareVersion(this.config.version, this._versionUser) > 0) {
6666
console.warn(i18n.t('builder.tips.template_version_warning', {
6767
version: this._versionUser,
6868
internalConfig: this.config.version,

0 commit comments

Comments
 (0)