-
Notifications
You must be signed in to change notification settings - Fork 14
/
build.gradle
175 lines (155 loc) · 7.85 KB
/
build.gradle
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
apply plugin: 'java'
defaultTasks 'jar', 'test'
sourceSets.main.java.srcDirs = ['src/']
sourceSets.test.java.srcDirs = ['test/']
sourceCompatibility = targetCompatibility = 8
tasks.withType(JavaCompile) { options.encoding = "UTF-8" }
javadoc.enabled = false
repositories {
if(System.getenv('FREETALK__DOWNLOAD_DEPENDENCIES') == '1') {
println 'WARNING: Download of dependencies is enabled! Watch out for supply chain attacks!'
mavenCentral()
}
}
configurations { junit } // Needed when we manually specify the tests' classpath
dependencies {
// Run fred's Gradle with "./gradlew jar copyRuntimeLibs" to produce this directory
// TODO: mvn.freenetproject.org is not browseable so I don't know the proper URI for fred and
// its dependencies and hence am including the dependencies as flat files.
// Use Gradle's dependency management + gradle-witness once this has been resolved.
implementation fileTree(dir: '../fred/build/output/', include: '*.jar')
compileOnly files('db4o-7.4/db4o.jar')
if(System.getenv('FREETALK__DOWNLOAD_DEPENDENCIES') == '1')
junit('junit:junit:4.11') // Hamcrest is automatically included as transitive dependency.
else
junit files('/usr/share/java/junit4.jar', '/usr/share/java/hamcrest-core.jar')
}
configurations {
// This adds the dependencies of the configuration "junit" to the classpath of the
// configuration "testImplementation", which is used when compiling the unit tests.
// Effectively this means the JUnit JARs are added to the classpath when compiling the tests,
// which is necessary because they use the JUnit classes.
// (In previous Gradle versions it could be specified at dependencies {}, this unfortunately
// isn't possible anymore, hence this poorly readable code which needs this large comment ...)
testImplementation.extendsFrom junit
}
task compileDb4o(type: Exec) {
// See https://bugs.freenetproject.org/view.php?id=7058
outputs.upToDateWhen { file('db4o-7.4/db4o.jar').exists() }
workingDir 'db4o-7.4'
commandLine 'ant', "-Djavac.source.version=" + sourceCompatibility,
"-Djavac.target.version=" + targetCompatibility
}
compileJava {
dependsOn compileDb4o
}
task getGitRevision(type: Exec) {
commandLine "git", "describe", "--always", "--abbrev=4", "--dirty"
standardOutput = new ByteArrayOutputStream()
ext.output = { return standardOutput.toString().trim() }
}
def generatedResources = "$buildDir/generated-resources/main"
sourceSets.main.output.dir(generatedResources, builtBy: 'prepareVersionFile')
task prepareVersionFile(dependsOn: getGitRevision) {
def packageOfClassVersion = "$generatedResources/plugins/Freetalk"
outputs.dir packageOfClassVersion
outputs.upToDateWhen { false }
doLast {
// TODO: Bug: The file should be encoded in ISO 8859-1 according to Properties.load()'s
// requirements, see plugins.Freetalk.Version.getGitRevision() which uses it upon the file.
new File(packageOfClassVersion, "Version.properties").text =
"git.revision=" + getGitRevision.output()
}
}
tasks.create("testJar", Jar) // TODO: Performance: Use register() once my Gradle is more recent.
["jar", "testJar"].each { jarType -> tasks.getByName("$jarType") {
// Set implicitly by the above usage of tasks.getByName()
// Also notice that we mustn't use overwrite = true because with Gradle versions starting with
// 5.0 it does not work properly - the "jar" task would retain its original contents just as it
// does now with it being false, so we must always assume it is false to avoid duplicating the
// from() inputs.
/* overwrite false */
// The task "classes" depends on everything which we need, including prepareVersionFile.
if(jarType == 'jar') dependsOn classes
if(jarType == 'testJar') dependsOn testClasses
preserveFileTimestamps = false
reproducibleFileOrder = true
duplicatesStrategy = "fail"
archiveBaseName = (jarType == 'testJar') ? 'Freetalk-with-unit-tests' : 'Freetalk'
destinationDirectory = new File(projectDir, (jarType == 'testJar') ? "build-test" : "dist")
manifest { attributes("Plugin-Main-Class": "plugins.Freetalk.Freetalk") }
// Now define the actual contents of the JARs.
if(jarType == 'jar') {
// For the "jar" task there is no need to include the actual classes via from(), it is a
// builtin of Gradle and thus populated by it (including the output of prepareVersionFile).
// We merely have to add stuff which Gradle doesn't detect:
// EDIT: TODO: Code quality: Use "sourceSets.main.resources {}" instead. See:
// https://stackoverflow.com/questions/24724383/add-resources-config-files-to-your-jar-using-gradle
from(sourceSets.main.java.srcDirs) { include 'plugins/Freetalk/l10n/*.l10n' }
from(sourceSets.main.java.srcDirs) { include 'plugins/Freetalk/ui/web/css/*.css' }
from zipTree('db4o-7.4/db4o.jar')
} else if(jarType == 'testJar') {
// The testJar task on the other hand was generated by us, so we need to fully populate its
// contents on our own.
// To make this maximally failsafe we just re-use the JAR generated by the JAR task as
// input instead of re-iterating the contents here, that could cause us to forget stuff.
// We merely add our unit test classes afterwards.
dependsOn jar
from zipTree(jar.archivePath)
from sourceSets.test.output.classesDirs
}
}}
test {
dependsOn testJar
// Reset classpath to only use the JAR, not the class files, because some tests may need a JAR
// to load into a Freenet node, and given the JAR is needed we shouldn't duplicate its classes.
classpath = fileTree(dir: '../fred/build/output/', include: '*.jar')
classpath+= files(testJar.archivePath)
classpath+= configurations.junit
scanForTestClasses = false
include '**/*Test.class'
exclude 'com/db4o/**'
// TODO: Enable once my distribution ships a more recent Gradle which supports this.
// failFast = true
// Workaround for db4o breaking, and thus unit tests failing, with Java >= 16:
// Java 16 disallows using reflection to look into JRE's core classes. But db4o needs that to
// fulfill its purpose of being a database which can store Java classes without adding any
// code to them. Thus we allow it by a command line option.
//
// We run this on Java 9 and above, not just 16 and above, to support old Gradle versions which
// won't be able to detect Java 16 as such. 9 is the minimum needed to support '--add-opens'.
if(JavaVersion.current().getMajorVersion().toInteger() >= 9)
jvmArgs '--add-opens', 'java.base/java.lang=ALL-UNNAMED'
maxHeapSize = "512m"
maxParallelForks = Runtime.runtime.availableProcessors()
forkEvery = 1 // One VM per test, for safety and probably needed for maxParallelForks to work
systemProperties += [
"is_FT_unit_test": "true",
"FT_test_jar": testJar.archivePath
]
workingDir = "${buildDir}/tmp/testsWorkingDir"
doFirst { delete workingDir ; mkdir workingDir }
testLogging {
events "passed", "skipped", "failed"
exceptionFormat "full"
// Allow enabling stdout/stderr so developers can obtain random seeds to reproduce failed
// test runs.
// TODO: Code quality: Have developers (by updating the README.md) and .travis.yml do this
// on the command line without requiring this code here once Travis CI contains a
// sufficiently recent Gradle for
// "-Doverride.test.testLogging.info.showStandardStreams=true" to work.
// Notice that the ".info" may be a typo from the person who posted this to
// stackoverflow.com as the working code below does not contain ".info", so you may have to
// remove that string.
//
// Enabling stdout/stderr requires us to tell Gradle to assume that the outputs are
// outdated to ensure they are updated even if the user doesn't run the 'clean' target.
outputs.upToDateWhen { false }
showStandardStreams = (System.getenv('FREETALK__SHOW_GRADLE_TEST_OUTPUT') == '1')
}
}
clean {
[ 'build-test', 'test-coverage', 'dist' ].each { // Beyond defaults also delete Ant's output
delete "${projectDir}/" + it }
doLast { exec { workingDir 'db4o-7.4' ; commandLine 'ant','clean' } }
}