commit 932f690610ef76b3880b31a84ec632e5e88b629f Author: Tad Fisher Date: Sun Mar 31 20:18:55 2019 -0700 First stab diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..80d269a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea/ +.gradle/ +*.iml +**/build/ +result \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..ce74a90 --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,45 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") version "1.3.21" + application +} + +group = "org.nixos" +version = "1.0.0-SNAPSHOT" + +application { + mainClassName = "org.nixos.gradle2nix.MainKt" + applicationName = "gradle2nix" + applicationDefaultJvmArgs += "-Dorg.nixos.gradle2nix.initScript=@APP_HOME@/gradle/init.gradle" + applicationDistribution + .from(tasks.getByPath(":plugin:shadowJar")) + .into("gradle") + .rename("plugin.*\\.jar", "plugin.jar") +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) + implementation("org.gradle:gradle-tooling-api:${gradle.gradleVersion}") + implementation("com.github.ajalt:clikt:1.7.0") +} + +repositories { + jcenter() + maven { url = uri("https://repo.gradle.org/gradle/libs-releases") } +} + +tasks { + val startScripts by existing(CreateStartScripts::class) + startScripts { + doLast { + unixScript.writeText(unixScript.readText().replace("@APP_HOME@", "\$APP_HOME")) + windowsScript.writeText(windowsScript.readText().replace("@APP_HOME@", "%APP_HOME%")) + } + } + withType { + kotlinOptions { + jvmTarget = "1.8" + } + } +} diff --git a/app/src/dist/gradle/init.gradle b/app/src/dist/gradle/init.gradle new file mode 100644 index 0000000..f0c230f --- /dev/null +++ b/app/src/dist/gradle/init.gradle @@ -0,0 +1,7 @@ +initscript { + dependencies { + classpath files("plugin.jar") + } +} + +apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt b/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt new file mode 100644 index 0000000..57ecc51 --- /dev/null +++ b/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt @@ -0,0 +1,45 @@ +package org.nixos.gradle2nix + +import org.gradle.tooling.GradleConnector +import java.io.File + +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") + } + + fun runGradle() { + GradleConnector.newConnector() + .apply { + if (useWrapper) { + useBuildDistribution() + } else if (gradleVersion != null) { + useGradleVersion(gradleVersion) + } + } + .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 diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt new file mode 100644 index 0000000..754ab73 --- /dev/null +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt @@ -0,0 +1,25 @@ +package org.nixos.gradle2nix + +import com.github.ajalt.clikt.core.CliktCommand +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.types.file +import java.io.File + +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 configurations: List by option(help = "Project configuration(s)").multiple() + val projectDir: File by argument(help = "Path to the project root") + .file(exists = true, fileOkay = false, folderOkay = true, readable = true) + .defaultLazy { File(".") } + + override fun run() { + GradleRunner(projectDir, wrapper, gradleVersion, configurations).runGradle() + } +} + +fun main(args: Array) = Main().main(args) \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..c0532f4 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + base +} + +tasks { + wrapper { + gradleVersion = "5.3" + distributionType = Wrapper.DistributionType.ALL + } +} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..a4885b0 --- /dev/null +++ b/default.nix @@ -0,0 +1,71 @@ +{ pkgs ? import {} }: + +with pkgs; + +let + gradleEnvJson = builtins.fromJSON (builtins.readFile ./gradle/nix/gradle-env.json); + gradleDist = builtins.fromJSON (builtins.readFile ./gradle/nix/gradle-dist.json); + + mkGradleEnv = callPackage ./gradle-env.nix {}; + gradle = pkgs.gradleGen.gradleGen { + name = "gradle-dist-${gradleDist.version}-${gradleDist.type}"; + src = pkgs.fetchurl { + inherit (gradleDist) url sha256; + }; + inherit (gradleDist) nativeVersion; + }; + + maven = r: ''maven { url = uri("${r}") }''; + + projects = lib.mapAttrsToList (path: envs: { + inherit path; + config = '' + buildscript { + repositories { + clear() + ${maven (mkGradleEnv envs.buildscript)} + } + } + repositories { + clear() + ${maven (mkGradleEnv envs.project)} + } + ''; + }) gradleEnvJson; + + initScript = pkgs.writeText "init.gradle" '' + gradle.settingsEvaluated { + it.pluginManagement.repositories { + clear() + ${maven (mkGradleEnv gradleEnvJson.":".plugins)} + } + } + gradle.projectsLoaded { + ${lib.concatMapStringsSep "\n" (p: '' + rootProject.project("${p.path}") { + ${p.config} + } + '') projects} + } + ''; + +in stdenv.mkDerivation rec { + name = "gradle2nix-${version}"; + version = "1.0"; + + src = ./.; + + nativeBuildInputs = [ gradle ]; + + buildPhase = '' + export GRADLE_USER_HOME=$(mktemp -d) + gradle --offline --no-daemon --info --full-stacktrace --init-script ${initScript} installDist + ''; + + installPhase = '' + mkdir -p $out + cp -r app/build/install/gradle2nix/* $out/ + ''; + + dontStrip = true; +} diff --git a/gradle-env.nix b/gradle-env.nix new file mode 100644 index 0000000..771d2cf --- /dev/null +++ b/gradle-env.nix @@ -0,0 +1,51 @@ +# This file is generated by gradle2nix. + +{ stdenvNoCC, lib, buildEnv, fetchurl }: + +{ path, env, repositories, artifacts }@args: + +let + mkPath = artifact: with artifact; lib.concatStringsSep "/" [ + (lib.replaceChars ["."] ["/"] artifact.groupId) + artifact.artifactId + artifact.version + ]; + + mkFilename = artifact: with artifact; + "${artifactId}-${version}${lib.optionalString (classifier != "") "-${classifier}"}.${extension}"; + + mkArtifactUrl = base: artifact: + "${lib.removeSuffix "/" base}/${mkPath artifact}/${mkFilename artifact}"; + + fetchArtifact = artifact: + let + artifactPath = mkPath artifact; + artifactName = mkFilename artifact; + in stdenvNoCC.mkDerivation rec { + name = with artifact; lib.concatStrings [ + (lib.replaceChars ["."] ["_"] groupId) "-" + (lib.replaceChars ["."] ["_"] artifactId) "-" + version + (lib.optionalString (classifier != "") "-${classifier}") + "-" extension + ]; + + src = fetchurl { + name = mkFilename artifact; + urls = map (url: mkArtifactUrl url artifact) repositories; + inherit (artifact) sha256; + }; + + phases = "installPhase fixupPhase"; + + installPhase = '' + mkdir -p $out/${artifactPath} + ln -s ${src} $out/${artifactPath}/${artifactName} + ''; + }; + +in +buildEnv { + name = "gradle-env-${builtins.replaceStrings [":"] ["-"] path}-${env}"; + paths = map fetchArtifact artifacts; +} diff --git a/gradle/nix/gradle-dist.json b/gradle/nix/gradle-dist.json new file mode 100644 index 0000000..ad2b370 --- /dev/null +++ b/gradle/nix/gradle-dist.json @@ -0,0 +1,7 @@ +{ + "version": "5.3", + "type": "all", + "url": "https://services.gradle.org/distributions/gradle-5.3-all.zip", + "sha256": "f4d820c2a9685710eba5b92f10e0e4fb20e0d6c0dd1f46971e658160f25e7147", + "nativeVersion": "0.17" +} \ No newline at end of file diff --git a/gradle/nix/gradle-env.json b/gradle/nix/gradle-env.json new file mode 100644 index 0000000..935b3aa --- /dev/null +++ b/gradle/nix/gradle-env.json @@ -0,0 +1,1732 @@ +{ + ":": { + "plugins": { + "path": ":", + "env": "plugins", + "repositories": [ + "https://plugins.gradle.org/m2" + ], + "artifacts": [ + { + "groupId": "com.github.jengelman.gradle.plugins", + "artifactId": "shadow", + "version": "4.0.0", + "classifier": "", + "extension": "jar", + "sha256": "cXwxDqo6FVM7Xq6mfLe4AdpE9yIv94v8+ez151VOHnc=" + }, + { + "groupId": "com.github.jengelman.gradle.plugins", + "artifactId": "shadow", + "version": "4.0.0", + "classifier": "", + "extension": "pom", + "sha256": "BX4poPG89L1LDAAiJP806YtZMsulREwz4ieYr2ILzuQ=" + }, + { + "groupId": "com.github.johnrengelman.shadow", + "artifactId": "com.github.johnrengelman.shadow.gradle.plugin", + "version": "4.0.0", + "classifier": "", + "extension": "pom", + "sha256": "nm10H2Q75H9lAIKNT2P4vN8tYyLUnYA0G+K56SC63Kg=" + }, + { + "groupId": "commons-io", + "artifactId": "commons-io", + "version": "2.6", + "classifier": "", + "extension": "jar", + "sha256": "+HfTBGYKwqFC84ZbrfyXHex+1zx0fH+NXS9ROcpzZRM=" + }, + { + "groupId": "commons-io", + "artifactId": "commons-io", + "version": "2.6", + "classifier": "", + "extension": "pom", + "sha256": "DCOGOJOiKR9aev29jRWSOzlIr9h+Vj+jQc3Pbq4zimA=" + }, + { + "groupId": "org.apache.ant", + "artifactId": "ant-launcher", + "version": "1.9.7", + "classifier": "", + "extension": "jar", + "sha256": "vDdvbWy1hiKfRRrEWfrxRDsUTCbWZHYY7Jy6YOVMK3k=" + }, + { + "groupId": "org.apache.ant", + "artifactId": "ant-launcher", + "version": "1.9.7", + "classifier": "", + "extension": "pom", + "sha256": "17zdOrD/Ve2+G5bQbwbawhNexjtafDLO86Q2tJye7ic=" + }, + { + "groupId": "org.apache.ant", + "artifactId": "ant-parent", + "version": "1.9.7", + "classifier": "", + "extension": "pom", + "sha256": "ddLO9kxlzL3S+vcmHlO0RHeNVtM4djFU4w+tpKQdEhU=" + }, + { + "groupId": "org.apache.ant", + "artifactId": "ant", + "version": "1.9.7", + "classifier": "", + "extension": "jar", + "sha256": "ml2+P18suRhUyGgsq4AXivpBKrNaWrcYvznOAbNDXZM=" + }, + { + "groupId": "org.apache.ant", + "artifactId": "ant", + "version": "1.9.7", + "classifier": "", + "extension": "pom", + "sha256": "G5+9TzJacembJ5CA1jCE8S2ITUIIGvKY+eVT4f4M10o=" + }, + { + "groupId": "org.apache.commons", + "artifactId": "commons-parent", + "version": "42", + "classifier": "", + "extension": "pom", + "sha256": "zTE0lMZwtIPsJWlyrxaYszDlmPgHACNU63ZUefYEsJw=" + }, + { + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j-api", + "version": "2.11.0", + "classifier": "", + "extension": "jar", + "sha256": "+lgolQJpsK5CXJbYifGPQLM26fqIaEGuBruSJVEfEhc=" + }, + { + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j-api", + "version": "2.11.0", + "classifier": "", + "extension": "pom", + "sha256": "Bcwtp3otDyS0gDy/641kog9UlNCTobzXhy/iiqOQadk=" + }, + { + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j-core", + "version": "2.11.0", + "classifier": "", + "extension": "jar", + "sha256": "wyApsy2j2M8v7KB5CkvCMx6n62KrNoqJgLkMfYyBAeA=" + }, + { + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j-core", + "version": "2.11.0", + "classifier": "", + "extension": "pom", + "sha256": "1WKcz1cr6lcZLPjHXXTn6gWmk8Qu1xJkf67Zrp+/OIA=" + }, + { + "groupId": "org.apache.logging.log4j", + "artifactId": "log4j", + "version": "2.11.0", + "classifier": "", + "extension": "pom", + "sha256": "x4aYPHv6lQoCMbnPwrwrU3ATTALBHg9X2FZggqiDhvM=" + }, + { + "groupId": "org.apache.logging", + "artifactId": "logging-parent", + "version": "1", + "classifier": "", + "extension": "pom", + "sha256": "NLK/T1MagJFolhZy/0GdGr+WcluN/lKYDwDIxOsTS9Y=" + }, + { + "groupId": "org.apache", + "artifactId": "apache", + "version": "18", + "classifier": "", + "extension": "pom", + "sha256": "eDEwcoX9R1u8NrIK4454gvEcMVOx1ZMPhS1E7ajzPBc=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-utils", + "version": "3.0.24", + "classifier": "", + "extension": "jar", + "sha256": "g+50ixLQavsK1AUKWREys+gCX7sZkPHtAC6Lcyk+abQ=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-utils", + "version": "3.0.24", + "classifier": "", + "extension": "pom", + "sha256": "EQZ/anX97RK83I2vembd2ULOKJw9r4ij/g+LEoWKLuY=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus", + "version": "4.0", + "classifier": "", + "extension": "pom", + "sha256": "ChtpLX/MkNakXa4uUPRmDUj3pEUE8XSqYO80++Eyf2o=" + }, + { + "groupId": "org.gradle.kotlin.kotlin-dsl", + "artifactId": "org.gradle.kotlin.kotlin-dsl.gradle.plugin", + "version": "1.2.5", + "classifier": "", + "extension": "pom", + "sha256": "/GETYUcM9nxmg0F/yZVoeaSWprC5j11s+zDG7OC1U4c=" + }, + { + "groupId": "org.gradle.kotlin", + "artifactId": "plugins", + "version": "1.2.5", + "classifier": "", + "extension": "jar", + "sha256": "hpQRbr0r/B1RZSpG75KTzxO+cX45Br5+5oKg+NZjIiw=" + }, + { + "groupId": "org.gradle.kotlin", + "artifactId": "plugins", + "version": "1.2.5", + "classifier": "", + "extension": "pom", + "sha256": "kEkRngpBhZfla6pdjhwTC0oTukscJuf8flnlt47lSuM=" + }, + { + "groupId": "org.jdom", + "artifactId": "jdom2", + "version": "2.0.6", + "classifier": "", + "extension": "jar", + "sha256": "E0XxG6YG0VYD1nQFUajCGUfAIVZAdw7GcnH+eL6pfPU=" + }, + { + "groupId": "org.jdom", + "artifactId": "jdom2", + "version": "2.0.6", + "classifier": "", + "extension": "pom", + "sha256": "R7I6ef4za3QbgkNMbgSdaBZSVuQF51wQkh/XL6imXY0=" + }, + { + "groupId": "org.jetbrains.intellij.deps", + "artifactId": "trove4j", + "version": "1.0.20181211", + "classifier": "", + "extension": "jar", + "sha256": "r/t8haPIe9z2n/HbuE3hH2PckxKTk0vAjNerGN4INgE=" + }, + { + "groupId": "org.jetbrains.intellij.deps", + "artifactId": "trove4j", + "version": "1.0.20181211", + "classifier": "", + "extension": "pom", + "sha256": "MQpqotkFNMMrj0bx/JjNDtrpXc38oj4oR+Xvqa4MAZo=" + }, + { + "groupId": "org.jetbrains.kotlin.jvm", + "artifactId": "org.jetbrains.kotlin.jvm.gradle.plugin", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "8VCZqLaNedv5VVciEMDiCYt8iQEVKcPC5bln4VO9LEQ=" + }, + { + "groupId": "org.jetbrains.kotlin.kapt", + "artifactId": "org.jetbrains.kotlin.kapt.gradle.plugin", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "TSKA8Hh+kGwH5V7vznjf+QM8rgX3GMGbZcYz5ntr2fw=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-android-extensions", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "KwRirD5LNt/9s7+mFzy0Gw4k4lp9fu4QEkcfHSeuot0=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-android-extensions", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "9jEKsCDHAlW7h+XUsHXCn67+ODhWtgQctTQ79ChdwVo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-annotation-processing-gradle", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "+viAMV1P1qZmzBeqXpYIx0aMcKJ5tJzMpn26KlSt9pI=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-annotation-processing-gradle", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "9X3OxdUN+KLeVw86yJcYidSUPyuqyogUACoudn0L6Mk=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-build-common", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "9NjQjG9ZZtnVF87WDFIkx+3KLYEeoKcCvXGZoA3U+iU=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-build-common", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "wmwuwUIkyn+halRUOik6ll74dzTLc2TF6MEennnJjS4=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "r6rtwyT79jlNnzlUTvzJPPxZ+KWqGhpccdYeJINmbGo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Uyu5QViDU4ZwPnZUMH56w2ccCUfZZWGs2quaC3Lp30Q=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-runner", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "c+cIigdPnFF81LsqhhGDQWhFlmHIMhNs82KMzVmUzDs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-runner", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "KB9vwpwuA5E5mJrjZBv4aDS3URFJ/e5l2NkICOwn4oM=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-daemon-client", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "s+zOEex7MR7g0czGXoEfN0jzKAEHZehsvbKbK3D3Pxw=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-daemon-client", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "itMzMl3sJgv3wlG4l9bZlAatonHFHSE8fFQX4f9DX7Q=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-gradle-plugin-api", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "7QqxFDcxDNQJZXxeX4pr9YmvCoNIV3zWAPVGAfyXw2k=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-gradle-plugin-api", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "RhrUeSzPSgDhyR+JBIHL688FQdTsbWrEyiTqcFols5U=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-gradle-plugin-model", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "+63meio/sjTi1MG48Hsq9sCWmT807XMv5vra9pa8IIo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-gradle-plugin-model", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "vMX1stCbzYkO35paf1ugyMDAMQrBjmGFJOq2OHCVDjs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-gradle-plugin", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "eFjFj0xnioQWUg9MCUKCpIGYHP5wLSMSERjJx+mtIyY=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-gradle-plugin", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "uABbgVT1VnJ6aviVPC6AuOWrspGXMZRXYU06zvIIe9g=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-native-utils", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "QGAQo59MjN0jUcwRELmO2ATAqoEMthBue59PK8whzUc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-native-utils", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "AG/oxlzaUE9MrkwrMlR/Hx+7nG+99YAuk0fgt7J+Xes=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "owZcgiYzGR4KPj7hKim+wjT8SyhkpruH70jM4+ngwmo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "QtTq+ZQiO5Yet71owWo7tK775B8vdL1wJ0Lv+QkXC8w=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-sam-with-receiver", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "DYASsAOo2O/p+0ADrkyyuOtJvfH6FNmPW9oKIy+BZ3I=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-sam-with-receiver", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "wdYGy0qD/mrV8VugwzRbVH/Si9DJXqqWGIO+G+BhDd4=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "LiW6vI3NIkucR54sFs57TFBAfSXxjWDR/SYveMK0dMs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "65n/mMkw7B9deLEt5j+o0aqEnLp+ZjyNuYz/F83HV0c=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-scripting-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "9Ob5/ThNQhZ+m4n5he5KSKBna/5wWy4vnRPhWR1LfAs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-scripting-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "zogfIC+Za2bxr3XBK3JgBI+Zy6IqDyqNXVquIGI1g1Y=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "zqYfe2EYleZPWFaal1f8CrDVgvEHIR4ZMODOKgrdUqc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "HkQzMKGrEIPdEjMesYI7zaGM06YWLtxTagNeTeHXhz0=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk7", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "qHh1YE/UIUDaaTiuTTXuYQgfRIJTbvxtJhW4tiahmK8=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk7", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Jke6QWznPfilAYm2gN2TuHn7031z4xEIt5+9tVAAWnY=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk8", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "WCPtZqwSKhxVRC68paIJqEPM2H9WLtwxp4fz0uR/dNQ=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk8", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Vy3BzP3Nbd1GkYKm1Ty8eAKIsyXaUvJ8J/pc+mv5mYc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "OLojcNnwb1BDPgayyndblEc8LieF9BCSYHmreTxysDQ=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "nOHqMzlsW/5I7IQSoM1WHsyQnXHI+TZZZ6FPnyT9uaU=" + }, + { + "groupId": "org.jetbrains", + "artifactId": "annotations", + "version": "13.0", + "classifier": "", + "extension": "jar", + "sha256": "rOKhDcji1f00kl7KwD5JiLLA+FFlDJS4zvSbob0RFHg=" + }, + { + "groupId": "org.jetbrains", + "artifactId": "annotations", + "version": "13.0", + "classifier": "", + "extension": "pom", + "sha256": "llrrK+3/NpgZvd4b96CzuJuCR91pyIuGN112Fju4w5c=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-analysis", + "version": "6.2.1", + "classifier": "", + "extension": "jar", + "sha256": "TJNCyY50bpwtfyzcaJb3NIMX6bHlpsWRBH/Ilp3vSyM=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-analysis", + "version": "6.2.1", + "classifier": "", + "extension": "pom", + "sha256": "jq++RQVJv6RBWjjRM6qg1CrzTTELxaZJ4LtMeBa5wxI=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-commons", + "version": "6.2.1", + "classifier": "", + "extension": "jar", + "sha256": "P1eNMe8w+UttH0SBL0H+T5inzUKvNTNfXUhmqzuQGGU=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-commons", + "version": "6.2.1", + "classifier": "", + "extension": "pom", + "sha256": "Xv6KkF/PEsDrWd/JLazN17lP1DZiK1MAWX8vXjjFtWk=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-parent", + "version": "6.0", + "classifier": "", + "extension": "pom", + "sha256": "eR0GS7nsyaRtQ7ye/s10yRRk38RR8yG4AtImHizNfRQ=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-tree", + "version": "6.2.1", + "classifier": "", + "extension": "jar", + "sha256": "pSC1THvk4H5TPbhCDd+Tb+g0H/VqXfJVurWER43ZCqs=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-tree", + "version": "6.2.1", + "classifier": "", + "extension": "pom", + "sha256": "9HsK0Kct4wRIb9PsWQDqghtgSQBwApCW1kdIaKPdMQM=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-util", + "version": "6.0", + "classifier": "", + "extension": "jar", + "sha256": "NWr+vbD4cBdSYuUYj4cJo7F6oqWmpLA0CwTUtEm8pfY=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm-util", + "version": "6.0", + "classifier": "", + "extension": "pom", + "sha256": "PN/GH5iNFnuXUDQZ2oKlgIsg9CBa60bDlObn/9MhHxI=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm", + "version": "6.2.1", + "classifier": "", + "extension": "jar", + "sha256": "FGDbbDPMmchOXLMORrAX5NHMmn+8F0EB1vhIKbtkwIU=" + }, + { + "groupId": "org.ow2.asm", + "artifactId": "asm", + "version": "6.2.1", + "classifier": "", + "extension": "pom", + "sha256": "rCBe+QYK3x8qssJLyUKcd7zkih+0lv37WTjq9ZD046M=" + }, + { + "groupId": "org.ow2", + "artifactId": "ow2", + "version": "1.3", + "classifier": "", + "extension": "pom", + "sha256": "USFcZ9LAaNi30vb4D1E3KgmAdd7MxEjUvde5h7qDKPs=" + }, + { + "groupId": "org.ow2", + "artifactId": "ow2", + "version": "1.5", + "classifier": "", + "extension": "pom", + "sha256": "D4obEW52C4/mOJxRuE5LB6cPwRCC1Pk25FO1g91QtDs=" + }, + { + "groupId": "org.sonatype.forge", + "artifactId": "forge-parent", + "version": "10", + "classifier": "", + "extension": "pom", + "sha256": "wU+5wytZzAMlH2CUFtt8DP8B+BHtzMtPaoZdbnBGvQs=" + }, + { + "groupId": "org.vafer", + "artifactId": "jdependency", + "version": "1.3", + "classifier": "", + "extension": "jar", + "sha256": "DRE1VU9pho+SfUauQV5BnqFVlZJcVW5VohuO+bfJ8rE=" + }, + { + "groupId": "org.vafer", + "artifactId": "jdependency", + "version": "1.3", + "classifier": "", + "extension": "pom", + "sha256": "1L6Tzna2f9ir8rCYa5rBB7VeIo+PGgb4lkDAzxlBFFU=" + } + ] + }, + "buildscript": { + "path": ":", + "env": "buildscript", + "repositories": [], + "artifacts": [] + }, + "project": { + "path": ":", + "env": "project", + "repositories": [], + "artifacts": [] + } + }, + ":app": { + "buildscript": { + "path": ":app", + "env": "buildscript", + "repositories": [], + "artifacts": [] + }, + "project": { + "path": ":app", + "env": "project", + "repositories": [ + "https://jcenter.bintray.com/", + "https://repo.gradle.org/gradle/libs-releases" + ], + "artifacts": [ + { + "groupId": "com.github.ajalt", + "artifactId": "clikt", + "version": "1.7.0", + "classifier": "", + "extension": "jar", + "sha256": "BvUGcF+n7UlzPQFz7treWWKKPZxcoj30apGDBq2Y8X8=" + }, + { + "groupId": "com.github.ajalt", + "artifactId": "clikt", + "version": "1.7.0", + "classifier": "", + "extension": "pom", + "sha256": "D6xVOlI5cEVPsyl04UrY+jUqfinPs5K2VZtqNbrkmG0=" + }, + { + "groupId": "org.gradle", + "artifactId": "gradle-tooling-api", + "version": "5.3", + "classifier": "", + "extension": "jar", + "sha256": "3AflRCc5b3i/wZFbTJ9Tbp8Vqi95mxaVSg1G+L3QKvo=" + }, + { + "groupId": "org.gradle", + "artifactId": "gradle-tooling-api", + "version": "5.3", + "classifier": "", + "extension": "pom", + "sha256": "yIh7MGQj1zfYLXbGfkcRddqSUn9Css56Kv+tDB8oPcM=" + }, + { + "groupId": "org.jetbrains.intellij.deps", + "artifactId": "trove4j", + "version": "1.0.20181211", + "classifier": "", + "extension": "jar", + "sha256": "r/t8haPIe9z2n/HbuE3hH2PckxKTk0vAjNerGN4INgE=" + }, + { + "groupId": "org.jetbrains.intellij.deps", + "artifactId": "trove4j", + "version": "1.0.20181211", + "classifier": "", + "extension": "pom", + "sha256": "MQpqotkFNMMrj0bx/JjNDtrpXc38oj4oR+Xvqa4MAZo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "r6rtwyT79jlNnzlUTvzJPPxZ+KWqGhpccdYeJINmbGo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Uyu5QViDU4ZwPnZUMH56w2ccCUfZZWGs2quaC3Lp30Q=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "owZcgiYzGR4KPj7hKim+wjT8SyhkpruH70jM4+ngwmo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "QtTq+ZQiO5Yet71owWo7tK775B8vdL1wJ0Lv+QkXC8w=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "LiW6vI3NIkucR54sFs57TFBAfSXxjWDR/SYveMK0dMs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "65n/mMkw7B9deLEt5j+o0aqEnLp+ZjyNuYz/F83HV0c=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-scripting-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "9Ob5/ThNQhZ+m4n5he5KSKBna/5wWy4vnRPhWR1LfAs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-scripting-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "zogfIC+Za2bxr3XBK3JgBI+Zy6IqDyqNXVquIGI1g1Y=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "zqYfe2EYleZPWFaal1f8CrDVgvEHIR4ZMODOKgrdUqc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "HkQzMKGrEIPdEjMesYI7zaGM06YWLtxTagNeTeHXhz0=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk7", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "qHh1YE/UIUDaaTiuTTXuYQgfRIJTbvxtJhW4tiahmK8=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk7", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Jke6QWznPfilAYm2gN2TuHn7031z4xEIt5+9tVAAWnY=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk8", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "WCPtZqwSKhxVRC68paIJqEPM2H9WLtwxp4fz0uR/dNQ=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk8", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Vy3BzP3Nbd1GkYKm1Ty8eAKIsyXaUvJ8J/pc+mv5mYc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "OLojcNnwb1BDPgayyndblEc8LieF9BCSYHmreTxysDQ=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "nOHqMzlsW/5I7IQSoM1WHsyQnXHI+TZZZ6FPnyT9uaU=" + }, + { + "groupId": "org.jetbrains", + "artifactId": "annotations", + "version": "13.0", + "classifier": "", + "extension": "jar", + "sha256": "rOKhDcji1f00kl7KwD5JiLLA+FFlDJS4zvSbob0RFHg=" + }, + { + "groupId": "org.jetbrains", + "artifactId": "annotations", + "version": "13.0", + "classifier": "", + "extension": "pom", + "sha256": "llrrK+3/NpgZvd4b96CzuJuCR91pyIuGN112Fju4w5c=" + }, + { + "groupId": "org.slf4j", + "artifactId": "slf4j-api", + "version": "1.7.25", + "classifier": "", + "extension": "jar", + "sha256": "GMSgCV1cHaa4F1kudnuyPSndL1YK1033X/OWHb3iW3k=" + }, + { + "groupId": "org.slf4j", + "artifactId": "slf4j-api", + "version": "1.7.25", + "classifier": "", + "extension": "pom", + "sha256": "fNnXoLXZPf1GGhSIkbQ1Cc9AOpx/n7SQYNNVTfHIHh4=" + }, + { + "groupId": "org.slf4j", + "artifactId": "slf4j-parent", + "version": "1.7.25", + "classifier": "", + "extension": "pom", + "sha256": "GPXFISDbA26I1hNviDnIMtB0vdqVx1bG9CkknS21SsY=" + } + ] + } + }, + ":plugin": { + "buildscript": { + "path": ":plugin", + "env": "buildscript", + "repositories": [], + "artifacts": [] + }, + "project": { + "path": ":plugin", + "env": "project", + "repositories": [ + "https://repo.maven.apache.org/maven2/" + ], + "artifacts": [ + { + "groupId": "com.google.auto", + "artifactId": "auto-common", + "version": "0.10", + "classifier": "", + "extension": "jar", + "sha256": "uHa1/drO66fTWWZ/bE+4xvhljaGrkC/7eeyaQV3u3l8=" + }, + { + "groupId": "com.google.auto", + "artifactId": "auto-common", + "version": "0.10", + "classifier": "", + "extension": "pom", + "sha256": "RnreF6BwnXsdXEYeZ/NZ5O/8UjD8Yr0L4oDs4aCPAzI=" + }, + { + "groupId": "com.google.auto", + "artifactId": "auto-parent", + "version": "6", + "classifier": "", + "extension": "pom", + "sha256": "BfdAxmSBZdsAz2GN1WwgDEcl41jm1U9YU+C+wVc06go=" + }, + { + "groupId": "com.google.code.findbugs", + "artifactId": "jsr305", + "version": "1.3.9", + "classifier": "", + "extension": "jar", + "sha256": "kFchoO6pCoFTSrt+5u9OouXmRfod7wpc2IQC3xtGye0=" + }, + { + "groupId": "com.google.code.findbugs", + "artifactId": "jsr305", + "version": "1.3.9", + "classifier": "", + "extension": "pom", + "sha256": "/quRkTEcPXru8rZtYGSvyA09HVLZgPsHrkPHjJh7qTo=" + }, + { + "groupId": "com.google.errorprone", + "artifactId": "error_prone_annotations", + "version": "2.0.18", + "classifier": "", + "extension": "jar", + "sha256": "y0z62HC/VjoHGZ8+vqV2Pw3sRA/NoLMYZAsf6qeIZWs=" + }, + { + "groupId": "com.google.errorprone", + "artifactId": "error_prone_annotations", + "version": "2.0.18", + "classifier": "", + "extension": "pom", + "sha256": "kUQScZLW9hLCNmgl3OrrI7DVMTC4Pgvx/+EH0UcKhIc=" + }, + { + "groupId": "com.google.errorprone", + "artifactId": "error_prone_parent", + "version": "2.0.18", + "classifier": "", + "extension": "pom", + "sha256": "zxSZVSebB9TxHoF5hcEWSmnpMNc9t0QbQ6bvU7vShsQ=" + }, + { + "groupId": "com.google.guava", + "artifactId": "guava-parent", + "version": "20.0", + "classifier": "", + "extension": "pom", + "sha256": "8SJv0H/HKvjWIyvfpwvzHYg6GgHLxUfyOnTpBmxpLfE=" + }, + { + "groupId": "com.google.guava", + "artifactId": "guava-parent", + "version": "23.5-jre", + "classifier": "", + "extension": "pom", + "sha256": "1pr4WZD3fvVLSqjnRMAU3oEcrYpi55Cxd8IZtZx12Rg=" + }, + { + "groupId": "com.google.guava", + "artifactId": "guava", + "version": "20.0", + "classifier": "", + "extension": "jar", + "sha256": "NqZm47ca5/Dw3KI2VLZ+CG5sk9GS9gul39VRnbbCiMg=" + }, + { + "groupId": "com.google.guava", + "artifactId": "guava", + "version": "20.0", + "classifier": "", + "extension": "pom", + "sha256": "NjzIN2e3YNelZNUwHglGfm1I/BwcFmSx4YxQgVzhkHY=" + }, + { + "groupId": "com.google.guava", + "artifactId": "guava", + "version": "23.5-jre", + "classifier": "", + "extension": "jar", + "sha256": "yUZ3iO/7x+awZUo/18fgRE1wRmSjItIY6oxydrFkIrs=" + }, + { + "groupId": "com.google.guava", + "artifactId": "guava", + "version": "23.5-jre", + "classifier": "", + "extension": "pom", + "sha256": "TLEZ2NT4pf4purQgSDvVSOHfHffnOm9oe1ZqgoO6I9k=" + }, + { + "groupId": "com.google.j2objc", + "artifactId": "j2objc-annotations", + "version": "1.1", + "classifier": "", + "extension": "jar", + "sha256": "KZSn63jycQvT07+2ObLJTiGc7awNTQhNUW54wW3d7PY=" + }, + { + "groupId": "com.google.j2objc", + "artifactId": "j2objc-annotations", + "version": "1.1", + "classifier": "", + "extension": "pom", + "sha256": "8MmMVx6Tp8tN0Y3w+jCPCWPnoGIKwtQkTmHnCdA61r4=" + }, + { + "groupId": "com.squareup.moshi", + "artifactId": "moshi-kotlin-codegen", + "version": "1.8.0", + "classifier": "", + "extension": "jar", + "sha256": "9ntaKPRwWpgqs5WTBBT0WDUprk9CeQ4kZ1fbSm9MsmU=" + }, + { + "groupId": "com.squareup.moshi", + "artifactId": "moshi-kotlin-codegen", + "version": "1.8.0", + "classifier": "", + "extension": "pom", + "sha256": "W5vWOvAMhcIsn0grubfVz7B4mYQEHkFoegr3Vd0KNg8=" + }, + { + "groupId": "com.squareup.moshi", + "artifactId": "moshi-parent", + "version": "1.8.0", + "classifier": "", + "extension": "pom", + "sha256": "2t8UzX/uSexrgqkORdccwax1imVTFwGtlNy+98xgP7c=" + }, + { + "groupId": "com.squareup.moshi", + "artifactId": "moshi", + "version": "1.8.0", + "classifier": "", + "extension": "jar", + "sha256": "Qv50bSaU6hH+agK+zZ2iyj2v6Xye/VCg+a9cRZbnSmo=" + }, + { + "groupId": "com.squareup.moshi", + "artifactId": "moshi", + "version": "1.8.0", + "classifier": "", + "extension": "pom", + "sha256": "FLuAWbnddiACWSkN+IfjfmaaB0qsnImUAePIEC/lII8=" + }, + { + "groupId": "com.squareup.okio", + "artifactId": "okio-parent", + "version": "1.16.0", + "classifier": "", + "extension": "pom", + "sha256": "C3Qkw/qrO7UzMJbjmVf4j41QzgyYv7pxo/z6oKrwVSw=" + }, + { + "groupId": "com.squareup.okio", + "artifactId": "okio", + "version": "1.16.0", + "classifier": "", + "extension": "jar", + "sha256": "7ASE/xkDZA44RcKxCruZ7/LTIwj/40WeX5IwmkUbnH4=" + }, + { + "groupId": "com.squareup.okio", + "artifactId": "okio", + "version": "1.16.0", + "classifier": "", + "extension": "pom", + "sha256": "HSUhYhwIdRI6qRMRsv6O3v0O2T9mvm3+oYzGG8XJnjY=" + }, + { + "groupId": "com.squareup.okio", + "artifactId": "okio", + "version": "2.2.2", + "classifier": "", + "extension": "jar", + "sha256": "5YyXQGprsROIk3UCmaxjxqoEs4trSerhv8rRpj75uhs=" + }, + { + "groupId": "com.squareup.okio", + "artifactId": "okio", + "version": "2.2.2", + "classifier": "", + "extension": "pom", + "sha256": "/WIZiPf2lXAlc13G3QkLAKIPOju413ynkDYHf2KbFAs=" + }, + { + "groupId": "me.eugeniomarletti.kotlin.metadata", + "artifactId": "kotlin-compiler-lite", + "version": "1.0.3-k-1.2.40", + "classifier": "", + "extension": "jar", + "sha256": "fQ4eR9yYT/wPS8QoXmKY+FFaaNKmzsKPEHr5WRa0L0A=" + }, + { + "groupId": "me.eugeniomarletti.kotlin.metadata", + "artifactId": "kotlin-compiler-lite", + "version": "1.0.3-k-1.2.40", + "classifier": "", + "extension": "pom", + "sha256": "RZzOYInqbcmuceVUuqxR0WN1Em/otGAACBV5MhVt6LY=" + }, + { + "groupId": "me.eugeniomarletti.kotlin.metadata", + "artifactId": "kotlin-metadata", + "version": "1.4.0", + "classifier": "", + "extension": "jar", + "sha256": "gucO7w0UgtrgWelR3s4ShtYDIZYxaoFD6yxtLSlZ5I0=" + }, + { + "groupId": "me.eugeniomarletti.kotlin.metadata", + "artifactId": "kotlin-metadata", + "version": "1.4.0", + "classifier": "", + "extension": "pom", + "sha256": "1JJVW7TRHs4dBFbSfRif/vtYi+GG9BdDC0SFx/Qf+OY=" + }, + { + "groupId": "org.apache.commons", + "artifactId": "commons-lang3", + "version": "3.5", + "classifier": "", + "extension": "jar", + "sha256": "islvxoZRLXd/yoXhRPGWzXz+DArsIxJyKUl9Gjj/ZRw=" + }, + { + "groupId": "org.apache.commons", + "artifactId": "commons-lang3", + "version": "3.5", + "classifier": "", + "extension": "pom", + "sha256": "Ref7ssIx25A6XVqtr8Y2oXOk1UVg94oR/0mAKO+eNF4=" + }, + { + "groupId": "org.apache.commons", + "artifactId": "commons-parent", + "version": "41", + "classifier": "", + "extension": "pom", + "sha256": "sod8gBb4sokkyOkN1a5AzRHzKNAqHemNgN4iV0qzbsc=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-artifact", + "version": "3.5.4", + "classifier": "", + "extension": "jar", + "sha256": "b78l3obM46+69cUC3/V99tfJDPm+wK4P/lqyRnJDw1s=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-artifact", + "version": "3.5.4", + "classifier": "", + "extension": "pom", + "sha256": "TlRXCRfQUZHbgztcTku6Q3NeXePzf6043VoHe1lJgXo=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-builder-support", + "version": "3.5.4", + "classifier": "", + "extension": "jar", + "sha256": "Q4Vc4p/IAB72Y6W7K7BHNIGx+PgM6ns8wdQmr5lpYLI=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-builder-support", + "version": "3.5.4", + "classifier": "", + "extension": "pom", + "sha256": "uQVYL/SmxiEWLL2MdCykLe0G6mmh9IoFAE5Tj/o8nbM=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-model-builder", + "version": "3.5.4", + "classifier": "", + "extension": "jar", + "sha256": "XcENaf0KbjjzrDeIvx5j79Zorx/COgii/c/9hZIdb1Y=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-model-builder", + "version": "3.5.4", + "classifier": "", + "extension": "pom", + "sha256": "t/YeBFhitMjFKMXa5itKq7oyppzRmps4BoVwcsMPBp8=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-model", + "version": "3.5.4", + "classifier": "", + "extension": "jar", + "sha256": "XsG5TpJUwlSAVIYzpIt66Kmtp1J+KPXFdZQ/4MKrc1A=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-model", + "version": "3.5.4", + "classifier": "", + "extension": "pom", + "sha256": "6vlL7ccg1cKihoSCJU2g9xQTpo7ATxez+ENUnjnUMUE=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven-parent", + "version": "31", + "classifier": "", + "extension": "pom", + "sha256": "Qv3nY6bm/oSAsWCK3/LDXQJhLieeyc5y+rtP2PtcV1M=" + }, + { + "groupId": "org.apache.maven", + "artifactId": "maven", + "version": "3.5.4", + "classifier": "", + "extension": "pom", + "sha256": "55XO8tL4cloZoALAkl2W+w6GrudCK1GdjyERBSopr2c=" + }, + { + "groupId": "org.apache", + "artifactId": "apache", + "version": "18", + "classifier": "", + "extension": "pom", + "sha256": "eDEwcoX9R1u8NrIK4454gvEcMVOx1ZMPhS1E7ajzPBc=" + }, + { + "groupId": "org.apache", + "artifactId": "apache", + "version": "19", + "classifier": "", + "extension": "pom", + "sha256": "kfejMJbqabrCy69tAf65NMrAAsSNjIz6nCQLQPHsId8=" + }, + { + "groupId": "org.checkerframework", + "artifactId": "checker-qual", + "version": "2.0.0", + "classifier": "", + "extension": "jar", + "sha256": "/IRBYy9fpVN0ksnwJtHIsa22p3lvRgMbBLTMBiJCeZU=" + }, + { + "groupId": "org.checkerframework", + "artifactId": "checker-qual", + "version": "2.0.0", + "classifier": "", + "extension": "pom", + "sha256": "3rEDU90rG+4OVIt0AU2AoReaj6r40NiGwBtNbKkwAGg=" + }, + { + "groupId": "org.codehaus.mojo", + "artifactId": "animal-sniffer-annotations", + "version": "1.14", + "classifier": "", + "extension": "jar", + "sha256": "IGgyC9a610TDZzqwSPZ+ML749RiZb6OAAzVWYAZpkF0=" + }, + { + "groupId": "org.codehaus.mojo", + "artifactId": "animal-sniffer-annotations", + "version": "1.14", + "classifier": "", + "extension": "pom", + "sha256": "GHnxmgWZHj7ZWRC5ZokzM5awxGeiFdxNH5ABhAS3KiY=" + }, + { + "groupId": "org.codehaus.mojo", + "artifactId": "animal-sniffer-parent", + "version": "1.14", + "classifier": "", + "extension": "pom", + "sha256": "9RVQoGsUEL1JYssOcd8Lkhpgp+9Hv6nEgloUvnIxbuo=" + }, + { + "groupId": "org.codehaus.mojo", + "artifactId": "mojo-parent", + "version": "34", + "classifier": "", + "extension": "pom", + "sha256": "Pjldb7xDwJo3dMrIaUzlJzmDBeo/1UktgOJa8n04Kpw=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-component-annotations", + "version": "1.7.1", + "classifier": "", + "extension": "jar", + "sha256": "p/7pQ123Fr/1k+n7ViK8+fJeUnGWSFkpsM1AZcQ+Yd8=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-component-annotations", + "version": "1.7.1", + "classifier": "", + "extension": "pom", + "sha256": "qQmgy+KS5UEitreF9pJKsvCbFjC3iJyADgmeJif5Gng=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-containers", + "version": "1.7.1", + "classifier": "", + "extension": "pom", + "sha256": "VWagu1HcmUwDUCBmCMe0zcybZogUl7q1ajLELtylPnk=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-interpolation", + "version": "1.24", + "classifier": "", + "extension": "jar", + "sha256": "j+K+BLBnp10C+4oanK9sHIYV8NVXfM7QLpC1IHY9L3c=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-interpolation", + "version": "1.24", + "classifier": "", + "extension": "pom", + "sha256": "tdi6wu9/0RNimCI+U0iZgK16B30cnlTAayiEZwdxgZ8=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-utils", + "version": "3.1.0", + "classifier": "", + "extension": "jar", + "sha256": "D/oK0ITr/1cSVAp7fqCr2kh8U9Ohj3jJjRo2ddq5v2E=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus-utils", + "version": "3.1.0", + "classifier": "", + "extension": "pom", + "sha256": "FHPR654v++0CWBmJKweJhcXdVcGQsdgv0bVoVQWyuBk=" + }, + { + "groupId": "org.codehaus.plexus", + "artifactId": "plexus", + "version": "4.0", + "classifier": "", + "extension": "pom", + "sha256": "ChtpLX/MkNakXa4uUPRmDUj3pEUE8XSqYO80++Eyf2o=" + }, + { + "groupId": "org.codehaus", + "artifactId": "codehaus-parent", + "version": "4", + "classifier": "", + "extension": "pom", + "sha256": "a4cjfejC4XQM+AYnx/POPhXeGTC7JQxVoeypT6PgFN8=" + }, + { + "groupId": "org.jetbrains.intellij.deps", + "artifactId": "trove4j", + "version": "1.0.20181211", + "classifier": "", + "extension": "jar", + "sha256": "r/t8haPIe9z2n/HbuE3hH2PckxKTk0vAjNerGN4INgE=" + }, + { + "groupId": "org.jetbrains.intellij.deps", + "artifactId": "trove4j", + "version": "1.0.20181211", + "classifier": "", + "extension": "pom", + "sha256": "MQpqotkFNMMrj0bx/JjNDtrpXc38oj4oR+Xvqa4MAZo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-annotation-processing-embeddable", + "version": "1.2.71", + "classifier": "", + "extension": "jar", + "sha256": "rPoYJ6iKfJ5VHkyqpzWrn7tsVChe4y+wawJ2/sLGx6c=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-annotation-processing-embeddable", + "version": "1.2.71", + "classifier": "", + "extension": "pom", + "sha256": "uDtOT5E2+uv6fskLjJ11vS6xwpTEku3a6fgNpUvJquE=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-annotation-processing-gradle", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "+viAMV1P1qZmzBeqXpYIx0aMcKJ5tJzMpn26KlSt9pI=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-annotation-processing-gradle", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "9X3OxdUN+KLeVw86yJcYidSUPyuqyogUACoudn0L6Mk=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.2.71", + "classifier": "", + "extension": "jar", + "sha256": "Yj5UYxDT2ontK8DPn3/t14+t2c1l0v95j6iUwU5SdmU=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.2.71", + "classifier": "", + "extension": "pom", + "sha256": "4XIB+2uoiBi8K3Vs4XnWGYJiaToL73BIUZvnPqj0200=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "r6rtwyT79jlNnzlUTvzJPPxZ+KWqGhpccdYeJINmbGo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Uyu5QViDU4ZwPnZUMH56w2ccCUfZZWGs2quaC3Lp30Q=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.2.71", + "classifier": "", + "extension": "jar", + "sha256": "Hz4Qq9aNCwgWvdq3MU9hJp4B2KosocvRIMEtO03JSw8=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.2.71", + "classifier": "", + "extension": "pom", + "sha256": "OiUeTEuWcSe0gO1fTVGtqebyz2Ibwz6qvkIlduJMaSs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "owZcgiYzGR4KPj7hKim+wjT8SyhkpruH70jM4+ngwmo=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-reflect", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "QtTq+ZQiO5Yet71owWo7tK775B8vdL1wJ0Lv+QkXC8w=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-sam-with-receiver", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "DYASsAOo2O/p+0ADrkyyuOtJvfH6FNmPW9oKIy+BZ3I=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-sam-with-receiver", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "wdYGy0qD/mrV8VugwzRbVH/Si9DJXqqWGIO+G+BhDd4=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.2.71", + "classifier": "", + "extension": "jar", + "sha256": "MH0KVnNEWKXlfj6niMFbIlkZEro5+BssyLCgkJRAErs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.2.71", + "classifier": "", + "extension": "pom", + "sha256": "NvuWlPDSbW2lK6KkmPLa4eoX0Sr0HZVf5cLwLQREI9c=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "LiW6vI3NIkucR54sFs57TFBAfSXxjWDR/SYveMK0dMs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-script-runtime", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "65n/mMkw7B9deLEt5j+o0aqEnLp+ZjyNuYz/F83HV0c=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-scripting-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "9Ob5/ThNQhZ+m4n5he5KSKBna/5wWy4vnRPhWR1LfAs=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-scripting-compiler-embeddable", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "zogfIC+Za2bxr3XBK3JgBI+Zy6IqDyqNXVquIGI1g1Y=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.2.71", + "classifier": "", + "extension": "jar", + "sha256": "Y5mWh/8vzopZLdGA/7v48dIcJrQETFXNx0/zzzs88yg=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.2.71", + "classifier": "", + "extension": "pom", + "sha256": "qMPtWJIDK56TlVJKTaKVOXXJlii5Mt8zNrJdVG58ZpM=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "zqYfe2EYleZPWFaal1f8CrDVgvEHIR4ZMODOKgrdUqc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-common", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "HkQzMKGrEIPdEjMesYI7zaGM06YWLtxTagNeTeHXhz0=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk7", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "qHh1YE/UIUDaaTiuTTXuYQgfRIJTbvxtJhW4tiahmK8=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk7", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Jke6QWznPfilAYm2gN2TuHn7031z4xEIt5+9tVAAWnY=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk8", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "WCPtZqwSKhxVRC68paIJqEPM2H9WLtwxp4fz0uR/dNQ=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib-jdk8", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "Vy3BzP3Nbd1GkYKm1Ty8eAKIsyXaUvJ8J/pc+mv5mYc=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.2.71", + "classifier": "", + "extension": "jar", + "sha256": "TIlcJwuH9f7ConluHYnBVAfugh3pYVJ8KFiLtGr7xos=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.2.71", + "classifier": "", + "extension": "pom", + "sha256": "cT23fJoMR6Zw+VwjsAUbm9lCs6DqH2zJu12eq6H6da4=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.3.21", + "classifier": "", + "extension": "jar", + "sha256": "OLojcNnwb1BDPgayyndblEc8LieF9BCSYHmreTxysDQ=" + }, + { + "groupId": "org.jetbrains.kotlin", + "artifactId": "kotlin-stdlib", + "version": "1.3.21", + "classifier": "", + "extension": "pom", + "sha256": "nOHqMzlsW/5I7IQSoM1WHsyQnXHI+TZZZ6FPnyT9uaU=" + }, + { + "groupId": "org.jetbrains", + "artifactId": "annotations", + "version": "13.0", + "classifier": "", + "extension": "jar", + "sha256": "rOKhDcji1f00kl7KwD5JiLLA+FFlDJS4zvSbob0RFHg=" + }, + { + "groupId": "org.jetbrains", + "artifactId": "annotations", + "version": "13.0", + "classifier": "", + "extension": "pom", + "sha256": "llrrK+3/NpgZvd4b96CzuJuCR91pyIuGN112Fju4w5c=" + }, + { + "groupId": "org.sonatype.forge", + "artifactId": "forge-parent", + "version": "10", + "classifier": "", + "extension": "pom", + "sha256": "wU+5wytZzAMlH2CUFtt8DP8B+BHtzMtPaoZdbnBGvQs=" + }, + { + "groupId": "org.sonatype.oss", + "artifactId": "oss-parent", + "version": "7", + "classifier": "", + "extension": "pom", + "sha256": "tR+IZ8kranIkmVV/w6H96ne9+e9XRyL+kM5DailVlFQ=" + } + ] + } + } +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..457aad0 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..b8a51fe --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.3-all.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..af6708f --- /dev/null +++ b/gradlew @@ -0,0 +1,172 @@ +#!/usr/bin/env sh + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..0f8d593 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,84 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts new file mode 100644 index 0000000..ee802b2 --- /dev/null +++ b/plugin/build.gradle.kts @@ -0,0 +1,34 @@ +plugins { + id("com.github.johnrengelman.shadow") version "4.0.0" + `java-gradle-plugin` + `kotlin-dsl` + `maven-publish` + kotlin("kapt") version embeddedKotlinVersion +} + +group = "org.nixos" +version = "1.0.0-SNAPSHOT" + +repositories { + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) + implementation("org.apache.maven:maven-model:3.5.4") + implementation("org.apache.maven:maven-model-builder:3.5.4") + 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") +} + +gradlePlugin { + plugins { + register("gradle2nix") { + id = "org.nixos.gradle2nix" + displayName = "gradle2nix" + description = "Create Nix configurations suitable for reproducible packaging" + implementationClass = "org.nixos.gradle2nix.Gradle2NixPlugin" + } + } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt new file mode 100644 index 0000000..6d40da9 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt @@ -0,0 +1,137 @@ +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.file.RegularFile +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.internal.DocumentationRegistry +import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionSelectorScheme +import org.gradle.api.internal.plugins.PluginRegistry +import org.gradle.api.invocation.Gradle +import org.gradle.api.provider.Provider +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.property +import org.gradle.kotlin.dsl.register +import org.gradle.kotlin.dsl.withType +import org.gradle.plugin.management.PluginRequest +import org.gradle.plugin.use.internal.PluginDependencyResolutionServices +import org.gradle.plugin.use.internal.PluginResolverFactory +import java.io.File +import java.net.URL +import java.util.Locale +import javax.inject.Inject + +open class Gradle2NixPlugin : Plugin { + override fun apply(gradle: Gradle) { + val configurationNames: List = + System.getProperty("org.nixos.gradle2nix.configurations")?.split(",") ?: emptyList() + + 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 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) + } + } + + private fun collectPlugins(gradle: Gradle): List { + val pluginRequests = mutableListOf() + gradle.settingsEvaluated { + pluginManagement.resolutionStrategy.eachPlugin { + if (requested.id.namespace != null && requested.id.namespace != "org.gradle") { + pluginRequests.add(target) + } + } + } + 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(""" + Failed to find native-platform jar in ${gradle.gradleHomeDir}. + + Ask Tad to fix this. + """.trimIndent()) + ) + } + val gradleDistTask = + gradle.rootProject.tasks.register("nixGradleDist", NixGradleDist::class) { + this.gradleDist.set(gradleDist) + outputDir.set(extension.outputDir) + } + gradleEnv.configure { + dependsOn(gradleDistTask) + } + } + } +} + +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 { + connect() + getInputStream().source().buffer().use { source -> + source.readUtf8() + } + } +} + +private val nativePlatformJarRegex = Regex("""native-platform-(\d\.\d+)\.jar""") + diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt new file mode 100644 index 0000000..09095c2 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixBuildscriptEnv.kt @@ -0,0 +1,43 @@ +package org.nixos.gradle2nix + +import okio.buffer +import okio.source +import org.gradle.api.tasks.InputFile +import java.lang.IllegalStateException +import java.net.URI + +open class NixBuildscriptEnv : NixEnv() { + @InputFile + val pluginEnvFile = project.objects.fileProperty() + + 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" +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt new file mode 100644 index 0000000..e6803e4 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixEnv.kt @@ -0,0 +1,73 @@ +package org.nixos.gradle2nix + +import com.squareup.moshi.JsonClass +import com.squareup.moshi.Moshi +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.OutputDirectory +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.objects.directoryProperty() + .convention(project.layout.buildDirectory.dir("nix")) + + @OutputFile + val outputFile = project.objects.fileProperty() + .convention(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" } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt new file mode 100644 index 0000000..eb338b7 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleDist.kt @@ -0,0 +1,44 @@ +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.objects.directoryProperty() + + @OutputFile + val outputFile = project.objects.fileProperty() + .convention(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 \ No newline at end of file diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt new file mode 100644 index 0000000..99a7b58 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixGradleEnv.kt @@ -0,0 +1,58 @@ +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.file.RegularFile +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Internal +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.kotlin.dsl.listProperty + +open class NixGradleEnv : DefaultTask() { + + @InputFiles + val inputEnvs = project.objects.fileCollection() + + @Internal + val outputDir = project.objects.directoryProperty() + + @OutputFile + val outputFile = project.objects.fileProperty() + .convention(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/NixPluginEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixPluginEnv.kt new file mode 100644 index 0000000..0d118af --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixPluginEnv.kt @@ -0,0 +1,110 @@ +package org.nixos.gradle2nix + +import org.gradle.api.artifacts.ExternalModuleDependency +import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionSelectorScheme +import org.gradle.api.internal.plugins.PluginImplementation +import org.gradle.plugin.management.PluginRequest +import org.gradle.plugin.management.internal.PluginRequestInternal +import org.gradle.plugin.use.PluginId +import org.gradle.plugin.use.internal.PluginDependencyResolutionServices +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( + private val pluginDependencyResolutionServices: PluginDependencyResolutionServices, + versionSelectorScheme: VersionSelectorScheme, + private val pluginRequests: Collection +) : NixEnv() { + private val repositories by lazy { + pluginDependencyResolutionServices.resolveRepositoryHandler + } + + private val artifactRepositoriesPluginResolver = ArtifactRepositoriesPluginResolver( + pluginDependencyResolutionServices, + versionSelectorScheme + ) + + private val resolver by lazy { + Resolver( + pluginDependencyResolutionServices.configurationContainer, + pluginDependencyResolutionServices.dependencyHandler, + logger + ) + } + + private val pluginResult by lazy { + PluginResult().apply { + for (request in pluginRequests.filterIsInstance()) { + artifactRepositoriesPluginResolver.resolve(request, this) + } + } + } + + private val pluginContext by lazy { + PluginContext().apply { + for (result in pluginResult.found) result.execute(this) + } + } + + override fun environment(): String = "plugins" + + override fun repositories(): List { + return repositories.flatMap { it.repositoryUrls() }.map(URI::toString) + + pluginContext.repositories.toList() + } + + override 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() + + override fun notFound(sourceDescription: String?, notFoundMessage: 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) + } +} + +private class PluginContext : PluginResolveContext { + val dependencies = mutableSetOf() + val repositories = mutableSetOf() + + override fun add(plugin: PluginImplementation<*>) { + println("add: $plugin") + } + + 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) + } + } +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt new file mode 100644 index 0000000..0a1cb9f --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/NixProjectEnv.kt @@ -0,0 +1,41 @@ +package org.nixos.gradle2nix + +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.kotlin.dsl.setProperty +import java.net.URI + +open class NixProjectEnv : NixEnv() { + @Input @Optional + val configurations = project.objects.setProperty() + + 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" +} \ No newline at end of file diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/Resolver.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/Resolver.kt new file mode 100644 index 0000000..45af037 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/Resolver.kt @@ -0,0 +1,166 @@ +package org.nixos.gradle2nix + +import okio.ByteString +import okio.HashingSource +import okio.blackholeSink +import okio.buffer +import okio.source +import org.apache.maven.model.Parent +import org.apache.maven.model.Repository +import org.apache.maven.model.building.DefaultModelBuilderFactory +import org.apache.maven.model.building.DefaultModelBuildingRequest +import org.apache.maven.model.building.ModelBuildingRequest +import org.apache.maven.model.building.ModelSource2 +import org.apache.maven.model.resolution.ModelResolver +import org.gradle.api.artifacts.Configuration +import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.Dependency +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.maven.MavenModule +import org.gradle.maven.MavenPomArtifact +import java.io.File +import java.io.InputStream +import java.net.URI + +internal class Resolver( + private val configurations: ConfigurationContainer, + private val dependencies: DependencyHandler, + private val logger: Logger +) { + private val mavenPomResolver = MavenPomResolver(configurations, dependencies) + + 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( + groupId = moduleVersion.id.group, + artifactId = moduleVersion.id.name, + version = moduleVersion.id.version, + classifier = classifier ?: "", + extension = extension, + sha256 = sha256(file) + ) + } + } + } + + fun resolveDependencies( + dependencies: Collection, + includeTransitive: Boolean = false + ): Set { + val configuration = configurations.detachedConfiguration(*(dependencies.toTypedArray())) + configuration.isTransitive = includeTransitive + return resolveDependencies(configuration) + } + + fun resolvePoms(configuration: Configuration): Set { + return dependencies.createArtifactResolutionQuery() + .forComponents(configuration.incoming.resolutionResult.allComponents.map { it.id }) + .withArtifacts(MavenModule::class.java, MavenPomArtifact::class.java) + .execute() + .resolvedComponents.asSequence() + .flatMap { component -> + val id = component.id + if (id !is ModuleComponentIdentifier) { + emptySequence() + } else { + component.getArtifacts(MavenPomArtifact::class.java).asSequence() + .filterIsInstance() + .map { id to it } + } + } + .flatMapTo(sortedSetOf()) { (id, artifact) -> + sequenceOf(Artifact( + groupId = id.group, + artifactId = id.module, + version = id.version, + classifier = "", + extension = artifact.file.extension, + sha256 = sha256(artifact.file) + )) + mavenPomResolver.resolve(artifact.file).asSequence() + } + } + + fun resolvePoms( + dependencies: Collection, + includeTransitive: Boolean = false + ): Set { + val configuration = configurations.detachedConfiguration(*(dependencies.toTypedArray())) + configuration.isTransitive = includeTransitive + return resolvePoms(configuration) + } +} + +private class MavenPomResolver( + private val configurations: ConfigurationContainer, + private val dependencies: DependencyHandler +) : ModelResolver { + private val modelBuilder = DefaultModelBuilderFactory().newInstance() + private val resolvedDependencies = mutableSetOf() + + @Synchronized + fun resolve(pom: File): Set { + resolvedDependencies.clear() + modelBuilder.build( + DefaultModelBuildingRequest() + .setModelResolver(this) + .setPomFile(pom) + .setSystemProperties(System.getProperties()) + .setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL) + ).effectiveModel + return resolvedDependencies.toSet() + } + + override fun newCopy() = this + + override fun resolveModel( + groupId: String, + artifactId: String, + version: String + ): ModelSource2 { + val file = configurations + .detachedConfiguration(dependencies.create("$groupId:$artifactId:$version@pom")) + .singleFile + resolvedDependencies.add(Artifact( + groupId = groupId, + artifactId = artifactId, + version = version, + classifier = "", + extension = file.extension, + sha256 = sha256(file) + )) + + return object : ModelSource2 { + override fun getLocation(): String = file.absolutePath + override fun getLocationURI(): URI = file.absoluteFile.toURI() + override fun getRelatedSource(relPath: String?): ModelSource2? = null + override fun getInputStream(): InputStream = file.inputStream() + } + } + + override fun resolveModel(parent: Parent): ModelSource2 = + resolveModel(parent.groupId, parent.artifactId, parent.version) + + override fun resolveModel(dependency: org.apache.maven.model.Dependency): ModelSource2 = + resolveModel(dependency.groupId, dependency.artifactId, dependency.version) + + override fun addRepository(repository: Repository) {} + + override fun addRepository(repository: Repository, replace: Boolean) {} +} + +fun sha256(file: File): String { + val hashSource = HashingSource.sha256(file.source()) + val hash: ByteString = hashSource.buffer().use { source -> + source.readAll(blackholeSink()) + hashSource.hash + } + return hash.base64() +} \ No newline at end of file diff --git a/plugin/src/main/resources/gradle-env.nix b/plugin/src/main/resources/gradle-env.nix new file mode 100644 index 0000000..2904921 --- /dev/null +++ b/plugin/src/main/resources/gradle-env.nix @@ -0,0 +1,51 @@ +# This file is generated by gradle2nix. + +{ stdenvNoCC, lib, buildEnv, fetchurl }: + +{ name, repositories, dependencies }: + +let + mkPath = artifact: with artifact; lib.concatStringsSep "/" [ + (lib.replaceChars ["."] ["/"] artifact.groupId) + artifact.artifactId + artifact.version + ]; + + mkFilename = artifact: with artifact; + "${artifactId}-${version}${lib.optionalString (classifier != "") "-${classifier}"}.${extension}"; + + mkArtifactUrl = base: artifact: + "${lib.removeSuffix "/" base}/${mkPath artifact}/${mkFilename artifact}"; + + fetchArtifact = artifact: + let + artifactPath = mkPath artifact; + artifactName = mkFilename artifact; + in stdenvNoCC.mkDerivation rec { + name = with artifact; lib.concatStrings [ + (lib.replaceChars ["."] ["_"] groupId) "-" + (lib.replaceChars ["."] ["_"] artifactId) "-" + version + (lib.optionalString (classifier != "") "-${classifier}") + "-" type + ]; + + src = fetchurl { + name = mkFilename artifact; + urls = map (url: mkArtifactUrl url artifact) repositories; + inherit (artifact) sha256; + }; + + phases = "installPhase fixupPhase"; + + installPhase = '' + mkdir -p $out/${artifactPath} + ln -s ${src} $out/${artifactPath}/${artifactName} + ''; + }; + +in +buildEnv { + inherit name; + paths = map fetchArtifact dependencies; +} diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..2d198e9 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,2 @@ +include(":app") +include(":plugin")