Repository navigation
Expand file tree
/
Copy pathbuild.gradle
More file actions
438 lines (378 loc) · 15.1 KB
/
Copy pathbuild.gradle
File metadata and controls
438 lines (378 loc) · 15.1 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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
plugins {
id 'base' // Adds the clean task to the root project
id 'com.gradleup.shadow' version '9.2.2' apply false
id 'org.checkerframework' version '0.6.39' apply false
id 'io.papermc.paperweight.userdev' version '2.0.0-beta.21' apply false
id 'org.ajoberstar.git-publish' version '5.1.1'
// Useful for build debugging:
// https://gitlab.com/barfuin/gradle-taskinfo
//id 'org.barfuin.gradle.taskinfo' version '1.3.0'
id 'org.sonarqube' version '7.2.1.6560'
}
sonar {
properties {
property 'sonar.projectKey', 'Shopkeepers_Shopkeepers'
property 'sonar.organization', 'shopkeepers'
property 'sonar.host.url', 'https://sonarcloud.io'
}
}
ext.getGitHash = { ->
return providers.exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
}.standardOutput.asText.get().trim()
}
// We embed the git hash into jar files, and also use it for the plugin version of snapshot builds.
ext.buildVersion = version + '+' + getGitHash()
ext.isSnapshot = version.contains('-SNAPSHOT')
ext.pluginVersion = isSnapshot ? buildVersion : version
Locale.setDefault(new Locale(System.getProperty("user.language"), System.getProperty("user.country")))
println 'User home: ' + System.properties['user.home']
println 'Local Maven repository: ' + repositories.mavenLocal().url.path
println 'Locale: ' + Locale.getDefault()
println 'Project version: ' + version
println 'Build version: ' + buildVersion
println 'Plugin version: ' + pluginVersion
ext.configureJarTask = { project, jarTask ->
jarTask.inputs.property 'group', project.group
jarTask.inputs.property 'artifactId', project.artifactId
jarTask.inputs.property 'buildVersion', project.buildVersion
jarTask.archiveBaseName = project.artifactId
jarTask.manifest {
attributes 'Implementation-Title': "${project.group}:${project.artifactId}",
'Implementation-Version': project.buildVersion
}
}
ext.configureJarTaskWithMavenMetadata = { project, jarTask ->
configureJarTask(project, jarTask)
// If the maven-publish plugin is used, include the generated Maven metadata files into the jar:
project.plugins.withId('maven-publish') {
jarTask.into("META-INF/maven/$project.group/$project.artifactId") {
from { project.generatePomFileForMavenJavaPublication } {
rename '.*', 'pom.xml'
}
from { project.generateMavenPomPropertiesFile }
}
}
}
ext.configureShadowArtifacts = { project ->
project.artifacts {
// Similar to the regular jar, declare the shadow jar as output of the project for any
// projects that depend on it.
apiElements project.shadowJar
runtimeElements project.shadowJar
}
}
ext.configureMavenPublication = { project, publication ->
publication.artifactId = project.artifactId
publication.pom {
name = project.name
description = project.description
url = dboUrl
scm {
url = scmUrl
connection = scmConnection
developerConnection = scmDeveloperConnection
}
// Note: Gradle intentionally ignores and omits repositories from the pom file.
// https://github.com/gradle/gradle/issues/15932
// https://github.com/gradle/gradle/issues/8811
// Note: Gradle maps all api dependencies to 'compile' scope and all implementation
// dependencies to 'runtime' scope (instead of 'provided' scope). Although this does not
// match the project's compile configuration (since the runtime scope is not considered part
// of the project's compilation classpath), this is not an issue because the primary purpose
// of the published pom file is not to configure the build of this project, but only to
// ensure that any transitive compile and runtime dependencies are declared for consuming
// projects.
}
}
ext.configureShadowMavenPublication = { project, publication ->
configureMavenPublication(project, publication)
// Adding the java component here, instead of the shadow component, ensures that we generate the
// default pom contents, including entries for all dependencies. The shadow component would omit
// all dependencies (except those of the 'shadow' configuration), even if we configure the
// shadowJar task to only include some of the dependencies.
// However, the published artifacts are overridden to only publish the shadow jar instead.
publication.from project.components.java
publication.artifact project.shadowJar
}
ext.disableMavenPublications = { project ->
project.tasks.withType(AbstractPublishToMaven).configureEach {
enabled = false
}
}
allprojects {
// Set up default properties if they match the root project's values:
// Note: In order to allow subprojects to define their values of these properties inside their
// build files (instead of their 'gradle.properties' files), any task configurations that depend
// on these properties have to be deferred until after the subproject's build script has been
// evaluated.
if (project.properties['artifactId'] == rootProject.properties['artifactId']) {
project.ext.artifactId = project.name
}
afterEvaluate {
if (project.artifactId != project.name) {
println 'Artifact id: ' + project.artifactId
}
}
}
subprojects {
// Shared repositories:
repositories {
// Contains the locally built CraftBukkit and Spigot server dependencies.
mavenLocal()
mavenCentral()
// Bukkit, Spigot-API
maven { url = 'https://hub.spigotmc.org/nexus/content/groups/public/' }
// Paper
maven { url = 'https://repo.papermc.io/repository/maven-public/' }
}
// Shared plugin / task configurations:
project.plugins.withId('java-library') {
configurations {
ecj
paperCompileOnly
}
dependencies {
// ECJ compiler for null analysis
ecj 'org.eclipse.jdt:ecj:3.38.0'
paperCompileOnly libs.paper.api
}
java {
sourceCompatibility = JavaVersion.VERSION_21
}
// Null analysis with the Eclipse compiler:
// https://help.eclipse.org/latest/index.jsp?topic=/org.eclipse.jdt.doc.user/tasks/task-using_batch_compiler.htm
// Custom compilers with Gradle 8+: https://github.com/gradle/gradle/issues/23990
// See also https://github.com/TheMrMilchmann/gradle-ecj
task ecjAnalysis(type: JavaCompile) {
source = sourceSets.main.java
classpath = sourceSets.main.compileClasspath
destinationDirectory = layout.buildDirectory.dir("classes-ecj")
// The Java version required to run ECJ:
def ECJ_REQUIRED_JAVA_VERSION = 11
// The Java version to request the toolchain for if the project's toolchain is not
// compatible with the ECJ requirements:
def ECJ_PREFERRED_JAVA_VERSION = 21
def defaultJavaCompiler = provider {
def javaCompiler = javaToolchains.compilerFor(java.toolchain).get()
if (javaCompiler.metadata.languageVersion.canCompileOrRun(ECJ_REQUIRED_JAVA_VERSION)) {
javaCompiler
} else {
javaToolchains.compilerFor {
languageVersion.set(JavaLanguageVersion.of(ECJ_PREFERRED_JAVA_VERSION))
}.get()
}
}
javaCompiler = defaultJavaCompiler
// ECJ does not support generating JNI headers. Make sure the property is not used.
options.headerOutputDirectory.set(provider { null })
options.fork = true
options.forkOptions.jvmArgs += [
'-classpath', project.configurations.ecj.asPath,
'org.eclipse.jdt.internal.compiler.batch.Main',
'-properties', '.settings/org.eclipse.jdt.core.prefs',
'-warn:-deprecation,unused',
'-info:-warningToken',
'-annotationpath', 'CLASSPATH'
]
doFirst {
//println(classpath.getAsPath())
def javacExecutable = javaCompiler.get().executablePath.asFile
def javaExecutableName = javacExecutable.name.replace("javac", "java")
def javaExecutablePath = javacExecutable.parentFile.toPath().resolve(javaExecutableName).toAbsolutePath()
options.forkOptions.executable = javaExecutablePath
}
}
// Check that we can build against Paper's version of the Bukkit API (i.e. verify that we
// don't use any Bukkit API that is not available on Paper):
// TODO This only check compatibility against the lowest supported API version. Also compile
// the shared API and main modules against all other supported API versions of Spigot and
// Paper?
task compileWithPaper(type: JavaCompile) {
source = sourceSets.main.java
classpath = configurations.paperCompileOnly + sourceSets.main.compileClasspath
destinationDirectory = layout.buildDirectory.dir("classes-paperCheck")
// Always re-run this task regardless of existing build output:
outputs.upToDateWhen { false }
}
// Configure all JavaCompile tasks (compileJava, compileTestJava, etc):
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
//options.compilerArgs += ['-Xmaxerrs', '10000', '-Xmaxwarns', '10000']
}
processResources {
from rootProject.file('LICENSE')
from project.sourceSets.main.resources.srcDirs
// TODO Some plugins might add resource directories twice.
// See https://github.com/gradle/gradle/issues/17236
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}
jar { jarTask ->
afterEvaluate {
configureJarTaskWithMavenMetadata(project, jarTask)
}
}
javadoc {
options.locale = 'en_US'
options.encoding = 'UTF-8'
}
test {
// Run the ECJ analysis whenever we also run tests:
dependsOn ecjAnalysis
systemProperty 'file.encoding', 'UTF-8'
workingDir project.file("${project.buildDir}/test-work/")
// Gradle complains when this folder does not yet exist.
doFirst {
workingDir.mkdirs()
}
}
}
project.plugins.withId('eclipse') {
// "annotationpath" attribute: Needed for annotating external libraries from within Eclipse,
// but breaks the resolution of null annotations from other packages (e.g for the JDK).
// Compromise: Only set the annotation path for the Gradle dependencies container, but omit
// it from the JRE container.
afterEvaluate {
eclipse {
classpath {
// Link the External Eclipse Annotations (used for null analysis):
// This Gradle container might not exist yet when whenMerged is run. But we can
// manually add it, and it also retains our added attribute.
containers "org.eclipse.buildship.core.gradleclasspathcontainer"
file {
whenMerged { classpath ->
classpath.entries.forEach { entry ->
//if (entry.kind == 'con') {
if (entry.path == 'org.eclipse.buildship.core.gradleclasspathcontainer') {
entry.entryAttributes.put("annotationpath", "/shopkeepers-external-annotations/src/main/resources")
}
}
}
}
}
}
}
}
project.plugins.withId('org.checkerframework') {
dependencies {
compileOnly libs.checkerframework.qual
checkerFramework libs.checkerframework.checker
testImplementation libs.checkerframework.qual
}
checkerFramework {
// TODO: Disabled because of lots false-positives after the update from 3.21.2 to 3.43.0.
skipCheckerFramework = true
checkers = [
'org.checkerframework.checker.nullness.NullnessChecker'
]
extraJavacArgs = [
'-AassumeAssertionsAreEnabled'
//'-AsuppressWarnings=initialization'
]
}
}
project.plugins.withId('maven-publish') {
// The maven-publish plugin does not generate the 'pom.properties' file. In order to mimic a
// normal Maven artifact, this task can be used to generate the properties file ourselves.
task generateMavenPomPropertiesFile {
File directory = new File("${buildDir}/mavenProperties/")
File outputFile = new File(directory, 'pom.properties')
afterEvaluate {
inputs.property 'group', project.group
inputs.property 'artifactId', project.artifactId
inputs.property 'version', project.version
outputs.file outputFile
}
doLast {
directory.mkdirs()
outputFile.text = "" +
"groupId=${inputs.properties['group']}\n" +
"artifactId=${inputs.properties['artifactId']}\n" +
"version=${inputs.properties['version']}\n"
}
}
publishing {
repositories {
// Formerly nexus.cube-nation.de, nexus.lichtspiele.org
// Contact person: Kronox (Discord); formerly: d1rty (dbo: d1rtyseven)
// 2025-03-09: Replaced by https://github.com/Shopkeepers/Repository. Still mirrors
// the Shopkeepers artifacts for backwards compatibility for now.
/*maven {
name = 'projectshard'
credentials {
username = findProperty('dev.projectshard.repo-username') ?: 'UNSET'
password = findProperty('dev.projectshard.repo-password') ?: 'UNSET'
}
if (project.isSnapshot) {
url = 'https://repo.projectshard.dev/repository/snapshots/'
} else {
url = 'https://repo.projectshard.dev/repository/releases/'
}
}*/
maven {
name = 'staging'
if (project.isSnapshot) {
url = rootProject.layout.projectDirectory.dir('repo/snapshots')
} else {
url = rootProject.layout.projectDirectory.dir('repo/releases')
}
}
}
}
}
}
gitPublish {
commitMessage = 'Update repository: ' + pluginVersion
// where to publish to
repoUri = 'https://github.com/Shopkeepers/Repository.git'
// where to fetch from prior to fetching from the remote (i.e. a local repo to save time)
//referenceRepoUri = 'file:///home/human/projects/test-repo/'
// branch will be created if it doesn't exist
branch = 'main'
// if set, a shallow clone will be performed instead of pulling all history
fetchDepth = 1
// Defaults to $buildDir/gitPublish
// Outside the build directory to cache it across clean builds:
repoDir = rootProject.layout.projectDirectory.dir('repo')
// what to publish, this is a standard CopySpec
contents {
//from rootProject.layout.buildDirectory.dir('repo')
// We publish directly into the repo directory. No need to copy.
}
// what to keep in the existing branch
preserve {
include '**/*'
}
// for signing commits, omit to use the default from your gitconfig
// sign = false
username = findProperty('shopkeepers.repository.user') ?: 'UNSET'
password = findProperty('shopkeepers.repository.token') ?: 'UNSET'
}
// Prepare the local Maven repository via gitPublishReset, then publish artifacts into it, and then
// commit and push the Maven repository to Github:
gradle.afterProject { project ->
def repoStagingTask = project.tasks.findByName("publishMavenJavaPublicationToStagingRepository")
if (repoStagingTask != null) {
println "Found repository staging task for project ${project.name}"
repoStagingTask.dependsOn(rootProject.tasks.gitPublishReset)
rootProject.tasks.gitPublishCommit.dependsOn(repoStagingTask)
}
}
// Predefined task list aliases:
// Minimal build: Quicker build that skips building any Spigot dependencies and only builds the API
// project. For example used for building on Jitpack, because we run into issues if:
// 1) The build takes too long.
// 2) We try to build Spigot. For some reason, Jitpack does not find our Shopkeepers artifacts then,
// even though they are correctly installed in the local Maven repository.
def taskListAliases = [
'cleanAssemble' : ['clean', 'assemble'],
'cleanBuild' : ['clean', 'build'],
'cleanInstall' : ['clean', 'build', 'publishToMavenLocal'],
'cleanStaging' : ['clean', 'build', 'publishToMavenLocal', 'publishAllPublicationsToStagingRepository'],
'cleanPublish' : ['clean', 'build', 'publishToMavenLocal', 'publishAllPublicationsToStagingRepository', 'gitPublishPush'],
'cleanInstallMinimal' : ['clean', ':shopkeepers-api:publishToMavenLocal']
]
gradle.startParameter.taskNames = gradle.startParameter.taskNames.collect {
taskListAliases[it] ?: it
}.flatten()
println "Expanded task list: ${gradle.startParameter.taskNames}"