diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index ce0780ef8f..96eff761da 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -313,9 +313,10 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject } ); - this.$androidToolsInfo.validateTargetSdk({ + this.$androidToolsInfo.validateInfo({ showWarningsAsErrors: true, projectDir: projectData.projectDir, + validateTargetSdk: true, }); return { diff --git a/package-lock.json b/package-lock.json index 03652f57fc..c903e8a5b7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@nativescript/doctor": "2.0.7", + "@nativescript/doctor": "2.0.8", "@nativescript/schematics-executor": "0.0.2", "@rigor789/resolve-package-path": "^1.0.5", "axios": "^0.21.1", @@ -692,9 +692,9 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "node_modules/@nativescript/doctor": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@nativescript/doctor/-/doctor-2.0.7.tgz", - "integrity": "sha512-Pd3NlFGXN+SC03sBC/pj/9t5v5h7bh2xnbjbXHCo1MTjjm6fpLGFSxlCZRPPFgDIisf4OqGmEeIglNpy7CbyZg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nativescript/doctor/-/doctor-2.0.8.tgz", + "integrity": "sha512-/jVGBBBBY2BX1IwriDyXHNi0ZNAkSuzdDQuGY3nUl3BDLu5AM+FFg4qCG3D9IW664WLbA1KbJQd+HUSjRHM/ZQ==", "dependencies": { "lodash": "4.17.21", "osenv": "0.1.5", @@ -13607,9 +13607,9 @@ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" }, "@nativescript/doctor": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@nativescript/doctor/-/doctor-2.0.7.tgz", - "integrity": "sha512-Pd3NlFGXN+SC03sBC/pj/9t5v5h7bh2xnbjbXHCo1MTjjm6fpLGFSxlCZRPPFgDIisf4OqGmEeIglNpy7CbyZg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/@nativescript/doctor/-/doctor-2.0.8.tgz", + "integrity": "sha512-/jVGBBBBY2BX1IwriDyXHNi0ZNAkSuzdDQuGY3nUl3BDLu5AM+FFg4qCG3D9IW664WLbA1KbJQd+HUSjRHM/ZQ==", "requires": { "lodash": "4.17.21", "osenv": "0.1.5", diff --git a/package.json b/package.json index da149de312..205c05c56b 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "mobile" ], "dependencies": { - "@nativescript/doctor": "2.0.7", + "@nativescript/doctor": "2.0.8", "@nativescript/schematics-executor": "0.0.2", "@rigor789/resolve-package-path": "^1.0.5", "axios": "^0.21.1", diff --git a/packages/doctor/package.json b/packages/doctor/package.json index 9055c8a3e9..2da24df6c2 100644 --- a/packages/doctor/package.json +++ b/packages/doctor/package.json @@ -1,6 +1,6 @@ { "name": "@nativescript/doctor", - "version": "2.0.7", + "version": "2.0.8", "description": "Library that helps identifying if the environment can be used for development of {N} apps.", "main": "src/index.js", "types": "./typings/nativescript-doctor.d.ts", diff --git a/packages/doctor/src/android-tools-info.ts b/packages/doctor/src/android-tools-info.ts index 1c7c124a05..f2676ccbdf 100644 --- a/packages/doctor/src/android-tools-info.ts +++ b/packages/doctor/src/android-tools-info.ts @@ -31,10 +31,19 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { "android-32", ]; - if (runtimeVersion && semver.lt(semver.coerce(runtimeVersion), "6.1.0")) { - baseTargets.sort(); - const indexOfSdk29 = baseTargets.indexOf("android-29"); - baseTargets = baseTargets.slice(0, indexOfSdk29); + const isRuntimeVersionLessThan = (targetVersion: string) => { + return ( + runtimeVersion && + semver.lt(semver.coerce(runtimeVersion), targetVersion) + ); + }; + + if (isRuntimeVersionLessThan("6.1.0")) { + // limit baseTargets to android-17 - android-28 if the runtime is < 6.1.0 + baseTargets = baseTargets.slice(0, baseTargets.indexOf("android-29")); + } else if (isRuntimeVersionLessThan("8.2.0")) { + // limit baseTargets to android-17 - android-30 if the runtime is < 8.2.0 + baseTargets = baseTargets.slice(0, baseTargets.indexOf("android-31")); } return baseTargets; @@ -119,15 +128,16 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { message = `You have to install version ${versionRangeMatches[1]}.`; } - let invalidBuildToolsAdditionalMsg = `Run \`\$ ${this.getPathToSdkManagementTool()}\` from your command-line to install required \`Android Build Tools\`.`; + // let invalidBuildToolsAdditionalMsg = `Run \`\$ ${this.getPathToSdkManagementTool()}\` from your command-line to install required \`Android Build Tools\`.`; + let invalidBuildToolsAdditionalMsg = `Install the required build-tools through Android Studio.`; if (!isAndroidHomeValid) { invalidBuildToolsAdditionalMsg += - " In case you already have them installed, make sure `ANDROID_HOME` environment variable is set correctly."; + " In case you already have them installed, make sure the `ANDROID_HOME` environment variable is set correctly."; } errors.push({ warning: - "You need to have the Android SDK Build-tools installed on your system. " + + "No compatible version of the Android SDK Build-tools are installed on your system. " + message, additionalInformation: invalidBuildToolsAdditionalMsg, platforms: [Constants.ANDROID_PLATFORM_NAME], @@ -504,6 +514,7 @@ export class AndroidToolsInfo implements NativeScriptDoctor.IAndroidToolsInfo { private getMaxSupportedVersion(projectDir: string): number { const supportedTargets = this.getSupportedTargets(projectDir); + return this.parseAndroidSdkString( supportedTargets.sort()[supportedTargets.length - 1] ); diff --git a/packages/doctor/test/android-tools-info.ts b/packages/doctor/test/android-tools-info.ts index 1e2694166a..3ae274840d 100644 --- a/packages/doctor/test/android-tools-info.ts +++ b/packages/doctor/test/android-tools-info.ts @@ -47,9 +47,25 @@ describe("androidToolsInfo", () => { }, readDirectory: (path: string) => { if (path.indexOf("build-tools") >= 0) { - return ["20.0.0", "27.0.3", "28.0.3", "29.0.1"]; + return [ + "20.0.0", + "27.0.3", + "28.0.3", + "29.0.1", + "30.0.0", + "31.0.0", + "32.0.0", + ]; } else { - return ["android-16", "android-27", "android-28", "android-29"]; + return [ + "android-16", + "android-27", + "android-28", + "android-29", + "android-30", + "android-31", + "android-32", + ]; } }, }; @@ -58,34 +74,68 @@ describe("androidToolsInfo", () => { return new AndroidToolsInfo(childProcess, fs, hostInfo, helpers); }; - describe("getToolsInfo", () => { - it("runtime 6.0.0", () => { + describe("getToolsInfo -> compileSdkVersion", () => { + it("runtime 6.0.0 - 28", () => { const androidToolsInfo = getAndroidToolsInfo("6.0.0"); const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" }); assert.equal(toolsInfo.compileSdkVersion, 28); }); - it("runtime 6.1.0", () => { + it("runtime 6.1.0 - 30", () => { const androidToolsInfo = getAndroidToolsInfo("6.1.0"); const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" }); - assert.equal(toolsInfo.compileSdkVersion, 29); + assert.equal(toolsInfo.compileSdkVersion, 30); + }); + + it("runtime 8.1.1 - 30", () => { + const androidToolsInfo = getAndroidToolsInfo("8.1.1"); + const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" }); + + assert.equal(toolsInfo.compileSdkVersion, 30); + }); + + it("runtime 8.2.0 - 32", () => { + const androidToolsInfo = getAndroidToolsInfo("8.2.0"); + const toolsInfo = androidToolsInfo.getToolsInfo({ projectDir: "test" }); + + assert.equal(toolsInfo.compileSdkVersion, 32); }); }); describe("supportedAndroidSdks", () => { - it("should support android-17 - android-32", () => { - const min = 17; - const max = 32; + const assertSupportedRange = ( + runtimeVersion: string, + min: number, + max: number + ) => { let cnt = 0; - const androidToolsInfo = getAndroidToolsInfo("6.5.0"); + const androidToolsInfo = getAndroidToolsInfo(runtimeVersion); const supportedTargets = androidToolsInfo.getSupportedTargets("test"); for (let i = 0; i < supportedTargets.length; i++) { assert.equal(supportedTargets[i], `android-${min + i}`); cnt = min + i; } assert.equal(cnt, max); + }; + + it("runtime 6.0.0 should support android-17 - android-28", () => { + const min = 17; + const max = 28; + assertSupportedRange("6.0.0", min, max); + }); + + it("runtime 8.1.0 should support android-17 - android-30", () => { + const min = 17; + const max = 30; + assertSupportedRange("8.1.0", min, max); + }); + + it("runtime 8.2.0 should support android-17 - android-32", () => { + const min = 17; + const max = 32; + assertSupportedRange("8.2.0", min, max); }); }); @@ -295,6 +345,52 @@ describe("androidToolsInfo", () => { ); }); + describe("validataMaxSupportedTargetSdk", () => { + const testCases = [ + { + runtimeVersion: "8.1.0", + targetSdk: 30, + expectWarning: false, + }, + { + runtimeVersion: "8.1.0", + targetSdk: 31, + expectWarning: true, + }, + { + runtimeVersion: "8.1.0", + targetSdk: 32, + expectWarning: true, + }, + { + runtimeVersion: "8.2.0", + targetSdk: 32, + expectWarning: false, + }, + ]; + + testCases.forEach(({ runtimeVersion, targetSdk, expectWarning }) => { + it(`for runtime ${runtimeVersion} - and targetSdk ${targetSdk}`, () => { + const androidToolsInfo = getAndroidToolsInfo(runtimeVersion); + const actualWarnings = androidToolsInfo.validataMaxSupportedTargetSdk({ + projectDir: "test", + targetSdk, + }); + let expectedWarnings: NativeScriptDoctor.IWarning[] = []; + + if (expectWarning) { + expectedWarnings.push({ + additionalInformation: "", + platforms: ["Android"], + warning: `Support for the selected Android target SDK android-${targetSdk} is not verified. Your Android app might not work as expected.`, + }); + } + + assert.deepEqual(actualWarnings, expectedWarnings); + }); + }); + }); + after(() => { process.env["ANDROID_HOME"] = originalAndroidHome; }); diff --git a/packages/doctor/tsconfig.json b/packages/doctor/tsconfig.json index 6ba27864c0..3e110d9f3a 100644 --- a/packages/doctor/tsconfig.json +++ b/packages/doctor/tsconfig.json @@ -5,6 +5,7 @@ }, "include": [ "src/", - "test/" + "test/", + "typings/" ] } diff --git a/yarn.lock b/yarn.lock index 7343904631..43b1af8262 100644 --- a/yarn.lock +++ b/yarn.lock @@ -340,10 +340,10 @@ "resolved" "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz" "version" "1.1.1" -"@nativescript/doctor@2.0.7": - "integrity" "sha512-Pd3NlFGXN+SC03sBC/pj/9t5v5h7bh2xnbjbXHCo1MTjjm6fpLGFSxlCZRPPFgDIisf4OqGmEeIglNpy7CbyZg==" - "resolved" "https://registry.npmjs.org/@nativescript/doctor/-/doctor-2.0.7.tgz" - "version" "2.0.7" +"@nativescript/doctor@2.0.8": + "integrity" "sha512-/jVGBBBBY2BX1IwriDyXHNi0ZNAkSuzdDQuGY3nUl3BDLu5AM+FFg4qCG3D9IW664WLbA1KbJQd+HUSjRHM/ZQ==" + "resolved" "https://registry.npmjs.org/@nativescript/doctor/-/doctor-2.0.8.tgz" + "version" "2.0.8" dependencies: "lodash" "4.17.21" "osenv" "0.1.5"