tadfisher / gradle2nix

Generate Nix expressions which build Gradle-based projects.
MIT License
114 stars 57 forks source link

Leverage Gradle Lockfile #38

Open zsiegel opened 3 years ago

zsiegel commented 3 years ago

Hi there

I was reading about this project as I started to explore reproducible gradle builds.

I read the readme and understand (I think) how this package intends to function.

I am curious if enforcing the use of Gradle lockfiles would eliminate the need for the network based dependency tracking?

I was planning to use the single lockfile approach to ensure my gradle builds are reproducible before even attempting to integrate it into a Nix pkg but was curious if you have any thoughts on this?

Thank you for this project I will dig in further!

tadfisher commented 3 years ago

The problem this project solves is that Gradle deals only in dependencies, when what we want is artifacts.

Dependencies are generally Maven coordinates (group, module, version, and optionally classifier and type), and artifacts are the actual files needed to build the project or resolve further dependencies (Java JARs, Maven POMs, Ivy XML descriptors, and/or Gradle module metadata files).

Gradle locks dependency information, sure, but the process of resolving dependencies into artifacts is terribly complex. Moreover, resolution is impossible to reproduce in Nix, because a project can modify the resolution process with arbitrary code!

So while lockfiles are useful for other build systems such as Cargo or Yarn, they're not much use to us as they don't map 1:1 with the actual JARs you end up with on Gradle's classpath. So we need to coax Gradle itself to give us the artifact set after it has been resolved, and try to trace those artifacts back to URLs along with their hashes so we can later create a reproducible Maven/Ivy repository that Gradle can use to build the project in a Nix sandbox.

But now that I look into it, recent Gradle versions support dependency verification, which we may be able to abuse to produce something analogous to a lockfile for artifacts. I'll report back on this.

zsiegel commented 3 years ago

The distinction between a list of dependencies and a list of verified artifacts is a very interesting distinction I had not thought of!

Thank you for the explanation - Nix and its ecosystem are bending my brain a little bit but this makes a ton of sense.

Your build.gradle file may only list a small subset of dependencies - which then get transformed by Gradle in mysterious ways into a different list of dependencies that need to be verified and known before actually building an artifact.

tadfisher commented 3 years ago

Dependency verification metadata is almost what we want. However, the XML produced contains filenames of each artifact in the cache, which can be different from the filename in the external repository. I could still possibly use this information but it will require using private Gradle APIs to obtain the url field corresponding to the file in the Gradle metadata.