blob: 0dac6981e6ec71da45a34d13927a9d4c9c00bbeb [file] [log] [blame]
Marc Kupietz4f6ed422024-03-01 07:27:46 +01001plugins {
2 // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin.
dependabot[bot]099919a2025-12-22 09:10:46 +00003 id 'org.jetbrains.kotlin.jvm' version '2.3.0'
Marc Kupietz4f6ed422024-03-01 07:27:46 +01004
5 // Apply the application plugin to add support for building a CLI application in Java.
6 id 'application'
Marc Kupietz1b595992024-03-01 14:54:30 +01007 id 'com.github.johnrengelman.shadow' version '8.1.1'
Marc Kupietz4f6ed422024-03-01 07:27:46 +01008}
9
Marc Kupietz4f6ed422024-03-01 07:27:46 +010010repositories {
Marc Kupietz4f6ed422024-03-01 07:27:46 +010011 mavenCentral()
Marc Kupietz56a45562024-03-20 20:18:08 +010012 maven { url 'https://jitpack.io' }
Marc Kupietz4f6ed422024-03-01 07:27:46 +010013}
14
Marc Kupietz47b43c32024-03-27 20:43:32 +010015test {
Marc Kupietzfc18d282025-08-31 12:07:46 +020016 minHeapSize = "512m"
17 maxHeapSize = "4096m"
18 jvmArgs '-XX:MaxMetaspaceSize=1024m'
Marc Kupietz2a3223d2025-11-19 21:05:21 +010019
20 // Enable parallel test execution for faster builds
21 maxParallelForks = Runtime.runtime.availableProcessors().intdiv(2) ?: 1
Marc Kupietzec7c2ae2025-12-04 10:09:45 +010022 systemProperty 'korapxmltool.test', 'true'
Marc Kupietz47b43c32024-03-27 20:43:32 +010023}
24
Marc Kupietz4f6ed422024-03-01 07:27:46 +010025dependencies {
26 // Align versions of all Kotlin components
27 implementation platform('org.jetbrains.kotlin:kotlin-bom')
28
29 // Use the Kotlin JDK 8 standard library.
30 implementation 'org.jetbrains.kotlin:kotlin-stdlib'
Marc Kupietzfc18d282025-08-31 12:07:46 +020031 implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2'
Marc Kupietz4f6ed422024-03-01 07:27:46 +010032
33 // This dependency is used by the application.
Marc Kupietzde917592025-10-31 15:44:27 +010034 implementation 'com.google.guava:guava:33.5.0-jre'
Marc Kupietz4f6ed422024-03-01 07:27:46 +010035
Marc Kupietz31122362024-03-02 11:13:37 +010036
Marc Kupietzfc18d282025-08-31 12:07:46 +020037 implementation ("info.picocli:picocli:4.7.7")
Marc Kupietz31122362024-03-02 11:13:37 +010038
Marc Kupietz4f6ed422024-03-01 07:27:46 +010039 // Use the Kotlin test library.
40 testImplementation 'org.jetbrains.kotlin:kotlin-test'
41
42 // Use the Kotlin JUnit integration.
43 testImplementation 'org.jetbrains.kotlin:kotlin-test-junit'
dependabot[bot]099919a2025-12-22 09:10:46 +000044 testImplementation "org.jetbrains.kotlin:kotlin-test:2.3.0"
Marc Kupietz0c6e8772024-03-19 07:03:07 +010045
Marc Kupietz1465ce22024-03-26 09:51:17 +010046 implementation 'com.github.kupietz:cistern:v1.0.4'
Marc Kupietzaf682a42024-03-22 06:51:55 +010047 implementation 'org.maltparser:maltparser:1.9.2'
dependabot[bot]8ecd00c2025-12-15 08:36:52 +000048 implementation 'org.apache.opennlp:opennlp-tools:2.5.7'
Marc Kupietze481b6a2025-12-26 16:06:59 +010049 implementation('edu.stanford.nlp:stanford-corenlp') {
50 version {
51 strictly '[3.0.0, 4.0.0)'
52 prefer '3.9.2'
53 }
54 because 'CoreNLP 4.x changed model format incompatible with models currently used for DeReKo'
55 }
Marc Kupietzfc18d282025-08-31 12:07:46 +020056 implementation 'org.slf4j:slf4j-simple:2.0.17'
Marc Kupietz916bdfe2024-09-20 09:02:57 +020057 implementation 'org.apache.ant:ant:1.10.15'
Marc Kupietzfc18d282025-08-31 12:07:46 +020058 implementation 'org.apache.commons:commons-compress:1.28.0'
Marc Kupietzd698f0e2025-11-01 20:00:07 +010059 implementation 'me.tongfei:progressbar:0.10.1'
Marc Kupietzd4c6bd52025-11-17 22:18:23 +010060 implementation 'org.lz4:lz4-java:1.8.0'
Marc Kupietza92bacb2024-04-06 20:26:05 +020061
Marc Kupietzd8549e42025-11-16 17:23:04 +010062 // Fix XML APIs conflict - force resolution to the non-relocated version
dependabot[bot]76ae8f32025-11-21 10:56:44 +000063 implementation('xml-apis:xml-apis:2.0.2') {
64 because 'Avoid POM relocation warnings from xml-apis 2.0.2 -> 2.0.2'
Marc Kupietzd8549e42025-11-16 17:23:04 +010065 }
Marc Kupietz4f6ed422024-03-01 07:27:46 +010066}
67
Marc Kupietz64dce822025-11-02 14:39:39 +010068// Enforce JDK 21 Toolchain and Bytecode-Level 21
Marc Kupietz8d875cc2025-10-31 15:36:33 +010069java {
70 toolchain {
71 languageVersion = JavaLanguageVersion.of(21)
72 }
73}
Marc Kupietz4f6ed422024-03-01 07:27:46 +010074
Marc Kupietz8d875cc2025-10-31 15:36:33 +010075kotlin {
76 jvmToolchain(21)
77}
78
Marc Kupietz64dce822025-11-02 14:39:39 +010079// For any existing Java source code
Marc Kupietz8d875cc2025-10-31 15:36:33 +010080tasks.withType(JavaCompile).configureEach {
81 options.release = 21
82}
83
84tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
85 kotlinOptions {
86 jvmTarget = "21"
Marc Kupietz64dce822025-11-02 14:39:39 +010087 // If available, this ensures consistent API targets similar to Java --release
Marc Kupietz8d875cc2025-10-31 15:36:33 +010088 // freeCompilerArgs += ["-Xjdk-release=21"]
89 }
90}
Marc Kupietz9da19db2024-04-01 11:06:51 +020091
Marc Kupietz64dce822025-11-02 14:39:39 +010092// Explicitly inherit version from root project
Marc Kupietzf13fc7b2025-10-31 17:28:21 +010093version = rootProject.version
94
Marc Kupietz4f6ed422024-03-01 07:27:46 +010095application {
96 // Define the main class for the application.
Marc Kupietz07c60d32025-01-21 19:32:48 +010097 mainClass = 'de.ids_mannheim.korapxmltools.KorapXmlToolKt'
Marc Kupietz4f6ed422024-03-01 07:27:46 +010098}
99
100jar {
Marc Kupietz64dce822025-11-02 14:39:39 +0100101 // Mark standard JAR as "plain" to avoid conflicts with ShadowJar
Marc Kupietzf13fc7b2025-10-31 17:28:21 +0100102 archiveClassifier.set('plain')
Marc Kupietz4f6ed422024-03-01 07:27:46 +0100103 manifest.attributes(
104 'Class-Path': configurations.compileClasspath.collect { it.getName() }.join(' '),
Marc Kupietzde917592025-10-31 15:44:27 +0100105 'Main-Class': "de.ids_mannheim.korapxmltools.KorapXmlToolKt",
106 'Implementation-Title': rootProject.name,
107 'Implementation-Version': project.version
Marc Kupietz4f6ed422024-03-01 07:27:46 +0100108 )
Marc Kupietzf13fc7b2025-10-31 17:28:21 +0100109}
110
111shadowJar {
112 archiveBaseName.set('korapxmltool')
113 archiveClassifier.set('')
114 archiveVersion.set(project.version.toString())
115 manifest.attributes(
116 'Main-Class': "de.ids_mannheim.korapxmltools.KorapXmlToolKt",
117 'Implementation-Title': rootProject.name,
118 'Implementation-Version': project.version
119 )
120}
121
Marc Kupietz64dce822025-11-02 14:39:39 +0100122// Ensure that assemble also creates the ShadowJar
Marc Kupietzf13fc7b2025-10-31 17:28:21 +0100123tasks.named('assemble') {
124 dependsOn tasks.named('shadowJar')
125}
126
Marc Kupietz64dce822025-11-02 14:39:39 +0100127// Additionally create a symlink korapxmltool.jar to the current version for stable script paths
128tasks.register('createJarSymlink') {
129 dependsOn shadowJar
130 doLast {
131 def targetJar = shadowJar.archiveFile.get().asFile
132 def linkFile = new File(targetJar.parent, 'korapxmltool.jar')
133
134 // Remove existing symlink or file
135 if (linkFile.exists()) {
136 linkFile.delete()
137 }
138
139 // Create symlink (Java 7+ NIO)
140 try {
141 java.nio.file.Files.createSymbolicLink(
142 linkFile.toPath(),
143 java.nio.file.Paths.get(targetJar.name)
144 )
145 println "Created symlink: ${linkFile.name} -> ${targetJar.name}"
146 } catch (Exception e) {
147 // Fallback to copy on systems where symlinks aren't supported
148 println "Warning: Could not create symlink (${e.message}), copying instead"
149 java.nio.file.Files.copy(targetJar.toPath(), linkFile.toPath())
150 }
151 }
Marc Kupietzf13fc7b2025-10-31 17:28:21 +0100152}
153
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100154// Concatenate shebang + shaded jar into an executable launcher
155tasks.register('assembleShebangExecutable') {
156 dependsOn shadowJar
157 inputs.file(rootProject.file("korapxmltool.shebang"))
Marc Kupietz1869f502025-11-16 21:31:12 +0100158 inputs.file(shadowJar.archiveFile)
159
160 def binDir = rootProject.file("build/bin")
161 def targetExec = new File(binDir, "korapxmltool")
Marc Kupietz481643b2025-11-19 12:27:32 +0100162 def krillExec = new File(binDir, "korapxml2krill")
Marc Kupietzcec41012025-11-19 13:48:48 +0100163 def conlluExec = new File(binDir, "korapxml2conllu")
Marc Kupietza2c33982025-11-19 18:19:46 +0100164 def conllu2korapxmlExec = new File(binDir, "conllu2korapxml")
Marc Kupietz1869f502025-11-16 21:31:12 +0100165 outputs.file(targetExec)
Marc Kupietz481643b2025-11-19 12:27:32 +0100166 outputs.file(krillExec)
Marc Kupietzcec41012025-11-19 13:48:48 +0100167 outputs.file(conlluExec)
Marc Kupietza2c33982025-11-19 18:19:46 +0100168 outputs.file(conllu2korapxmlExec)
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100169
170 doLast {
171 def shebang = rootProject.file("korapxmltool.shebang")
172 if (!shebang.exists()) {
173 throw new GradleException("Missing shebang stub: ${shebang}")
174 }
175
Marc Kupietz1869f502025-11-16 21:31:12 +0100176 // Ensure bin directory exists
177 binDir.mkdirs()
178
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100179 def targetJar = shadowJar.archiveFile.get().asFile
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100180
Marc Kupietz481643b2025-11-19 12:27:32 +0100181 // Create main korapxmltool executable
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100182 targetExec.withOutputStream { os ->
183 os << shebang.bytes
184 os << targetJar.bytes
185 }
Marc Kupietz05d3bbb2025-11-17 15:17:03 +0100186 targetExec.setExecutable(true, false)
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100187 println "Created executable launcher: ${targetExec}"
Marc Kupietz481643b2025-11-19 12:27:32 +0100188
189 // Create korapxml2krill symlink for backward compatibility
190 if (krillExec.exists()) {
191 krillExec.delete()
192 }
193 try {
194 java.nio.file.Files.createSymbolicLink(
195 krillExec.toPath(),
196 java.nio.file.Paths.get("korapxmltool")
197 )
198 println "Created symlink: korapxml2krill -> korapxmltool"
199 } catch (Exception e) {
200 println "Warning: Could not create korapxml2krill symlink (${e.message}), copying instead"
201 java.nio.file.Files.copy(targetExec.toPath(), krillExec.toPath())
202 krillExec.setExecutable(true, false)
203 }
Marc Kupietzcec41012025-11-19 13:48:48 +0100204
205 // Create korapxml2conllu symlink for backward compatibility
206 if (conlluExec.exists()) {
207 conlluExec.delete()
208 }
209 try {
210 java.nio.file.Files.createSymbolicLink(
211 conlluExec.toPath(),
212 java.nio.file.Paths.get("korapxmltool")
213 )
214 println "Created symlink: korapxml2conllu -> korapxmltool"
215 } catch (Exception e) {
216 println "Warning: Could not create korapxml2conllu symlink (${e.message}), copying instead"
217 java.nio.file.Files.copy(targetExec.toPath(), conlluExec.toPath())
218 conlluExec.setExecutable(true, false)
219 }
Marc Kupietza2c33982025-11-19 18:19:46 +0100220
221 // Create conllu2korapxml symlink for CoNLL-U to KorAP XML ZIP conversion
222 if (conllu2korapxmlExec.exists()) {
223 conllu2korapxmlExec.delete()
224 }
225 try {
226 java.nio.file.Files.createSymbolicLink(
227 conllu2korapxmlExec.toPath(),
228 java.nio.file.Paths.get("korapxmltool")
229 )
230 println "Created symlink: conllu2korapxml -> korapxmltool"
231 } catch (Exception e) {
232 println "Warning: Could not create conllu2korapxml symlink (${e.message}), copying instead"
233 java.nio.file.Files.copy(targetExec.toPath(), conllu2korapxmlExec.toPath())
234 conllu2korapxmlExec.setExecutable(true, false)
235 }
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100236 }
237}
238
Marc Kupietz1869f502025-11-16 21:31:12 +0100239tasks.named('assemble') {
240 dependsOn createJarSymlink
241 dependsOn assembleShebangExecutable
242}
243
Marc Kupietzf13fc7b2025-10-31 17:28:21 +0100244tasks.named('build') {
Marc Kupietz64dce822025-11-02 14:39:39 +0100245 dependsOn createJarSymlink
Marc Kupietzfbfcd042025-11-16 13:33:32 +0100246 dependsOn assembleShebangExecutable
Marc Kupietz4f6ed422024-03-01 07:27:46 +0100247}
248
249
250configurations {
251 runtimeLib.extendsFrom implementation
252}