build-parameters icon indicating copy to clipboard operation
build-parameters copied to clipboard

Shareable parameter definitions

Open britter opened this issue 1 year ago • 5 comments

Context

It's common to have a set a parameters that are required in lots of projects. Examples from the GradleX organization are the CI flag as well as the signing key and passphrase. Currently there are two ways to make these available to all projects:

  1. Copy the build-parameter plugin definition into each project.
  2. Define a build-parameter plugin and publish it to the plugin portal.

Option 1) is not feasible because it violates DRY. Although parameters don't usually change very often, having to copy the configuration block around just feels wrong.

Option 2) is better. However it comes with the problem that project specific parameters can't be defined anymore. This is because the "local" generated plugin would clash with the published plugin. Even if different plugin ID is used, there will still be a clash with the name of the extension that is registered on the project.

One way of making option 2) work would be make the name of the extension registration configurable as well. In a build script it would look like this:

plugins {
    id("org.gradlex.base-parameters") // plugin published to plugin portal
    id("build-parameters") // local plugin generated by an included build
}

if (baseParameters.ci) { // extension name reconfigured in base-parameters plugin configuration
  // do something
}

if (buildParameters.foo) {
  // something else
}

While this would work, it feels a little bit awkward. Also there may be a case where users have several sets of parameters that they want to combine in a single project. This would require publishing multiple plugins and making sure non of the plugin IDs, extension registrations, and Java identifiers (packages, class names) clash.

Proposal

There's a third options that feels the most Gradle idiomatic way of sharing parameter definitons. That adding the ability to this plugin to publish an additional variant for the generated plugin. This variant would be a machine readable descriptions of the parameters, e.g. a JSON file. When defining parameters, users can define dependencies on published parameter definitions. This plugin will then resolve the published definition, parse the definition file, and merge the definitions back into the plugin being build. It would look something like this:

plugins {
    id("org.gradlex.build-parameters")
}

dependencies {
    // This plugin creates a configuration for consuming the published parameter definition variant 
    buildParameters("org.gradlex:base-parameters")
}

buildParameters {
    bool("foo") {
        default.set(true)
    }
}

And then:

plugins {
    id("build-parameters")
}

// ci was merged into the generated plugin by consuming base-parameters
if (buildParameters.ci) {
   // do something
}

britter avatar Apr 20 '23 08:04 britter