From 13a84d7518f95b2fafc56713706e3ee9372f028c Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Tue, 28 May 2019 17:19:32 -0700 Subject: [PATCH] Use Gradle Tooling API --- README.org | 12 ++ app/build.gradle.kts | 8 + .../compileClasspath.lockfile | 16 ++ .../runtimeClasspath.lockfile | 17 ++ .../testCompileClasspath.lockfile | 16 ++ .../testRuntimeClasspath.lockfile | 17 ++ .../org/nixos/gradle2nix/GradleRunner.kt | 71 +++---- .../kotlin/org/nixos/gradle2nix/Logger.kt | 19 ++ .../main/kotlin/org/nixos/gradle2nix/Main.kt | 96 ++++++++- .../kotlin/org/nixos/gradle2nix/Projects.kt | 17 ++ build.gradle.kts | 31 ++- model/build.gradle.kts | 15 ++ .../compileClasspath.lockfile | 10 + .../runtimeClasspath.lockfile | 3 + .../testCompileClasspath.lockfile | 8 + .../testRuntimeClasspath.lockfile | 8 + .../main/kotlin/org/nixos/gradle2nix/Impl.kt | 117 +++++++++++ .../main/kotlin/org/nixos/gradle2nix/Model.kt | 52 +++++ plugin/.stutter/java8.lock | 12 ++ plugin/build.gradle.kts | 100 +++++---- .../buildscript-classpath.lockfile | 25 +++ .../compatTestCompileClasspath.lockfile | 16 ++ .../compatTestRuntimeClasspath.lockfile | 18 ++ .../compileClasspath.lockfile | 18 ++ .../runtimeClasspath.lockfile | 15 ++ .../testCompileClasspath.lockfile | 17 ++ .../testRuntimeClasspath.lockfile | 17 ++ .../kotlin/org/nixos/gradle2nix/BasicTest.kt | 78 +++++++ .../{Resolver.kt => DependencyResolver.kt} | 23 +- .../org/nixos/gradle2nix/Gradle2NixPlugin.kt | 197 +++++++++--------- .../org/nixos/gradle2nix/GradleCompat.kt | 109 ---------- .../org/nixos/gradle2nix/NixBuildSrcEnv.kt | 28 --- .../org/nixos/gradle2nix/NixBuildscriptEnv.kt | 42 ---- .../kotlin/org/nixos/gradle2nix/NixEnv.kt | 73 ------- .../org/nixos/gradle2nix/NixGradleDist.kt | 44 ---- .../org/nixos/gradle2nix/NixGradleEnv.kt | 58 ------ .../org/nixos/gradle2nix/NixProjectEnv.kt | 41 ---- .../{NixPluginEnv.kt => PluginResolver.kt} | 84 ++++---- .../org/nixos/gradle2nix/gradle-env.nix | 3 + settings.gradle.kts | 3 +- 40 files changed, 921 insertions(+), 633 deletions(-) create mode 100644 README.org create mode 100644 app/gradle/dependency-locks/compileClasspath.lockfile create mode 100644 app/gradle/dependency-locks/runtimeClasspath.lockfile create mode 100644 app/gradle/dependency-locks/testCompileClasspath.lockfile create mode 100644 app/gradle/dependency-locks/testRuntimeClasspath.lockfile create mode 100644 app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt create mode 100644 app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt create mode 100644 model/build.gradle.kts create mode 100644 model/gradle/dependency-locks/compileClasspath.lockfile create mode 100644 model/gradle/dependency-locks/runtimeClasspath.lockfile create mode 100644 model/gradle/dependency-locks/testCompileClasspath.lockfile create mode 100644 model/gradle/dependency-locks/testRuntimeClasspath.lockfile create mode 100644 model/src/main/kotlin/org/nixos/gradle2nix/Impl.kt create mode 100644 model/src/main/kotlin/org/nixos/gradle2nix/Model.kt create mode 100644 plugin/.stutter/java8.lock create mode 100644 plugin/gradle/dependency-locks/buildscript-classpath.lockfile create mode 100644 plugin/gradle/dependency-locks/compatTestCompileClasspath.lockfile create mode 100644 plugin/gradle/dependency-locks/compatTestRuntimeClasspath.lockfile create mode 100644 plugin/gradle/dependency-locks/compileClasspath.lockfile create mode 100644 plugin/gradle/dependency-locks/runtimeClasspath.lockfile create mode 100644 plugin/gradle/dependency-locks/testCompileClasspath.lockfile create mode 100644 plugin/gradle/dependency-locks/testRuntimeClasspath.lockfile create mode 100644 plugin/src/compatTest/kotlin/org/nixos/gradle2nix/BasicTest.kt rename plugin/src/main/kotlin/org/nixos/gradle2nix/{Resolver.kt => DependencyResolver.kt} (90%) delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/GradleCompat.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildSrcEnv.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt rename plugin/src/main/kotlin/org/nixos/gradle2nix/{NixPluginEnv.kt => PluginResolver.kt} (54%) diff --git a/README.org b/README.org new file mode 100644 index 0000000..b45af3d --- /dev/null +++ b/README.org @@ -0,0 +1,12 @@ +* gradle2nix + +Application and Gradle plugin to generate Nix build scripts for Gradle-based +projects. + +** Installation + + +** Usage + + +** License diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 41a22ed..553d545 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,9 +14,17 @@ repositories { } dependencies { + implementation(project(":model")) implementation(kotlin("stdlib-jdk8")) + implementation(kotlin("reflect")) implementation("org.gradle:gradle-tooling-api:${gradle.gradleVersion}") implementation("com.github.ajalt:clikt:2.0.0") + implementation("org.slf4j:slf4j-api:1.7.26") + runtimeOnly("org.slf4j:slf4j-simple:1.7.26") + implementation("com.squareup.moshi:moshi:1.8.0") + implementation("com.squareup.moshi:moshi-adapters:1.8.0") + implementation("com.squareup.moshi:moshi-kotlin:1.8.0") + implementation("com.squareup.okio:okio:2.2.2") } application { diff --git a/app/gradle/dependency-locks/compileClasspath.lockfile b/app/gradle/dependency-locks/compileClasspath.lockfile new file mode 100644 index 0000000..8c9cc7e --- /dev/null +++ b/app/gradle/dependency-locks/compileClasspath.lockfile @@ -0,0 +1,16 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.github.ajalt:clikt:2.0.0 +com.squareup.moshi:moshi-adapters:1.8.0 +com.squareup.moshi:moshi-kotlin:1.8.0 +com.squareup.moshi:moshi:1.8.0 +com.squareup.okio:okio:2.2.2 +org.gradle:gradle-tooling-api:5.4.1 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.31 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.31 +org.jetbrains:annotations:13.0 +org.slf4j:slf4j-api:1.7.26 diff --git a/app/gradle/dependency-locks/runtimeClasspath.lockfile b/app/gradle/dependency-locks/runtimeClasspath.lockfile new file mode 100644 index 0000000..41ece95 --- /dev/null +++ b/app/gradle/dependency-locks/runtimeClasspath.lockfile @@ -0,0 +1,17 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.github.ajalt:clikt:2.0.0 +com.squareup.moshi:moshi-adapters:1.8.0 +com.squareup.moshi:moshi-kotlin:1.8.0 +com.squareup.moshi:moshi:1.8.0 +com.squareup.okio:okio:2.2.2 +org.gradle:gradle-tooling-api:5.4.1 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.31 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.31 +org.jetbrains:annotations:13.0 +org.slf4j:slf4j-api:1.7.26 +org.slf4j:slf4j-simple:1.7.26 diff --git a/app/gradle/dependency-locks/testCompileClasspath.lockfile b/app/gradle/dependency-locks/testCompileClasspath.lockfile new file mode 100644 index 0000000..8c9cc7e --- /dev/null +++ b/app/gradle/dependency-locks/testCompileClasspath.lockfile @@ -0,0 +1,16 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.github.ajalt:clikt:2.0.0 +com.squareup.moshi:moshi-adapters:1.8.0 +com.squareup.moshi:moshi-kotlin:1.8.0 +com.squareup.moshi:moshi:1.8.0 +com.squareup.okio:okio:2.2.2 +org.gradle:gradle-tooling-api:5.4.1 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.31 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.31 +org.jetbrains:annotations:13.0 +org.slf4j:slf4j-api:1.7.26 diff --git a/app/gradle/dependency-locks/testRuntimeClasspath.lockfile b/app/gradle/dependency-locks/testRuntimeClasspath.lockfile new file mode 100644 index 0000000..41ece95 --- /dev/null +++ b/app/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -0,0 +1,17 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.github.ajalt:clikt:2.0.0 +com.squareup.moshi:moshi-adapters:1.8.0 +com.squareup.moshi:moshi-kotlin:1.8.0 +com.squareup.moshi:moshi:1.8.0 +com.squareup.okio:okio:2.2.2 +org.gradle:gradle-tooling-api:5.4.1 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.31 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.31 +org.jetbrains:annotations:13.0 +org.slf4j:slf4j-api:1.7.26 +org.slf4j:slf4j-simple:1.7.26 diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt b/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt index 57ecc51..fa97210 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt @@ -1,45 +1,40 @@ package org.nixos.gradle2nix import org.gradle.tooling.GradleConnector -import java.io.File +import org.gradle.tooling.ProjectConnection -class GradleRunner( - private val projectDir: File, - private val useWrapper: Boolean, - private val gradleVersion: String?, - private val configurations: List -) { - companion object { - val initScript: String = System.getProperty("org.nixos.gradle2nix.initScript") +private val initScript: String = System.getProperty("org.nixos.gradle2nix.initScript") + +fun connect(config: Config): ProjectConnection = + GradleConnector.newConnector() + .apply { + if (config.wrapper) { + useBuildDistribution() + } else if (config.gradleVersion != null) { + useGradleVersion(config.gradleVersion) + } + } + .forProjectDirectory(config.projectDir) + .connect() + +fun ProjectConnection.getBuildModel(config: Config, path: String): DefaultBuild { + val arguments = mutableListOf( + "--init-script=$initScript", + "-Dorg.nixos.gradle2nix.configurations='${config.configurations.joinToString(",")}'" + ) + + if (path.isNotEmpty()) { + arguments += "--project-dir=$path" } - fun runGradle() { - GradleConnector.newConnector() - .apply { - if (useWrapper) { - useBuildDistribution() - } else if (gradleVersion != null) { - useGradleVersion(gradleVersion) - } + return model(Build::class.java) + .withArguments(arguments) + .apply { + if (config.verbose) { + setStandardOutput(System.out) + setStandardError(System.err) } - .forProjectDirectory(projectDir) - .connect() - .use { connection -> - connection.newBuild() - .withArguments("--init-script", initScript) - .apply { - if (configurations.isNotEmpty()) { - withArguments( - "-Dorg.nixos.gradle2nix.configurations=${configurations.joinToString( - "," - )}" - ) - } - } - .forTasks("nixGradleEnv") - .setStandardOutput(System.out) - .setStandardError(System.err) - .run() - } - } -} \ No newline at end of file + } + .get() + .let { DefaultBuild(it) } +} diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt new file mode 100644 index 0000000..eca8b32 --- /dev/null +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt @@ -0,0 +1,19 @@ +package org.nixos.gradle2nix + +import java.io.PrintStream + +class Logger( + val out: PrintStream = System.err, + val verbose: Boolean) { + + val log: (String) -> Unit = { if (verbose) out.println(it) } + val warn: (String) -> Unit = { out.println("Warning: $it")} + val error: (String) -> Unit = { + out.println("Error: $it") + System.exit(1) + } + + operator fun component1() = log + operator fun component2() = warn + operator fun component3() = error +} diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt index 754ab73..ee4604e 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt @@ -1,25 +1,103 @@ package org.nixos.gradle2nix +import com.github.ajalt.clikt.completion.CompletionCandidates import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.ProcessedArgument import com.github.ajalt.clikt.parameters.arguments.argument -import com.github.ajalt.clikt.parameters.arguments.defaultLazy -import com.github.ajalt.clikt.parameters.options.flag -import com.github.ajalt.clikt.parameters.options.multiple -import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.arguments.convert +import com.github.ajalt.clikt.parameters.arguments.default +import com.github.ajalt.clikt.parameters.options.* import com.github.ajalt.clikt.parameters.types.file +import com.squareup.moshi.Moshi +import okio.buffer +import okio.sink import java.io.File +data class Config( + val wrapper: Boolean, + val gradleVersion: String?, + val configurations: List, + val projectDir: File, + val includes: List, + val buildSrc: Boolean, + val verbose: Boolean +) { + val allProjects = listOf(projectDir) + includes +} + class Main : CliktCommand() { - val wrapper: Boolean by option(help = "Use the project's gradle wrapper for building").flag() - val gradleVersion: String? by option(help = "Use a specific Gradle version") + val wrapper: Boolean by option("--gradle-wrapper", "-w", + help = "Use the project's gradle wrapper for building") + .flag() + + val gradleVersion: String? by option("--gradle-version", "-g", + help = "Use a specific Gradle version") + val configurations: List by option(help = "Project configuration(s)").multiple() + val projectDir: File by argument(help = "Path to the project root") + .projectDir() + .default(File(".")) + + val outputDir: File by option("--out", "-o", + help = "Path to write Nix environment files") + .file(fileOkay = false, folderOkay = true) + .default(File(".")) + + val includes: List by option("--include", "-i", + help = "Path to included build(s)", + metavar = "DIR") .file(exists = true, fileOkay = false, folderOkay = true, readable = true) - .defaultLazy { File(".") } + .multiple() + .validate { files -> + val failures = files.filterNot { it.isProjectRoot() } + if (failures.isNotEmpty()) { + val message = failures.joinToString("\n ") + fail("Included builds are not Gradle projects:\n$message\n" + + "Gradle projects must contain a settings.gradle or settings.gradle.kts script.") + } + } + + val buildSrc: Boolean by option("--enableBuildSrc", help = "Include buildSrc project") + .flag("--disableBuildSrc", default = true) + + val verbose: Boolean by option("--verbose", "-v", help = "Enable verbose logging") + .flag(default = false) override fun run() { - GradleRunner(projectDir, wrapper, gradleVersion, configurations).runGradle() + val config = Config(wrapper, gradleVersion, configurations, projectDir, includes, buildSrc, verbose) + val (log, warn, error) = Logger(verbose = config.verbose) + + val json by lazy { Moshi.Builder().build().adapter(DefaultBuild::class.java).indent(" ") } + val out by lazy { outputDir.also { it.mkdirs() }} + + val paths = resolveProjects(config).map { p -> + p.toRelativeString(config.projectDir) + } + + connect(config).use { connection -> + for (project in paths) { + log("Resolving project model: ${project.takeIf { it.isNotEmpty() } ?: "root project"}") + val build = connection.getBuildModel(config, project) + val filename = build.rootProject.name + ".json" + val file = out.resolve(filename) + file.sink().buffer().use { sink -> json.toJson(sink, build) } + log(" --> $file") + } + } } } -fun main(args: Array) = Main().main(args) \ No newline at end of file +fun ProcessedArgument.projectDir(): ProcessedArgument { + return convert(completionCandidates = CompletionCandidates.Path) { + File(it).also { file -> + if (!file.exists()) fail("Directory \"$file\" does not exist.") + if (file.isFile) fail("Directory \"$file\" is a file.") + if (!file.canRead()) fail("Directory \"$file\" is not readable.") + if (!file.isProjectRoot()) fail("Directory \"$file\" is not a Gradle project.") + } + } +} + +fun main(args: Array) = Main().main(args) + diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt new file mode 100644 index 0000000..f112991 --- /dev/null +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt @@ -0,0 +1,17 @@ +package org.nixos.gradle2nix + +import java.io.File + +fun resolveProjects(config: Config) = config.allProjects.run { + if (config.buildSrc) { + flatMap { listOfNotNull(it, it.findBuildSrc()) } + } else { + this + } +} + +fun File.findBuildSrc(): File? = + resolve("buildSrc").takeIf { it.isDirectory } + +fun File.isProjectRoot(): Boolean = + isDirectory && (resolve("settings.gradle").isFile || resolve("settings.gradle.kts").isFile) diff --git a/build.gradle.kts b/build.gradle.kts index 37fa972..525b8e2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -5,7 +5,36 @@ plugins { kotlin("jvm") version embeddedKotlinVersion apply false kotlin("kapt") version embeddedKotlinVersion apply false id("com.github.johnrengelman.shadow") version "5.0.0" apply false - id("org.ysb33r.gradletest") version "2.0-rc.4" apply false + id("org.ajoberstar.stutter") version "0.5.0" apply false +} + +allprojects { + plugins.withType { + this@allprojects.withConvention(JavaPluginConvention::class) { + sourceSets.all { + configurations { + named(compileClasspathConfigurationName) { + resolutionStrategy.activateDependencyLocking() + } + named(runtimeClasspathConfigurationName) { + resolutionStrategy.activateDependencyLocking() + } + } + } + + tasks.register("lock") { + doFirst { + assert(gradle.startParameter.isWriteDependencyLocks) + } + doLast { + sourceSets.all { + configurations[compileClasspathConfigurationName].resolve() + configurations[runtimeClasspathConfigurationName].resolve() + } + } + } + } + } } tasks { diff --git a/model/build.gradle.kts b/model/build.gradle.kts new file mode 100644 index 0000000..491b563 --- /dev/null +++ b/model/build.gradle.kts @@ -0,0 +1,15 @@ +plugins { + `embedded-kotlin` + kotlin("kapt") +} + +repositories { + mavenCentral() + maven { url = uri("https://repo.gradle.org/gradle/libs-releases") } +} + +dependencies { + compileOnly("com.squareup.moshi:moshi:1.8.0") + compileOnly("com.squareup.okio:okio:2.2.2") + kapt("com.squareup.moshi:moshi-kotlin-codegen:1.8.0") +} diff --git a/model/gradle/dependency-locks/compileClasspath.lockfile b/model/gradle/dependency-locks/compileClasspath.lockfile new file mode 100644 index 0000000..d3f445e --- /dev/null +++ b/model/gradle/dependency-locks/compileClasspath.lockfile @@ -0,0 +1,10 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.squareup.moshi:moshi:1.8.0 +com.squareup.okio:okio:2.2.2 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/model/gradle/dependency-locks/runtimeClasspath.lockfile b/model/gradle/dependency-locks/runtimeClasspath.lockfile new file mode 100644 index 0000000..656c5db --- /dev/null +++ b/model/gradle/dependency-locks/runtimeClasspath.lockfile @@ -0,0 +1,3 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. diff --git a/model/gradle/dependency-locks/testCompileClasspath.lockfile b/model/gradle/dependency-locks/testCompileClasspath.lockfile new file mode 100644 index 0000000..4010c05 --- /dev/null +++ b/model/gradle/dependency-locks/testCompileClasspath.lockfile @@ -0,0 +1,8 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/model/gradle/dependency-locks/testRuntimeClasspath.lockfile b/model/gradle/dependency-locks/testRuntimeClasspath.lockfile new file mode 100644 index 0000000..4010c05 --- /dev/null +++ b/model/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -0,0 +1,8 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/model/src/main/kotlin/org/nixos/gradle2nix/Impl.kt b/model/src/main/kotlin/org/nixos/gradle2nix/Impl.kt new file mode 100644 index 0000000..dc3dc65 --- /dev/null +++ b/model/src/main/kotlin/org/nixos/gradle2nix/Impl.kt @@ -0,0 +1,117 @@ +package org.nixos.gradle2nix + +import com.squareup.moshi.JsonClass +import java.io.Serializable + +@JsonClass(generateAdapter = true) +data class DefaultBuild( + override val gradle: DefaultGradle, + override val pluginDependencies: DefaultDependencies, + override val rootProject: DefaultProject, + override val includedBuilds: List +) : Build, Serializable { + constructor(model: Build) : this( + DefaultGradle(model.gradle), + DefaultDependencies(model.pluginDependencies), + DefaultProject(model.rootProject), + model.includedBuilds.map { DefaultIncludedBuild(it) } + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultIncludedBuild( + override val name: String, + override val projectDir: String +) : IncludedBuild, Serializable { + constructor(model: IncludedBuild) : this( + model.name, + model.projectDir + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultGradle( + override val version: String, + override val type: String, + override val url: String, + override val sha256: String, + override val nativeVersion: String +) : Gradle, Serializable { + constructor(model: Gradle) : this( + model.version, + model.type, + model.url, + model.sha256, + model.nativeVersion + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultProject( + override val name: String, + override val path: String, + override val projectDir: String, + override val buildscriptDependencies: DefaultDependencies, + override val projectDependencies: DefaultDependencies, + override val children: List +) : Project, Serializable { + constructor(model: Project) : this( + model.name, + model.path, + model.projectDir, + DefaultDependencies(model.buildscriptDependencies), + DefaultDependencies(model.projectDependencies), + model.children.map { DefaultProject(it) } + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultDependencies( + override val repositories: DefaultRepositories, + override val artifacts: List +) : Dependencies, Serializable { + constructor(model: Dependencies) : this( + DefaultRepositories(model.repositories), + model.artifacts.map { DefaultArtifact(it) } + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultRepositories( + override val maven: List +) : Repositories, Serializable { + constructor(model: Repositories) : this( + model.maven.map { DefaultMaven(it) } + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultMaven( + override val urls: List +) : Maven, Serializable { + constructor(model: Maven) : this( + model.urls.toList() + ) +} + +@JsonClass(generateAdapter = true) +data class DefaultArtifact( + override val groupId: String, + override val artifactId: String, + override val version: String, + override val classifier: String, + override val extension: String, + override val sha256: String +) : Artifact, Comparable, Serializable { + constructor(model: Artifact) : this( + model.groupId, + model.artifactId, + model.version, + model.classifier, + model.extension, + model.sha256 + ) + + override fun toString() = "$groupId:$artifactId:$version:$classifier:$extension" + override fun compareTo(other: DefaultArtifact): Int = toString().compareTo(other.toString()) +} diff --git a/model/src/main/kotlin/org/nixos/gradle2nix/Model.kt b/model/src/main/kotlin/org/nixos/gradle2nix/Model.kt new file mode 100644 index 0000000..f2998d5 --- /dev/null +++ b/model/src/main/kotlin/org/nixos/gradle2nix/Model.kt @@ -0,0 +1,52 @@ +package org.nixos.gradle2nix + +interface Build { + val gradle: Gradle + val pluginDependencies: Dependencies + val rootProject: Project + val includedBuilds: List +} + +interface IncludedBuild { + val name: String + val projectDir: String +} + +interface Gradle { + val version: String + val type: String + val url: String + val sha256: String + val nativeVersion: String +} + +interface Project { + val name: String + val path: String + val projectDir: String + val buildscriptDependencies: Dependencies + val projectDependencies: Dependencies + val children: List +} + +interface Dependencies { + val repositories: Repositories + val artifacts: List +} + +interface Repositories { + val maven: List +} + +interface Maven { + val urls: List +} + +interface Artifact { + val groupId: String + val artifactId: String + val version: String + val classifier: String + val extension: String + val sha256: String +} diff --git a/plugin/.stutter/java8.lock b/plugin/.stutter/java8.lock new file mode 100644 index 0000000..c66434a --- /dev/null +++ b/plugin/.stutter/java8.lock @@ -0,0 +1,12 @@ +# DO NOT MODIFY: Generated by Stutter plugin. +4.5.1 +4.6 +4.7 +4.8.1 +4.9 +4.10.3 +5.0 +5.1.1 +5.2.1 +5.3.1 +5.4.1 diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 9e2ac30..503cd6e 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -1,26 +1,43 @@ +buildscript { + configurations.classpath { + resolutionStrategy.activateDependencyLocking() + } +} + plugins { - `java-gradle-plugin` `kotlin-dsl` - `maven-publish` - kotlin("kapt") id("com.github.johnrengelman.shadow") - id("org.ysb33r.gradletest") + id("org.ajoberstar.stutter") +} +apply { + plugin("kotlin") } group = "org.nixos" version = "1.0.0-SNAPSHOT" repositories { - jcenter() + mavenCentral() + maven { url = uri("https://repo.gradle.org/gradle/libs-releases") } +} + +dependencyLocking { + lockAllConfigurations() } dependencies { - implementation(kotlin("stdlib-jdk8")) - implementation("org.apache.maven:maven-model:3.6.1") - implementation("org.apache.maven:maven-model-builder:3.6.1") - implementation("com.squareup.okio:okio:2.2.2") - implementation("com.squareup.moshi:moshi:1.8.0") - kapt("com.squareup.moshi:moshi-kotlin-codegen:1.8.0") + implementation(project(":model")) + compileOnly("org.gradle:gradle-tooling-api:${gradle.gradleVersion}") + implementation("org.apache.maven:maven-model:latest.release") + implementation("org.apache.maven:maven-model-builder:latest.release") + implementation("com.squareup.okio:okio:latest.release") + + compatTestImplementation(embeddedKotlin("stdlib-jdk8")) + compatTestImplementation(embeddedKotlin("test-junit5")) + compatTestImplementation("org.junit.jupiter:junit-jupiter-api:5.4+") + compatTestRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.4+") + compatTestImplementation(gradleTestKit()) + compatTestImplementation(project(":model")) } gradlePlugin { @@ -28,37 +45,46 @@ gradlePlugin { register("gradle2nix") { id = "org.nixos.gradle2nix" displayName = "gradle2nix" - description = "Create Nix configurations suitable for reproducible packaging" + description = "Expose Gradle tooling model for the gradle2nix tool" implementationClass = "org.nixos.gradle2nix.Gradle2NixPlugin" } } } -tasks { - gradleTest { - versions("5.0", "5.1.1", "5.2.1", "5.3.1", "5.4.1") - kotlinDsl = true +kotlinDslPluginOptions { + experimentalWarning.set(false) +} + +stutter { + java(8) { + compatibleRange("4.5") } - - gradleTestGenerator { - dependsOn(shadowJar) - doLast { - file(gradleTest.get().initScript).bufferedWriter().use { out -> - out.appendln(""" - initscript { - dependencies { - classpath fileTree('file:${buildDir.absolutePath}/libs'.toURI()) { - include '*.jar' - } - """.trimIndent()) - - out.appendln(""" - } - } - - apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin - """.trimIndent()) - } - } + java(11) { + compatibleRange("5.0") } } + +tasks { + withType { + useJUnitPlatform() + } + +// gradleTestGenerator { +// dependsOn(shadowJar) +// doLast { +// file(gradleTest.get().initScript).bufferedWriter().use { out -> +// out.append(""" +// initscript { +// dependencies { +// classpath fileTree('file:${buildDir.absolutePath}/libs'.toURI()) { +// include '*.jar' +// } +// } +// } +// +// apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin +// """.trimIndent()) +// } +// } +// } +} diff --git a/plugin/gradle/dependency-locks/buildscript-classpath.lockfile b/plugin/gradle/dependency-locks/buildscript-classpath.lockfile new file mode 100644 index 0000000..00e853a --- /dev/null +++ b/plugin/gradle/dependency-locks/buildscript-classpath.lockfile @@ -0,0 +1,25 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:1.2.6 +org.gradle.kotlin:plugins:1.2.6 +org.jetbrains.intellij.deps:trove4j:1.0.20181211 +org.jetbrains.kotlin:kotlin-android-extensions:1.3.21 +org.jetbrains.kotlin:kotlin-annotation-processing-gradle:1.3.21 +org.jetbrains.kotlin:kotlin-build-common:1.3.21 +org.jetbrains.kotlin:kotlin-compiler-embeddable:1.3.21 +org.jetbrains.kotlin:kotlin-compiler-runner:1.3.21 +org.jetbrains.kotlin:kotlin-daemon-client:1.3.21 +org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.3.21 +org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.3.21 +org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.21 +org.jetbrains.kotlin:kotlin-native-utils:1.3.21 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-sam-with-receiver:1.3.21 +org.jetbrains.kotlin:kotlin-script-runtime:1.3.21 +org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/plugin/gradle/dependency-locks/compatTestCompileClasspath.lockfile b/plugin/gradle/dependency-locks/compatTestCompileClasspath.lockfile new file mode 100644 index 0000000..af7e415 --- /dev/null +++ b/plugin/gradle/dependency-locks/compatTestCompileClasspath.lockfile @@ -0,0 +1,16 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +org.apiguardian:apiguardian-api:1.0.0 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains.kotlin:kotlin-test-annotations-common:1.3.21 +org.jetbrains.kotlin:kotlin-test-common:1.3.21 +org.jetbrains.kotlin:kotlin-test-junit5:1.3.21 +org.jetbrains.kotlin:kotlin-test:1.3.21 +org.jetbrains:annotations:13.0 +org.junit.jupiter:junit-jupiter-api:5.4.2 +org.junit.platform:junit-platform-commons:1.4.2 +org.opentest4j:opentest4j:1.1.1 diff --git a/plugin/gradle/dependency-locks/compatTestRuntimeClasspath.lockfile b/plugin/gradle/dependency-locks/compatTestRuntimeClasspath.lockfile new file mode 100644 index 0000000..521d7cf --- /dev/null +++ b/plugin/gradle/dependency-locks/compatTestRuntimeClasspath.lockfile @@ -0,0 +1,18 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +org.apiguardian:apiguardian-api:1.0.0 +org.jetbrains.kotlin:kotlin-stdlib-common:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains.kotlin:kotlin-test-annotations-common:1.3.21 +org.jetbrains.kotlin:kotlin-test-common:1.3.21 +org.jetbrains.kotlin:kotlin-test-junit5:1.3.21 +org.jetbrains.kotlin:kotlin-test:1.3.21 +org.jetbrains:annotations:13.0 +org.junit.jupiter:junit-jupiter-api:5.4.2 +org.junit.jupiter:junit-jupiter-engine:5.4.2 +org.junit.platform:junit-platform-commons:1.4.2 +org.junit.platform:junit-platform-engine:1.4.2 +org.opentest4j:opentest4j:1.1.1 diff --git a/plugin/gradle/dependency-locks/compileClasspath.lockfile b/plugin/gradle/dependency-locks/compileClasspath.lockfile new file mode 100644 index 0000000..4dba989 --- /dev/null +++ b/plugin/gradle/dependency-locks/compileClasspath.lockfile @@ -0,0 +1,18 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.squareup.okio:okio:2.2.2 +org.apache.commons:commons-lang3:3.8.1 +org.apache.maven:maven-artifact:3.6.1 +org.apache.maven:maven-builder-support:3.6.1 +org.apache.maven:maven-model-builder:3.6.1 +org.apache.maven:maven-model:3.6.1 +org.codehaus.plexus:plexus-component-annotations:1.7.1 +org.codehaus.plexus:plexus-interpolation:1.25 +org.codehaus.plexus:plexus-utils:3.2.0 +org.gradle:gradle-tooling-api:5.4.1 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/plugin/gradle/dependency-locks/runtimeClasspath.lockfile b/plugin/gradle/dependency-locks/runtimeClasspath.lockfile new file mode 100644 index 0000000..7351deb --- /dev/null +++ b/plugin/gradle/dependency-locks/runtimeClasspath.lockfile @@ -0,0 +1,15 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.squareup.okio:okio:2.2.2 +org.apache.commons:commons-lang3:3.8.1 +org.apache.maven:maven-artifact:3.6.1 +org.apache.maven:maven-builder-support:3.6.1 +org.apache.maven:maven-model-builder:3.6.1 +org.apache.maven:maven-model:3.6.1 +org.codehaus.plexus:plexus-component-annotations:1.7.1 +org.codehaus.plexus:plexus-interpolation:1.25 +org.codehaus.plexus:plexus-utils:3.2.0 +org.jetbrains.kotlin:kotlin-stdlib-common:1.2.60 +org.jetbrains.kotlin:kotlin-stdlib:1.2.60 +org.jetbrains:annotations:13.0 diff --git a/plugin/gradle/dependency-locks/testCompileClasspath.lockfile b/plugin/gradle/dependency-locks/testCompileClasspath.lockfile new file mode 100644 index 0000000..98e2984 --- /dev/null +++ b/plugin/gradle/dependency-locks/testCompileClasspath.lockfile @@ -0,0 +1,17 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.squareup.okio:okio:2.2.2 +org.apache.commons:commons-lang3:3.8.1 +org.apache.maven:maven-artifact:3.6.1 +org.apache.maven:maven-builder-support:3.6.1 +org.apache.maven:maven-model-builder:3.6.1 +org.apache.maven:maven-model:3.6.1 +org.codehaus.plexus:plexus-component-annotations:1.7.1 +org.codehaus.plexus:plexus-interpolation:1.25 +org.codehaus.plexus:plexus-utils:3.2.0 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/plugin/gradle/dependency-locks/testRuntimeClasspath.lockfile b/plugin/gradle/dependency-locks/testRuntimeClasspath.lockfile new file mode 100644 index 0000000..98e2984 --- /dev/null +++ b/plugin/gradle/dependency-locks/testRuntimeClasspath.lockfile @@ -0,0 +1,17 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.squareup.okio:okio:2.2.2 +org.apache.commons:commons-lang3:3.8.1 +org.apache.maven:maven-artifact:3.6.1 +org.apache.maven:maven-builder-support:3.6.1 +org.apache.maven:maven-model-builder:3.6.1 +org.apache.maven:maven-model:3.6.1 +org.codehaus.plexus:plexus-component-annotations:1.7.1 +org.codehaus.plexus:plexus-interpolation:1.25 +org.codehaus.plexus:plexus-utils:3.2.0 +org.jetbrains.kotlin:kotlin-reflect:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21 +org.jetbrains.kotlin:kotlin-stdlib:1.3.21 +org.jetbrains:annotations:13.0 diff --git a/plugin/src/compatTest/kotlin/org/nixos/gradle2nix/BasicTest.kt b/plugin/src/compatTest/kotlin/org/nixos/gradle2nix/BasicTest.kt new file mode 100644 index 0000000..6ba9945 --- /dev/null +++ b/plugin/src/compatTest/kotlin/org/nixos/gradle2nix/BasicTest.kt @@ -0,0 +1,78 @@ +package org.nixos.gradle2nix + +import org.gradle.internal.classpath.DefaultClassPath +import org.gradle.testkit.runner.internal.PluginUnderTestMetadataReading +import org.gradle.tooling.GradleConnector +import org.gradle.tooling.internal.consumer.DefaultModelBuilder +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.io.TempDir +import java.io.File +import kotlin.test.assertEquals + + +class BasicTest { + companion object { + @JvmStatic @TempDir lateinit var projectDir: File + + val initScript: File by lazy { + projectDir.resolve("init.gradle").also { + it.writer().use { out -> +// val classpath = DefaultClassPath.of(PluginUnderTestMetadataReading.readImplementationClasspath()) +// .asFiles.joinToString(prefix = "'", postfix = "'") +// out.appendln(""" +// initscript { +// dependencies { +// classpath files($classpath) +// } +// } +// +// apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin +// """.trimIndent()) + out.appendln("apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin") + } + } + } + } + + @Test + fun `builds basic project with kotlin dsl`() { + projectDir.resolve("build.gradle.kts").writeText(""" + plugins { + java + } + + repositories { + jcenter() + } + + dependencies { + implementation("com.squareup.okio:okio:2.2.2") + implementation("com.squareup.moshi:moshi:1.8.0") + } + """.trimIndent()) + + val connection = GradleConnector.newConnector() + .useGradleVersion(System.getProperty("compat.gradle.version")) + .forProjectDirectory(projectDir) + .connect() + + val model = (connection.model(Build::class.java) as DefaultModelBuilder) + .withArguments( + "--init-script=$initScript", + "--stacktrace" + ) + .withInjectedClassPath(DefaultClassPath.of(PluginUnderTestMetadataReading.readImplementationClasspath())) + .setStandardOutput(System.out) + .setStandardError(System.out) + .get() + + assertEquals(model.gradle.version, System.getProperty("compat.gradle.version")) + + with(model.rootProject.projectDependencies) { + with(repositories) { + assertEquals(1, maven.size) + assertEquals(maven[0].urls[0], "https://jcenter.bintray.com/") + } + } + } +} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/Resolver.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/DependencyResolver.kt similarity index 90% rename from plugin/src/main/kotlin/org/nixos/gradle2nix/Resolver.kt rename to plugin/src/main/kotlin/org/nixos/gradle2nix/DependencyResolver.kt index bd58295..37498c0 100644 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/Resolver.kt +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/DependencyResolver.kt @@ -15,27 +15,28 @@ import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.result.ResolvedArtifactResult import org.gradle.api.logging.Logger +import org.gradle.api.logging.Logging import org.gradle.maven.MavenModule import org.gradle.maven.MavenPomArtifact import java.io.File import java.io.InputStream import java.net.URI -internal class Resolver( +internal class DependencyResolver( private val configurations: ConfigurationContainer, private val dependencies: DependencyHandler, - private val logger: Logger + private val logger: Logger = Logging.getLogger(DependencyResolver::class.simpleName) ) { private val mavenPomResolver = MavenPomResolver(configurations, dependencies) - fun resolveDependencies(configuration: Configuration): Set { + fun resolveDependencies(configuration: Configuration): Set { if (!configuration.isCanBeResolved) { logger.warn("Cannot resolve configuration ${configuration.name}; ignoring.") return emptySet() } return configuration.resolvedConfiguration.resolvedArtifacts.mapTo(sortedSetOf()) { with (it) { - Artifact( + DefaultArtifact( groupId = moduleVersion.id.group, artifactId = moduleVersion.id.name, version = moduleVersion.id.version, @@ -50,13 +51,13 @@ internal class Resolver( fun resolveDependencies( dependencies: Collection, includeTransitive: Boolean = false - ): Set { + ): Set { val configuration = configurations.detachedConfiguration(*(dependencies.toTypedArray())) configuration.isTransitive = includeTransitive return resolveDependencies(configuration) } - fun resolvePoms(configuration: Configuration): Set { + fun resolvePoms(configuration: Configuration): Set { return dependencies.createArtifactResolutionQuery() .forComponents(configuration.incoming.resolutionResult.allComponents.map { it.id }) .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java) @@ -73,7 +74,7 @@ internal class Resolver( } } .flatMapTo(sortedSetOf()) { (id, artifact) -> - sequenceOf(Artifact( + sequenceOf(DefaultArtifact( groupId = id.group, artifactId = id.module, version = id.version, @@ -87,7 +88,7 @@ internal class Resolver( fun resolvePoms( dependencies: Collection, includeTransitive: Boolean = false - ): Set { + ): Set { val configuration = configurations.detachedConfiguration(*(dependencies.toTypedArray())) configuration.isTransitive = includeTransitive return resolvePoms(configuration) @@ -99,10 +100,10 @@ private class MavenPomResolver( private val dependencies: DependencyHandler ) : ModelResolver { private val modelBuilder = DefaultModelBuilderFactory().newInstance() - private val resolvedDependencies = mutableSetOf() + private val resolvedDependencies = mutableSetOf() @Synchronized - fun resolve(pom: File): Set { + fun resolve(pom: File): Set { resolvedDependencies.clear() modelBuilder.build( DefaultModelBuildingRequest() @@ -124,7 +125,7 @@ private class MavenPomResolver( val file = configurations .detachedConfiguration(dependencies.create("$groupId:$artifactId:$version@pom")) .singleFile - resolvedDependencies.add(Artifact( + resolvedDependencies.add(DefaultArtifact( groupId = groupId, artifactId = artifactId, version = version, diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt index 134c180..ad90491 100644 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt @@ -1,21 +1,25 @@ package org.nixos.gradle2nix -import com.squareup.moshi.Moshi import okio.buffer import okio.source import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.api.artifacts.repositories.MavenArtifactRepository import org.gradle.api.invocation.Gradle -import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.wrapper.Wrapper -import org.gradle.kotlin.dsl.create import org.gradle.kotlin.dsl.named -import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.newInstance +import org.gradle.kotlin.dsl.support.serviceOf import org.gradle.plugin.management.PluginRequest -import java.io.File +import org.gradle.tooling.provider.model.ToolingModelBuilder +import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry import java.net.URL import java.util.* +import org.nixos.gradle2nix.Gradle as NixGradle +import org.nixos.gradle2nix.Project as NixProject +@Suppress("unused") open class Gradle2NixPlugin : Plugin { override fun apply(gradle: Gradle) { val configurationNames: List = @@ -24,52 +28,8 @@ open class Gradle2NixPlugin : Plugin { val pluginRequests = collectPlugins(gradle) gradle.projectsLoaded { - val extension = rootProject.extensions.create( - "gradle2nix", - rootProject, - configurationNames - ) - - val gradleEnv = rootProject.tasks.register("nixGradleEnv", NixGradleEnv::class) { - outputDir.set(extension.outputDir) - } - - val buildSrcDir = rootProject.projectDir.resolve("buildSrc") - if (buildSrcDir.exists() && buildSrcDir.isDirectory) { - val buildSrcEnv = - rootProject.tasks.register("nixBuildSrcEnv", NixBuildSrcEnv::class) { - dir = buildSrcDir - val buildFile = buildSrcDir.listFiles().let { files -> - files.find { it.name == "build.gradle.kts" } ?: - files.find { it.name == "build.gradle" } - } - if (buildFile != null) this.buildFile = buildFile - } - gradleEnv.configure { - dependsOn(buildSrcEnv) - } - } - - val pluginEnv = - rootProject.tasks.register("nixPluginEnv", NixPluginEnv::class, pluginRequests) - gradleEnv.configure { - inputEnvs.from(pluginEnv) - } - - allprojects { - val buildscriptEnv = tasks.register("nixBuildscriptEnv", NixBuildscriptEnv::class) { - pluginEnvFile.set(pluginEnv.flatMap { it.outputFile }) - } - val projectEnv = tasks.register("nixProjectEnv", NixProjectEnv::class) { - configurations.addAll(extension.configurations) - } - gradleEnv.configure { - inputEnvs.from(buildscriptEnv) - inputEnvs.from(projectEnv) - } - } - - resolveGradleDist(gradle, extension, gradleEnv) + rootProject.serviceOf() + .register(NixToolingModelBuilder(configurationNames, pluginRequests)) } } @@ -84,54 +44,98 @@ open class Gradle2NixPlugin : Plugin { } return pluginRequests } +} - private fun resolveGradleDist( - gradle: Gradle, - extension: Gradle2NixExtension, - gradleEnv: TaskProvider - ) { - gradle.projectsEvaluated { - val gradleDist = rootProject.tasks.named("wrapper", Wrapper::class).map { - GradleDist( - version = it.gradleVersion, - type = it.distributionType.name.toLowerCase(Locale.US), - url = it.distributionUrl, - sha256 = it.distributionSha256Sum ?: fetchDistSha256(it.distributionUrl), - nativeVersion = gradle.gradleHomeDir?.resolve("lib")?.listFiles() - ?.firstOrNull { f -> f.name.matches(nativePlatformJarRegex) }?.let { nf -> - nativePlatformJarRegex.find(nf.name)?.groupValues?.get(1) - } - ?: throw IllegalStateException(""" +private class NixToolingModelBuilder( + private val explicitConfigurations: List, + private val pluginRequests: List +) : ToolingModelBuilder { + override fun canBuild(modelName: String): Boolean { + return modelName == "org.nixos.gradle2nix.Build" + } + + override fun buildAll(modelName: String, project: Project): Build = project.run { + val plugins = buildPlugins(pluginRequests) + DefaultBuild( + gradle = buildGradle(), + pluginDependencies = plugins, + rootProject = buildProject(explicitConfigurations, plugins), + includedBuilds = includedBuilds() + ) + } +} + +private fun Project.buildGradle(): DefaultGradle = + with(tasks.named("wrapper").get()) { + DefaultGradle( + version = gradleVersion, + type = distributionType.name.toLowerCase(Locale.US), + url = distributionUrl, + sha256 = distributionSha256Sum ?: fetchDistSha256(distributionUrl), + nativeVersion = gradle.gradleHomeDir?.resolve("lib")?.listFiles() + ?.firstOrNull { f -> nativePlatformJarRegex matches f.name }?.let { nf -> + nativePlatformJarRegex.find(nf.name)?.groupValues?.get(1) + } + ?: throw IllegalStateException( + """ Failed to find native-platform jar in ${gradle.gradleHomeDir}. Ask Tad to fix this. - """.trimIndent()) + """.trimIndent() ) - } - val gradleDistTask = - gradle.rootProject.tasks.register("nixGradleDist", NixGradleDist::class) { - this.gradleDist.set(gradleDist) - outputDir.set(extension.outputDir) - } - gradleEnv.configure { - dependsOn(gradleDistTask) - } + ) + } + +private fun Project.buildPlugins(pluginRequests: List): DefaultDependencies = + with(objects.newInstance(pluginRequests)) { + DefaultDependencies(repositories.repositories(), artifacts()) + } + +private fun Project.includedBuilds(): List = + gradle.includedBuilds.map { + DefaultIncludedBuild(it.name, it.projectDir.toRelativeString(project.projectDir)) + } + +private fun Project.buildProject( + explicitConfigurations: List, + plugins: DefaultDependencies +): DefaultProject = + DefaultProject( + name = name, + path = path, + projectDir = projectDir.toRelativeString(rootProject.projectDir), + buildscriptDependencies = buildscriptDependencies(plugins), + projectDependencies = projectDependencies(explicitConfigurations), + children = childProjects.values.map { it.buildProject(explicitConfigurations, plugins) } + ) + +private fun Project.buildscriptDependencies(plugins: DefaultDependencies): DefaultDependencies = + with(DependencyResolver(buildscript.configurations, buildscript.dependencies)) { + DefaultDependencies( + repositories = buildscript.repositories.repositories(), + artifacts = buildscript.configurations + .filter { it.isCanBeResolved } + .flatMap { resolveDependencies(it) + resolvePoms(it) } + .minus(plugins.artifacts) + .distinct() + ) + } + +private fun Project.projectDependencies(explicitConfigurations: List): DefaultDependencies = + with(DependencyResolver(configurations, dependencies)) { + val toResolve = if (explicitConfigurations.isEmpty()) { + configurations.filter { it.isCanBeResolved } + } else { + configurations.filter { it.name in explicitConfigurations } } + + DefaultDependencies( + repositories = repositories.repositories(), + artifacts = toResolve.flatMap { resolveDependencies(it) + resolvePoms(it) } + .sorted() + .distinct() + ) } -} - -internal val pluginJar by lazy { - File(Gradle2NixPlugin::class.java.protectionDomain.codeSource.location.toURI()).absoluteFile -} - -internal val moshi by lazy { Moshi.Builder().build() } - -open class Gradle2NixExtension(project: Project, defaultConfigurations: List) { - var outputDir: File = project.projectDir.resolve("gradle/nix") - var configurations: MutableList = mutableListOf().apply { - addAll(defaultConfigurations) - } -} private fun fetchDistSha256(url: String): String { return URL("$url.sha256").openConnection().run { @@ -142,5 +146,12 @@ private fun fetchDistSha256(url: String): String { } } -private val nativePlatformJarRegex = Regex("""native-platform-(\d\.\d+)\.jar""") +private val nativePlatformJarRegex = Regex("""native-platform-([\d.]+)\.jar""") +internal fun RepositoryHandler.repositories() = DefaultRepositories( + maven = filterIsInstance() + .filterNot { it.name == "Embedded Kotlin Repository" } + .map { repo -> + DefaultMaven(listOf(repo.url.toString()) + repo.artifactUrls.map { it.toString() }) + } +) diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/GradleCompat.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/GradleCompat.kt deleted file mode 100644 index f9556a9..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/GradleCompat.kt +++ /dev/null @@ -1,109 +0,0 @@ -package org.nixos.gradle2nix - -import org.gradle.api.Project -import org.gradle.api.file.Directory -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFile -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider -import org.gradle.util.GradleVersion - -private fun versionAtLeast(version: String): Boolean = - GradleVersion.current() >= GradleVersion.version(version) - -internal fun Property.conventionCompat(value: T): Property { - return if (versionAtLeast("5.1")) { - convention(value) - } else { - apply { set(value) } - } -} - -internal fun Property.conventionCompat(valueProvider: Provider): Property { - return if (versionAtLeast("5.1")) { - convention(valueProvider) - } else { - apply { set(valueProvider) } - } -} - -internal fun DirectoryProperty.conventionCompat( - value: Directory -): DirectoryProperty { - return if (versionAtLeast("5.1")) { - convention(value) - } else { - apply { set(value) } - } -} - -internal fun DirectoryProperty.conventionCompat( - valueProvider: Provider -): DirectoryProperty { - return if (versionAtLeast("5.1")) { - convention(valueProvider) - } else { - apply { set(valueProvider) } - } -} - -internal fun ListProperty.conventionCompat( - elements: Iterable -): ListProperty { - return if (versionAtLeast("5.1")) { - convention(elements) - } else { - apply { set(elements) } - } -} - -internal fun ListProperty.conventionCompat( - provider: Provider> -): ListProperty { - return if (versionAtLeast("5.1")) { - convention(provider) - } else { - apply { set(provider) } - } -} - - -internal fun RegularFileProperty.conventionCompat( - value: RegularFile -): RegularFileProperty { - return if (versionAtLeast("5.1")) { - convention(value) - } else { - apply { set(value) } - } -} - -internal fun RegularFileProperty.conventionCompat( - valueProvider: Provider -): RegularFileProperty { - return if (versionAtLeast("5.1")) { - convention(valueProvider) - } else { - apply { set(valueProvider) } - } -} - -@Suppress("DEPRECATION") -internal fun Project.directoryPropertyCompat(): DirectoryProperty { - return if (versionAtLeast("5.0")) { - objects.directoryProperty() - } else { - layout.directoryProperty() - } -} - -@Suppress("DEPRECATION") -internal fun Project.filePropertyCompat(): RegularFileProperty { - return if (versionAtLeast("5.0")) { - objects.fileProperty() - } else { - layout.fileProperty() - } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildSrcEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildSrcEnv.kt deleted file mode 100644 index daa06ed..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildSrcEnv.kt +++ /dev/null @@ -1,28 +0,0 @@ -package org.nixos.gradle2nix - -import org.gradle.api.tasks.GradleBuild -import org.gradle.kotlin.dsl.configure -import java.io.File - -open class NixBuildSrcEnv : GradleBuild() { - init { - configure { - tasks = listOf("nixGradleEnv") - startParameter.addInitScript(writeInitScriptTo(dir.resolve("build/nix/init.gradle"))) - } - } -} - -private fun writeInitScriptTo(dest: File): File { - dest.parentFile.mkdirs() - dest.writeText(""" - initscript { - dependencies { - classpath files("$pluginJar") - } - } - - apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin - """.trimIndent()) - return dest -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt deleted file mode 100644 index f225a08..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.nixos.gradle2nix - -import okio.buffer -import okio.source -import org.gradle.api.tasks.InputFile -import java.net.URI - -open class NixBuildscriptEnv : NixEnv() { - @InputFile - val pluginEnvFile = project.filePropertyCompat() - - private val pluginEnv: BuildEnv by lazy { - pluginEnvFile.get().asFile.source().buffer().use { src -> - moshi.adapter(BuildEnv::class.java).fromJson(src) - ?: throw IllegalStateException( - "Cannot load plugin env from ${pluginEnvFile.get().asFile.path}") - } - } - - private val resolver by lazy { - Resolver(project.buildscript.configurations, - project.buildscript.dependencies, - logger - ) - } - - override fun environment(): String = "buildscript" - - override fun repositories(): List = - project.buildscript.repositories.flatMap { it.repositoryUrls() }.map(URI::toString) - - override fun artifacts(): List { - return project.buildscript.configurations - .filter { it.isCanBeResolved } - .flatMap { resolver.resolveDependencies(it) + resolver.resolvePoms(it) } - .minus(pluginEnv.artifacts) - .sorted() - .distinct() - } - - override fun filename(): String = "buildscript.json" -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt deleted file mode 100644 index bb4c187..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt +++ /dev/null @@ -1,73 +0,0 @@ -@file:Suppress("UnstableApiUsage") - -package org.nixos.gradle2nix - -import com.squareup.moshi.JsonClass -import okio.buffer -import okio.sink -import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.repositories.ArtifactRepository -import org.gradle.api.artifacts.repositories.MavenArtifactRepository -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction -import java.net.URI - -abstract class NixEnv: DefaultTask() { - abstract fun environment(): String - abstract fun repositories(): List - abstract fun artifacts(): List - abstract fun filename(): String - - @Internal - val outputDir = project.directoryPropertyCompat() - .conventionCompat(project.layout.buildDirectory.dir("nix")) - - @OutputFile - val outputFile = project.filePropertyCompat() - .conventionCompat(outputDir.map { it.file(filename()) }) - - @TaskAction - open fun run() { - val outFile = outputFile.get().asFile - outFile.parentFile.mkdirs() - - val buildEnv = BuildEnv(project.path, environment(), repositories(), artifacts()) - outFile.sink().buffer().use { out -> - moshi.adapter(BuildEnv::class.java) - .indent(" ") - .toJson(out, buildEnv) - } - } -} - -@JsonClass(generateAdapter = true) -data class BuildEnv( - val path: String, - val env: String, - val repositories: List, - val artifacts: List -) - -@JsonClass(generateAdapter = true) -data class Artifact( - val groupId: String, - val artifactId: String, - val version: String, - val classifier: String, - val extension: String, - val sha256: String -) : Comparable { - override fun toString() = "$groupId:$artifactId:$version:$classifier:$extension" - - override fun compareTo(other: Artifact): Int { - return toString().compareTo(other.toString()) - } -} - -internal fun ArtifactRepository.repositoryUrls(): Set { - return when (this) { - is MavenArtifactRepository -> setOf(url) + artifactUrls - else -> emptySet() - }.filterNotTo(mutableSetOf()) { it.scheme == "file" } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt deleted file mode 100644 index b8c3c2b..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.nixos.gradle2nix - -import com.squareup.moshi.JsonClass -import okio.buffer -import okio.sink -import org.gradle.api.DefaultTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.property -import java.io.Serializable - -open class NixGradleDist : DefaultTask() { - @Input - internal val gradleDist = project.objects.property() - - @OutputDirectory - val outputDir = project.directoryPropertyCompat() - - @OutputFile - val outputFile = project.filePropertyCompat() - .conventionCompat(outputDir.file("gradle-dist.json")) - - @TaskAction - fun run() { - if (gradleDist.isPresent) { - outputFile.asFile.get().also { it.parentFile.mkdirs() }.sink().buffer().use { out -> - moshi.adapter(GradleDist::class.java) - .indent(" ") - .toJson(out, gradleDist.get()) - } - } - } -} - -@JsonClass(generateAdapter = true) -internal data class GradleDist( - val version: String, - val type: String, - val url: String, - val sha256: String, - val nativeVersion: String -) : Serializable diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt deleted file mode 100644 index 3e274ed..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt +++ /dev/null @@ -1,58 +0,0 @@ -package org.nixos.gradle2nix - -import com.squareup.moshi.JsonWriter -import okio.buffer -import okio.sink -import okio.source -import org.gradle.api.DefaultTask -import org.gradle.api.model.ObjectFactory -import org.gradle.api.tasks.InputFiles -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction -import javax.inject.Inject - -open class NixGradleEnv @Inject constructor( - objects: ObjectFactory -) : DefaultTask() { - - @InputFiles - val inputEnvs = project.files() - - @Internal - val outputDir = objects.directoryProperty() - - @OutputFile - val outputFile = objects.fileProperty() - .conventionCompat(outputDir.file("gradle-env.json")) - - @TaskAction - fun run() { - val envsByPath = inputEnvs.map { file -> - file.source().buffer().use { - moshi.adapter(BuildEnv::class.java).fromJson(it) - ?: throw IllegalStateException( - "Failed to load build env from ${file.path}." - ) - } - }.groupBy(BuildEnv::path) - - val outFile = outputFile.get().asFile.also { it.parentFile.mkdirs() } - - JsonWriter.of(outFile.sink().buffer()).use { writer -> - val adapter = moshi.adapter(BuildEnv::class.java).indent(" ") - writer.indent = " " - writer.beginObject() - for ((path, envs) in envsByPath) { - writer.name(path) - writer.beginObject() - for (env in envs) { - writer.name(env.env) - adapter.toJson(writer, env) - } - writer.endObject() - } - writer.endObject() - } - } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt deleted file mode 100644 index 93d1910..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.nixos.gradle2nix - -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Optional -import org.gradle.kotlin.dsl.listProperty -import java.net.URI - -open class NixProjectEnv : NixEnv() { - @Input @Optional - val configurations = project.objects.listProperty().conventionCompat(emptyList()) - - private val resolveConfigurations by lazy { - val configs = configurations.get() - if (configs.isEmpty()) { - project.configurations.filter { it.isCanBeResolved } - } else { - project.configurations.filter { it.name in configs } - } - } - - private val resolver by lazy { - Resolver(project.configurations, - project.dependencies, - logger - ) - } - - override fun environment(): String = "project" - - override fun repositories(): List = - project.repositories.flatMap { it.repositoryUrls() }.map(URI::toString) - - override fun artifacts(): List { - return resolveConfigurations - .flatMap { resolver.resolveDependencies(it) + resolver.resolvePoms(it) } - .sorted() - .distinct() - } - - override fun filename(): String = "project.json" -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixPluginEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/PluginResolver.kt similarity index 54% rename from plugin/src/main/kotlin/org/nixos/gradle2nix/NixPluginEnv.kt rename to plugin/src/main/kotlin/org/nixos/gradle2nix/PluginResolver.kt index 0cbb2dd..d84804f 100644 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixPluginEnv.kt +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/PluginResolver.kt @@ -11,15 +11,14 @@ import org.gradle.plugin.use.resolve.internal.ArtifactRepositoriesPluginResolver import org.gradle.plugin.use.resolve.internal.PluginResolution import org.gradle.plugin.use.resolve.internal.PluginResolutionResult import org.gradle.plugin.use.resolve.internal.PluginResolveContext -import java.net.URI import javax.inject.Inject -open class NixPluginEnv @Inject constructor( +open class PluginResolver @Inject constructor( private val pluginDependencyResolutionServices: PluginDependencyResolutionServices, versionSelectorScheme: VersionSelectorScheme, private val pluginRequests: Collection -) : NixEnv() { - private val repositories by lazy { +) { + val repositories by lazy { pluginDependencyResolutionServices.resolveRepositoryHandler } @@ -29,10 +28,9 @@ open class NixPluginEnv @Inject constructor( ) private val resolver by lazy { - Resolver( + DependencyResolver( pluginDependencyResolutionServices.configurationContainer, - pluginDependencyResolutionServices.dependencyHandler, - logger + pluginDependencyResolutionServices.dependencyHandler ) } @@ -50,61 +48,53 @@ open class NixPluginEnv @Inject constructor( } } - override fun environment(): String = "plugins" - - override fun repositories(): List { - return repositories.flatMap { it.repositoryUrls() }.map(URI::toString) + - pluginContext.repositories.toList() - } - - override fun artifacts(): List { + fun artifacts(): List { return (resolver.resolveDependencies(pluginContext.dependencies, true) + resolver.resolvePoms(pluginContext.dependencies, true)) .sorted() .distinct() } - override fun filename(): String = "plugins.json" -} + private class PluginResult : PluginResolutionResult { + val found = mutableSetOf() -private class PluginResult : PluginResolutionResult { - val found = mutableSetOf() + override fun notFound(sourceDescription: String?, notFoundMessage: String?) {} - override fun notFound(sourceDescription: String?, notFoundMessage: String?) {} + override fun notFound( + sourceDescription: String?, + notFoundMessage: String?, + notFoundDetail: String? + ) { + } - override fun notFound( - sourceDescription: String?, - notFoundMessage: String?, - notFoundDetail: String? - ) { + override fun isFound(): Boolean = true + + override fun found(sourceDescription: String, pluginResolution: PluginResolution) { + found.add(pluginResolution) + } } - override fun isFound(): Boolean = true + private class PluginContext : PluginResolveContext { + val dependencies = mutableSetOf() + val repositories = mutableSetOf() - override fun found(sourceDescription: String, pluginResolution: PluginResolution) { - found.add(pluginResolution) - } -} + override fun add(plugin: PluginImplementation<*>) { + println("add: $plugin") + } -private class PluginContext : PluginResolveContext { - val dependencies = mutableSetOf() - val repositories = mutableSetOf() + override fun addFromDifferentLoader(plugin: PluginImplementation<*>) { + println("addFromDifferentLoader: $plugin") + } - override fun add(plugin: PluginImplementation<*>) { - println("add: $plugin") - } + override fun addLegacy(pluginId: PluginId, m2RepoUrl: String, dependencyNotation: Any) { + repositories.add(m2RepoUrl) + } - override fun addFromDifferentLoader(plugin: PluginImplementation<*>) { - println("addFromDifferentLoader: $plugin") - } - - override fun addLegacy(pluginId: PluginId, m2RepoUrl: String, dependencyNotation: Any) { - repositories.add(m2RepoUrl) - } - - override fun addLegacy(pluginId: PluginId, dependencyNotation: Any) { - if (dependencyNotation is ExternalModuleDependency) { - dependencies.add(dependencyNotation) + override fun addLegacy(pluginId: PluginId, dependencyNotation: Any) { + if (dependencyNotation is ExternalModuleDependency) { + dependencies.add(dependencyNotation) + } } } } + diff --git a/plugin/src/main/resources/org/nixos/gradle2nix/gradle-env.nix b/plugin/src/main/resources/org/nixos/gradle2nix/gradle-env.nix index 2904921..35fb953 100644 --- a/plugin/src/main/resources/org/nixos/gradle2nix/gradle-env.nix +++ b/plugin/src/main/resources/org/nixos/gradle2nix/gradle-env.nix @@ -14,6 +14,9 @@ let mkFilename = artifact: with artifact; "${artifactId}-${version}${lib.optionalString (classifier != "") "-${classifier}"}.${extension}"; + mkMavenUrls = repo: artifact: + + mkArtifactUrl = base: artifact: "${lib.removeSuffix "/" base}/${mkPath artifact}/${mkFilename artifact}"; diff --git a/settings.gradle.kts b/settings.gradle.kts index 2d198e9..c7d93a0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,2 +1 @@ -include(":app") -include(":plugin") +include(":app", ":model", ":plugin")