Skip to content

Commit 855440d

Browse files
committed
refactor(Gradle): Move Git-related code to ValueSource providers
This is a better way to make running external processes compatible with the configuration cache, see [1]. [1]: https://docs.gradle.org/current/userguide/configuration_cache.html#config_cache:requirements:external_processes Signed-off-by: Sebastian Schuberth <[email protected]>
1 parent 9c10b44 commit 855440d

File tree

3 files changed

+82
-76
lines changed

3 files changed

+82
-76
lines changed

build.gradle.kts

Lines changed: 10 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,7 @@
1919

2020
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
2121

22-
import org.eclipse.jgit.api.Git
2322
import org.eclipse.jgit.ignore.FastIgnoreRule
24-
import org.eclipse.jgit.lib.Config
25-
import org.eclipse.jgit.lib.Constants
26-
import org.eclipse.jgit.revwalk.RevWalk
27-
import org.eclipse.jgit.storage.file.FileBasedConfig
28-
import org.eclipse.jgit.treewalk.TreeWalk
29-
import org.eclipse.jgit.util.FS
30-
import org.eclipse.jgit.util.SystemReader
3123

3224
import org.jetbrains.gradle.ext.Gradle
3325
import org.jetbrains.gradle.ext.runConfigurations
@@ -40,48 +32,10 @@ plugins {
4032
alias(libs.plugins.versions)
4133
}
4234

43-
buildscript {
44-
repositories {
45-
mavenCentral()
46-
}
47-
48-
dependencies {
49-
classpath(libs.jgit)
50-
}
51-
}
52-
53-
class GitConfigNoSystemReader(private val delegate: SystemReader) : SystemReader() {
54-
override fun getenv(variable: String): String? {
55-
if (variable == "GIT_CONFIG_NOSYSTEM") return "true"
56-
return delegate.getenv(variable)
57-
}
58-
59-
override fun openSystemConfig(parent: Config?, fs: FS): FileBasedConfig =
60-
object : FileBasedConfig(parent, null, fs) {
61-
override fun load() = Unit
62-
override fun isOutdated(): Boolean = false
63-
}
64-
65-
override fun getHostname(): String = delegate.hostname
66-
override fun getProperty(key: String): String? = delegate.getProperty(key)
67-
override fun openUserConfig(parent: Config?, fs: FS): FileBasedConfig = delegate.openUserConfig(parent, fs)
68-
override fun openJGitConfig(parent: Config?, fs: FS): FileBasedConfig = delegate.openJGitConfig(parent, fs)
69-
override fun getCurrentTime(): Long = delegate.currentTime
70-
override fun getTimezone(`when`: Long): Int = delegate.getTimezone(`when`)
71-
}
72-
73-
SystemReader.setInstance(GitConfigNoSystemReader(SystemReader.getInstance()))
74-
7535
// Only override a default version (which usually is "unspecified"), but not a custom version.
7636
if (version == Project.DEFAULT_VERSION) {
77-
version = Git.open(rootDir).use { git ->
78-
// Make the output exactly match "git describe --abbrev=10 --always --tags --dirty --match=[0-9]*", which is
79-
// what is used in "scripts/docker_build.sh", to make the hash match what JitPack uses.
80-
val description = git.describe().setAbbrev(10).setAlways(true).setTags(true).setMatch("[0-9]*").call()
81-
82-
// Simulate the "--dirty" option with JGit.
83-
description.takeUnless { git.status().call().hasUncommittedChanges() } ?: "$description-dirty"
84-
}
37+
val gitVersionProvider = providers.of(GitVersionValueSource::class) { parameters { workingDir = rootDir } }
38+
version = gitVersionProvider.get()
8539
}
8640

8741
logger.lifecycle("Building ORT version $version.")
@@ -135,30 +89,6 @@ tasks.register("allDependencies") {
13589
}
13690
}
13791

138-
fun getCommittedFilePaths(rootDir: File): List<File> {
139-
val filePaths = mutableListOf<File>()
140-
141-
Git.open(rootDir).use { git ->
142-
TreeWalk(git.repository).use { treeWalk ->
143-
val headCommit = RevWalk(git.repository).use {
144-
val head = git.repository.resolve(Constants.HEAD)
145-
it.parseCommit(head)
146-
}
147-
148-
with(treeWalk) {
149-
addTree(headCommit.tree)
150-
isRecursive = true
151-
}
152-
153-
while (treeWalk.next()) {
154-
filePaths += rootDir.resolve(treeWalk.pathString)
155-
}
156-
}
157-
}
158-
159-
return filePaths
160-
}
161-
16292
val copyrightExcludedPaths = listOf(
16393
"LICENSE",
16494
"NOTICE",
@@ -191,14 +121,17 @@ val copyrightExcludedExtensions = listOf(
191121
"ttf"
192122
)
193123

194-
fun getCopyrightableFiles(rootDir: File): List<File> =
195-
getCommittedFilePaths(rootDir).filter { file ->
124+
fun getCopyrightableFiles(rootDir: File): List<File> {
125+
val gitFilesProvider = providers.of(GitFilesValueSource::class) { parameters { workingDir = rootDir } }
126+
127+
return gitFilesProvider.get().filter { file ->
196128
val isHidden = file.toPath().any { it.toString().startsWith(".") }
197129

198130
!isHidden
199131
&& copyrightExcludedPaths.none { it in file.invariantSeparatorsPath }
200132
&& file.extension !in copyrightExcludedExtensions
201133
}
134+
}
202135

203136
val maxCopyrightLines = 50
204137

@@ -338,13 +271,14 @@ val checkLicenseHeaders by tasks.registering {
338271
}
339272

340273
val checkGitAttributes by tasks.registering {
341-
val files = getCommittedFilePaths(rootDir)
274+
val gitFilesProvider = providers.of(GitFilesValueSource::class) { parameters { workingDir = rootDir } }
342275

343-
inputs.files(files)
276+
inputs.files(gitFilesProvider)
344277

345278
doLast {
346279
var hasErrors = false
347280

281+
val files = gitFilesProvider.get()
348282
val gitAttributesFiles = files.filter { it.endsWith(".gitattributes") }
349283
val commentChars = setOf('#', '/')
350284

buildSrc/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ dependencies {
3838
implementation(libs.detekt)
3939
implementation(libs.dokkatoo)
4040
implementation(libs.graalVmNativeImage)
41+
implementation(libs.jgit)
4142
implementation(libs.kotlin)
4243
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (C) 2023 The ORT Project Authors (see <https://github.com/oss-review-toolkit/ort/blob/main/NOTICE>)
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
* License-Filename: LICENSE
18+
*/
19+
20+
import java.io.File
21+
22+
import org.eclipse.jgit.api.Git
23+
import org.eclipse.jgit.lib.Constants
24+
import org.eclipse.jgit.revwalk.RevWalk
25+
import org.eclipse.jgit.treewalk.TreeWalk
26+
27+
import org.gradle.api.file.DirectoryProperty
28+
import org.gradle.api.provider.ValueSource
29+
import org.gradle.api.provider.ValueSourceParameters
30+
31+
interface GitParameters : ValueSourceParameters {
32+
val workingDir: DirectoryProperty
33+
}
34+
35+
abstract class GitVersionValueSource : ValueSource<String, GitParameters> {
36+
override fun obtain(): String = Git.open(parameters.workingDir.get().asFile).use { git ->
37+
// Make the output exactly match "git describe --abbrev=10 --always --tags --dirty --match=[0-9]*", which is
38+
// what is used in "scripts/docker_build.sh", to make the hash match what JitPack uses.
39+
val description = git.describe().setAbbrev(10).setAlways(true).setTags(true).setMatch("[0-9]*").call()
40+
41+
// Simulate the "--dirty" option with JGit.
42+
description.takeUnless { git.status().call().hasUncommittedChanges() } ?: "$description-dirty"
43+
}
44+
}
45+
46+
abstract class GitFilesValueSource : ValueSource<List<File>, GitParameters> {
47+
override fun obtain(): List<File> {
48+
val filePaths = mutableListOf<File>()
49+
val workingDir = parameters.workingDir.get().asFile
50+
51+
Git.open(workingDir).use { git ->
52+
TreeWalk(git.repository).use { treeWalk ->
53+
val headCommit = RevWalk(git.repository).use {
54+
val head = git.repository.resolve(Constants.HEAD)
55+
it.parseCommit(head)
56+
}
57+
58+
with(treeWalk) {
59+
addTree(headCommit.tree)
60+
isRecursive = true
61+
}
62+
63+
while (treeWalk.next()) {
64+
filePaths += workingDir.resolve(treeWalk.pathString)
65+
}
66+
}
67+
}
68+
69+
return filePaths
70+
}
71+
}

0 commit comments

Comments
 (0)