-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.gradle.kts
More file actions
170 lines (147 loc) · 5.21 KB
/
build.gradle.kts
File metadata and controls
170 lines (147 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import com.vanniktech.maven.publish.DeploymentValidation
import com.vanniktech.maven.publish.VersionCatalog
import com.xenoterracide.gradle.convention.publish.GithubPublicRepositoryConfiguration
import org.semver4j.Semver
// SPDX-FileCopyrightText: Copyright © 2024-2026 Caleb Cushing
//
// SPDX-License-Identifier: MIT
buildscript { dependencyLocking { lockAllConfigurations() } }
plugins {
`lifecycle-base`
`version-catalog`
alias(libs.plugins.publish)
alias(libs.plugins.semver)
alias(libs.plugins.vanniktech.maven.publish)
}
group = "com.xenoterracide.gradle.vc"
dependencyLocking {
lockAllConfigurations()
}
val isPublishing =
providers
.environmentVariable("IS_PUBLISHING")
version =
isPublishing
.flatMap { semver.provider }
.getOrElse(Semver.ZERO)
description = "Spring Boot Version Catalog - All Dependencies"
repositoryHost(GithubPublicRepositoryConfiguration())
repositoryHost.namespace.set("xenoterracide")
publicationLegal {
inceptionYear.set(2025)
spdxLicenseIdentifiers.add("Apache-2.0")
}
mavenPublishing {
signAllPublications()
configure(VersionCatalog())
publishToMavenCentral(false, DeploymentValidation.VALIDATED)
}
publishing {
publications {
this.withType<MavenPublication>().configureEach {
pom {
name.set(project.name)
description.set(project.description)
url.set(
repositoryHost.repository.websiteUrl
.zip(git.tag.map { "/tree/$it" }.orElse("")) { uri, tag ->
uri.toString() + tag
},
)
scm { tag.set(git.tag) }
}
}
}
}
tasks.register("stagingPath") {
description = "Print path to staging repository for the primary publication"
group = "Publishing"
val stagingDir = layout.buildDirectory.dir("repo")
val groupPath = project.group.toString().replace(".", "/")
val artifactId = project.name
val setVersion = version
doLast {
print(
stagingDir
.get()
.asFile
.resolve("$groupPath/$artifactId/$setVersion")
.absolutePath,
)
}
}
catalog {
// Build the version catalog programmatically from the TOON file.
// We intentionally DO NOT declare versions here; consumers should use Spring Boot's platform/BOM
// (e.g., implementation(platform("org.springframework.boot:spring-boot-dependencies:<ver>"))).
versionCatalog {
// implementation written by Junie
// Helper: aliasing and registration (shared for any parser)
fun normalizeToken(token: String): String = token.lowercase().replace(Regex("[^a-z0-9]+"), "-").trim('-')
fun registerEntries(pairs: List<Pair<String, String>>) {
val used = mutableMapOf<String, Int>()
fun uniqueAlias(base: String): String {
val n = used.getOrDefault(base, 0)
return if (n == 0) {
used[base] = 1
base
} else {
val next = n + 1
used[base] = next
"$base-$next"
}
}
val artifactCounts = pairs.groupingBy { it.second }.eachCount()
pairs.forEach { (group, artifact) ->
val artifactNorm = normalizeToken(artifact)
val baseAlias =
if ((artifactCounts[artifact] ?: 0) > 1) {
val groupKey = normalizeToken(group)
"$groupKey-$artifactNorm"
} else {
artifactNorm
}
val alias = uniqueAlias(baseAlias)
library(alias, group, artifact).withoutVersion()
}
}
// Parse dependencies.html leniently (no strict XML). Works with imperfect HTML.
val htmlFile = file("dependencies.html")
if (!htmlFile.exists()) {
throw GradleException("dependencies.html not found at ${htmlFile.absolutePath}. Provide the Spring Boot dependencies table HTML.")
}
try {
val html = htmlFile.readText()
// Extract the first <tbody> ... </tbody> block (case-insensitive, dotall)
val tbodyMatch = Regex("(?is)<tbody[^>]*>(.*?)</tbody>").find(html)
val tbody =
tbodyMatch?.groupValues?.get(1)
?: throw GradleException("Could not locate <tbody> ... </tbody> in dependencies.html")
// Collect all <code>...</code> tokens in order (group, artifact, version repeating)
val codeRegex = Regex("(?is)<code[^>]*>(.*?)</code>")
val tokens =
codeRegex
.findAll(tbody)
.map { m ->
// Strip any nested tags and trim
m.groupValues[1].replace(Regex("(?is)<[^>]+>"), "").trim()
}.toList()
if (tokens.isEmpty() || tokens.size % 3 != 0) {
throw GradleException(
"Expected triples of <code>group</code>, <code>artifact</code>, <code>version</code> within <tbody>. Found ${tokens.size} tokens.",
)
}
val pairs =
tokens.chunked(3).map { chunk ->
val group = chunk[0]
val artifact = chunk[1]
group to artifact
}
require(pairs.isNotEmpty()) { "No dependency rows parsed from dependencies.html" }
registerEntries(pairs.sortedWith(compareBy({ it.first }, { it.second })))
logger.lifecycle("Version catalog: loaded ${pairs.size} entries from dependencies.html via lenient HTML parsing")
} catch (e: Throwable) {
throw GradleException("Failed to parse dependencies.html using lenient HTML parsing", e)
}
}
}