Skip to content

Commit 842c6be

Browse files
committed
feat(android): support android-37 SDK targets
Accept minor-versioned SDK platform directories (e.g. android-37.0) for --compile-sdk, map the android-37 targets to Android 17 for emulator listing, and update @nativescript/doctor to 2.0.18 which resolves the compile SDK from such directories. Ref: NS-261289
1 parent aeecea3 commit 842c6be

5 files changed

Lines changed: 84 additions & 58 deletions

File tree

lib/android-tools-info.ts

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
1717
private $errors: IErrors,
1818
private $logger: ILogger,
1919
private $options: IOptions,
20-
protected $staticConfig: Config.IStaticConfig
20+
protected $staticConfig: Config.IStaticConfig,
2121
) {}
2222

2323
@cache()
@@ -29,18 +29,18 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
2929
infoData.androidHomeEnvVar = androidToolsInfo.androidHome;
3030
infoData.compileSdkVersion = this.getCompileSdkVersion(
3131
infoData.installedTargets,
32-
infoData.compileSdkVersion
32+
infoData.compileSdkVersion,
3333
);
3434
infoData.targetSdkVersion = this.getTargetSdk(infoData.compileSdkVersion);
3535
infoData.generateTypings = this.shouldGenerateTypings();
3636

3737
this.$logger.trace(
3838
"Installed Android Targets are: ",
39-
infoData.installedTargets
39+
infoData.installedTargets,
4040
);
4141
this.$logger.trace(
4242
"Selected buildToolsVersion is:",
43-
infoData.buildToolsVersion
43+
infoData.buildToolsVersion,
4444
);
4545

4646
return infoData;
@@ -55,7 +55,7 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
5555
androidToolsInfo
5656
.validateInfo({ projectDir: options.projectDir })
5757
.map((warning) =>
58-
this.printMessage(warning.warning, showWarningsAsErrors)
58+
this.printMessage(warning.warning, showWarningsAsErrors),
5959
).length > 0;
6060

6161
if (options && options.validateTargetSdk) {
@@ -78,7 +78,7 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
7878
projectDir: options.projectDir,
7979
})
8080
.map((warning) =>
81-
this.printMessage(warning.warning, options.showWarningsAsErrors)
81+
this.printMessage(warning.warning, options.showWarningsAsErrors),
8282
).length > 0;
8383

8484
if (!detectedErrors) {
@@ -95,15 +95,15 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
9595

9696
public validateJavacVersion(
9797
installedJavacVersion: string,
98-
options?: IAndroidToolsInfoOptions
98+
options?: IAndroidToolsInfoOptions,
9999
): boolean {
100100
const showWarningsAsErrors = options && options.showWarningsAsErrors;
101101

102102
return (
103103
androidToolsInfo
104104
.validateJavacVersion(installedJavacVersion)
105105
.map((warning) =>
106-
this.printMessage(warning.warning, showWarningsAsErrors)
106+
this.printMessage(warning.warning, showWarningsAsErrors),
107107
).length > 0
108108
);
109109
}
@@ -118,8 +118,8 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
118118
`Error while executing '${path.join(
119119
androidToolsInfo.androidHome,
120120
"platform-tools",
121-
"adb"
122-
)} help'. Error is: ${err.message}`
121+
"adb",
122+
)} help'. Error is: ${err.message}`,
123123
);
124124
}
125125

@@ -128,15 +128,15 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
128128

129129
@cache()
130130
public validateAndroidHomeEnvVariable(
131-
options?: IAndroidToolsInfoOptions
131+
options?: IAndroidToolsInfoOptions,
132132
): boolean {
133133
const showWarningsAsErrors = options && options.showWarningsAsErrors;
134134

135135
return (
136136
androidToolsInfo
137137
.validateAndroidHomeEnvVariable()
138138
.map((warning) =>
139-
this.printMessage(warning.warning, showWarningsAsErrors)
139+
this.printMessage(warning.warning, showWarningsAsErrors),
140140
).length > 0
141141
);
142142
}
@@ -163,15 +163,30 @@ export class AndroidToolsInfo implements IAndroidToolsInfo {
163163

164164
private getCompileSdkVersion(
165165
installedTargets: string[],
166-
latestCompileSdk: number
166+
latestCompileSdk: number,
167167
): number {
168168
const userSpecifiedCompileSdk = this.$options.compileSdk;
169169

170170
if (userSpecifiedCompileSdk) {
171171
const androidCompileSdk = `${androidToolsInfo.ANDROID_TARGET_PREFIX}-${userSpecifiedCompileSdk}`;
172-
if (!_.includes(installedTargets, androidCompileSdk)) {
172+
// SDK platforms newer than android-36 may install into directories named
173+
// "android-<api>.<minor>" (e.g. "android-37.0") with no plain
174+
// "android-<api>" directory, so installed targets are matched on their
175+
// API level rather than the exact directory name.
176+
const isTargetInstalled = _.some(installedTargets, (target) => {
177+
if (target === androidCompileSdk) {
178+
return true;
179+
}
180+
181+
const targetMatch = target.match(/^android-(\d+)(?:\.\d+)?$/);
182+
return (
183+
targetMatch &&
184+
parseInt(targetMatch[1], 10) === userSpecifiedCompileSdk
185+
);
186+
});
187+
if (!isTargetInstalled) {
173188
this.$errors.fail(
174-
`You have specified '${userSpecifiedCompileSdk}' for compile sdk, but it is not installed on your system.`
189+
`You have specified '${userSpecifiedCompileSdk}' for compile sdk, but it is not installed on your system.`,
175190
);
176191
}
177192

lib/common/mobile/emulator-helper.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ import { injector } from "../yok";
55
export class EmulatorHelper implements Mobile.IEmulatorHelper {
66
// https://developer.android.com/guide/topics/manifest/uses-sdk-element
77
public mapAndroidApiLevelToVersion = {
8+
"android-37": "17.0.0",
9+
"android-37.0": "17.0.0",
10+
"android-37.1": "17.0.0",
811
"android-36": "16.0.0",
912
"android-36.1": "16.0.0",
1013
"android-35": "15.0.0",

package-lock.json

Lines changed: 10 additions & 38 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
],
4444
"dependencies": {
4545
"@foxt/js-srp": "0.0.3-patch2",
46-
"@nativescript/doctor": "2.0.17",
46+
"@nativescript/doctor": "2.0.18",
4747
"@nativescript/hook": "3.0.5",
4848
"@npmcli/arborist": "9.1.8",
4949
"@rigor789/resolve-package-path": "1.0.7",

test/android-tools-info.ts

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,54 @@ describe("androidToolsInfo", () => {
3939
return testInjector;
4040
};
4141

42+
describe("getCompileSdkVersion", () => {
43+
const resolveCompileSdk = (
44+
compileSdk: number,
45+
installedTargets: string[],
46+
): number => {
47+
const testInjector = createTestInjector();
48+
testInjector.register("options", { compileSdk });
49+
const androidToolsInfo: any = testInjector.resolve(AndroidToolsInfo);
50+
return androidToolsInfo.getCompileSdkVersion(installedTargets, 36);
51+
};
52+
53+
it("accepts a user-specified compile sdk matching an exact installed target", () => {
54+
assert.equal(resolveCompileSdk(36, ["android-35", "android-36"]), 36);
55+
});
56+
57+
it("accepts a user-specified compile sdk installed as a minor-versioned target", () => {
58+
assert.equal(
59+
resolveCompileSdk(37, ["android-36", "android-37.0", "android-37.1"]),
60+
37,
61+
);
62+
});
63+
64+
it("fails when the user-specified compile sdk is not installed", () => {
65+
assert.throws(
66+
() => resolveCompileSdk(38, ["android-36", "android-37.0"]),
67+
"You have specified '38' for compile sdk, but it is not installed on your system.",
68+
);
69+
});
70+
71+
it("does not treat extension targets as the base platform", () => {
72+
assert.throws(
73+
() => resolveCompileSdk(35, ["android-34", "android-35-ext15"]),
74+
"You have specified '35' for compile sdk, but it is not installed on your system.",
75+
);
76+
});
77+
});
78+
4279
describe("validateJavacVersion", () => {
4380
it("throws error when passing showWarningsAsErrors to true and javac is not installed", () => {
4481
const testInjector = createTestInjector();
45-
const androidToolsInfo = testInjector.resolve<IAndroidToolsInfo>(
46-
AndroidToolsInfo
47-
);
82+
const androidToolsInfo =
83+
testInjector.resolve<IAndroidToolsInfo>(AndroidToolsInfo);
4884
assert.throws(
4985
() =>
5086
androidToolsInfo.validateJavacVersion(null, {
5187
showWarningsAsErrors: true,
5288
}),
53-
"Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable."
89+
"Error executing command 'javac'. Make sure you have installed The Java Development Kit (JDK) and set JAVA_HOME environment variable.",
5490
);
5591
});
5692
});

0 commit comments

Comments
 (0)