This flake provides a way to build gradle projects in sandboxed nix environments.
No configuration should be needed, just import the flake and use the provided outputs.
Yes there are still IFDs left in the code. If you have any idea how to get rid of them, please let me know or open a PR.
A sample project that uses this flake can be found here.
(The following descriptions assume you use a pretty default gradle project structure. If you have a more complex setup, you might need to adjust accordingly.)
To start using this flake, you need to generate a gradle/verification-metadata.xml
file in your project and check it into your VCS.
This file can be generated by running the following command in your project:
gradle -M sha256 build
This will generate a gradle/verification-metadata.xml
file that contains the sha256 hashes of all the dependencies used in the build.
Note: I have not tried it with more custom verification-metadata.xml
files, so I cannot guarantee that it will work with those. If you run into any such problem please open an issue.
There is a gradle-init
output that can be used to create a gradle init script.
This is a more straightforward way to use the flake, as it does not require any configuration in the actual project.
gradle-init-script =
(import gradle-dot-nix {
inherit pkgs;
gradle-verification-metadata-file = ./gradle/verification-metadata.xml;
}).gradle-init;
This init script can be used like this:
gradle -I ${gradle-init-script} build
There should be no need to modify any files in the project to use this.
The generated init script will automatically set the maven repository for the project and remove repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
from the settings.
If you want to have a sandbox friedly maven repository, you can use the mvn-repo
output.
This is useful if you already use a version of such a maven repo in your project.
maven-repo =
(import gradle-dot-nix {
inherit pkgs;
gradle-verification-metadata-file = ./gradle/verification-metadata.xml;
}).mvn-repo;
This maven repo can be used in your build.gradle
file like this:
repositories {
if(project.hasProperty("nixMavenRepo")) {
maven { url = nixMavenRepo }
}
}
or in .kts files like this:
repositories {
val nixMavenRepo: String? by settings
if (nixMavenRepo != null) {
maven { url = uri(nixMavenRepo!!) }
}
}
And then you can build your project with the following command:
gradle -PnixMavenRepo=${maven-repo} build
If you don't want to use the standard repositories gradle uses, you can set the optional public-maven-repos
input to a JSON array that contains the repositories you want to query.
gradle-dot-nix-instance =
import gradle-dot-nix {
inherit pkgs;
gradle-verification-metadata-file = ./gradle/verification-metadata.xml;
public-maven-repos = ''
[
"https://dl.google.com/dl/android/maven2",
"https://repo.maven.apache.org/maven2",
"https://plugins.gradle.org/m2",
"https://maven.google.com"
]
'';
};
If some your dependencies are already available locally, you can set the optional local-maven-repos
input to an array of store paths.
This is especially useful for react-native apps, where some maven repos are available through NPM.
gradle-dot-nix-instance =
import gradle-dot-nix {
inherit pkgs;
gradle-verification-metadata-file = ./gradle/verification-metadata.xml;
local-maven-repos = [
"${nodeModules}/node_modules/jsc-android/dist"
];
};
Implementing proper support for private repositories is a bit more complex, as the credentials should not be leaked into the nix store.
Thanks to @eeedean, there is now support for .netrc files.
The usage of those is not quite trivial, but it works without leaking credentials into the store, the credentials "only" need to be readable by any nixbld user. This is less of an issue than it sounds, since the flag that allows access to the file is only available to trusted-users
.
Add the following to your nix.conf:
experimental-features = nix-command flakes configurable-impure-env
trusted-users = YOUR_USER
impure-env = NETRC=/path/to/netrc/that/nixbld/can/access
and then you can start you nix build using
nix build --extra-sandbox-paths /path/to/netrc/that/nixbld/can/access
You could also still:
- run a custom fetcher that fetches the specific required repos beforehand and makes them available via Custom Local Repositories
- run a proxy server that internally authenticates against the specific protected API and to the localhost provides a passwordless API, which in turn is set via Custom Public Repositories
The project currently uses python3 to parse the gradle/verification-metadata.xml
file and to fetch the dependencies from the maven repository.
This is done to simplify the nix expressions and to avoid having to deal with the xml in nix.
It also speeds up the development process, as the python scripts are easier to write and debug than nix expressions.
The python scripts are not very complex and should be easy to understand nixify if you want to do that. I don't have any motivation to do that myself, but I would be happy to accept a PR that does that.
A starting point for that would be to convert the python scripts to bash scripts, as they are self-contained and don't do too much magic.
There are several IFDs that (need to?) exist in the code.
- The
gradle/verification-metadata.xml
file gets read to determine the further derivations. There shouldn't be a way around this, as the dependencies are variable and the derivations thus need to be determined at runtime. nixpkgs.symlinkJoin
collects multiple store paths into one. Store paths are not known before evaluation and need to be determined at runtime.
- Tad Fisher for providing a gist that cleared up some questions I had (and some code I stole).
- Brian McGee for providing a blog post that gave me the idea to use a gradle init script.
- Martin Schwaighofer for teaching me the basics of nix and for providing valuable feedback to get the project working.
This work has been carried out within the scope of Digidow, the Christian Doppler Laboratory for Private Digital Authentication in the Physical World and has partially been supported by the LIT Secure and Correct Systems Lab. We gratefully acknowledge financial support by the Austrian Federal Ministry of Labour and Economy, the National Foundation for Research, Technology and Development, the Christian Doppler Research Association, 3 Banken IT GmbH, ekey biometric systems GmbH, Kepler Universitätsklinikum GmbH, NXP Semiconductors Austria GmbH & Co KG, Österreichische Staatsdruckerei GmbH, and the State of Upper Austria.
This flake is licensed under the MIT license. See the LICENSE file for details.