Configuration Operation APIs
Because Gradle Configuration Cache makes it impossible to use the Project
instance after the configuration phase has ended, plugin authors can no longer rely on calling methods in this class.
The only exceptions are within constructors of tasks and within extensions.
Plugin authors should take extra care as to not call the Task.getProject()
method anywhere except in the constructor.
In order to help with compatibility across versions that has a configuration caching and those that don’t, the ProjectOperations was originally introduced.
It was subsequently found that some of the operations referenced within the instantiation was still not configuration cache-compatible and thus the ConfigurationCacheSafeOperations API was introduced in Grolifant 5.
Instances of the latter can be made members of tasks and their operations can be called within task actions.
The original ProjectOperations
can still be used, but should not be referenced from with tasks (except in constructors).
As from 5.5, ProjectOperations
has been deprecated and replaced with the ConfigurationPhaseOperations interface.
The latter implements all of ConfigCacheSafeOperations
, plus additional tools that can be used in the configuration phase only.
Furthermore from 5.5, the grolifantOps
extension now implements ConfigurationPhaseOperations
instead of ProjectOperations
.
For compatibility, it makes a number of deprecated methods available of which any usage will be reported in the Gradle problem report.
Usage
It can either be used as an extension or as a standalone instance.
import org.ysb33r.grolifant.api.core.plugins.GrolifantServicePlugin (1)
import org.ysb33r.grolifant.api.core.ProjectOperations
class MyPlugin implements Plugin<Project> {
void apply(Project project) {
project.pluginManager.apply(GrolifantServicePlugin) (2)
final cpo = ConfigurationPhaseOperations.from(project) (3)
final ccso = ConfigurationCacheSafeOperations.from(project) (4)
}
}
1 | Required import |
2 | Install the core plugin. |
3 | How to get operations that can be used during the configuration phase. |
4 | How to get a configuration cache-compatible set of operations. |
You can also access it in a buildscript via the grolifantOps
extension.
Any downstream plugin in the wild that uses Grolifant 5+, will automatically make this extension available to its build script authors.
grolifantOps.taskTools() (1)
1 | Gain access to the Grolifant tools. |
Legacy migration
If you are still using any of the below bootstrap techniques, then change it to use the plugin instead as described earlier.
import org.ysb33r.grolifant.api.core.ProjectOperations
ProjectOperations grolifant = ProjectOperations.maybeCreateExtension(project)
ProjectOperations po = ProjectOperations.create(project)
Migration of deprecated methods
There are a number of methods on ProjectOperations
that have been deprecated for a while, and the rest were deprecated in 5.5.
The following table describes the necessary migrations.
Deprecated grolifantOps / ProjectOperations method |
Correct method | Configuration-phase only? |
---|---|---|
asProvider |
- |
- |
atConfigurationTime |
|
N |
buildDirDescendant |
fsOperations().buildDirDescendant |
N |
bzip2Resource |
fsOperations().bzip2Resource |
N |
copySpec |
fsOperations().copySpec |
N |
delete |
fsOperations().delete |
N |
environmentVariable |
providerTools().environmentVariable |
N |
exec |
execTools().exec |
N |
fileTree |
fsOperations().fileTree |
N |
getBuildDir |
project.getLayout().getBuildDirectory().map( x → x.getAsFile() ) |
Y |
getConfigurations |
configurations() |
Y |
getConsoleOutput |
projectTools().getConsoleOutput() |
N |
getExecTools |
execTools() |
N |
getFsOperations |
fsOperations() |
N |
getFullProjectPath |
projectTools().getFullProjectPath() |
N |
getGradleLogLevel |
projectTools().getGradleLogLevel() |
N |
getGradleHomeDir |
fsOperations().getGradleHomeDir() |
N |
getGradleUserHomeDir |
fsOperations().getGradleUserHomeDir() |
N |
getGroupProvider() |
projectTools().getGroupProvider() |
N |
getJvmTools |
jvmTools() |
N |
getProblemReporter |
problemReporter() |
N |
getProjectCacheDir |
fsOperations().getProjectCacheDir() |
N |
getProjectDir |
fsOperations().getProjectDir() |
N |
getProjectName |
projectTools().getProjectNameProvider().get() |
N |
getProjectPath |
projectTools().getFullProjectPath() |
N |
getProjectRootDir |
fsOperations().getProjectRootDir() |
N |
getProjectTools |
projectTools() |
N |
getProviders |
project.getProviders() |
Y |
getProviderTools |
providerTools() |
N |
getRepositoryTools |
repositoryTools() |
Y |
getStringTools |
stringTools() |
N |
getTaskTools |
taskTools() |
Y |
gradleProperty |
providerTools().gradleProperty |
N |
gzipResource |
fsOperations().gzipResource |
N |
isConfigurationCacheEnabled |
projectTools().isConfigurationCacheEnabled() |
N |
isOffline |
projectTools().isOffline() |
N |
isRefreshDependencies |
projectTools().isRefreshDependencies() |
N |
isRerunTasks |
projectTools().isRerunTasks() |
N |
isRoot |
projectTools().isRoot() |
N |
javaexec |
execTools.javaexec |
N |
provider |
|
Y |
systemProperty |
providerTools().systemProperty |
N |
tarTree |
fsOperations().tarTree |
N |
zipTree |
fsOperations().zipTree |
N |
Obtaining access to methods
Outside a task you can do this
ConfigurationPhaseOperations grolifant = ConfigurationPhaseOperations.from(project) (1)
1 | Shortcut for finding the project extension. Will throw an exception if the extension was not attached to the project. |
Inside a task you should not refer to the ConfigurationPhaseOperations
task.
Instead, use any of the methods available on ConfigurationCacheSafeOperations
.
GrolifantDefaultTask
import org.ysb33r.grolifant5.api.core.runnable.GrolifantDefaultTask (1)
class MyTask extends GrolifantDefaultTask { (2)
String showString() {
stringTools().stringize(123) (3)
}
}
1 | Required imports |
2 | Use GrolifantDefaultTask instead of DefaultTask |
3 | Use method such as GrolifantTaskMethods.stringTools() to access to the methods you are familiar with |
The exception is that inside the constructor you may use ConfigurationPhaseOperations only to do certain operations.
Once the constructor exits, any reference to non-configuration-cache tools msut NOT be stored.
|