Skip to content

Commit 221d1ca

Browse files
committed
fix: use Android SDK28 if runtime lower that 6.1.0
1 parent 21d994a commit 221d1ca

File tree

5 files changed

+116
-48
lines changed

5 files changed

+116
-48
lines changed

lib/android-tools-info.ts

Lines changed: 53 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,31 @@ import * as _ from "lodash";
1010

1111
export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
1212
public readonly ANDROID_TARGET_PREFIX = "android";
13-
private static SUPPORTED_TARGETS = [
14-
"android-17",
15-
"android-18",
16-
"android-19",
17-
"android-21",
18-
"android-22",
19-
"android-23",
20-
"android-24",
21-
"android-25",
22-
"android-26",
23-
"android-27",
24-
"android-28",
25-
"android-29"
26-
];
13+
private getSupportedTargets(projectDir: string) {
14+
const runtimeVersion = this.getRuntimeVersion({projectDir});
15+
let baseTargets = [
16+
"android-17",
17+
"android-18",
18+
"android-19",
19+
"android-21",
20+
"android-22",
21+
"android-23",
22+
"android-24",
23+
"android-25",
24+
"android-26",
25+
"android-27",
26+
"android-28",
27+
"android-29"
28+
];
29+
30+
if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) {
31+
baseTargets.sort();
32+
const indexOfSdk29 = baseTargets.indexOf("android-29");
33+
baseTargets = baseTargets.slice(0, indexOfSdk29);
34+
}
35+
36+
return baseTargets;
37+
}
2738
private static MIN_REQUIRED_COMPILE_TARGET = 28;
2839
private static REQUIRED_BUILD_TOOLS_RANGE_PREFIX = ">=23";
2940
private static VERSION_REGEX = /((\d+\.){2}\d+)/;
@@ -40,23 +51,23 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
4051
private hostInfo: HostInfo,
4152
private helpers: Helpers) { }
4253

43-
public getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData {
54+
public getToolsInfo(config: Partial<NativeScriptDoctor.IProjectDir> = {}): NativeScriptDoctor.IAndroidToolsInfoData {
4455
if (!this.toolsInfo) {
4556
const infoData: NativeScriptDoctor.IAndroidToolsInfoData = Object.create(null);
4657
infoData.androidHomeEnvVar = this.androidHome;
4758
infoData.installedTargets = this.getInstalledTargets();
48-
infoData.compileSdkVersion = this.getCompileSdk(infoData.installedTargets);
49-
infoData.buildToolsVersion = this.getBuildToolsVersion();
59+
infoData.compileSdkVersion = this.getCompileSdk(infoData.installedTargets, config.projectDir);
60+
infoData.buildToolsVersion = this.getBuildToolsVersion(config.projectDir);
5061

5162
this.toolsInfo = infoData;
5263
}
5364

5465
return this.toolsInfo;
5566
}
5667

57-
public validateInfo(): NativeScriptDoctor.IWarning[] {
68+
public validateInfo(config: Partial<NativeScriptDoctor.IProjectDir> = {}): NativeScriptDoctor.IWarning[] {
5869
const errors: NativeScriptDoctor.IWarning[] = [];
59-
const toolsInfoData = this.getToolsInfo();
70+
const toolsInfoData = this.getToolsInfo(config);
6071
const isAndroidHomeValid = this.isAndroidHomeValid();
6172
if (!toolsInfoData.compileSdkVersion) {
6273
errors.push({
@@ -67,7 +78,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
6778
}
6879

6980
if (!toolsInfoData.buildToolsVersion) {
70-
const buildToolsRange = this.getBuildToolsRange();
81+
const buildToolsRange = this.getBuildToolsRange(config.projectDir);
7182
const versionRangeMatches = buildToolsRange.match(/^.*?([\d\.]+)\s+.*?([\d\.]+)$/);
7283
let message = `You can install any version in the following range: '${buildToolsRange}'.`;
7384

@@ -110,7 +121,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
110121
if (semver.lt(installedJavaCompilerSemverVersion, AndroidToolsInfo.MIN_JAVA_VERSION)) {
111122
warning = `Javac version ${installedJavaCompilerVersion} is not supported. You have to install at least ${AndroidToolsInfo.MIN_JAVA_VERSION}.`;
112123
} else {
113-
runtimeVersion = this.getRealRuntimeVersion(runtimeVersion || this.getAndroidRuntimeVersionFromProjectDir(projectDir));
124+
runtimeVersion = this.getRuntimeVersion({runtimeVersion, projectDir});
114125
if (runtimeVersion) {
115126
// get the item from the dictionary that corresponds to our current Javac version:
116127
let runtimeMinVersion: string = null;
@@ -184,13 +195,14 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
184195
return errors;
185196
}
186197

187-
public validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] {
198+
public validateMinSupportedTargetSdk({targetSdk, projectDir}: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] {
188199
const errors: NativeScriptDoctor.IWarning[] = [];
189200
const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`;
190-
const targetSupported = _.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget);
201+
const supportedTargets = this.getSupportedTargets(projectDir);
202+
const targetSupported = _.includes(supportedTargets, newTarget);
191203

192-
if (!_.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget)) {
193-
const supportedVersions = AndroidToolsInfo.SUPPORTED_TARGETS.sort();
204+
if (!_.includes(supportedTargets, newTarget)) {
205+
const supportedVersions = supportedTargets.sort();
194206
const minSupportedVersion = this.parseAndroidSdkString(_.first(supportedVersions));
195207

196208
if (!targetSupported && targetSdk && (targetSdk < minSupportedVersion)) {
@@ -205,12 +217,12 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
205217
return errors;
206218
}
207219

208-
public validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[] {
220+
public validataMaxSupportedTargetSdk({targetSdk, projectDir}: NativeScriptDoctor.ITargetValidationOptions): NativeScriptDoctor.IWarning[] {
209221
const errors: NativeScriptDoctor.IWarning[] = [];
210222
const newTarget = `${this.ANDROID_TARGET_PREFIX}-${targetSdk}`;
211-
const targetSupported = _.includes(AndroidToolsInfo.SUPPORTED_TARGETS, newTarget);
223+
const targetSupported = _.includes(this.getSupportedTargets(projectDir), newTarget);
212224

213-
if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion()) {
225+
if (!targetSupported && !targetSdk || targetSdk > this.getMaxSupportedVersion(projectDir)) {
214226
errors.push({
215227
warning:`Support for the selected Android target SDK ${newTarget} is not verified. Your Android app might not work as expected.`,
216228
additionalInformation: "",
@@ -264,8 +276,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
264276
return sdkManagementToolPath;
265277
}
266278

267-
private getCompileSdk(installedTargets: string[]): number {
268-
const latestValidAndroidTarget = this.getLatestValidAndroidTarget(installedTargets);
279+
private getCompileSdk(installedTargets: string[], projectDir: string): number {
280+
const latestValidAndroidTarget = this.getLatestValidAndroidTarget(installedTargets, projectDir);
269281
if (latestValidAndroidTarget) {
270282
const integerVersion = this.parseAndroidSdkString(latestValidAndroidTarget);
271283

@@ -300,23 +312,23 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
300312
return selectedVersion;
301313
}
302314

303-
private getBuildToolsRange(): string {
304-
return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion()}`;
315+
private getBuildToolsRange(projectDir: string): string {
316+
return `${AndroidToolsInfo.REQUIRED_BUILD_TOOLS_RANGE_PREFIX} <=${this.getMaxSupportedVersion(projectDir)}`;
305317
}
306318

307-
private getBuildToolsVersion(): string {
319+
private getBuildToolsVersion(projectDir: string): string {
308320
let buildToolsVersion: string;
309321
if (this.androidHome) {
310322
const pathToBuildTools = path.join(this.androidHome, "build-tools");
311-
const buildToolsRange = this.getBuildToolsRange();
323+
const buildToolsRange = this.getBuildToolsRange(projectDir);
312324
buildToolsVersion = this.getMatchingDir(pathToBuildTools, buildToolsRange);
313325
}
314326

315327
return buildToolsVersion;
316328
}
317329

318-
private getLatestValidAndroidTarget(installedTargets: string[]): string {
319-
return _.findLast(AndroidToolsInfo.SUPPORTED_TARGETS.sort(), supportedTarget => _.includes(installedTargets, supportedTarget));
330+
private getLatestValidAndroidTarget(installedTargets: string[], projectDir: string): string {
331+
return _.findLast(this.getSupportedTargets(projectDir).sort(), supportedTarget => _.includes(installedTargets, supportedTarget));
320332
}
321333

322334
private parseAndroidSdkString(androidSdkString: string): number {
@@ -336,8 +348,9 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
336348
}
337349
}
338350

339-
private getMaxSupportedVersion(): number {
340-
return this.parseAndroidSdkString(AndroidToolsInfo.SUPPORTED_TARGETS.sort()[AndroidToolsInfo.SUPPORTED_TARGETS.length - 1]);
351+
private getMaxSupportedVersion(projectDir: string): number {
352+
const supportedTargets = this.getSupportedTargets(projectDir);
353+
return this.parseAndroidSdkString(supportedTargets.sort()[supportedTargets.length - 1]);
341354
}
342355

343356
private getSystemRequirementsLink(): string {
@@ -363,7 +376,8 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo {
363376
return runtimeVersion;
364377
}
365378

366-
private getRealRuntimeVersion(runtimeVersion: string): string {
379+
private getRuntimeVersion({ runtimeVersion, projectDir } : { runtimeVersion?: string, projectDir?: string}): string {
380+
runtimeVersion = runtimeVersion || this.getAndroidRuntimeVersionFromProjectDir(projectDir);
367381
if (runtimeVersion) {
368382
// Check if the version is not "next" or "rc", i.e. tag from npm
369383
if (!semver.valid(runtimeVersion)) {

lib/doctor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class Doctor implements NativeScriptDoctor.IDoctor {
8787
platforms: [Constants.ANDROID_PLATFORM_NAME]
8888
}),
8989
this.processValidationErrors({
90-
warnings: this.androidToolsInfo.validateInfo(),
90+
warnings: this.androidToolsInfo.validateInfo({projectDir}),
9191
infoMessage: "A compatible Android SDK for compilation is found.",
9292
platforms: [Constants.ANDROID_PLATFORM_NAME]
9393
}),

lib/local-build-requirements/android-local-build-requirements.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export class AndroidLocalBuildRequirements {
33
private sysInfo: NativeScriptDoctor.ISysInfo) { }
44

55
public async checkRequirements(projectDir?: string, runtimeVersion?: string): Promise<boolean> {
6-
const androidToolsInfo = await this.androidToolsInfo.validateInfo();
6+
const androidToolsInfo = await this.androidToolsInfo.validateInfo({projectDir});
77
const javacVersion = await this.sysInfo.getJavaCompilerVersion();
88
const isJavacVersionInvalid = !javacVersion || (await this.androidToolsInfo.validateJavacVersion(javacVersion, projectDir, runtimeVersion)).length;
99
if (androidToolsInfo.length ||

test/android-tools-info.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@ interface ITestData {
1515
}
1616

1717
describe("androidToolsInfo", () => {
18+
const originalAndroidHome = process.env["ANDROID_HOME"];
1819
const defaultAdditionalInformation = "You will not be able to build your projects for Android." + EOL
1920
+ "To be able to build for Android, verify that you have installed The Java Development Kit (JDK) and configured it according to system requirements as" + EOL +
2021
" described in " + Constants.SYSTEM_REQUIREMENTS_LINKS[process.platform];
21-
22+
before(() => {
23+
process.env["ANDROID_HOME"] = "test";
24+
});
2225
const getAndroidToolsInfo = (runtimeVersion?: string): AndroidToolsInfo => {
2326
const childProcess: ChildProcess = <any>{};
2427
const fs: FileSystem = <any>{
@@ -32,13 +35,46 @@ describe("androidToolsInfo", () => {
3235
}
3336
}
3437
} : null;
38+
},
39+
readDirectory: (path: string) => {
40+
if (path.indexOf("build-tools") >= 0) {
41+
return [
42+
"20.0.0",
43+
"27.0.3",
44+
"28.0.3",
45+
"29.0.1"
46+
];
47+
} else {
48+
return [
49+
"android-16",
50+
"android-27",
51+
"android-28",
52+
"android-29"
53+
];
54+
}
3555
}
3656
};
3757
const hostInfo: HostInfo = <any>{};
3858
const helpers: Helpers = new Helpers(<any>{});
3959
return new AndroidToolsInfo(childProcess, fs, hostInfo, helpers);
4060
};
4161

62+
describe("getToolsInfo", () => {
63+
it("runtime 6.0.0", () => {
64+
const androidToolsInfo = getAndroidToolsInfo("6.0.0");
65+
const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"});
66+
67+
assert.equal(toolsInfo.compileSdkVersion, 28);
68+
});
69+
70+
it("runtime 6.0.0", () => {
71+
const androidToolsInfo = getAndroidToolsInfo("6.1.0");
72+
const toolsInfo = androidToolsInfo.getToolsInfo({projectDir: "test"});
73+
74+
assert.equal(toolsInfo.compileSdkVersion, 29);
75+
});
76+
});
77+
4278
describe("validateJavacVersion", () => {
4379
const testData: ITestData[] = [
4480
{
@@ -197,4 +233,8 @@ describe("androidToolsInfo", () => {
197233
});
198234
});
199235
});
236+
237+
after(() => {
238+
process.env["ANDROID_HOME"] = originalAndroidHome;
239+
});
200240
});

typings/interfaces.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -460,13 +460,13 @@ declare module NativeScriptDoctor {
460460
* Returns the Android tools info.
461461
* @return {NativeScriptDoctor.IAndroidToolsInfoData} returns the Android tools info.
462462
*/
463-
getToolsInfo(): NativeScriptDoctor.IAndroidToolsInfoData;
463+
getToolsInfo(config: IProjectDir): NativeScriptDoctor.IAndroidToolsInfoData;
464464

465465
/**
466466
* Checks if the Android tools are valid.
467467
* @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return [].
468468
*/
469-
validateInfo(): NativeScriptDoctor.IWarning[];
469+
validateInfo(config: IProjectDir): NativeScriptDoctor.IWarning[];
470470

471471
/**
472472
* Checks if the current javac version is valid.
@@ -492,17 +492,17 @@ declare module NativeScriptDoctor {
492492

493493
/**
494494
* Validates if the provided targetSdk is greater that the minimum supported target SDK.
495-
* @param {number} targetSdk The targetSdk to be validated.
495+
* @param {ITargetValidationOptions} options The targetSdk to be validated and the project directory - used to determine the Android Runtime version.
496496
* @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return [].
497497
*/
498-
validateMinSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[];
498+
validateMinSupportedTargetSdk(options: ITargetValidationOptions): NativeScriptDoctor.IWarning[];
499499

500500
/**
501501
* Validates if the provided targetSdk is lower that the maximum supported target SDK.
502-
* @param {number} targetSdk The targetSdk to be validated.
502+
* @param {ITargetValidationOptions} options The targetSdk to be validated and the project directory - used to determine the Android Runtime version.
503503
* @return {NativeScriptDoctor.IWarning[]} An array of errors from the validation checks. If there are no errors will return [].
504504
*/
505-
validataMaxSupportedTargetSdk(targetSdk: number): NativeScriptDoctor.IWarning[];
505+
validataMaxSupportedTargetSdk(options: ITargetValidationOptions): NativeScriptDoctor.IWarning[];
506506

507507
/**
508508
* Returns the path to the emulator executable.
@@ -511,6 +511,13 @@ declare module NativeScriptDoctor {
511511
getPathToEmulatorExecutable(): string;
512512
}
513513

514+
/**
515+
* The targetSdk to be validated.
516+
*/
517+
interface ITargetValidationOptions extends Partial<IProjectDir> {
518+
targetSdk: number;
519+
}
520+
514521
/**
515522
* Describes information about installed Android tools and SDKs.
516523
*/
@@ -535,4 +542,11 @@ declare module NativeScriptDoctor {
535542
*/
536543
installedTargets: string[];
537544
}
545+
546+
/**
547+
* Object with a single property - projectDir. This is the root directory where NativeScript project is located.
548+
*/
549+
interface IProjectDir {
550+
projectDir: string;
551+
}
538552
}

0 commit comments

Comments
 (0)