Skip to content

Commit

Permalink
Make plugin work during configuration phase again
Browse files Browse the repository at this point in the history
The changes in n0mer#164 to support the Gradle configuration cache broke
using the plugin during configuration phase of Gradle (e. g. as part of
a custom plugin via `buildSrc` and similar use cases).

Fixes n0mer#169
  • Loading branch information
joschi committed Apr 7, 2021
1 parent 1696dfa commit b32d23d
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 41 deletions.
14 changes: 0 additions & 14 deletions src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy
Expand Up @@ -148,27 +148,13 @@ public class GenerateGitPropertiesTask extends DefaultTask {
} else {
logger.info("Skip writing properties to [${file}] as it is up-to-date.")
}

}

private File getDotGitDirectory() {
DirectoryProperty dotGitDirectory = gitProperties.dotGitDirectory
return new GitDirLocator(layout.projectDirectory.asFile).lookupGitDirectory(dotGitDirectory.asFile.get())
}


public void onJavaPluginAvailable() {
// if Java plugin is used, this method will be called to register gitPropertiesResourceDir to classpath
// at the end of evaluation phase (to make sure extension values are set)
logger.debug "GenerateGitPropertiesTask: found Java plugin"
if (gitProperties.gitPropertiesResourceDir) {
logger.debug("gitProperties.gitPropertiesResourceDir=${gitProperties.gitPropertiesResourceDir}")
String gitPropertiesDir = getGitPropertiesDir().asFile.absolutePath
project.sourceSets.main.resources.srcDir gitPropertiesDir
logger.info "GenerateGitPropertiesTask: added classpath entry(gitPropertiesResourceDir): ${gitPropertiesDir}"
}
}

private Directory getGitPropertiesDir() {
if (gitProperties.gitPropertiesResourceDir.present) {
return gitProperties.gitPropertiesResourceDir.get()
Expand Down
55 changes: 29 additions & 26 deletions src/main/groovy/com/gorylenko/GitPropertiesPlugin.groovy
@@ -1,54 +1,57 @@
package com.gorylenko

import groovy.transform.ToString

import org.gradle.api.Action
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileTree
import org.gradle.api.file.ProjectLayout
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider

import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer

class GitPropertiesPlugin implements Plugin<Project> {

private static final String EXTENSION_NAME = "gitProperties"

private static final String DEFAULT_OUTPUT_DIR = "resources/main"

@Override
void apply(Project project) {

project.extensions.create(EXTENSION_NAME, GitPropertiesPluginExtension, project)
def extension = project.extensions.create(EXTENSION_NAME, GitPropertiesPluginExtension, project)
def task = project.tasks.register(GenerateGitPropertiesTask.TASK_NAME, GenerateGitPropertiesTask) {
it.setGroup(BasePlugin.BUILD_GROUP)
group = BasePlugin.BUILD_GROUP
}

ensureTaskRunsOnJavaClassesTask(project, task)
}

private static void ensureTaskRunsOnJavaClassesTask(Project project, TaskProvider<GenerateGitPropertiesTask> task) {
// if Java plugin is applied, execute this task automatically when "classes" task is executed
// see https://guides.gradle.org/implementing-gradle-plugins/#reacting_to_plugins
project.getPlugins().withType(JavaPlugin.class, new Action<JavaPlugin>() {
public void execute(JavaPlugin javaPlugin) {
project.tasks.named(JavaPlugin.CLASSES_TASK_NAME).configure {
dependsOn(task)
project.plugins.withType(JavaBasePlugin) {
project.tasks.named(JavaPlugin.CLASSES_TASK_NAME).configure {
dependsOn(task)

project.gradle.projectsEvaluated {
// Defer to end of the step to make sure extension config values are set
task.get().onJavaPluginAvailable()
// if Java plugin is used, this method will be called to register gitPropertiesResourceDir to classpath
// at the end of evaluation phase (to make sure extension values are set)
if (extension.gitPropertiesResourceDir.present) {
String gitPropertiesDir = getGitPropertiesDir(extension, project.layout).asFile.absolutePath
def sourceSets = project.extensions.getByType(SourceSetContainer)
sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME).configure {
it.resources.srcDir(gitPropertiesDir)
}
}
}
})
}
}

private static Directory getGitPropertiesDir(GitPropertiesPluginExtension extension, ProjectLayout layout) {
if (extension.gitPropertiesResourceDir.present) {
return extension.gitPropertiesResourceDir.get()
} else if (extension.gitPropertiesDir.present) {
return extension.gitPropertiesDir.get()
} else {
return layout.buildDirectory.dir(DEFAULT_OUTPUT_DIR).get()
}
}
}

Expand Down
Expand Up @@ -20,7 +20,7 @@ public class BackwardCompatibilityFunctionalTest {
@Parameterized.Parameters(name = "Gradle {0}")
static List<Object[]> data() {
return [
["7.0-rc-1", ["generateGitProperties", "--configuration-cache", "--build-cache"], "16"],
["7.0-rc-2", ["generateGitProperties", "--configuration-cache", "--build-cache"], "16"],
["6.8.3", ["generateGitProperties", "--configuration-cache", "--build-cache"], "15"],
["6.7.1", ["generateGitProperties", "--configuration-cache", "--build-cache"], "15"],
["6.6.1", ["generateGitProperties", "--configuration-cache", "--build-cache"], "15"],
Expand Down
135 changes: 135 additions & 0 deletions src/test/groovy/com/gorylenko/BuildSrcFunctionalTest.groovy
@@ -0,0 +1,135 @@
package com.gorylenko

import com.gorylenko.properties.GitRepositoryBuilder
import org.gradle.testkit.runner.GradleRunner
import org.gradle.testkit.runner.TaskOutcome
import org.junit.Rule
import org.junit.Test
import org.junit.rules.TemporaryFolder

import static org.junit.Assert.assertEquals
import static org.junit.Assert.assertTrue

public class BuildSrcFunctionalTest {
@Rule
public final TemporaryFolder temporaryFolder = new TemporaryFolder()

@Test
public void testPluginSucceedsDuringConfigurationPhase() {
def projectDir = temporaryFolder.newFolder()
def runner = GradleRunner.create()
.withPluginClasspath()
.withArguments("check")
.withProjectDir(projectDir)

def classpathString = runner.pluginClasspath
.collect { "'$it'" }
.join(", ")

def buildSrcDir = new File(projectDir, "buildSrc")
buildSrcDir.mkdirs()
new File(buildSrcDir, "build.gradle") << """\
plugins {
id("groovy-gradle-plugin")
}
repositories {
gradlePluginPortal()
}
dependencies {
runtimeClasspath files($classpathString)
}
"""
def pluginSourceDir = buildSrcDir.toPath().resolve("src").resolve("main").resolve("groovy").toFile()
pluginSourceDir.mkdirs()
new File(pluginSourceDir, "test-plugin.gradle") << """\
plugins {
id("java")
id("com.gorylenko.gradle-git-properties")
}
"""
new File(projectDir, "settings.gradle") << """\
pluginManagement {
plugins {
id("com.gorylenko.gradle-git-properties")
}
}
""".stripIndent()
new File(projectDir, "build.gradle") << """\
plugins {
id("test-plugin")
}
""".stripIndent()

GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder ->
// commit 1 new file "hello.txt"
gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt")
})

def result = runner.build()

assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome)
}

@Test
public void testPluginCanOverrideGitPropertiesResourceDir() {
def projectDir = temporaryFolder.newFolder()
def runner = GradleRunner.create()
.withPluginClasspath()
.withArguments("check")
.withProjectDir(projectDir)

def classpathString = runner.pluginClasspath
.collect { "'$it'" }
.join(", ")

def buildSrcDir = new File(projectDir, "buildSrc")
buildSrcDir.mkdirs()
def gitPropDir = new File(projectDir, "gitProp")
gitPropDir.mkdirs()
new File(buildSrcDir, "build.gradle") << """\
plugins {
id("groovy-gradle-plugin")
}
repositories {
gradlePluginPortal()
}
dependencies {
runtimeClasspath files($classpathString)
}
"""
def pluginSourceDir = buildSrcDir.toPath().resolve("src").resolve("main").resolve("groovy").toFile()
pluginSourceDir.mkdirs()
new File(pluginSourceDir, "test-plugin.gradle") << """\
plugins {
id("java")
id("com.gorylenko.gradle-git-properties")
}
"""
new File(projectDir, "settings.gradle") << """\
pluginManagement {
plugins {
id("com.gorylenko.gradle-git-properties")
}
}
""".stripIndent()
new File(projectDir, "build.gradle") << """\
plugins {
id("test-plugin")
}
gitProperties {
gitPropertiesResourceDir = layout.projectDirectory.dir("gitProp")
}
""".stripIndent()

GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder ->
// commit 1 new file "hello.txt"
gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt")
})

def result = runner.build()

assertEquals(TaskOutcome.SUCCESS, result.task(":generateGitProperties").outcome)
assertTrue(gitPropDir.list().contains("git.properties"))
}
}

0 comments on commit b32d23d

Please sign in to comment.