diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..22a0345 --- /dev/null +++ b/COPYING @@ -0,0 +1,20 @@ +Copyright © Tad Fisher and the gradle2nix contributors + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.org b/README.org index b45af3d..1a7b75e 100644 --- a/README.org +++ b/README.org @@ -1,12 +1,156 @@ -* gradle2nix +#+STARTUP: inlineimages -Application and Gradle plugin to generate Nix build scripts for Gradle-based -projects. +[[./assets/gradle2nix.png]] + +Generate [[https://nixos.org/nix/][Nix]] expressions which build [[https://gradle.org/][Gradle]]-based projects. + +** Why? + +Nix is an OS-agnostic package manager, a language-agnostic build +system, and a bespoke programming language. One of its unique features +is that it is purely functional; a "package" is a function which +accepts inputs (source code, configuration, etc) and produces an +output (binaries, a Java JAR, documentation, really anything). + +One benefit of a functional build system is [[https://reproducible-builds.org/][reproducibility]]. If you +specify your inputs precisely, and take care not to introduce +impurities—such as files retrieved over a network without tracking +their content—you will receive, byte-for-byte, the exact output as +someone else running the same function over the same inputs. + +Gradle is not a functional build system. Most Gradle-based projects +will produce highly variable outputs depending on a host of impure +inputs, including: + +- The JVM hosting the build +- The Gradle installation running the build +- Any usage of dynamic version constraints for dependencies +- SNAPSHOT dependencies +- Environment variables and command-line options +- Artifacts cached on the system hosting the build + +=gradle2nix= helps to solve this problem by leveraging Nix to control +the most common inputs to a Gradle build. When run on a project, it +will record all dependencies for both the build environment (including +=plugins= and =buildscript= blocks) and the project, and provide a Nix +expression to run the build given these dependencies. The build itself +is then run in a sandbox, where only content-tracked network requests +are allowed to fetch dependencies, and a local Maven repository is +created on-the-fly to host the dependency artifacts somewhere Gradle +can resolve them without a network. + +This tool is useful for both development and packaging. You can use +=gradle2nix= to: + +- Create isolated and reproducible development environments that work + anywhere Nix itself can run; +- Reduce or eliminate flakiness and maintenance headaches from CI/CD + pipelines +- Distribute a recipe which can reliably build a Gradle project in + repositories such as the [[https://nixos.org/nixpkgs/][Nix Package Collection]]. ** Installation +A [[./default.nix][Nix expression]] (generated by =gradle2nix= itself) is provided for +convenience. The following expression will fetch and build the latest +version of this package: + +#+begin_src nix +import (fetchTarball "https://github.com/tadfisher/gradle2nix/archive/master.tar.gz") {} +#+end_src + +If this expression is in, say, =gradle2nix.nix=, =gradle2nix= can be +built and placed in =.//result= with the following: + +#+begin_example +nix build -f gradle2nix.nix +#+end_example + +You can also use the following one-liners to build or install +=gradle2nix= in your user profile: + +#+begin_example +# Build and place in ./result/ +nix build -f "https://github.com/tadfisher/gradle2nix/archive/master.tar.gz" + +# Build and install in the user profile +nix-env -if "https://github.com/tadfisher/gradle2nix/archive/master.tar.gz" +#+end_example + +=gradle2nix= is not yet packaged in =nixpkgs= itself, but work is +[[https://github.com/NixOS/nixpkgs/pull/77422][in progress]]. ** Usage +#+begin_example +Usage: gradle2nix [OPTIONS] [PROJECT-DIR] + +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 + +Arguments: + PROJECT-DIR Path to the project root (default: .) +#+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 +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]]. + +*** Specifying the Gradle version + +By default, if the project has configured the Gradle wrapper, that +version will be detected and pinned; otherwise, the version of Gradle +installed on your system will be pinned. You can override this with +the =--gradle-version= argument, which also avoids the need to have +Gradle installed. + +#+begin_example +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. + +[[https://github.com/tadfisher/gradle2nix/issues/new][Create an issue]] + +Code contributions are also encouraged. Please review the test cases +in the [[./fixtures][fixtures]] directory and create a new one to reproduce any fixes +or test new features. See the [[./plugin/src/compatTest/kotlin/org/nixos/gradle2nix][existing compatibility tests]] for +examples of testing with these fixtures. ** License + +=gradle2nix= is licensed under the [[./COPYING][MIT License]]. diff --git a/assets/gradle2nix.png b/assets/gradle2nix.png new file mode 100644 index 0000000..a0d4efe Binary files /dev/null and b/assets/gradle2nix.png differ diff --git a/assets/gradle2nix.svg b/assets/gradle2nix.svg new file mode 100644 index 0000000..0569dea --- /dev/null +++ b/assets/gradle2nix.svg @@ -0,0 +1,680 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + gradle 2 nix + + +