The Gradle version project property is unspecified
When you use the version
project property and it yields to the unspecified
value although you expected it to be something else the reason may be:
- you are in a multi project scenario and you’re querying a sub-project
version
property instead of the root projects - you have applied as a project plugin instead of a settings plugin
unspecified
is the default value for the version
standard Gradle property so it’s what you get unless it is set to any other value either statically or dinamically.
Here are solutions to these issues.
Use the right version
property or propagate
Let’s assume you have a multi-project hierarchy like:
rootProject
|- subProjectA
| \- subProjectA1
\- subProjectB
When you get the right version
in the rootProject
but not in the sub projects that simply means that you need to replace the project.version
expressions in your build scripts to rootProject.version
. Do this for all the projects in the hierarchy you want the same project version for.
If you want all the projects in the hierarchy to have the same version you may go the other way so, in order to propagate the version from the root project to children, add the following to your root project build script:
subprojects {
version = rootProject.version
}
If you have applied as a project plugin instead of a settings plugin you may prefer the afterEvaluate
version, like:
subprojects {
afterEvaluate {
version = rootProject.version
}
}
Remember that even with this, when using the project plugin version, some properties may still be unspecified, as illustrated below.
Apply the plugin at the settings level
You can apply the plugin as a project plugin or a settings plugin, and here are the differences:
- the project plugin is applied in the
build.gradle
file while the settings plugin is applied in thesettings.gradle
file. You can use the same plugin DSL to apply and the same grammar to configure - the project plugin should be applied to the root project only, the settings plugin must be applied to the root project only as Gradle restricts the
settings.gradle
file to appear at the root level only - the project plugin defines tasks for you to use at any time in your build script, the settings plugin does that too, but also triggers inference during the initialization of the Gradle project, before the configuration and execution take place (which is where you need properties like the project
version
)
This last point is what makes the real difference as inferred properties, including the project version
, are evaluated in advance and made available to the build scripts as if they were statically defined.
What Nyx does behind the scenes is running the nyxInfer
task in the early initialization phase, before build scripts are evaluated and project plugins applied. While you still have these tasks (along with others) available for you to invoke at any time during the build process, invoking them again won’t change the value of the inferred properties (as long as the Git repository contents don’t change).
Let’s take a common example of using the Maven Publish Plugin. The plugin uses the project version
to define the version of the artifacts that will be published and it does so in the evaluation phase. For example:
publishing {
publications {
maven(MavenPublication) {
groupId = 'com.example.library'
artifactId = 'library'
version = project.version
...
}
}
}
In this example the version = project.version
assignment is superfluous as it’s the default, but helps making the example clearer. What’s important is that if you apply the Nyx plugin as a project plugin the Maven artifacts will have their version set as unspecified, while if you apply as a settings plugin the version will be what is inferred by nyxInfer
. That’s because the settings plugin kicks in before the Maven publications are evaluated.