com.grab.grazel.migrate.internal.WorkspaceBuilder.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of grazel-gradle-plugin Show documentation
Show all versions of grazel-gradle-plugin Show documentation
A Gradle plugin to automate Bazel migration for Android projects
The newest version!
/*
* Copyright 2022 Grabtaxi Holdings PTE LTD (GRAB)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.grab.grazel.migrate.internal
import com.android.build.gradle.BaseExtension
import com.grab.grazel.GrazelExtension
import com.grab.grazel.bazel.rules.DAGGER_ARTIFACTS
import com.grab.grazel.bazel.rules.DAGGER_REPOSITORIES
import com.grab.grazel.bazel.rules.GRAB_BAZEL_COMMON_ARTIFACTS
import com.grab.grazel.bazel.rules.androidNdkRepository
import com.grab.grazel.bazel.rules.androidSdkRepository
import com.grab.grazel.bazel.rules.bazelCommonRepository
import com.grab.grazel.bazel.rules.daggerWorkspaceRules
import com.grab.grazel.bazel.rules.kotlinCompiler
import com.grab.grazel.bazel.rules.kotlinRepository
import com.grab.grazel.bazel.rules.loadBazelCommonArtifacts
import com.grab.grazel.bazel.rules.loadDaggerArtifactsAndRepositories
import com.grab.grazel.bazel.rules.mavenInstall
import com.grab.grazel.bazel.rules.registerKotlinToolchain
import com.grab.grazel.bazel.rules.setupMavenInstall
import com.grab.grazel.bazel.rules.toolAndroidRepository
import com.grab.grazel.bazel.rules.workspace
import com.grab.grazel.bazel.starlark.LoadStrategy
import com.grab.grazel.bazel.starlark.StatementsBuilder
import com.grab.grazel.bazel.starlark.add
import com.grab.grazel.bazel.starlark.statements
import com.grab.grazel.di.qualifiers.RootProject
import com.grab.grazel.gradle.DefaultGradleProjectInfo
import com.grab.grazel.gradle.GradleProjectInfo
import com.grab.grazel.gradle.dependencies.model.WorkspaceDependencies
import com.grab.grazel.gradle.isAndroidApplication
import com.grab.grazel.migrate.BazelFileBuilder
import com.grab.grazel.migrate.android.parseCompileSdkVersion
import com.grab.grazel.migrate.dependencies.MavenInstallArtifactsCalculator
import org.gradle.api.Project
import org.gradle.kotlin.dsl.the
import javax.inject.Inject
import javax.inject.Singleton
internal class WorkspaceBuilder(
private val rootProject: Project,
private val projectsToMigrate: List,
private val grazelExtension: GrazelExtension,
private val gradleProjectInfo: GradleProjectInfo,
private val workspaceDependencies: WorkspaceDependencies,
private val mavenInstallArtifactsCalculator: MavenInstallArtifactsCalculator
) : BazelFileBuilder {
@Singleton
class Factory
@Inject
constructor(
@param:RootProject private val rootProject: Project,
private val grazelExtension: GrazelExtension,
private val gradleProjectInfoFactory: DefaultGradleProjectInfo.Factory,
private val mavenInstallArtifactsCalculator: MavenInstallArtifactsCalculator,
) {
fun create(
projectsToMigrate: List,
gradleProjectInfo: GradleProjectInfo,
workspaceDependencies: WorkspaceDependencies = WorkspaceDependencies(emptyMap()),
) = WorkspaceBuilder(
rootProject,
projectsToMigrate,
grazelExtension,
gradleProjectInfoFactory.create(workspaceDependencies),
workspaceDependencies,
mavenInstallArtifactsCalculator
)
}
override fun build() = statements(loadStrategy = LoadStrategy.Inline()) {
workspace(name = rootProject.name)
kotlinRules()
bazelCommon()
buildJvmRules()
addAndroidSdkRepositories(this)
toolsAndroid()
}
private fun StatementsBuilder.buildJvmRules() {
val hasDagger = gradleProjectInfo.hasDagger
val externalArtifacts = mutableListOf()
val externalRepositories = mutableListOf()
if (hasDagger) {
daggerWorkspaceRules(grazelExtension.rules.dagger)
loadDaggerArtifactsAndRepositories()
// TODO Remove dagger rules and build generic annotation processor config
externalArtifacts += DAGGER_ARTIFACTS
externalRepositories += DAGGER_REPOSITORIES
}
loadBazelCommonArtifacts(grazelExtension.rules.bazelCommon.repository.name)
externalArtifacts += GRAB_BAZEL_COMMON_ARTIFACTS
val mavenInstall = grazelExtension.rules.mavenInstall.apply {
add(repository)
setupMavenInstall()
}
mavenInstallArtifactsCalculator.get(
rootProject.layout,
workspaceDependencies,
externalArtifacts.toSortedSet(),
externalRepositories.toSortedSet(),
).forEach { mavenInstallData ->
mavenInstall(
name = mavenInstallData.name,
rulesJvmExternalName = mavenInstall.repository.name,
artifacts = mavenInstallData.artifacts,
externalArtifacts = mavenInstallData.externalArtifacts,
mavenRepositories = mavenInstallData.repositories,
externalRepositories = mavenInstallData.externalRepositories,
jetify = mavenInstallData.jetifierConfig.isEnabled,
jetifyArtifacts = mavenInstallData.jetifierConfig.artifacts,
failOnMissingChecksum = false,
resolveTimeout = mavenInstallData.resolveTimeout,
excludeArtifacts = mavenInstallData.excludeArtifacts,
overrideTargets = mavenInstallData.overrideTargets,
versionConflictPolicy = mavenInstallData.versionConflictPolicy,
artifactPinning = mavenInstallData.artifactPinning,
mavenInstallJson = mavenInstallData.mavenInstallJson,
mavenInstallJsonEnabled = mavenInstallData.isMavenInstallJsonEnabled,
)
}
}
/** Configure imports for Grab bazel common repository */
private fun StatementsBuilder.bazelCommon() {
val bazelCommon = grazelExtension.rules.bazelCommon
val bazelCommonRepo = bazelCommon.repository
val toolchains = bazelCommon.toolchains
val buildifier = toolchains.buildifier
bazelCommonRepository(
bazelCommonRepo,
buildifier.releaseVersion,
)
}
private fun StatementsBuilder.toolsAndroid() {
if (gradleProjectInfo.hasGooglePlayServices) {
toolAndroidRepository(grazelExtension.rules.googleServices.repository)
}
}
internal fun addAndroidSdkRepositories(statementsBuilder: StatementsBuilder) {
statementsBuilder.run {
// Find the android application module and extract compileSdk and buildToolsVersion
rootProject
.subprojects
.firstOrNull(Project::isAndroidApplication)
?.let { project ->
val baseExtension = project.the()
// Parse API level using DefaultApiVersion since AGP rewrites declared compileSdkVersion to string.
androidSdkRepository(
apiLevel = parseCompileSdkVersion(baseExtension.compileSdkVersion),
buildToolsVersion = baseExtension.buildToolsVersion
)
} ?: androidSdkRepository()
// Add repository for NDK
validateNdkApiLevel()
androidNdkRepository(
ndkApiLevel = grazelExtension.android.ndkApiLevel
)
}
}
private fun validateNdkApiLevel() {
val ndkApiLevel = grazelExtension.android.ndkApiLevel ?: return
if (ndkApiLevel <= 0) {
throw IllegalStateException("ndkApiLevel value should be greater than 0")
}
}
/**
* Add Kotlin specific statements to WORKSPACE namely
* * Kotlin repository
* * Kotlin compiler
* * Registering toolchains
*/
private fun StatementsBuilder.kotlinRules() {
val kotlin = grazelExtension.rules.kotlin
kotlinRepository(repositoryRule = kotlin.repository)
kotlinCompiler(kotlin.compiler.tag, kotlin.compiler.sha)
registerKotlinToolchain(toolchain = kotlin.toolchain)
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy