From 43c4b71928694aa7c642a6f2cc22f06d6d2f7a51 Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Sun, 19 May 2024 13:56:09 -0700 Subject: [PATCH] Update CLI interface --- README.org | 71 ++++++++-------- app/build.gradle.kts | 15 ++-- .../main/kotlin/org/nixos/gradle2nix/Main.kt | 80 +++++++++---------- gradle.lock | 64 ++++++++------- gradle/libs.versions.toml | 3 +- 5 files changed, 119 insertions(+), 114 deletions(-) diff --git a/README.org b/README.org index a49c565..9803d1d 100644 --- a/README.org +++ b/README.org @@ -51,7 +51,7 @@ This tool is useful for both development and packaging. You can use ** Installation -A [[./default.nix][Nix expression]] (generated by =gradle2nix= itself) is provided for +A [[./gradle.nix][Nix expression]] (generated by =gradle2nix= itself) is provided for convenience. The following expression will fetch and build the latest version of this package: @@ -60,7 +60,7 @@ import (fetchTarball "https://github.com/tadfisher/gradle2nix/archive/master.tar #+end_src If this expression is in, say, =gradle2nix.nix=, =gradle2nix= can be -built and placed in =.//result= with the following: +built and placed in =./result= with the following: #+begin_example nix build -f gradle2nix.nix @@ -93,36 +93,49 @@ nix run github:tadfisher/gradle2nix -- --help ** Usage #+begin_example -Usage: gradle2nix [OPTIONS] [PROJECT-DIR] +Usage: gradle2nix [] []... Options: - -g, --gradle-version VERSION Use a specific Gradle version - -a, --gradle-args ARGS Extra arguments to pass to Gradle - -c, --configuration NAME Add a configuration to resolve (default: - all configurations) - -i, --include DIR Add an additional project to include - -p, --project PATH Only resolve these subproject paths, e.g. - ':', or ':sub:project' (default: all - projects) - -o, --out-dir DIR Path to write generated files (default: - PROJECT-DIR) - -e, --env FILENAME Prefix for environment files (.json and - .nix) (default: gradle-env) - -b, --build-src / -nb, --no-build-src - Include buildSrc project (default: true) - -q, --quiet Disable logging - -h, --help Show this message and exit + -t, --tasks= Gradle tasks to run + -p, --project= Path to the project root (default: Current directory) + -o, --out-dir= Path to write generated files (default: ) + -l, --lock-file= Name of the generated lock file (default: gradle.lock) + -n, --nix-file= Name of the generated Nix file (default: gradle.nix) + -g, --gradle-version= Use a specific Gradle version + -j, --gradle-jdk= JDK home directory to use for launching Gradle (default: JAVA_HOME) + --log=(debug|info|warn|error) Print messages with this priority or higher (default: error) + --dump-events Dump Gradle event logs to the output directory + --stacktrace Print a stack trace on error + -h, --help Show this message and exit Arguments: - PROJECT-DIR Path to the project root (default: .) + Extra arguments to pass to Gradle #+end_example Simply running =gradle2nix= in the root directory of a project should be enough for most projects. This will produce two files, by default -called =gradle-env.json= and =gradle-env.nix=, which contain the +called =gradle.lock= and =gradle.nix=, which contain the pinned dependencies for the project and a standard build expression which can be imported or called by other Nix expressions. An example -of such an expression can be found in this project's [[./default.nix][default.nix]]. +of such an expression can be found in this project's [[./gradle2nix.nix][gradle2nix.nix]]. + +*** For packagers + +If you're creating a Nix package for an existing Gradle project, you +can reduce the number of pinned dependencies by passing one or more +=--task= arguments. This will only pin the dependencies that were +resolved as part of the build, instead of the default behavior where +all possible dependencies are pinned. + +For example, if the package produces its build output via the +=:app:installDist= task, use the following: + +#+begin_example +gradle2nix -t :app:installDist +#+end_example + +/Note:/ This may be *required* if the build resolves configurations +at execution time. *** Specifying the Gradle version @@ -136,20 +149,6 @@ Gradle installed. gradle2nix -g 6.1 #+end_example -*** Multi-project builds - -If you want to resolve only a subset of projects in a [[https://docs.gradle.org/current/userguide/intro_multi_project_builds.html][multi-project -build]], add the =--project= option for each project. For example, in a -project where you only want to build the subprojects =:app= and -=:widget=: - -#+begin_example -gradle2nix -p :app -p :widget -#+end_example - -Any [[https://docs.gradle.org/current/userguide/declaring_dependencies.html#sub:project_dependencies][project dependencies]] will be also be included when pinning -dependency artifacts. - ** Contributing Bug reports and feature requests are encouraged. diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3140c14..896149e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,7 +13,6 @@ dependencies { implementation(libs.kotlinx.coroutines.core) implementation(libs.okio) implementation(libs.serialization.json) - implementation(libs.slf4j.api) runtimeOnly(libs.slf4j.simple) implementation(libs.xmlutil) @@ -30,7 +29,10 @@ dependencies { application { mainClass.set("org.nixos.gradle2nix.MainKt") applicationName = "gradle2nix" - applicationDefaultJvmArgs += "-Dorg.nixos.gradle2nix.share=@APP_HOME@/share" + applicationDefaultJvmArgs = listOf( + "-Dorg.nixos.gradle2nix.share=@APP_HOME@/share", + "-Dslf4j.internal.verbosity=ERROR" + ) applicationDistribution .from(configurations.named("share")) .into("share") @@ -58,13 +60,10 @@ tasks { startScripts { doLast { unixScript.writeText( - unixScript.readText() - .replace("@APP_HOME@", "\\\"\$APP_HOME\\\"") - .replace(Regex("DEFAULT_JVM_OPTS=\'(.*)\'")) { match -> - "DEFAULT_JVM_OPTS=${match.groupValues[1]}" - } + unixScript.readText().replace("@APP_HOME@", "'\$APP_HOME'") ) - windowsScript.writeText(windowsScript.readText().replace("@APP_HOME@", "%APP_HOME%")) + windowsScript.writeText( + windowsScript.readText().replace("@APP_HOME@", "%APP_HOME%")) } } diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt index c0074c0..af98723 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt @@ -6,6 +6,7 @@ import com.github.ajalt.clikt.output.MordantHelpFormatter import com.github.ajalt.clikt.parameters.arguments.argument import com.github.ajalt.clikt.parameters.arguments.multiple import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.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 @@ -50,6 +51,43 @@ enum class LogLevel { class Gradle2Nix : CliktCommand( name = "gradle2nix" ) { + private val tasks: List by option( + "--task", "-t", + metavar = "TASK", + help = "Gradle tasks to run" + ).multiple() + + private val projectDir: File by option( + "--project", "-p", + help = "Path to the project root") + .file() + .default(File("."), "Current directory") + .validate { 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.") + } + + private val outDir: File? by option( + "--out-dir", "-o", + metavar = "DIR", + help = "Path to write generated files") + .file(canBeFile = false, canBeDir = true) + .defaultLazy("") { projectDir } + + private val lockFile: String by option( + "--lock-file", "-l", + metavar = "FILENAME", + help = "Name of the generated lock file" + ).default("gradle.lock") + + private val nixFile: String by option( + "--nix-file", "-n", + metavar = "FILENAME", + help = "Name of the generated Nix file" + ).default("gradle.nix") + private val gradleVersion: String? by option( "--gradle-version", "-g", metavar = "VERSION", @@ -62,50 +100,12 @@ class Gradle2Nix : CliktCommand( help = "JDK home directory to use for launching Gradle (default: ${System.getProperty("java.home")})" ).file(canBeFile = false, canBeDir = true) - val outDir: File? by option( - "--out-dir", "-o", - metavar = "DIR", - help = "Path to write generated files (default: PROJECT-DIR)") - .file(canBeFile = false, canBeDir = true) - - val lockFile: String by option( - "--lock-file", "-l", - metavar = "FILENAME", - help = "Name of the generated lock file" - ).default("gradle.lock") - - val nixFile: String by option( - "--nix-file", "-n", - metavar = "FILENAME", - help = "Name of the generated Nix file" - ).default("gradle.nix") - private val logLevel: LogLevel by option( "--log", - metavar = "LEVEL", - help = "Print messages with priority of at least LEVEL") + help = "Print messages with this priority or higher") .enum() .default(LogLevel.error) - private val projectDir: File by option( - "--projectDir", "-d", - metavar = "PROJECT-DIR", - help = "Path to the project root (default: .)") - .file() - .default(File("."), "Current directory") - .validate { 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.") - } - - private val tasks: List by option( - "--tasks", "-t", - metavar = "TASKS", - help = "Gradle tasks to run" - ).multiple() - private val dumpEvents: Boolean by option( "--dump-events", help = "Dump Gradle event logs to the output directory", @@ -132,7 +132,7 @@ class Gradle2Nix : CliktCommand( val logger = Logger(logLevel = logLevel, stacktrace = stacktrace) val appHome = System.getProperty("org.nixos.gradle2nix.share")?.let(::File) - ?: error("could not locate the /share directory in the gradle2nix installation") + ?: error("could not locate the /share directory in the gradle2nix installation: ${System.getenv("APP_HOME")}") val gradleHome = System.getenv("GRADLE_USER_HOME")?.let(::File) ?: File("${System.getProperty("user.home")}/.gradle") val config = Config( diff --git a/gradle.lock b/gradle.lock index 0964060..721903c 100644 --- a/gradle.lock +++ b/gradle.lock @@ -52,6 +52,12 @@ } }, "com.github.ajalt.clikt:clikt:4.4.0": { + "clikt-4.4.0.jar": { + "urls": [ + "https://repo.maven.apache.org/maven2/com/github/ajalt/clikt/clikt/4.4.0/clikt-4.4.0.jar" + ], + "hash": "sha256-pGJRQhCAqew0Cm92KHhUIOuyx9Ccw7BVOZ+j+676doY=" + }, "clikt-4.4.0.module": { "urls": [ "https://repo.maven.apache.org/maven2/com/github/ajalt/clikt/clikt/4.4.0/clikt-4.4.0.module" @@ -86,6 +92,12 @@ } }, "com.github.ajalt.colormath:colormath:3.5.0": { + "colormath-3.5.0.jar": { + "urls": [ + "https://repo.maven.apache.org/maven2/com/github/ajalt/colormath/colormath/3.5.0/colormath-3.5.0.jar" + ], + "hash": "sha256-vSKbrzuv1VbRid5yRx2dF8KaofXTJEVgJwvvjmOiMZo=" + }, "colormath-3.5.0.module": { "urls": [ "https://repo.maven.apache.org/maven2/com/github/ajalt/colormath/colormath/3.5.0/colormath-3.5.0.module" @@ -120,6 +132,12 @@ } }, "com.github.ajalt.mordant:mordant:2.5.0": { + "mordant-2.5.0.jar": { + "urls": [ + "https://repo.maven.apache.org/maven2/com/github/ajalt/mordant/mordant/2.5.0/mordant-2.5.0.jar" + ], + "hash": "sha256-j80uWaxhZQy8d7paxqDaZlMD6xvVURejzZSpi+ir0xM=" + }, "mordant-2.5.0.module": { "urls": [ "https://repo.maven.apache.org/maven2/com/github/ajalt/mordant/mordant/2.5.0/mordant-2.5.0.module" @@ -3199,50 +3217,40 @@ "hash": "sha256-x+nvk73YqzYwMs5TgvzGTQAtbFicF1IzI2zSmOUaPBY=" } }, - "org.slf4j:slf4j-api:2.1.0-alpha1": { - "slf4j-api-2.1.0-alpha1.jar": { + "org.slf4j:slf4j-api:1.7.36": { + "slf4j-api-1.7.36.jar": { "urls": [ - "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.1.0-alpha1/slf4j-api-2.1.0-alpha1.jar" + "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar" ], - "hash": "sha256-mrf/pkYgK0mdBZlaPsgvMbzLelA0XBUU2MtC7IzOo1M=" + "hash": "sha256-0+9XXj5JeWeNwBvx3M5RAhSTtNEft/G+itmCh3wWocA=" }, - "slf4j-api-2.1.0-alpha1.pom": { + "slf4j-api-1.7.36.pom": { "urls": [ - "https://repo.gradle.org/gradle/libs-releases/org/slf4j/slf4j-api/2.1.0-alpha1/slf4j-api-2.1.0-alpha1.pom", - "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/2.1.0-alpha1/slf4j-api-2.1.0-alpha1.pom" + "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.pom" ], - "hash": "sha256-QirqW+u6gwWzxhT6Zo7SKePJYQkw7PQvhzOO4F4minU=" + "hash": "sha256-+wRqnCKUN5KLsRwtJ8i113PriiXmDL0lPZhSEN7cJoQ=" } }, - "org.slf4j:slf4j-bom:2.1.0-alpha1": { - "slf4j-bom-2.1.0-alpha1.pom": { + "org.slf4j:slf4j-parent:1.7.36": { + "slf4j-parent-1.7.36.pom": { "urls": [ - "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-bom/2.1.0-alpha1/slf4j-bom-2.1.0-alpha1.pom" + "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/1.7.36/slf4j-parent-1.7.36.pom" ], - "hash": "sha256-qOgTiZePRAcJJBuYPTHvp4cRO+EbgYwsa82e0wlv1IU=" + "hash": "sha256-uziNN/vN083mTDzt4hg4aTIY3EUfBAQMXfNgp47X6BI=" } }, - "org.slf4j:slf4j-parent:2.1.0-alpha1": { - "slf4j-parent-2.1.0-alpha1.pom": { + "org.slf4j:slf4j-simple:1.7.36": { + "slf4j-simple-1.7.36.jar": { "urls": [ - "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-parent/2.1.0-alpha1/slf4j-parent-2.1.0-alpha1.pom" + "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-simple/1.7.36/slf4j-simple-1.7.36.jar" ], - "hash": "sha256-zkc1sfnIId4Lkrjb5AsHHG6jIHMuWTVZxupt+WX4c48=" - } - }, - "org.slf4j:slf4j-simple:2.1.0-alpha1": { - "slf4j-simple-2.1.0-alpha1.jar": { - "urls": [ - "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-simple/2.1.0-alpha1/slf4j-simple-2.1.0-alpha1.jar" - ], - "hash": "sha256-AU/trHoyKI7W+PcqEAfn+zKuxb/tsnFGfkluCVNIL3U=" + "hash": "sha256-Lzm+2UPWJN+o9BAtBXEoOhCHC2qjbxl6ilBvFHAQwQ8=" }, - "slf4j-simple-2.1.0-alpha1.pom": { + "slf4j-simple-1.7.36.pom": { "urls": [ - "https://repo.gradle.org/gradle/libs-releases/org/slf4j/slf4j-simple/2.1.0-alpha1/slf4j-simple-2.1.0-alpha1.pom", - "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-simple/2.1.0-alpha1/slf4j-simple-2.1.0-alpha1.pom" + "https://repo.maven.apache.org/maven2/org/slf4j/slf4j-simple/1.7.36/slf4j-simple-1.7.36.pom" ], - "hash": "sha256-RgReG+EA94JLUITh83eCxoBJcEeKRXPejEmgfQOpSGM=" + "hash": "sha256-xWuAoKa+oqBGPnDQiSrjOKnlB+SGdnpSBFNAmBIFjRs=" } }, "org.sonatype.oss:oss-parent:9": { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e390556..5a048ce 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,8 +15,7 @@ ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" } ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" } okio = "com.squareup.okio:okio:3.9.0" serialization-json = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3" -slf4j-api = "org.slf4j:slf4j-api:+" -slf4j-simple = "org.slf4j:slf4j-simple:+" +slf4j-simple = "org.slf4j:slf4j-simple:1.7.36" xmlutil = "io.github.pdvrieze.xmlutil:serialization-jvm:+" [plugins]