diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index a25346adfa..15910d8370 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -139,6 +139,8 @@ interface INsConfigAndroid extends INsConfigPlaform { enableLineBreakpoints?: boolean; enableMultithreadedJavascript?: boolean; + + gradleVersion?: string; } interface INsConfigHooks { diff --git a/lib/services/android-plugin-build-service.ts b/lib/services/android-plugin-build-service.ts index 0ba08ec83c..43cad19f55 100644 --- a/lib/services/android-plugin-build-service.ts +++ b/lib/services/android-plugin-build-service.ts @@ -394,7 +394,18 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService { this.$fs.copyFile(path.join(dir, "*"), destination); } } - + private extractNamespaceFromManifest(manifestPath:string): string { + const fileContent = this.$fs.readText(manifestPath); + const contentRegex = new RegExp('package="(.*)"'); + const match = fileContent.match(contentRegex); + let namespace: string; + if (match) { + namespace = match[1]; + const replacedFileContent = fileContent.replace(contentRegex, ""); + this.$fs.writeFile(manifestPath, replacedFileContent); + } + return namespace; + } private async setupGradle( pluginTempDir: string, platformsAndroidDirPath: string, @@ -413,14 +424,29 @@ export class AndroidPluginBuildService implements IAndroidPluginBuildService { const runtimeGradleVersions = await this.getRuntimeGradleVersions( projectDir ); + let gradleVersion = runtimeGradleVersions.gradleVersion; + if (this.$projectData.nsConfig.android.gradleVersion) { + gradleVersion = this.$projectData.nsConfig.android.gradleVersion; + } this.replaceGradleVersion( pluginTempDir, - runtimeGradleVersions.gradleVersion + gradleVersion ); this.replaceGradleAndroidPluginVersion( buildGradlePath, runtimeGradleVersions.gradleAndroidPluginVersion ); + + // In gradle 8 every android project must have a namespace in "android" + // and the package property in manifest is now forbidden + // let s replace it + const manifestFilePath = this.getManifest(path.join(pluginTempDir, 'src', 'main')); + let pluginNamespace = this.extractNamespaceFromManifest(manifestFilePath); + if (!pluginNamespace) { + pluginNamespace = pluginName.replace(/@/g, '').replace(/[/-]/g, '.') + } + + this.replaceFileContent(buildGradlePath, "{{pluginNamespace}}", pluginNamespace); this.replaceFileContent(buildGradlePath, "{{pluginName}}", pluginName); this.replaceFileContent(settingsGradlePath, "{{pluginName}}", pluginName); } diff --git a/lib/services/android-project-service.ts b/lib/services/android-project-service.ts index 71335ef5b6..655932b1f3 100644 --- a/lib/services/android-project-service.ts +++ b/lib/services/android-project-service.ts @@ -459,6 +459,24 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject gradleSettingsFilePath ); + + const gradleVersion = projectData.nsConfig.android.gradleVersion; + if (gradleVersion) { + // user defined a custom gradle version, let's apply it + const gradleWrapperFilePath = path.join( + this.getPlatformData(projectData).projectRoot, + "gradle", + "wrapper", + "gradle-wrapper.properties" + ); + shell.sed( + "-i", + /gradle-([0-9.]+)-bin.zip/, + `gradle-${gradleVersion}-bin.zip`, + gradleWrapperFilePath + ); + } + try { // will replace applicationId in app/App_Resources/Android/app.gradle if it has not been edited by the user const appGradleContent = this.$fs.readText(projectData.appGradlePath); @@ -487,6 +505,17 @@ export class AndroidProjectService extends projectServiceBaseLib.PlatformProject projectData.projectIdentifiers.android, manifestPath ); + const buildGradlePath = path.join( + this.getPlatformData(projectData).projectRoot, + "app", + "build.gradle" + ); + shell.sed( + "-i", + /__PACKAGE__/, + projectData.projectIdentifiers.android, + buildGradlePath + ); } private getProjectNameFromId(projectData: IProjectData): string { diff --git a/vendor/gradle-plugin/build.gradle b/vendor/gradle-plugin/build.gradle index 38092efde4..ae69a335c0 100644 --- a/vendor/gradle-plugin/build.gradle +++ b/vendor/gradle-plugin/build.gradle @@ -13,12 +13,16 @@ buildscript { } def computeKotlinVersion = { -> project.hasProperty("kotlinVersion") ? kotlinVersion : "1.8.20" } def kotlinVersion = computeKotlinVersion() + def computeBuildToolsVersion = { -> + project.hasProperty("androiBuildToolsVersion") ? buildToolsVersion : "{{runtimeAndroidPluginVersion}}" + } + def androiBuildToolsVersion = computeBuildToolsVersion() repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:{{runtimeAndroidPluginVersion}}' + classpath "com.android.tools.build:gradle:$androiBuildToolsVersion" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" // NOTE: Do not place your application dependencies here; they belong @@ -152,6 +156,7 @@ def computeBuildToolsVersion = { -> } android { + namespace "{{pluginNamespace}}" def applyPluginGradleConfigurations = { -> nativescriptDependencies.each { dep -> def includeGradlePath = "${getDepPlatformDir(dep)}/include.gradle" @@ -166,6 +171,11 @@ android { compileSdkVersion computeCompileSdkVersion() buildToolsVersion computeBuildToolsVersion() + compileOptions { + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 + } + defaultConfig { targetSdkVersion computeTargetSdkVersion() versionCode 1 @@ -205,24 +215,24 @@ task addDependenciesFromNativeScriptPlugins { } } -afterEvaluate { - def generateBuildConfig = project.hasProperty("generateBuildConfig") ? project.generateBuildConfig : false - def generateR = project.hasProperty("generateR") ? project.generateR : false - generateReleaseBuildConfig.enabled = generateBuildConfig - generateDebugBuildConfig.enabled = generateBuildConfig - generateReleaseResValues.enabled = generateR - generateDebugResValues.enabled = generateR -} - -tasks.whenTaskAdded({ DefaultTask currentTask -> - if (currentTask.name == 'bundleRelease' || currentTask.name == 'bundleDebug') { +// This wont work with gradle 8 + should be the same as the code just after +// afterEvaluate { +// def generateBuildConfig = project.hasProperty("generateBuildConfig") ? project.generateBuildConfig : false +// def generateR = project.hasProperty("generateR") ? project.generateR : false +// generateReleaseBuildConfig.enabled = generateBuildConfig +// generateDebugBuildConfig.enabled = generateBuildConfig +// generateReleaseResValues.enabled = generateR +// generateDebugResValues.enabled = generateR +// } +project.tasks.configureEach { + if (name == 'bundleRelease') { def generateBuildConfig = project.hasProperty("generateBuildConfig") ? project.generateBuildConfig : false def generateR = project.hasProperty("generateR") ? project.generateR : false if (!generateBuildConfig) { - currentTask.exclude '**/BuildConfig.class' + it.exclude '**/BuildConfig.class' } if (!generateR) { - currentTask.exclude '**/R.class', '**/R$*.class' + it.exclude '**/R.class', '**/R$*.class' } } -}) +}