name.remal.gradle_plugins.toolkit.build_logic.helpers.gradle Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of build-logic Show documentation
Show all versions of build-logic Show documentation
Remal Gradle plugins: toolkit: build-logic
The newest version!
import static java.nio.charset.StandardCharsets.UTF_8
import static java.util.stream.Collectors.toList
import static org.gradle.api.attributes.Category.CATEGORY_ATTRIBUTE
import static org.gradle.api.attributes.Category.DOCUMENTATION
import static org.gradle.api.attributes.Category.ENFORCED_PLATFORM
import static org.gradle.api.attributes.Category.REGULAR_PLATFORM
import static org.gradle.api.attributes.Category.VERIFICATION
import groovy.json.JsonGenerator
import groovy.json.JsonSlurper
import groovy.xml.XmlSlurper
import groovy.xml.slurpersupport.GPathResult
import java.lang.reflect.Method
import java.lang.reflect.Modifier
import java.net.http.HttpClient
import java.net.http.HttpRequest
import java.net.http.HttpResponse
import java.security.MessageDigest
import java.time.Duration
import java.util.concurrent.Callable
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentMap
import java.util.function.Supplier
import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.DefaultVersionComparator
import org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionParser
import org.gradle.internal.resource.transport.http.HttpErrorStatusCodeException
import org.gradle.util.GradleVersion
import org.json.JSONArray
import org.json.JSONObject
import org.json.JSONTokener
import org.jsoup.Jsoup
import org.jsoup.nodes.Document
import org.xml.sax.EntityResolver
import org.xml.sax.InputSource
import org.xml.sax.SAXException
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
buildscript {
dependencies {
classpath "org.json:json:20240303"
classpath "org.jsoup:jsoup:1.18.3"
classpath "com.vdurmont:semver4j:3.1.0"
}
repositories {
mavenCentral()
}
}
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Object MUTEX = new Object[0]
project.ext.isBuildSrcProject = rootProject.name == 'buildSrc'
File rootProjectDir = project.ext.rootProjectDir = project.rootDir
if (project.isBuildSrcProject) {
rootProjectDir = project.ext.rootProjectDir = rootProjectDir.parentFile
}
project.ext.unwrapProviders = { object ->
while (true) {
if (object instanceof Provider) {
object = object.get()
} else if (object instanceof Supplier) {
object = object.get()
} else if (object instanceof Callable) {
object = object.call()
} else {
return object
}
}
}
allprojects {
project.ext.afterEvaluateOrNow = { Closure action ->
if (project.state.executed) {
project.configure(project, action)
} else {
project.afterEvaluate(action)
}
}
project.ext.withPluginAfterEvaluateOrNow = { String pluginId, Closure action ->
project.afterEvaluateOrNow {
project.pluginManager.withPlugin(pluginId) {
project.configure(project, action)
}
}
}
}
project.ext.startWithWord = { CharSequence untypedString, CharSequence untypedNeedle ->
if (untypedString == null || untypedNeedle == null) {
return false
}
if (untypedNeedle.length() == 0) {
return true
}
if (untypedString.length() == 0) {
return false
}
String string = untypedString.toString()
String needle = untypedNeedle.toString()
if (string == needle) {
return true
}
if (string.startsWith(needle)) {
String remaining = string.substring(needle.length())
char firstRemainingChar = remaining.charAt(0)
char lastNeedleChar = needle.charAt(needle.length() - 1)
if (Character.isDigit(lastNeedleChar)) {
return !Character.isDigit(firstRemainingChar)
} else if (Character.isLetter(lastNeedleChar)) {
if (!Character.isLetter(lastNeedleChar)) {
return true
} else if (Character.isUpperCase(firstRemainingChar) && !Character.isUpperCase(lastNeedleChar)) {
return true
} else if (Character.isLowerCase(firstRemainingChar) && !Character.isLowerCase(lastNeedleChar)) {
return true
} else {
return false
}
} else {
return Character.isLetter(firstRemainingChar)
}
}
return false
}
project.ext.isInstanceOf = { Object object, String parentClassName ->
if (object == null) {
return false
}
Class> parentClass = Class.forName(parentClassName, true, object.class.classLoader)
return parentClass.isInstance(object)
}
project.ext.disableTask = { Task task ->
task.enabled = false
task.onlyIf { false }
task.dependsOn = []
Iterator registeredFileProperties = task.inputs.registeredFileProperties.iterator()
while (registeredFileProperties.hasNext()) {
registeredFileProperties.next()
registeredFileProperties.remove()
}
}
project.ext.isVerificationTask = { Task task ->
if (task instanceof VerificationTask
|| task instanceof AbstractTestTask
|| task instanceof ValidatePlugins
|| task instanceof JacocoCoverageVerification
) {
return true
}
return false
}
List sourceSetGetConfigurationNameMethods = SourceSet.getMethods().findAll {
it.name.startsWith('get')
&& it.name.endsWith('ConfigurationName')
&& it.returnType == String
&& it.parameterCount == 0
&& !Modifier.isStatic(it.modifiers)
}
project.ext.getSourceSetConfigurationNames = { SourceSet sourceSet ->
return sourceSetGetConfigurationNameMethods.collect { it.invoke(sourceSet) }
.findAll { it != null }
.toSet()
}
allprojects {
project.ext.getAllSourceSetConfigurations = { SourceSet sourceSet ->
Collection sourceSetConfigurationNames = project.getSourceSetConfigurationNames(sourceSet)
return project.configurations.matching { sourceSetConfigurationNames.contains(it.name) }
}.memoize()
DomainObjectSet allSourceSetsConfigurations = project.ext.allSourceSetsConfigurations = project.objects.domainObjectSet(Configuration)
project.pluginManager.withPlugin('java') {
project.sourceSets.all { SourceSet sourceSet ->
project.getAllSourceSetConfigurations(sourceSet).all { allSourceSetsConfigurations.add(it) }
}
}
}
project.ext.getDependencyCategory = { Object dep ->
AttributeContainer attributes = null
if (dep instanceof ModuleDependency) {
attributes = dep.attributes
} else if (dep instanceof ResolvedDependencyResult) {
attributes = dep.resolvedVariant.attributes
} else if (dep instanceof UnresolvedDependencyResult) {
attributes = dep.attempted.attributes
} else if (dep instanceof Dependency) {
return false
} else {
throw new GradleException("Unsupported dependency type: ${dep.class}")
}
Attribute categoryAttribute = attributes.keySet().find { attr ->
if (attr instanceof String) {
return attr == CATEGORY_ATTRIBUTE.name
} else {
return attr.name == CATEGORY_ATTRIBUTE.name
}
}
if (categoryAttribute == null) {
return null;
}
Object value = attributes.getAttribute(categoryAttribute)
if (value instanceof String) {
return value
}
return value.name
}
project.ext.isPlatformDependency = { Object dep ->
String category = getDependencyCategory(dep)
return [REGULAR_PLATFORM, ENFORCED_PLATFORM].contains(category)
}
project.ext.isEnforcedPlatformDependency = { Object dep ->
String category = getDependencyCategory(dep)
return [ENFORCED_PLATFORM].contains(category)
}
project.ext.isDocumentationDependency = { Object dep ->
String category = getDependencyCategory(dep)
return [DOCUMENTATION].contains(category)
}
project.ext.isVerificationDependency = { Object dep ->
String category = getDependencyCategory(dep)
return [VERIFICATION].contains(category)
}
project.ext.calculateBaseJavaPackageFor = { Project project ->
String baseJavaPackage = project.ext.find('baseJavaPackage')
if (baseJavaPackage != null) {
return baseJavaPackage
}
List baseJavaPackageTokens = "${rootProject.group}:${rootProject.name}${project.path}".split(/[.:]+/)
.findAll { !it.isEmpty() }
int hiddenTokenPos = baseJavaPackageTokens.findIndexOf { it.contains('--') }
if (hiddenTokenPos >= 0) {
baseJavaPackageTokens = baseJavaPackageTokens.subList(0, hiddenTokenPos)
}
for (int window = 1; window <= baseJavaPackageTokens.size() / 2; ++window) {
int index = -1
while (true) {
++index
int start = index
int end = start + window
int nextStart = end
int nextEnd = nextStart + window
if (nextEnd > baseJavaPackageTokens.size()) {
break
}
String token = baseJavaPackageTokens.subList(start, end).join('.')
String nextToken = baseJavaPackageTokens.subList(nextStart, nextEnd).join('.')
if (token == nextToken) {
for (int n = 1; n <= window; ++n) {
baseJavaPackageTokens.remove(index)
}
--index
} else if ("${token}-root" == nextToken) {
for (int n = 1; n <= window; ++n) {
baseJavaPackageTokens.remove(index + 1)
}
--index
} else if (token == "${nextToken}-root") {
for (int n = 1; n <= window; ++n) {
baseJavaPackageTokens.remove(index)
}
--index
}
}
}
return baseJavaPackageTokens.join('.')
.replaceAll(/[^\w.]+/, '_')
.replaceAll(/_{2,}/, '_')
.replaceAll(/_\./, '.')
.replaceAll(/\._/, '.')
.replaceAll(/\.{2,}/, '.')
.replaceFirst(/^\./, '')
.replaceFirst(/\.$/, '')
}.memoize()
allprojects {
project.ext.calculateBaseJavaPackage = {
return project.calculateBaseJavaPackageFor(project)
}.memoize()
project.ext.calculateJavaModuleName = {
return project.findProperty('javaModuleName') ?: project.calculateBaseJavaPackage()
}.memoize()
}
allprojects {
Closure maybeRegisterTask = { String taskName, Closure configurer ->
try {
return tasks.named(taskName)
} catch (UnknownTaskException ignore) {
// do nothing
}
return tasks.register(taskName) { Task task -> configurer(task) }
}
Closure findSourceSet = { String sourceSetName, boolean isRequired = true ->
if (isRequired) {
return project.sourceSets.getByName(sourceSetName)
} else {
return project.sourceSets.findByName(sourceSetName)
}
}
project.ext.registerResolveSourceSetCompileClasspathTask = { String sourceSetName, boolean isRequired = true ->
String taskName = "resolve${sourceSetName.capitalize()}SourceSetCompileClasspath"
TaskProvider taskProvider = maybeRegisterTask(taskName) { Task task ->
task.ext.isRequired = false
task.dependsOn(project.provider { findSourceSet(sourceSetName, task.isRequired)?.with { project.configurations[it.compileClasspathConfigurationName].allDependencies } ?: [] })
task.doLast { findSourceSet(sourceSetName, task.isRequired)?.compileClasspath?.files }
}
if (isRequired) {
taskProvider.configure { Task task ->
task.ext.isRequired = true
}
}
return taskProvider
}
project.ext.registerResolveSourceSetRuntimeClasspathTask = { String sourceSetName, boolean isRequired = true ->
String taskName = "resolve${sourceSetName.capitalize()}SourceSetRuntimeClasspath"
TaskProvider taskProvider = maybeRegisterTask(taskName) { Task task ->
task.ext.isRequired = false
task.dependsOn(project.provider { findSourceSet(sourceSetName, task.isRequired)?.with { project.configurations[it.runtimeClasspathConfigurationName].allDependencies } ?: [] })
task.dependsOn(project.provider { findSourceSet(sourceSetName, task.isRequired)?.classesTaskName ?: [] })
task.doLast { findSourceSet(sourceSetName, task.isRequired)?.runtimeClasspath?.files }
}
if (isRequired) {
taskProvider.configure { Task task ->
task.ext.isRequired = true
}
}
return taskProvider
}
Closure findConfiguration = { String configurationName, boolean isRequired = true ->
if (isRequired) {
return project.configurations.getByName(configurationName)
} else {
return project.configurations.findByName(configurationName)
}
}
project.ext.registerResolveConfigurationTask = { String configurationName, boolean isRequired = true ->
String taskName = "resolve${configurationName.capitalize()}Configuration"
TaskProvider taskProvider = maybeRegisterTask(taskName) { Task task ->
task.ext.isRequired = false
task.dependsOn(project.provider { findConfiguration(configurationName, task.isRequired)?.allDependencies ?: [] })
task.doLast { findConfiguration(configurationName, task.isRequired)?.resolve() }
}
if (isRequired) {
taskProvider.configure { Task task ->
task.ext.isRequired = true
}
}
return taskProvider
}
}
Closure sha512hex = project.ext.sha512hex = { Object content ->
if (content instanceof CharSequence) {
content = content.toString().getBytes('UTF-8')
}
if (!(content instanceof byte[])) {
throw new IllegalAccessException("content must be instance of CharSequence or byte[]")
}
MessageDigest md = MessageDigest.getInstance("SHA-512")
byte[] hash = md.digest((byte[]) content)
StringBuilder hex = new StringBuilder(hash.length * 2)
for (byte b : hash) {
hex.append(String.format("%02x", b))
}
return hex.toString()
}
File downloadedContentCacheDir = project.layout.buildDirectory.dir('downloaded-content-cache').get().asFile
Closure getCacheFileForDownloadedUrl = project.ext.getCacheFileForDownloadedUrl = { Object untypedUrl, String cacheFileNameSuffix = null ->
URL url = project.uri(untypedUrl).toURL()
if (cacheFileNameSuffix == null) {
cacheFileNameSuffix = url.path.with { String path ->
path = new File(path).getName()
int dotPos = path.lastIndexOf('.')
return dotPos >= 0 ? path.substring(dotPos) : ''
}
}
return new File(downloadedContentCacheDir, sha512hex(url.toString()) + cacheFileNameSuffix)
}
Closure loadUrlContent = project.ext.loadUrlContent = { Object untypedUrl, String cacheFileNameSuffix = null ->
synchronized (MUTEX) {
File cacheFile = getCacheFileForDownloadedUrl(untypedUrl, cacheFileNameSuffix)
if (cacheFile.exists()) {
return cacheFile.bytes
}
URL url = project.uri(untypedUrl).toURL()
URLConnection connection = url.openConnection()
connection.connectTimeout = 5_000
connection.readTimeout = 30_000
connection.useCaches = false
try {
if (connection instanceof HttpURLConnection) {
if (connection.responseCode != 200) {
throw new HttpErrorStatusCodeException(
'GET',
url.toString(),
connection.responseCode,
'Not Found'
)
}
}
byte[] content = connection.inputStream.bytes
cacheFile.parentFile.mkdirs()
cacheFile.bytes = content
return content
} finally {
if (connection instanceof HttpURLConnection) {
connection.disconnect()
}
}
}
}
Closure loadTextUrlContent = project.ext.loadTextUrlContent = { Object untypedUrl, String encoding = null, String cacheFileNameSuffix = null ->
byte[] content = loadUrlContent(untypedUrl, cacheFileNameSuffix)
return new String(content, encoding ?: 'UTF-8')
}
Closure loadJsonFromUrl = project.ext.loadJsonFromUrl = { Object untypedUrl, String encoding = null ->
String content = loadTextUrlContent(untypedUrl, encoding, '.json')
return new JSONTokener(content).nextValue()
}
Closure loadHtmlFromUrl = project.ext.loadHtmlFromUrl = { Object untypedUrl, String encoding = null ->
String content = loadTextUrlContent(untypedUrl, encoding, '.html')
return Jsoup.parse(content, project.uri(untypedUrl).toString())
}
Closure loadXmlFromUrl = project.ext.loadXmlFromUrl = { Object untypedUrl, String encoding = null ->
XmlSlurper xmlParser = new XmlSlurper(false, true, true)
xmlParser.entityResolver = new EntityResolver() {
@Override
InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
new InputSource(new StringReader(""))
}
}
String content = loadTextUrlContent(untypedUrl, encoding, '.xml')
return xmlParser.parseText(content)
}
Closure> getAllGradleVersions = project.ext.getAllGradleVersions = {
List result = []
JSONArray versionObjects = loadJsonFromUrl('https://services.gradle.org/versions/all')
for (JSONObject versionObject : versionObjects) {
if (versionObject.optBoolean('snapshot')) {
continue
}
if (versionObject.optBoolean('nightly')) {
continue
}
if (versionObject.optBoolean('releaseNightly')) {
continue
}
if (versionObject.optBoolean('broken')) {
continue
}
if (!versionObject.optString('milestoneFor').isEmpty()) {
continue
}
if (!versionObject.optBoolean('activeRc') && !versionObject.optString('rcFor').isEmpty()) {
continue
}
String version = versionObject.getString('version')
if (version.containsIgnoreCase('milestone')) {
continue
}
if (version.startsWith('0.')) {
continue
}
GradleVersion gradleVersion = GradleVersion.version(version)
if (gradleVersion.baseVersion == gradleVersion) {
result.add(gradleVersion)
}
}
result.sort(Comparator.reverseOrder())
return result
}.memoize()
Closure> getStableGradleVersions = project.ext.getStableGradleVersions = {
return getAllGradleVersions().findAll { it.baseVersion == it }
}.memoize()
Closure> getMinorGradleVersions = project.ext.getMinorGradleVersions = {
return getStableGradleVersions().findAll { it.version.count('.') == 1 }
}
Closure> getFilteredJavaRuntimeVersions = { Closure filter ->
List result = []
JSONArray versionObjects = loadJsonFromUrl('https://api.foojay.io/disco/v3.0/major_versions?ea=false&ga=true&discovery_scope_id=public&include_versions=false')['result']
for (JSONObject versionObject : versionObjects) {
if (versionObject.optBoolean('early_access_only')) {
continue
}
if (versionObject.optString('release_status') == 'ea') {
continue
}
if (!filter(versionObject)) {
continue
}
int version = versionObject.getInt('major_version')
if (version < 8) {
continue
}
result.add(version)
}
result.sort(Comparator.reverseOrder())
return result
}
Closure> getAllJavaRuntimeVersions = project.ext.getAllJavaRuntimeVersions = {
return getFilteredJavaRuntimeVersions { true }
}.memoize()
Closure> getLtsJavaRuntimeVersions = project.ext.getLtsJavaRuntimeVersions = {
return getFilteredJavaRuntimeVersions { JSONObject versionObject ->
versionObject.getString('term_of_support') == 'LTS'
}
}.memoize()
Property publishedVersionsDirRelativePathProperty = project.ext.publishedVersionsDirRelativePath = project.objects.property(String)
Closure> getPluginVersions = project.ext.getPluginVersions = { String pluginId ->
def metadata = null
try {
metadata = loadXmlFromUrl("https://plugins.gradle.org/m2/${pluginId.replace('.', '/')}/${pluginId}.gradle.plugin/maven-metadata.xml")
} catch (HttpErrorStatusCodeException e) {
if (e.statusCode == 404) {
return []
}
}
List versions = metadata.versioning.versions.version*.text().collect()
String publishedVersionsDirRelativePath = publishedVersionsDirRelativePathProperty.orNull
if (publishedVersionsDirRelativePath != null) {
File publishedVersionFile = new File(rootProjectDir, "$publishedVersionsDirRelativePath/$pluginId/${pluginId}.gradle.plugin.version")
if (publishedVersionFile.isFile()) {
String publishedVersion = publishedVersionFile.getText('UTF-8')
if (!publishedVersion.isEmpty()) {
versions.add(publishedVersion)
}
}
}
VersionParser parser = new VersionParser()
Comparator comparator = new DefaultVersionComparator().asVersionComparator()
versions = versions.stream()
.map { it.trim() }
.filter { !it.isEmpty() }
.distinct()
.map { parser.transform(it) }
.sorted(comparator.reversed())
.map { it.toString() }
.collect(toList())
return versions
}.memoize()
Closure getPluginLastVersion = project.ext.getPluginLastVersion = { String pluginId ->
List versions = getPluginVersions(pluginId)
if (!versions.isEmpty()) {
return versions.first()
}
throw new IllegalStateException("No versions were found for plugin '$pluginId'")
}
Closure getPluginLastVersionWithCurrentAsFallback = project.ext.getPluginLastVersionWithCurrentAsFallback = { String pluginId ->
List versions = getPluginVersions(pluginId)
if (!versions.isEmpty()) {
return versions.first()
}
String currentVersion = project.allprojects.stream()
.filter { it.pluginManager.hasPlugin('maven-publish') }
.flatMap { it.publishing.publications.withType(MavenPublication).stream() }
.map { MavenPublication.cast(it) }
.filter { it.groupId == pluginId && it.artifactId == "${pluginId}.gradle.plugin" }
.map { it.version }
.filter { it != null && !it.isEmpty() }
.findFirst()
.orElse(null)
if (currentVersion != null) {
return currentVersion;
}
throw new IllegalStateException("No versions were found for plugin '$pluginId'")
}
ConcurrentMap getGradleApiDependencyVersionCache = new ConcurrentHashMap<>()
allprojects {
project.ext.getGradleApiDependencyVersion = { String notation ->
return getGradleApiDependencyVersionCache.computeIfAbsent(notation) {
String gradleApiVersion = project.configurations.projectDependencyConstraints
.allDependencyConstraints
.find { "${it.group}:${it.name}" == 'name.remal.gradle-api:gradle-api' }
?.version
if (gradleApiVersion == null) {
throw new GradleException('Unknown Gradle API version')
}
Configuration tempConf = project.configurations.detachedConfiguration(
project.dependencies.create("name.remal.gradle-api:gradle-api:$gradleApiVersion")
)
String version = tempConf.resolvedConfiguration
.resolvedArtifacts
.collect { it.moduleVersion }
.collect { it.id }
.find { "${it.group}:*" == notation || "${it.group}:${it.name}" == notation }
?.version
if (version == null) {
throw new GradleException("Gradle API dependency not found: $notation")
}
return version
}
}
}
allprojects {
project.ext.fatJarWithDependentTaskNames = [
'generateJava',
'generateResources',
'classes',
'jar',
'sourcesJar',
'javadocJar',
]
Closure fatJarWithImpl = { Project otherProject ->
configurations.compileOnly.dependencies.add(dependencies.create(otherProject))
otherProject.tasks.withType(Javadoc).configureEach { enabled = false }
project.fatJarWithDependentTaskNames.forEach { String taskName ->
tasks.matching { it.name == taskName }.configureEach {
dependsOn(otherProject.tasks.matching { it.name == taskName })
}
}
sourceSets.main.allSource.srcDirs(otherProject.sourceSets.main.allSource.srcDirs)
otherProject.sourceSets.main.output.forEach { sourceSets.main.output.dir(it) }
tasks.withType(AbstractCopyTask).configureEach {
filesMatching(['**/package-info.class', '**/package-info.java']) {
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
}
tasks.withType(Javadoc).configureEach { Javadoc task ->
task.dependsOn(project.provider { otherProject.registerResolveConfigurationTask('optionalHidden') })
task.onlyIf {
task.classpath += otherProject.configurations.optionalHidden
otherProject.tasks.withType(Javadoc).forEach { Javadoc otherTask ->
task.classpath += otherTask.classpath
}
return true
}
Set processedPackageInfoResources = new LinkedHashSet<>()
task.exclude { FileTreeElement element ->
String path = element.path
if ("/$path".endsWith('/package-info.class') || "/$path".endsWith('/package-info.java')) {
return !processedPackageInfoResources.add(path)
}
}
task.source(project.provider {
otherProject.tasks.withType(Javadoc)
.collect { it.source }
})
}
}
Set fatJarWithProjects = new LinkedHashSet<>()
project.ext.fatJarWith = { Project otherProject ->
if (!fatJarWithProjects.add(otherProject)) {
return
}
project.withPluginAfterEvaluateOrNow('java') {
otherProject.withPluginAfterEvaluateOrNow('java') {
fatJarWithImpl(otherProject)
}
}
}
}
Closure getClassLocationFile = project.ext.getClassLocationFile = { Class clazz ->
URL location = clazz?.protectionDomain?.codeSource?.location
if (location == null) {
return null
}
try {
return project.file(location)
} catch (IllegalArgumentException ignored) {
return null
}
}
Closure addClassLocationFileToInputs = project.ext.addClassLocationFileToInputs = { Class clazz, TaskInputs inputs ->
File file = getClassLocationFile(clazz)
if (file == null) {
// do nothing
} else if (file.isDirectory()) {
inputs.dir(file).optional()
} else {
inputs.file(file).optional()
}
}
project.ext.sendGitHubRestApiRequest = { String uriString, String method = null, Object requestBody = null ->
URI uri = new URI(uriString)
if (!uri.absolute) {
if (uri.toString().startsWith('/')) {
uri = new URI(
project.ext['github-api-url'].replaceFirst('/+$', '')
+ '/'
+ uri.toString().replaceFirst('^/+', '')
)
} else {
uri = new URI(
project.ext['repository-api-url'].replaceFirst('/+$', '')
+ '/'
+ uri.toString().replaceFirst('^/+', '')
)
}
}
int maxAttempts = 3
int attempt = 0
while (true) {
++attempt
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.timeout(Duration.ofMinutes(1))
.uri(uri)
.header('Authorization', "token ${project.ext['github-actions-token']}")
.header('Accept', 'application/vnd.github+json')
.header('Content-Type', 'application/json;charset=UTF-8')
if (requestBody !== null) {
HttpRequest.BodyPublisher bodyPublisher
if (requestBody instanceof HttpRequest.BodyPublisher) {
bodyPublisher = requestBody
} else {
JsonGenerator jsonGenerator = new JsonGenerator.Options()
.excludeNulls()
.excludeFieldsByName('contentHash', 'originalClassName')
.build()
String jsonContent = jsonGenerator.toJson(requestBody)
bodyPublisher = HttpRequest.BodyPublishers.ofString(jsonContent, UTF_8)
}
method = method?.toUpperCase() ?: 'PUT'
requestBuilder = requestBuilder.method(method, bodyPublisher)
} else {
method = method?.toUpperCase() ?: 'GET'
requestBuilder = requestBuilder."$method"()
}
HttpRequest request = requestBuilder.build()
logger.info("{}", request)
HttpResponse response = HttpClient.newHttpClient().send(request, HttpResponse.BodyHandlers.ofString(UTF_8))
int statusCode = response.statusCode()
if (statusCode == 404 || statusCode == 204) {
return null
}
if (statusCode >= 400) {
if (statusCode == 429
|| statusCode >= 500
) {
if (attempt < maxAttempts) {
Thread.sleep(5_000)
continue
}
}
}
String responseBodyJson = response.body()
Object responseBody = responseBodyJson.isEmpty() ? null : new JsonSlurper().parseText(responseBodyJson)
if (statusCode >= 400) {
throw new HttpErrorStatusCodeException(
method,
uri.toString(),
statusCode,
responseBody.toString()
)
}
return responseBody
}
}
allprojects {
project.ext.redefineDependencyTargetJvmVersion = { String moduleNotation, int jvmVersion ->
allprojects {
dependencies.components {
withModule(moduleNotation, TargetJvmVersionRule) { params(jvmVersion) }
}
}
}
}
@CacheableRule
abstract class TargetJvmVersionRule implements ComponentMetadataRule {
final Integer jvmVersion
@Inject
TargetJvmVersionRule(Integer jvmVersion) {
this.jvmVersion = jvmVersion
}
void execute(ComponentMetadataContext context) {
context.details.allVariants {
attributes {
attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, jvmVersion)
}
}
}
@Override
String toString() {
return "${getClass().simpleName}[$jvmVersion]"
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy