[gradle-plugin] Use project properties instead of env variables

This commit is contained in:
Ilya Matveev
2018-04-12 15:38:21 +07:00
committed by ilmat192
parent 1d2558cd94
commit 2bf307f823
5 changed files with 240 additions and 7 deletions
@@ -83,6 +83,9 @@ dependencies {
testCompile gradleTestKit()
testCompile 'junit:junit:4.12'
testCompile "org.jetbrains.kotlin:kotlin-test:$buildKotlinVersion"
testCompile "org.jetbrains.kotlin:kotlin-test-junit:$buildKotlinVersion"
testCompile "org.tools4j:tools4j-spockito:1.6"
testCompile('org.spockframework:spock-core:1.1-groovy-2.4') {
exclude module: 'groovy-all'
}
@@ -124,6 +127,10 @@ processResources {
from(file("$rootBuildDirectory/utilities/env_blacklist"))
}
compileTestGroovy.dependsOn.remove('compileTestJava')
compileTestKotlin.dependsOn compileTestGroovy
compileTestKotlin.classpath += files(compileTestGroovy.destinationDir)
// TODO: Get rid of manual pom generation.
publishing {
publications {
@@ -70,12 +70,40 @@ internal class EnvironmentVariablesImpl: EnvironmentVariables {
get() = System.getenv("KONAN_ENABLE_OPTIMIZATIONS")?.toUpperCase() == "YES"
}
/**
* Due to https://github.com/gradle/gradle/issues/3468 we cannot use environment
* variables in Java 9. Until Gradle API for environment variables is provided
* we use project properties instead of them. TODO: Return to using env vars when the issue is fixed.
*/
internal class EnvironmentVariablesFromProperties(val project: Project): EnvironmentVariables {
override val configurationBuildDir: File?
get() = project.findProperty(ProjectProperty.KONAN_CONFIGURATION_BUILD_DIR)?.let {
project.file(it)
}
override val debuggingSymbols: Boolean
get() = project.findProperty(ProjectProperty.KONAN_DEBUGGING_SYMBOLS)?.toString()?.toUpperCase().let {
it == "YES" || it == "TRUE"
}
override val enableOptimizations: Boolean
get() = project.findProperty(ProjectProperty.KONAN_OPTIMIZATIONS_ENABLE)?.toString()?.toUpperCase().let {
it == "YES" || it == "TRUE"
}
}
internal val Project.useEnvironmentVariables: Boolean
get() = findProperty(ProjectProperty.KONAN_USE_ENVIRONMENT_VARIABLES)?.toString()?.toBoolean() ?: false
/*
TODO: Return to using env vars when the issue is fixed.
Take into account the useEnvironmentVariables property (and may be rename it) in the following way:
if (useEnvironmentVariables) {
EnvironmentVariablesImpl(project)
} else {
EnvironmentVariablesUnused()
}
*/
internal val Project.environmentVariables: EnvironmentVariables
get() = if (useEnvironmentVariables) {
EnvironmentVariablesImpl()
} else {
EnvironmentVariablesUnused()
}
get() = EnvironmentVariablesFromProperties(project)
@@ -277,7 +277,13 @@ class KonanPlugin @Inject constructor(private val registry: ToolingModelBuilderR
KONAN_BUILD_TARGETS ("konan.build.targets"),
KONAN_JVM_ARGS ("konan.jvmArgs"),
KONAN_USE_ENVIRONMENT_VARIABLES("konan.useEnvironmentVariables"),
DOWNLOAD_COMPILER ("download.compiler")
DOWNLOAD_COMPILER ("download.compiler"),
// Properties used instead of env vars until https://github.com/gradle/gradle/issues/3468 is fixed.
// TODO: Remove them when an API for env vars is provided.
KONAN_CONFIGURATION_BUILD_DIR ("konan.configuration.build.dir"),
KONAN_DEBUGGING_SYMBOLS ("konan.debugging.symbols"),
KONAN_OPTIMIZATIONS_ENABLE ("konan.optimizations.enable")
}
companion object {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.gradle.plugin.test
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import spock.lang.Ignore
import spock.lang.Unroll
import static org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes
@@ -109,10 +110,13 @@ class EnvVariableSpecification extends BaseKonanSpecification {
prefix = target.family.dynamicPrefix
suffix = target.family.dynamicSuffix
break
case ArtifactType.FRAMEWORK:
suffix = "framework"
}
return "$prefix${baseName}.$suffix"
}
@Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.")
@Unroll("Plugin should support #action via an env variable")
def 'Plugin should support enabling/disabling debug/opt via an env variable'() {
when:
@@ -126,7 +130,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
task assertEnableDebug {
doLast {
konanArtifacts.main.forEach {
if (!$assertion) throw new AssertionError("$message for \${it.name}")
if (!($assertion)) throw new AssertionError("$message for \${it.name}")
}
}
}
@@ -146,6 +150,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
"disabling opt" |"KONAN_ENABLE_OPTIMIZATIONS" |"NO" |"!it.enableOptimizations" |"Opts should be disabled"
}
@Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.")
def 'Plugin should support setting destination directory via an env variable'() {
when:
def project = createProjectWithWrapper()
@@ -194,6 +199,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
}
}
@Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.")
def 'Plugin should throw an exception if CONFIGURATION_BUILD_DIR contains a relative path'() {
when:
def project = createProjectWithWrapper()
@@ -210,6 +216,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
wrapperResult.getStderr().contains("A path passed using CONFIGURATION_BUILD_DIR should be absolute")
}
@Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.")
def 'Plugin should rerun tasks if CONFIGURATION_BUILD_DIR has been changed'() {
when:
def project = createProjectWithWrapper()
@@ -241,6 +248,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
files2.contains(artifactFileName("main", ArtifactType.LIBRARY))
}
@Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.")
def 'Plugin should ignore environmentVariables if konan.useEnvironmentVariables is false or is not set'() {
when:
def project = createProjectWithWrapper()
@@ -292,6 +300,7 @@ class EnvVariableSpecification extends BaseKonanSpecification {
resultFalseValue == 0
}
@Ignore("The plugin doesn't use env vars until https://github.com/gradle/gradle/issues/3468 is fixed.")
def 'Up-to-date checks should work with different directories for different targets'() {
when:
def project = createProjectWithWrapper()
@@ -0,0 +1,183 @@
package org.jetbrains.kotlin.gradle.plugin.test
import org.jetbrains.kotlin.gradle.plugin.test.KonanProject.escapeBackSlashes
import org.jetbrains.kotlin.konan.target.HostManager
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.junit.Rule
import org.junit.rules.TemporaryFolder
import org.junit.runner.RunWith
import org.tools4j.spockito.Spockito
import java.io.File
import kotlin.test.*
@RunWith(Spockito::class)
open class PropertiesAsEnvVariables {
val tmpFolder = TemporaryFolder()
@Rule get
val projectDirectory: File
get() = tmpFolder.root
private fun artifactFileName(baseName: String, type: ArtifactType, target: KonanTarget = HostManager.host): String {
var suffix = ""
var prefix = ""
when (type) {
ArtifactType.PROGRAM -> suffix = target.family.exeSuffix
ArtifactType.INTEROP,
ArtifactType.LIBRARY -> suffix = "klib"
ArtifactType.BITCODE -> suffix = "bc"
ArtifactType.FRAMEWORK -> suffix = "framework"
ArtifactType.DYNAMIC -> {
prefix = target.family.dynamicPrefix
suffix = target.family.dynamicSuffix
}
}
return "$prefix${baseName}.$suffix"
}
private fun assertFileExists(directory: File, filename: String) = assert(directory.list().contains(filename)) {
"No such file: $filename in directory: ${directory.absolutePath}"
}
@Test
@Spockito.Unroll(
"|property |value |assertion |message |",
"|konan.debugging.symbols |YES |it.enableDebug |Debug should be enabled |",
"|konan.debugging.symbols |true |it.enableDebug |Debug should be enabled |",
"|konan.debugging.symbols |NO |!it.enableDebug |Debug should be disabled |",
"|konan.debugging.symbols |false |!it.enableDebug |Debug should be disabled |",
"|konan.optimizations.enable |YES |it.enableOptimizations |Opts should be enabled |",
"|konan.optimizations.enable |true |it.enableOptimizations |Opts should be enabled |",
"|konan.optimizations.enable |NO |!it.enableOptimizations |Opts should be disabled |",
"|konan.optimizations.enable |false |!it.enableOptimizations |Opts should be disabled |"
)
@Spockito.Name("[{row}]: {variable}={value}")
fun `Plugin should support enabling and disabling debug and opt options via a project property`(
property: String,
value: String,
assertion: String,
message: String
) {
val project = KonanProject.createEmpty(projectDirectory)
project.buildFile.appendText("""
apply plugin: 'konan'
konanArtifacts {
library('main')
}
task assertEnableDebug {
doLast {
konanArtifacts.main.forEach {
if (!($assertion)) throw new AssertionError("$message for ${'$'}it.name")
}
}
}
""".trimIndent())
project.createRunner()
.withArguments("assertEnableDebug", "-P${property}=${value}")
.build()
}
@Test
fun `Plugin should support setting destination directory via a project property`() {
val project = KonanProject.createEmpty(projectDirectory)
val newDestinationDir = project.createSubDir("newDestination")
val newDestinationPath = newDestinationDir.absolutePath
project.buildFile.appendText("""
apply plugin: 'konan'
konanArtifacts {
program('program')
library('library')
dynamic('dynamic')
framework('framework')
}
task assertDestinationDir {
doLast {
konanArtifacts.forEach { artifact ->
artifact.forEach {
if (it.destinationDir.absolutePath != '${escapeBackSlashes(newDestinationPath)}'){
throw new AssertionError("Unexpected destination dir for ${'$'}it.name\\n" +
"expected: ${escapeBackSlashes(newDestinationPath)}\\n" +
"actual: ${'$'}it.destinationDir")
}
}
}
}
}
""".trimIndent())
project.generateSrcFile("main.kt")
project.createRunner()
.withArguments("assertDestinationDir", "build", "-Pkonan.configuration.build.dir=$newDestinationPath")
.build()
assertFileExists(newDestinationDir, artifactFileName("program", ArtifactType.PROGRAM))
assertFileExists(newDestinationDir, artifactFileName("library", ArtifactType.LIBRARY))
assertFileExists(newDestinationDir, artifactFileName("dynamic", ArtifactType.DYNAMIC))
if (HostManager.hostIsMac) {
assertFileExists(newDestinationDir, artifactFileName("framework", ArtifactType.FRAMEWORK))
}
}
@Test
fun `Plugin should rerun tasks if konan_configuration_build_dir has been changed`() {
val project = KonanProject.createEmpty(projectDirectory)
val destination1 = project.createSubDir("destination1", "subdir")
val destination2 = project.createSubDir("destination2", "subdir")
project.buildFile.appendText("""
apply plugin: 'konan'
konanArtifacts {
library('main')
}
""".trimIndent())
project.generateSrcFile("main.kt")
project.createRunner()
.withArguments("build", "-Pkonan.configuration.build.dir=${destination1.absolutePath}")
.build()
project.createRunner()
.withArguments("build", "-Pkonan.configuration.build.dir=${destination2.absolutePath}")
.build()
assertFileExists(destination1, artifactFileName("main", ArtifactType.LIBRARY))
assertFileExists(destination2, artifactFileName("main", ArtifactType.LIBRARY))
}
fun `Up-to-date checks should work with different directories for different targets`() {
val project = KonanProject.createEmpty(projectDirectory)
val fooDir = project.createSubDir("foo")
val barDir = project.createSubDir("bar")
project.buildFile.appendText("""
apply plugin: 'konan'
konanArtifacts {
library('foo')
library('bar')
}
task assertUpToDate {
dependsOn 'compileKonanFoo'
doLast {
if (!konanArtifacts.foo.getByTarget('host').state.upToDate) {
throw new AssertionError("Compilation task is not up-to-date")
}
}
}
""".trimIndent())
project.generateSrcFile("main.kt")
project.createRunner()
.withArguments("compileKonanFoo", "-Pkonan.configuration.build.dir=${fooDir.absolutePath}")
.build()
project.createRunner()
.withArguments("compileKonanBar", "-Pkonan.configuration.build.dir=${barDir.absolutePath}")
.build()
project.createRunner()
.withArguments("assertUpToDate", "-Pkonan.configuration.build.dir=${fooDir.absolutePath}")
.build()
}
}