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.

Usage as a plugin (recommended)
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.

Legacy approach
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

true / false (ignored for Gradle 8+)

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

providerTools().provider or project.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

Obtaining the project extension
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.

Using 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.