From 9f5c89e9f09d66c6a46e544b63306366883477b5 Mon Sep 17 00:00:00 2001 From: Igor Mukhin Date: Sat, 26 Oct 2024 23:35:02 +0200 Subject: [PATCH 1/2] Refactors plugin's inputs to support configuration cache for modern Gradle versions Breaks backward compatibility: The locations of the .git directory is not searched up the directory tree automatically anymore. --- README.md | 15 ++-- .../GenerateGitPropertiesTask.groovy | 67 ++++++++---------- .../groovy/com/gorylenko/GitDirLocator.groovy | 53 --------------- .../com/gorylenko/GitPropertiesPlugin.groovy | 3 - .../com/gorylenko/BasicFunctionalTest.groovy | 5 +- .../com/gorylenko/GitDirLocatorTest.groovy | 68 ------------------- 6 files changed, 38 insertions(+), 173 deletions(-) delete mode 100644 src/main/groovy/com/gorylenko/GitDirLocator.groovy delete mode 100644 src/test/groovy/com/gorylenko/GitDirLocatorTest.groovy diff --git a/README.md b/README.md index f400c60..6214482 100644 --- a/README.md +++ b/README.md @@ -139,22 +139,19 @@ gitProperties { > ``` -The `.git` directory for the project should be detected automatically, otherwise it can be specified manually using `dotGitDirectory`: +If the `.git` directory is not located in the same directory as the Gradle project, you will need to specify it using `dotGitDirectory`: ```groovy gitProperties { + // if .git directory is on the same level as the root project + dotGitDirectory = project.rootProject.layout.projectDirectory.dir(".git") + + // if .git directory is in a different location dotGitDirectory = "${project.rootDir}/../somefolder/.git" } ``` -Note: Kotlin DSL syntax -```kotlin -configure { - (dotGitDirectory as DirectoryProperty).set("${project.rootDir}/../somefolder/.git") -} -``` - -If for some reason, the `.git` directory for the project doesn't exist and you don't want the task to fail in that case, use `failOnNoGitDirectory=false`: +If for some reason, the `.git` directory for the project doesn't exist, and you don't want the task to fail in that case, use `failOnNoGitDirectory=false`: ```groovy gitProperties { diff --git a/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy b/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy index 4b61198..1fc9194 100644 --- a/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy +++ b/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy @@ -4,7 +4,6 @@ import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Transformer 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.file.RegularFileProperty @@ -28,20 +27,30 @@ public class GenerateGitPropertiesTask extends DefaultTask { private final GitPropertiesPluginExtension gitProperties + private final FileTree source + private final Object projectVersion + GenerateGitPropertiesTask() { // Description for the task description = 'Generate a git.properties file.' this.gitProperties = project.extensions.getByType(GitPropertiesPluginExtension) + // we will not be able to access the project in the @TaskAction method, + // if the configuration cache is enabled + this.source = project.fileTree(gitProperties.dotGitDirectory) { + include('config') + include('HEAD') + include('refs/**') + } + this.projectVersion = project.version + outputs.upToDateWhen { GenerateGitPropertiesTask task -> // when extProperty is configured or failOnNoGitDirectory=false always execute the task - return !task.getGitProperties().extProperty && task.getGitProperties().failOnNoGitDirectory + return !task.gitProperties.extProperty && task.gitProperties.failOnNoGitDirectory } } - private Map generatedProperties - @Inject ObjectFactory getObjectFactory() { throw new UnsupportedOperationException() @@ -55,8 +64,7 @@ public class GenerateGitPropertiesTask extends DefaultTask { @InputFiles @PathSensitive(PathSensitivity.RELATIVE) public FileTree getSource() { - File dotGitDirectory = getDotGitDirectory() - return (dotGitDirectory == null) ? layout.files().asFileTree : layout.files(dotGitDirectory).asFileTree + return source } @OutputFile @@ -64,45 +72,31 @@ public class GenerateGitPropertiesTask extends DefaultTask { return getGitPropertiesFile() } - /** - * To support cacheable task and UP-TO-DATE check - */ @Input - public Map getGeneratedProperties() { - - if (this.generatedProperties != null) return this.generatedProperties + public Object getProjectVersion() { + return projectVersion + } + private Map generateProperties() { if (logger.debugEnabled) { logger.debug("gitProperties = ${gitProperties}") } - if (!gitProperties.failOnNoGitDirectory && getSource().empty) { - logger.info("Exiting because no Git repository found and failOnNoGitDirectory = false.") - return [:] - } - - File dotGitDirectory = getDotGitDirectory() - - if (dotGitDirectory == null) { - throw new GradleException("No Git repository found.") - } - + File dotGitDirectory = gitProperties.dotGitDirectory.get().asFile logger.info("dotGitDirectory = [${dotGitDirectory?.absolutePath}]") - // Generate properties GitProperties builder = new GitProperties() Map newMap = builder.generate(dotGitDirectory, gitProperties.keys, gitProperties.dateFormat, gitProperties.dateFormatTimeZone, gitProperties.branch, - project.version, gitProperties.customProperties) + projectVersion, gitProperties.customProperties) if (logger.debugEnabled) { logger.debug("Generated Git properties = ${newMap}") } - generatedProperties = newMap - return this.generatedProperties + return newMap } @Internal @@ -113,22 +107,24 @@ public class GenerateGitPropertiesTask extends DefaultTask { @TaskAction void generate() { - if (!gitProperties.failOnNoGitDirectory && getSource().empty) { - logger.info("Exiting because no Git repository found and failOnNoGitDirectory = false.") - return + if (getSource().empty) { + if (gitProperties.failOnNoGitDirectory) { + throw new GradleException("No Git repository found. Please set gitProperties.dotGitDirectory to the correct path.") + } else { + logger.info("No Git repository found and failOnNoGitDirectory = false.") + return + } } - Map newMap = getGeneratedProperties() + Map newMap = generateProperties() // Expose generated properties to project.ext[gitProperties.extProperty] if configured - if (gitProperties.extProperty) { logger.debug("Exposing git properties model to project.ext[${gitProperties.extProperty}]") project.ext[gitProperties.extProperty] = new HashMap(newMap) } // Write to git.properties file - logger.debug("gitProperties.gitPropertiesResourceDir=${gitProperties.gitPropertiesResourceDir}") logger.debug("gitProperties.gitPropertiesDir=${gitProperties.gitPropertiesDir}") logger.debug("gitProperties.gitPropertiesName=${gitProperties.gitPropertiesName}") @@ -150,11 +146,6 @@ public class GenerateGitPropertiesTask extends DefaultTask { } } - private File getDotGitDirectory() { - DirectoryProperty dotGitDirectory = gitProperties.dotGitDirectory - return new GitDirLocator(layout.projectDirectory.asFile).lookupGitDirectory(dotGitDirectory.asFile.get()) - } - private Directory getGitPropertiesDir() { if (gitProperties.gitPropertiesResourceDir.present) { return gitProperties.gitPropertiesResourceDir.get() diff --git a/src/main/groovy/com/gorylenko/GitDirLocator.groovy b/src/main/groovy/com/gorylenko/GitDirLocator.groovy deleted file mode 100644 index 9889b1f..0000000 --- a/src/main/groovy/com/gorylenko/GitDirLocator.groovy +++ /dev/null @@ -1,53 +0,0 @@ -package com.gorylenko - -import java.io.File -import org.ajoberstar.grgit.Grgit - -/** - * Encapsulates logic to locate a valid .git directory. - * - */ -class GitDirLocator { - - private File projectBasedir - - public GitDirLocator(File projectBasedir) { - this.projectBasedir = projectBasedir - } - - public File lookupGitDirectory(File manuallyConfiguredDir) { - Grgit grgit - - if (manuallyConfiguredDir && manuallyConfiguredDir.exists()) { - try { - grgit = Grgit.open(dir: manuallyConfiguredDir) - } catch (Exception e) { - // could not open the configured dotGit dir - } - } - - if (!grgit) { - try { - // Detect automatically from project dir and go up until until find .git dir or .git file - grgit = Grgit.open(currentDir: projectBasedir) - } catch (Exception e) { - } - } - - File dotGitDir - - if (grgit != null) { - dotGitDir = grgit.repository.rootDir - // Workaround to avoid Gradle bug on Java 11 regarding changing working directory unsuccessfully causing issues regarding relative file paths - if (dotGitDir.exists() && !dotGitDir.absoluteFile.exists()) { - dotGitDir = new File(projectBasedir, dotGitDir.getPath()) - } - grgit.close() - } else { - dotGitDir = null - } - - return dotGitDir - } - -} diff --git a/src/main/groovy/com/gorylenko/GitPropertiesPlugin.groovy b/src/main/groovy/com/gorylenko/GitPropertiesPlugin.groovy index 8294bae..00a0f86 100644 --- a/src/main/groovy/com/gorylenko/GitPropertiesPlugin.groovy +++ b/src/main/groovy/com/gorylenko/GitPropertiesPlugin.groovy @@ -56,12 +56,9 @@ class GitPropertiesPlugin implements Plugin { @ToString(includeNames=true) class GitPropertiesPluginExtension { - @InputDirectory final DirectoryProperty gitPropertiesDir - @InputDirectory final DirectoryProperty gitPropertiesResourceDir String gitPropertiesName = "git.properties" - @InputDirectory final DirectoryProperty dotGitDirectory List keys = GitProperties.standardProperties Map customProperties = [:] diff --git a/src/test/groovy/com/gorylenko/BasicFunctionalTest.groovy b/src/test/groovy/com/gorylenko/BasicFunctionalTest.groovy index 933ea86..a14d45b 100644 --- a/src/test/groovy/com/gorylenko/BasicFunctionalTest.groovy +++ b/src/test/groovy/com/gorylenko/BasicFunctionalTest.groovy @@ -7,8 +7,9 @@ import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder +import static org.hamcrest.CoreMatchers.containsString import static org.junit.Assert.assertEquals -import static org.junit.Assert.assertTrue +import static org.junit.Assert.assertThat public class BasicFunctionalTest { @Rule @@ -32,7 +33,7 @@ public class BasicFunctionalTest { def result = runner.buildAndFail() assertEquals(TaskOutcome.FAILED, result.task(":generateGitProperties").outcome) - assertTrue(result.output.contains("No Git repository found.")) + assertThat(result.output, containsString("No Git repository found.")) } @Test diff --git a/src/test/groovy/com/gorylenko/GitDirLocatorTest.groovy b/src/test/groovy/com/gorylenko/GitDirLocatorTest.groovy deleted file mode 100644 index 71ca9f8..0000000 --- a/src/test/groovy/com/gorylenko/GitDirLocatorTest.groovy +++ /dev/null @@ -1,68 +0,0 @@ -package com.gorylenko - -import static org.junit.Assert.* - -import java.io.File - -import org.junit.After -import org.junit.Before -import org.junit.Test - -import com.gorylenko.properties.GitRepositoryBuilder - -class GitDirLocatorTest { - File projectDir - - @Before - public void setUp() throws Exception { - projectDir = File.createTempDir("BranchPropertyTest", ".tmp") - } - @After - public void tearDown() throws Exception { - projectDir.deleteDir() - } - - @Test - public void testNonGitProject() { - GitDirLocator locator = new GitDirLocator(projectDir) - - assertNull(locator.lookupGitDirectory(null)) - } - - @Test - public void testAutodetectedGitRepoInCurrentDirectory() { - GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> - // commit 1 new file "hello.txt" - gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") - }) - GitDirLocator locator = new GitDirLocator(projectDir) - - assertEquals(new File(projectDir, '.git'), locator.lookupGitDirectory(null)) - } - - @Test - public void testAutodetectedGitRepoInParentDirectory() { - - GitRepositoryBuilder.setupProjectDir(projectDir, { gitRepoBuilder -> - // commit 1 new file "hello.txt" - gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") - }) - File projectSubDir = new File(projectDir, "subDir") - GitDirLocator locator = new GitDirLocator(projectSubDir) - - assertEquals(new File(projectDir, '.git'), locator.lookupGitDirectory(null)) - } - - @Test - public void testManuallyConfiguredGitProject() { - - File projectDir2 = File.createTempDir("BranchPropertyTest", ".tmp") - GitRepositoryBuilder.setupProjectDir(projectDir2, { gitRepoBuilder -> - // commit 1 new file "hello.txt" - gitRepoBuilder.commitFile("hello.txt", "Hello", "Added hello.txt") - }) - GitDirLocator locator = new GitDirLocator(projectDir) - - assertEquals(new File(projectDir2, '.git'), locator.lookupGitDirectory(new File(projectDir2, '.git'))) - } -} From 9c0a4a9102622f0f007007a49efe02f4b41ebed4 Mon Sep 17 00:00:00 2001 From: Igor Mukhin Date: Sun, 27 Oct 2024 15:03:25 +0100 Subject: [PATCH 2/2] improves the message if the dotGit directory is not configured properly --- .../com/gorylenko/GenerateGitPropertiesTask.groovy | 13 ++++++++----- .../com/gorylenko/GitPropertiesPluginTests.groovy | 4 +++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy b/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy index 1fc9194..3e49f66 100644 --- a/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy +++ b/src/main/groovy/com/gorylenko/GenerateGitPropertiesTask.groovy @@ -8,6 +8,7 @@ import org.gradle.api.file.FileTree import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RegularFileProperty import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property import org.gradle.api.tasks.CacheableTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputFiles @@ -28,7 +29,7 @@ public class GenerateGitPropertiesTask extends DefaultTask { private final GitPropertiesPluginExtension gitProperties private final FileTree source - private final Object projectVersion + private final Property projectVersion GenerateGitPropertiesTask() { // Description for the task @@ -43,7 +44,7 @@ public class GenerateGitPropertiesTask extends DefaultTask { include('HEAD') include('refs/**') } - this.projectVersion = project.version + this.projectVersion = project.objects.property(Object).convention(project.version) outputs.upToDateWhen { GenerateGitPropertiesTask task -> // when extProperty is configured or failOnNoGitDirectory=false always execute the task @@ -73,7 +74,7 @@ public class GenerateGitPropertiesTask extends DefaultTask { } @Input - public Object getProjectVersion() { + public Property getProjectVersion() { return projectVersion } @@ -90,7 +91,7 @@ public class GenerateGitPropertiesTask extends DefaultTask { GitProperties builder = new GitProperties() Map newMap = builder.generate(dotGitDirectory, gitProperties.keys, gitProperties.dateFormat, gitProperties.dateFormatTimeZone, gitProperties.branch, - projectVersion, gitProperties.customProperties) + projectVersion.get(), gitProperties.customProperties) if (logger.debugEnabled) { logger.debug("Generated Git properties = ${newMap}") @@ -109,7 +110,9 @@ public class GenerateGitPropertiesTask extends DefaultTask { if (getSource().empty) { if (gitProperties.failOnNoGitDirectory) { - throw new GradleException("No Git repository found. Please set gitProperties.dotGitDirectory to the correct path.") + throw new GradleException( + "No Git repository found. " + + "Ensure the gitProperties.dotGitDirectory property points to the correct .git directory.") } else { logger.info("No Git repository found and failOnNoGitDirectory = false.") return diff --git a/src/test/groovy/com/gorylenko/GitPropertiesPluginTests.groovy b/src/test/groovy/com/gorylenko/GitPropertiesPluginTests.groovy index 380b4f5..3fe3486 100644 --- a/src/test/groovy/com/gorylenko/GitPropertiesPluginTests.groovy +++ b/src/test/groovy/com/gorylenko/GitPropertiesPluginTests.groovy @@ -7,9 +7,11 @@ import org.junit.After import org.junit.Before import org.junit.Test +import static org.hamcrest.CoreMatchers.startsWith import static org.junit.Assert.assertEquals import static org.junit.Assert.assertFalse import static org.junit.Assert.assertNotNull +import static org.junit.Assert.assertThat import static org.junit.Assert.assertTrue import static org.junit.Assert.fail @@ -93,7 +95,7 @@ class GitPropertiesPluginTests { fail('should have gotten a GradleException') } catch (Exception e) { assertEquals(GradleException, e.class) - assertEquals("No Git repository found.", e.message) + assertThat(e.message, startsWith("No Git repository found.")) } } }