Skip to content

Commit 65a3b01

Browse files
committed
feat(doctor): support android-37 and minor-versioned SDK platform directories
SDK platforms newer than android-36 may install into directories named android-<api>.<minor> (e.g. android-37.0) with no plain android-<api> directory, so installed targets are now matched on their API level rather than the exact directory name. Extension directories such as android-33-ext4 are not treated as the base platform. Ref: NS-261289
1 parent ef90697 commit 65a3b01

2 files changed

Lines changed: 81 additions & 18 deletions

File tree

packages/doctor/src/android-tools-info.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
3434
"android-35",
3535
"android-36",
3636
"android-36.1",
37+
"android-37",
3738
];
3839

3940
const isRuntimeVersionLessThan = (targetVersion: string) => {
@@ -495,12 +496,29 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
495496
installedTargets: string[],
496497
projectDir: string,
497498
): string {
499+
// SDK platforms newer than android-36 may install into directories named
500+
// "android-<api>.<minor>" (e.g. "android-37.0") with no plain
501+
// "android-<api>" directory, so installed targets are matched on their
502+
// API level rather than the exact directory name. Extension directories
503+
// like "android-33-ext4" are deliberately not treated as the base
504+
// platform - they don't contain a full SDK.
498505
return _.findLast(
499506
this.getSupportedTargets(projectDir).sort(),
500-
(supportedTarget) => _.includes(installedTargets, supportedTarget),
507+
(supportedTarget) =>
508+
_.includes(installedTargets, supportedTarget) ||
509+
installedTargets.some(
510+
(installedTarget) =>
511+
AndroidToolsInfo.getInstalledTargetApiLevel(installedTarget) ===
512+
this.parseAndroidSdkString(supportedTarget),
513+
),
501514
);
502515
}
503516

517+
private static getInstalledTargetApiLevel(installedTarget: string): number {
518+
const match = installedTarget.match(/^android-(\d+)(?:\.\d+)?$/);
519+
return match ? parseInt(match[1], 10) : null;
520+
}
521+
504522
private parseAndroidSdkString(androidSdkString: string): number {
505523
return parseInt(
506524
androidSdkString.replace(`${this.ANDROID_TARGET_PREFIX}-`, ""),

packages/doctor/test/android-tools-info.ts

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ describe("androidToolsInfo", () => {
2626
beforeAll(() => {
2727
process.env["ANDROID_HOME"] = "test";
2828
});
29-
const getAndroidToolsInfo = (runtimeVersion?: string): AndroidToolsInfo => {
29+
const getAndroidToolsInfo = (
30+
runtimeVersion?: string,
31+
installedTargets?: string[],
32+
): AndroidToolsInfo => {
3033
const childProcess: ChildProcess = <any>{};
3134
const fs: FileSystem = <any>{
3235
exists: () => true,
@@ -59,20 +62,22 @@ describe("androidToolsInfo", () => {
5962
"34.0.0",
6063
];
6164
} else {
62-
return [
63-
"android-16",
64-
"android-27",
65-
"android-28",
66-
"android-29",
67-
"android-30",
68-
"android-31",
69-
"android-32",
70-
"android-33",
71-
"android-34",
72-
"android-35",
73-
"android-36",
74-
"android-36.1",
75-
];
65+
return (
66+
installedTargets || [
67+
"android-16",
68+
"android-27",
69+
"android-28",
70+
"android-29",
71+
"android-30",
72+
"android-31",
73+
"android-32",
74+
"android-33",
75+
"android-34",
76+
"android-35",
77+
"android-36",
78+
"android-36.1",
79+
]
80+
);
7681
}
7782
},
7883
};
@@ -109,6 +114,34 @@ describe("androidToolsInfo", () => {
109114

110115
assert.equal(toolsInfo.compileSdkVersion, 36);
111116
});
117+
118+
it("resolves android-37 from minor-versioned SDK directories", () => {
119+
const androidToolsInfo = getAndroidToolsInfo("8.2.0", [
120+
"android-36",
121+
"android-37.0",
122+
"android-37.1",
123+
]);
124+
const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" });
125+
126+
assert.equal(toolsInfo.compileSdkVersion, 37);
127+
});
128+
129+
it("resolves android-36 when only android-36.1 is installed", () => {
130+
const androidToolsInfo = getAndroidToolsInfo("8.2.0", ["android-36.1"]);
131+
const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" });
132+
133+
assert.equal(toolsInfo.compileSdkVersion, 36);
134+
});
135+
136+
it("does not treat extension directories as the base platform", () => {
137+
const androidToolsInfo = getAndroidToolsInfo("8.2.0", [
138+
"android-33",
139+
"android-35-ext15",
140+
]);
141+
const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" });
142+
143+
assert.equal(toolsInfo.compileSdkVersion, 33);
144+
});
112145
});
113146

114147
describe("supportedAndroidSdks", () => {
@@ -135,18 +168,20 @@ describe("androidToolsInfo", () => {
135168
);
136169
});
137170

138-
it("runtime 8.2.0 should support android-17 through android-36 and android-36.1", () => {
171+
it("runtime 8.2.0 should support android-17 through android-37 including android-36.1", () => {
139172
const expectedTargets = [
140173
...Array.from({ length: 20 }, (_, index) => `android-${17 + index}`),
141174
"android-36.1",
175+
"android-37",
142176
];
143177
assertSupportedTargets("8.2.0", expectedTargets);
144178
});
145179

146-
it("runtime 8.3.0 should support android-17 through android-36 and android-36.1", () => {
180+
it("runtime 8.3.0 should support android-17 through android-37 including android-36.1", () => {
147181
const expectedTargets = [
148182
...Array.from({ length: 20 }, (_, index) => `android-${17 + index}`),
149183
"android-36.1",
184+
"android-37",
150185
];
151186
assertSupportedTargets("8.3.0", expectedTargets);
152187
});
@@ -380,6 +415,16 @@ describe("androidToolsInfo", () => {
380415
targetSdk: 32,
381416
expectWarning: false,
382417
},
418+
{
419+
runtimeVersion: "8.2.0",
420+
targetSdk: 37,
421+
expectWarning: false,
422+
},
423+
{
424+
runtimeVersion: "8.2.0",
425+
targetSdk: 38,
426+
expectWarning: true,
427+
},
383428
];
384429

385430
testCases.forEach(({ runtimeVersion, targetSdk, expectWarning }) => {

0 commit comments

Comments
 (0)