Giter Club home page Giter Club logo

build-parameters's People

Contributors

britter avatar dependabot[bot] avatar jjohannes avatar simonmarquis avatar timyates avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

build-parameters's Issues

Generated Enums: toString() should return the original (non-escaped) value

Generate an override to toString() that does the inverse of what parse() is doning now.

The use case is that I want to use the value in the build logic (e.g. to pass it to another tool like git) and not just check the enum values in a if/switch statement. I still want to use enumeration instead of string as parameter type to limit the set of allowed values.

Allow defining parameters without configuration action

Currently the configuration closure that can be passed to the various parameter definition methods is mandatory. So right now I need to write, e.g.:

buildParameters {
  string("myString") { }
}

It would be nice if the closure could be omitted if I don't want to add any additional configuration:

buildParameters {
  string("myString")
}

Validate plugin on each commit

Version 1.2.0 of plugin-publish plugin added the --validate-only flag which can be used to check whether a plugin will pass validity checks from the plugin portal. We should update the publish conventions plugin to use 1.2.0 of plugin-publish and then add ./gradlew publishPlugins --validate-only to the CI build.

Provide a way to figure out whether a parameter was used

Given I run some build like ./gradlew build -Pfoo=bar it would be great to have a way to figure out whether buildParameters.foo was used in this build invocation. In the first step, the plugin could log a warning pointing out that the parameter was not used, although it was passed.

Give good error if an optional parameter is not set

An optional build parameter is of typ Provider<> and returns a 'standard' Gradle provider implementation. If Gradle calls .get() on it when the value is set, you always get the following (very useless) error:

> Cannot query the value of this provider because it has no value available.

In the case if the Build Parameters plugin, we have all the information which property is not set (property name and env variable name). So we should be able to construct providers that automatically give a better error.

Example

Would be nice to write a task like this and automatically get a good error if CATALINA_HOME is not set:

tasks.register<Copy>("deployWebApp") {
    from(tasks.war) { into("webapps") }
    into(buildParameters.catalina.home)
}

Right now I have to add a custom error through .orElse(provider { ... which is a bit ugly and verbose.

tasks.register<Copy>("deployWebApp") {
    from(tasks.war) { into("webapps") }
    into(buildParameters.catalina.home.orElse(provider {
        throw RuntimeException("CATALINA_HOME environment variable not set")
    }))
}

Boolean Parameters: Map empty value to 'true'

If I specify a boolean parameter, e.g. debugMode, like this -PdebugMode, which is quite common practice, it should map to true.

Right now, this maps to false and you have to do -PdebugMode=true instead.

In addition, the build could fail for other values which are not clear but currently all map to false. We could implement the following mapping:

  • "" (empty value) -> true
  • "true" -> true
  • "false" -> false
  • (everything else) -> FAIL

Reading from .properties files?

Any chance of adding support for reading parameter values from local.properties or gradle.properties files too?

Not sure how idiomatic it is, but I've seen a few projects that use those areas to store things that I would consider to be build parameters :)

Exclude parameters in the `org.gradle` namespace from parameter validation

There are legitimate use cases for passing an org.gradle... parameter directly via the command line. An example for this is passing the configuration of toolchain discovery and download on CI (see https://github.com/junit-team/junit5/actions/runs/4285959661/jobs/7464897624#step:5:234). If I want to enable validation, I would have to model every single build parameter in that namespace just to make my build work. Since that's quite tedious, the plugin should ignore parameters in the org.gradle namespace when validating the command line.

Use toUpperCase(Locale.ROOT) to prevent locale-sensitive property accessors

See

return str.substring(0, 1).toUpperCase() + str.substring(1);
}
static String screamingSnakeCase(String str) {
return str.toUpperCase().replace(".", "_");

It makes obscure failures like

build-logic.test-junit5.gradle.kts: (24, 25): Cannot access 'includeTestTags': it is private in 'BuildParametersExtension'

The reason is that with tr_TR locale, the getter for includeTestTags becomes getİncludeTestTags (note İ with dot), so the code that calls getIncludeTestTags can't really compile.

In practice, it means that build parameters starting with i can't work in tr_TR locale with the current versions of build-parameters plugin.

I suggest using .toUpperCase(Locale.ROOT) instead.

Support defining parameters per-subproject

The current usage recommendation of this plugins shows all build parameters defined globally for the entire project.

We typically operate with a larger root project which multiple sub-projects. Each of those sub-projects may have parameters that are distinct to just that project.

Ideally we would like to apply the plugin to a sub-project, define the build parameters for that project, and reference from within the build file the parameters are defined in.

Is it possible to use this plugin to define build parameters per sub-project?

Cross version testing

We currently only test against the Gradle version that's running the build. We should extend our testing to cover more Gradle versions, also to explore what the minimal Gradle version is that we support.

fromEnvironment() should set environmentVariableName to id.toEnvironmentVariableName

For some reason when the fromEnvironment() is called we set the environmentVariableName property to an empty string. Later on during code generation we check whether this property has the value empty string and then call id.toEnvironmentVariableName. We should simplify this buy setting id.toEnvironmentVariableName as the value in fromEnvironment().

Enum Build Parameters: Support values that are not valid Java names

Automatically detect this and convert them to a name that is supported in the generated code:

  • Names that contain -
    • convert - to _
    • example my-value -> my_value
  • Names that are Java keywords
    • prepend a _ (?)
    • for example int -> _int

Use case: You may have existing parameters already. Values are then often dictated by existing systems/setups in a company and you can't pick them freely (for example branch names in a git-flow like process). It would be nice if the plugin could still support such parameters as Enums. The current solution is to use a string(...) parameter instead.

Dependent properties

It would be nice if we could configure one property based on the value of another. For instance, in an android project, we might want to alter the way a build works if it's ran from within android studio. Android studio sets android.injected.invoked.from.ide=true but we might want to map that to a more generic flag that's used from the command line called fastBuild (for example).

So, in the setup for fastBuild we might have something like this where we use something that results in a Boolean:

    bool("fastBuild") {
        description.set("Skips production logic resulting in much faster builds.")
        defaultValue.from("android.injected.invoked.from.ide" || anotherProperty)
    }

This would let us pull the default value from another variable, rather than hard coding it. I do see that we could pass in a Provider<Boolean> as the default value - could that be used to achieve this logic?

Another option could be something like this, but it feels really messy (pseudocode..). This also might just be checking to see if we have a property with the path, rather than what it's value is - it doesn't seem like you can do a "lazy" lookup and get a value.

defaultValue.set(!buildParameters.parameters.get().none { it -> it.propertyPath == "android.injected.invoked.from.ide" })

Think about what to do with ./samples

In the beginning we used the ./samples build to quickly iterate on plugin features and to have an example on how to use the plugin. Later on we introduced exemplar to check samples used in the asciidoc documentation. We should think about what to do with the ./samples build.

Use version catalog for dependencies

Dependatbot added support for automatically updating dependency versions declared in Gradle version catalogs. If we define dependencies and plugin versions using the catalog, we will get automatic dependency updates from Dependabot.

Problems with configuration caching caused by build-parameters plugin are fixed

When building this project I frequently see the following log message:

❯ ./gradlew check
Configuration cache is an incubating feature.
Calculating task graph as configuration cache cannot be reused because an input to task ':plugins:build-parameters:jar' has changed.

What this means is that due to the application of the released build-parameters plugin to this project, the configuration cache can not be reused sometimes. It looks like the plugin we're building produces unstable outputs. Me first guess is that we're using collections that produce unstable outputs somewhere, e.g a HashMap.

Parameter validation fails during IDEA sync

When running an IDEA sync using plugin release 1.4, the sync fails (see stacktrace below). One way to fix this is to look into the system properties and look for idea.version to detect that the build was started from an IDEA sync. This is how the common-custom-user-data-gradle-plugin detects this as well.

An exception occurred applying plugin request [id: 'build-parameters']
> Failed to apply plugin 'build-parameters'.
   > Unknown build parameter: android.injected.build.model.only.advanced

* Try:
> Run with --info or --debug option to get more log output.

* Exception is:
org.gradle.api.plugins.InvalidPluginException: An exception occurred applying plugin request [id: 'build-parameters']
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.exceptionOccurred(DefaultPluginRequestApplicator.java:222)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:204)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyLegacyPlugin(DefaultPluginRequestApplicator.java:157)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.access$300(DefaultPluginRequestApplicator.java:60)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator$1$1.lambda$addLegacy$0(DefaultPluginRequestApplicator.java:113)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyPlugins$0(DefaultPluginRequestApplicator.java:142)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugins(DefaultPluginRequestApplicator.java:142)
	at org.gradle.kotlin.dsl.provider.PluginRequestsHandler.handle(PluginRequestsHandler.kt:48)
	at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator$InterpreterHost.applyPluginsTo(KotlinScriptEvaluator.kt:202)
	at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.applyPluginsTo(Interpreter.kt:405)
	at Program.execute(Unknown Source)
	at org.gradle.kotlin.dsl.execution.Interpreter$ProgramHost.eval(Interpreter.kt:540)
	at org.gradle.kotlin.dsl.execution.Interpreter.eval(Interpreter.kt:189)
	at org.gradle.kotlin.dsl.provider.StandardKotlinScriptEvaluator.evaluate(KotlinScriptEvaluator.kt:118)
	at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:51)
	at org.gradle.kotlin.dsl.provider.KotlinScriptPluginFactory$create$1.invoke(KotlinScriptPluginFactory.kt:48)
	at org.gradle.kotlin.dsl.provider.KotlinScriptPlugin.apply(KotlinScriptPlugin.kt:34)
	at org.gradle.configuration.BuildOperationScriptPlugin$1.run(BuildOperationScriptPlugin.java:65)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
	at org.gradle.configuration.BuildOperationScriptPlugin.lambda$apply$0(BuildOperationScriptPlugin.java:62)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:44)
	at org.gradle.configuration.BuildOperationScriptPlugin.apply(BuildOperationScriptPlugin.java:62)
	at org.gradle.initialization.ScriptEvaluatingSettingsProcessor.applySettingsScript(ScriptEvaluatingSettingsProcessor.java:75)
	at org.gradle.initialization.ScriptEvaluatingSettingsProcessor.process(ScriptEvaluatingSettingsProcessor.java:68)
	at org.gradle.initialization.SettingsEvaluatedCallbackFiringSettingsProcessor.process(SettingsEvaluatedCallbackFiringSettingsProcessor.java:34)
	at org.gradle.initialization.RootBuildCacheControllerSettingsProcessor.process(RootBuildCacheControllerSettingsProcessor.java:46)
	at org.gradle.initialization.BuildOperationSettingsProcessor$2.call(BuildOperationSettingsProcessor.java:49)
	at org.gradle.initialization.BuildOperationSettingsProcessor$2.call(BuildOperationSettingsProcessor.java:46)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.initialization.BuildOperationSettingsProcessor.process(BuildOperationSettingsProcessor.java:46)
	at org.gradle.initialization.DefaultSettingsLoader.findSettingsAndLoadIfAppropriate(DefaultSettingsLoader.java:140)
	at org.gradle.initialization.DefaultSettingsLoader.findAndLoadSettings(DefaultSettingsLoader.java:62)
	at org.gradle.initialization.SettingsAttachingSettingsLoader.findAndLoadSettings(SettingsAttachingSettingsLoader.java:33)
	at org.gradle.internal.composite.CommandLineIncludedBuildSettingsLoader.findAndLoadSettings(CommandLineIncludedBuildSettingsLoader.java:35)
	at org.gradle.internal.composite.ChildBuildRegisteringSettingsLoader.findAndLoadSettings(ChildBuildRegisteringSettingsLoader.java:44)
	at org.gradle.internal.composite.CompositeBuildSettingsLoader.findAndLoadSettings(CompositeBuildSettingsLoader.java:35)
	at org.gradle.initialization.InitScriptHandlingSettingsLoader.findAndLoadSettings(InitScriptHandlingSettingsLoader.java:33)
	at org.gradle.api.internal.initialization.CacheConfigurationsHandlingSettingsLoader.findAndLoadSettings(CacheConfigurationsHandlingSettingsLoader.java:36)
	at org.gradle.initialization.GradlePropertiesHandlingSettingsLoader.findAndLoadSettings(GradlePropertiesHandlingSettingsLoader.java:38)
	at org.gradle.initialization.DefaultSettingsPreparer.prepareSettings(DefaultSettingsPreparer.java:31)
	at org.gradle.initialization.BuildOperationFiringSettingsPreparer$LoadBuild.doLoadBuild(BuildOperationFiringSettingsPreparer.java:71)
	at org.gradle.initialization.BuildOperationFiringSettingsPreparer$LoadBuild.run(BuildOperationFiringSettingsPreparer.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
	at org.gradle.initialization.BuildOperationFiringSettingsPreparer.prepareSettings(BuildOperationFiringSettingsPreparer.java:54)
	at org.gradle.initialization.VintageBuildModelController.lambda$prepareSettings$1(VintageBuildModelController.java:80)
	at org.gradle.internal.model.StateTransitionController.lambda$doTransition$13(StateTransitionController.java:247)
	at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:258)
	at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:246)
	at org.gradle.internal.model.StateTransitionController.lambda$transitionIfNotPreviously$11(StateTransitionController.java:221)
	at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:34)
	at org.gradle.internal.model.StateTransitionController.transitionIfNotPreviously(StateTransitionController.java:217)
	at org.gradle.initialization.VintageBuildModelController.prepareSettings(VintageBuildModelController.java:80)
	at org.gradle.initialization.VintageBuildModelController.getLoadedSettings(VintageBuildModelController.java:57)
	at org.gradle.internal.model.StateTransitionController.lambda$notInState$4(StateTransitionController.java:154)
	at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
	at org.gradle.internal.model.StateTransitionController.notInState(StateTransitionController.java:150)
	at org.gradle.internal.build.DefaultBuildLifecycleController.loadSettings(DefaultBuildLifecycleController.java:101)
	at org.gradle.internal.build.AbstractBuildState.ensureProjectsLoaded(AbstractBuildState.java:109)
	at org.gradle.plugins.ide.internal.tooling.GradleBuildBuilder.create(GradleBuildBuilder.java:58)
	at org.gradle.plugins.ide.internal.tooling.GradleBuildBuilder.create(GradleBuildBuilder.java:38)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildScopedBuilder.build(DefaultToolingModelBuilderRegistry.java:206)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingBuilder$1.call(DefaultToolingModelBuilderRegistry.java:337)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.tooling.provider.model.internal.DefaultToolingModelBuilderRegistry$BuildOperationWrappingBuilder.build(DefaultToolingModelBuilderRegistry.java:334)
	at org.gradle.internal.build.DefaultBuildToolingModelController$AbstractToolingScope.getModel(DefaultBuildToolingModelController.java:82)
	at org.gradle.tooling.internal.provider.runner.DefaultBuildController.getModel(DefaultBuildController.java:106)
	at org.gradle.tooling.internal.consumer.connection.ParameterAwareBuildControllerAdapter.getModel(ParameterAwareBuildControllerAdapter.java:39)
	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getModel(UnparameterizedBuildController.java:113)
	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getModel(NestedActionAwareBuildControllerAdapter.java:31)
	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getModel(UnparameterizedBuildController.java:76)
	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getModel(NestedActionAwareBuildControllerAdapter.java:31)
	at org.gradle.tooling.internal.consumer.connection.UnparameterizedBuildController.getBuildModel(UnparameterizedBuildController.java:71)
	at org.gradle.tooling.internal.consumer.connection.NestedActionAwareBuildControllerAdapter.getBuildModel(NestedActionAwareBuildControllerAdapter.java:31)
	at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:120)
	at org.jetbrains.plugins.gradle.model.ProjectImportAction.execute(ProjectImportAction.java:42)
	at org.gradle.tooling.internal.consumer.connection.InternalBuildActionAdapter.execute(InternalBuildActionAdapter.java:64)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.runAction(AbstractClientProvidedBuildActionRunner.java:131)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner$ActionAdapter.beforeTasks(AbstractClientProvidedBuildActionRunner.java:99)
	at org.gradle.internal.buildtree.DefaultBuildTreeModelCreator.beforeTasks(DefaultBuildTreeModelCreator.java:52)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$fromBuildModel$2(DefaultBuildTreeLifecycleController.java:74)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.lambda$runBuild$4(DefaultBuildTreeLifecycleController.java:98)
	at org.gradle.internal.model.StateTransitionController.lambda$transition$6(StateTransitionController.java:177)
	at org.gradle.internal.model.StateTransitionController.doTransition(StateTransitionController.java:258)
	at org.gradle.internal.model.StateTransitionController.lambda$transition$7(StateTransitionController.java:177)
	at org.gradle.internal.work.DefaultSynchronizer.withLock(DefaultSynchronizer.java:44)
	at org.gradle.internal.model.StateTransitionController.transition(StateTransitionController.java:177)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.runBuild(DefaultBuildTreeLifecycleController.java:95)
	at org.gradle.internal.buildtree.DefaultBuildTreeLifecycleController.fromBuildModel(DefaultBuildTreeLifecycleController.java:73)
	at org.gradle.tooling.internal.provider.runner.AbstractClientProvidedBuildActionRunner.runClientAction(AbstractClientProvidedBuildActionRunner.java:43)
	at org.gradle.tooling.internal.provider.runner.ClientProvidedPhasedActionRunner.run(ClientProvidedPhasedActionRunner.java:53)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.internal.buildtree.ProblemReportingBuildActionRunner.run(ProblemReportingBuildActionRunner.java:49)
	at org.gradle.launcher.exec.BuildOutcomeReportingBuildActionRunner.run(BuildOutcomeReportingBuildActionRunner.java:65)
	at org.gradle.tooling.internal.provider.FileSystemWatchingBuildActionRunner.run(FileSystemWatchingBuildActionRunner.java:140)
	at org.gradle.launcher.exec.BuildCompletionNotifyingBuildActionRunner.run(BuildCompletionNotifyingBuildActionRunner.java:41)
	at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.lambda$execute$0(RootBuildLifecycleBuildActionExecutor.java:40)
	at org.gradle.composite.internal.DefaultRootBuildState.run(DefaultRootBuildState.java:122)
	at org.gradle.launcher.exec.RootBuildLifecycleBuildActionExecutor.execute(RootBuildLifecycleBuildActionExecutor.java:40)
	at org.gradle.internal.buildtree.DefaultBuildTreeContext.execute(DefaultBuildTreeContext.java:40)
	at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.lambda$execute$0(BuildTreeLifecycleBuildActionExecutor.java:65)
	at org.gradle.internal.buildtree.BuildTreeState.run(BuildTreeState.java:53)
	at org.gradle.launcher.exec.BuildTreeLifecycleBuildActionExecutor.execute(BuildTreeLifecycleBuildActionExecutor.java:65)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:61)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor$3.call(RunAsBuildOperationBuildActionExecutor.java:57)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:199)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionExecutor.execute(RunAsBuildOperationBuildActionExecutor.java:57)
	at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.lambda$execute$0(RunAsWorkerThreadBuildActionExecutor.java:36)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:249)
	at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:109)
	at org.gradle.launcher.exec.RunAsWorkerThreadBuildActionExecutor.execute(RunAsWorkerThreadBuildActionExecutor.java:36)
	at org.gradle.tooling.internal.provider.continuous.ContinuousBuildActionExecutor.execute(ContinuousBuildActionExecutor.java:110)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionExecutor.execute(SubscribableBuildActionExecutor.java:64)
	at org.gradle.internal.session.DefaultBuildSessionContext.execute(DefaultBuildSessionContext.java:46)
	at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:100)
	at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter$ActionImpl.apply(BuildSessionLifecycleBuildActionExecuter.java:88)
	at org.gradle.internal.session.BuildSessionState.run(BuildSessionState.java:69)
	at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:62)
	at org.gradle.tooling.internal.provider.BuildSessionLifecycleBuildActionExecuter.execute(BuildSessionLifecycleBuildActionExecuter.java:41)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:63)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:31)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:50)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:38)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:47)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:31)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:65)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:39)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:29)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:35)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:78)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.create(ForwardClientInput.java:75)
	at org.gradle.util.internal.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:75)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:64)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:63)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:84)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:104)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:52)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:49)
Caused by: org.gradle.api.internal.plugins.PluginApplicationException: Failed to apply plugin 'build-parameters'.
	at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:173)
	at org.gradle.api.internal.plugins.DefaultPluginManager.apply(DefaultPluginManager.java:146)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.lambda$applyLegacyPlugin$2(DefaultPluginRequestApplicator.java:159)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.applyPlugin(DefaultPluginRequestApplicator.java:199)
	... 183 more
Caused by: java.lang.RuntimeException: Unknown build parameter: android.injected.build.model.only.advanced
	at buildparameters.GeneratedBuildParametersPlugin.apply(GeneratedBuildParametersPlugin.java:22)
	at buildparameters.GeneratedBuildParametersPlugin.apply(GeneratedBuildParametersPlugin.java:11)
	at org.gradle.api.internal.plugins.ImperativeOnlyPluginTarget.applyImperative(ImperativeOnlyPluginTarget.java:43)
	at org.gradle.api.internal.plugins.DefaultPluginManager.addPlugin(DefaultPluginManager.java:187)
	at org.gradle.api.internal.plugins.DefaultPluginManager.access$100(DefaultPluginManager.java:52)
	at org.gradle.api.internal.plugins.DefaultPluginManager$AddPluginBuildOperation.run(DefaultPluginManager.java:282)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:29)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$1.execute(DefaultBuildOperationRunner.java:26)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
	at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
	at org.gradle.internal.operations.DefaultBuildOperationRunner.run(DefaultBuildOperationRunner.java:47)
	at org.gradle.internal.operations.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:68)
	at org.gradle.api.internal.plugins.DefaultPluginManager.lambda$doApply$0(DefaultPluginManager.java:167)
	at org.gradle.configuration.internal.DefaultUserCodeApplicationContext.apply(DefaultUserCodeApplicationContext.java:44)
	at org.gradle.api.internal.plugins.DefaultPluginManager.doApply(DefaultPluginManager.java:166)
	... 186 more

One way to fix this is to look into the system properties and look for idea.version to detect that the build was started from an IDEA sync.

Add more verification

The plugin should verify that

  • group and parameter names are all valid java identifiers (starting with a letter, only letters, numbers and underscores).
  • group and parameter names are not reserved keywords, e.g. primitive type names, modifier names, "class"/"interface"/"enum"
  • the name passed to fromEnvironment represents a valid environment variable name.
  • the default value of an enum parameter is part of the values list

Generate Settings Plugin

Next to the "Project Plugin" that applies the generated Extension to a project (build file) we should also generate a "Settings Plugin" that can be applied in the settings file to access build parameters there. An example is this from the plugins very own build:

if ("CI" in System.getenv()) {
    gradleEnterprise {
        buildScan {
            publishAlways()
            termsOfServiceUrl = "https://gradle.com/terms-of-service"
            termsOfServiceAgree = "yes"
        }
    }
}

Shareable parameter definitions

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
}

Check that only valid build parameters are passed via -P (and not -D)

This is a common gotcha where some users source properties from Gradle, some source them from System. Preferring only one will guarantee to leave some users behind or scratching their heads into why their properties were not considered. Or worst, it will be a silent error (i.e. property.getOrNull()) The suggestion is always to follow the general Gradle precedence ordering: https://docs.gradle.org/current/userguide/build_environment.html#header

If sourcing from both property types is not wanted, give a guiding error message (even if there is a default value, which would mostly be a warning message), aka "you are requesting Gradle property 'foo' but a System property 'foo' was found, don't do that". The solution can be either in the plugin or in Gradle itself. Already requested that feature long ago; maybe you will have better luck making things move.

Allow for renaming of values

When working with builds, sometimes we cannot control the names that variables have. For instance, when running a build from Android Studio a flag is passed called "android.injected.invoked.from.ide".

It would be great to be able to read that into builds in a better way than miss-using groups:

    group("android"){
        group("injected"){
            group("invoked") {
                group("from") {
                    bool("ide") {
                        description.set("Whether or not the current build was started from within Android Studio")
                        defaultValue.set(false)
                    }
                }
            }
        }
    }

Would it be possible to simplify this in any way? Could build-parameters allow for renaming properties perhaps? For example, it would be nicer if we could define this like:

    bool("invokedFromIde"){ 
        source = "android.injected.invoked.from.ide"
        //...
    }

Allow for customization of project property source

Currently a Gradle project property can be used as a source for a buildParameter but the property name is identical to the buildParameter path <group>.<property>.

This causes problems when overriding properties from the environment (via ORG_GRADLE_PROJECT_<propName>) as *nix systems cannot use . in environment variable names. Much like the fromEnvironment method accepts a source variable name, it would be great if we could override a "source property name" as well.

It could be via an propertyAlias function that would fall back on the alias property name if the original property was unset.

The primary use case for overriding properties via environment variables is in unified CICD systems where abstracting on top of Gradle lifecycle tasks may still require individual projects to override their own pipeline/environment variables.

PluginCodeGeneration should be cacheable

It's easy to make this task cacheable by adding the annotation. But it's not clear whether it's worth caching a task that just write a few lines of Java code.

Incompatibility with Android projects

👋 I'm trying to add build-parameters but it seems to be incompatible with Android projects. Can the java plugin be avoided?

A problem occurred configuring project ':backend'.
> com.android.build.gradle.internal.BadPluginException: The 'java' plugin has been applied, but it is not compatible with the Android plugins.

Display the default and the current values in parameters task

Currently, parameters task lists the parameters, and it is hard to tell which of them are required, which of them have values, and so on. I know --details exist, however, it does not scale.

It would be nice to execute something like ./gradlew -Pmy.param= parameters and check the output for the resulting values.

Here's my current list:

------------------------------------------------------------
Supported Build Parameters
------------------------------------------------------------

enableMavenLocal - Add mavenLocal() to repositories
enableJavaFx - Build and include classes that depend on JavaFX. Disabled by default since JavaFX is not included in the default Java distributions
coverage - Collect test coverage
targetJavaVersion - Java version for source and target compatibility
jdkBuildVersion - JDK version to use for building JMeter. If the value is 0, then current Java is used. (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:consuming)
jdkBuildVendor - JDK vendor to use building JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:vendors)
jdkBuildImplementation - Vendor-specific virtual machine implementation to use building JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#selecting_toolchains_by_virtual_machine_implementation)
jdkTestVersion - JDK version to use for testing JMeter. If the value is 0, then current Java is used. (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:consuming)
jdkTestVendor - JDK vendor to use testing JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#sec:vendors)
jdkTestImplementation - Vendor-specific virtual machine implementation to use testing JMeter (see https://docs.gradle.org/8.0/userguide/toolchains.html#selecting_toolchains_by_virtual_machine_implementation)
spotbugs - Run SpotBugs verifications
sonarqube - Report verification results to Sonarqube
ignoreSpotBugsFailures - Ignore SpotBugs failures
enableCheckerframework - Run CheckerFramework (nullness) verifications
skipAutostyle - Skip AutoStyle verifications
skipCheckstyle - Skip Checkstyle verifications
skipDist - Allow to skip building source/binary distributions
skipForbiddenApis - Skip forbidden-apis verifications
suppressPomMetadataWarnings - Skip suppressPomMetadataWarningsFor warnings triggered by inability to map test fixtures dependences to Maven pom.xml
enableErrorprone - Enable ErrorProne verifications
skipJavadoc - Skip javadoc generation
failOnJavadocWarning - Fail build on javadoc warnings
enableGradleMetadata - Generate and publish Gradle Module Metadata
useGpgCmd - By default use Java implementation to sign artifacts. When useGpgCmd=true, then gpg command line tool is used for signing artifacts
werror - Treat javac, javadoc, kotlinc warnings as errors

Example for boolean parameters with default false should be setting it to true

When inspecting the details of a boolean parameter that defaults to false, the example will show setting it to false as well:

> Task :build-logic:build-parameters:parameters
Detailed build parameter information for enterprise.enableTestDistribution

Type
     Boolean

Description
     Whether or not to use Test Distribution for executing tests

Default value
     false

Environment Variable
     ENTERPRISE_ENABLETESTDISTRIBUTION

Examples
     -Penterprise.enableTestDistribution
     -Penterprise.enableTestDistribution=false

In this case I think the second example should be changed to -Penterprise.enableTestDistribution=true

Multi language samples

Currently the documentation only has examples for Kotlin DSL. We should add he corresponding examples for Groovy DSL as well.

Repository credentials produce "Unknown build parameter" error

Starting with version 1.4 unrecognized parameters lead to an exception (see #28).

When using the gradle repository credentials feature, locally I enter the username and password (let's say they are called nexusUsername and nexusPassword as my repository is called nexus) in my ~/gradle.properties and everything works fine.

But when running on CI (gitlab in my case), I have the credentials of a technical user as secret CI/CD variables and pass them via -PnexusUsername=$TECHNICAL_USER_NAME -PnexusPassword=$TECHNICAL_USER_PASSWORD to gradle.
Then I receive the following exception: Unknown build parameter: nexusPassword

What would be your advice to handle this situation?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.