Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shareable parameter definitions #114

Open
britter opened this issue Apr 20, 2023 · 5 comments
Open

Shareable parameter definitions #114

britter opened this issue Apr 20, 2023 · 5 comments
Labels
a:enhancement New feature or request

Comments

@britter
Copy link
Member

britter commented Apr 20, 2023

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
}
@jjohannes
Copy link
Member

I Like the proposals. Sounds similar to how version catalogs a re shared and reused/combined.

@yogurtearl
Copy link

What if I want to consume multiple different sets of base parameters, and they all contain param with the same name?

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

My preference would be to have it all namespaced to keep the parameters separately even they happen to have the same name.

if(buildParameters.baseParameters1.ci) { ... }
if(buildParameters.baseParameters2.ci) { ... }

@britter
Copy link
Member Author

britter commented Nov 14, 2023

@yogurtearl could you please give a more concrete example? What kind of parameters do you have in each of the base plugins. Which parameters are overlapping? Do the overlapping parameters have different parameter definitions?

@yogurtearl
Copy link

I want to use build-parameters in my various different plugins and not have to worry about conflicts with other plugins that also use build-parameters to manage their params.

I.e. I might build to plugins upload-stuff, download-stuff, both in turn use build-parameters to control each of them.

Maybe they both have a url param, and each plugin is completely independent.

Want to be able to use both in a build like this

if(buildParameters.uploadStuff.url.isNotEmptyOnNull()) { ... }
if(buildParameters.downloadStuff.url.isNotEmptyOnNull()) { ... }

@britter
Copy link
Member Author

britter commented Nov 17, 2023

Thank you for providing more feedback. We will take this into consideration once we work on implementing this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a:enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants