On 19/12/2012, at 12:13 AM, Hans Dockter wrote: > > On Dec 18, 2012, at 2:09 AM, Adam Murdoch <[email protected]> wrote: > >> Hi, >> >> I've written up a rough spec for how we might improve our support for >> declarative and customised build runtimes. This covers things like improving >> the wrapper, injecting a set of custom plugins and configuration into a >> build, splitting up the Gradle distribution and so on. >> >> The spec is at: >> https://github.com/gradle/gradle/blob/master/design-docs/custom-build-runtimes.md > > Is the main reason to separate between the bootstrapped and the launcher to > make the bootstrapper minimal (e.g. make it VCS friendly) but than have a > less minimal launcher to reuse Gradle code?
Yes. It means we can start using core capabilities much earlier in the whole download and startup sequence, so that once the launcher has been downloaded we can, for example, start using the console integration and progress reporting stuff for the remaining stuff to download. We get multi-process safe caching with artefact reuse, or native credentials management, or whatever. But it also means that if the bootstrapper cannot download the launcher for some reason (say there's some kind of authentication that's not supported by java.net.URL), there's a relatively small ZIP (say 1 or 2 mb) that you can download manually and place somewhere for the bootstrapper to find. We could also put together a bin distribution that contains just the boostrapper and the launcher ZIP that you could install. The trade-off is that we need to find some way to share the stuff bundled in the launcher with the rest of the runtime. The spec goes with the option of expecting that the launcher and the Gradle runtime both come from the same Gradle version, to keep this relatively simple. The pluggable meta-data providers give us some options here, so that you might opt in to check in a larger, more complex provider for when you want some kind of dynamic resolution. > > I like the idea of a local metadata provider SPI very much. One positive > aspect of this for example is that I think current wrapper properties are a > bit over engineered to deal with some rare use cases. Delegating rare use > cases to a custom provider will make handling those much more flexible and > the default metadata simpler. > > Additionally we could also have a default build environment metadata which > can be modified via Gradle commands (either provided by the Launcher or > Gradle Runtime). > > - Define the default Gradle version of your machine via a Gradle command. > This version is used if no project specific metadata is provided. Just make > it easy for example to switch between Gradle runtime versions. > - Provide a command line switch to ignore project metadata and use the > default metadata (i.e. a build master wants to try the build with the default > version of Gradle). > - Provide a command line metadata provider, i.e. a way to describe the build > environment you want to run the build with from the command line. How is this different to the previous item? > - A sub aspect of this is to provide a way to enable/disable the daemon from > the command line. These are all good things. I'll add them to the spec. > > Just to make it explicit. Another use case this solves is the separation > between the Gradle runtime and custom configuration of the Gradle runtime > (i.e. Build Runtime). Right now you have to physically bundle your own build > runtime by taking a Gradle runtime, adding init scripts to the init.d > directory and packaging this as a zip. With the new mechanisms people > wouldn't need to repackage and it will be much easier to provide different > build runtimes to different teams/environments. Another thing this will > enable is to define a central Gradle version for an organization, not just > per project via the wrapper properties. Whether this is a good idea can be > argued and it depends (e.g. you no longer have the information in version > control that says which Gradle version should be used to build your project > at this point in time). Because we're using dependency management to express and resolve the build runtime, we can take advantage of whatever support we add for reproducibility. So, when we capture the environment that was used to build some artefacts, this will include information about the Java runtime, the Gradle runtime, and all of the plugins used by the build. When you ask Gradle to reproduce some artefacts, it can substitute in the right versions in the right places. But this goes beyond reproducibility. For example: * You can use the existing (and future) reporting and visualisation stuff to ask questions about the build runtime you're using, or about the build runtime that you're producing. * You will be able to do automated downstream checks for things that use your plugins or build runtime, just like you will be able to do this for a library you produce. * The should-use/must-use/will-work/should-work stuff (however that ends up looking like) can be used for the build runtime. So, we can make assertions about whether a given graph of runtimes + plugins + their dependencies will work together, or choose a combination that will. You might be able to ask Gradle to select a Java runtime and Gradle runtime that 'will-work' with the build runtime you're using. And, most importantly, the description of your entire build environment (Java version, Gradle runtime, plugins + their dependencies) is versioned just like everything else. -- Adam Murdoch Gradle Co-founder http://www.gradle.org VP of Engineering, Gradleware Inc. - Gradle Training, Support, Consulting http://www.gradleware.com
