SoftwareQuality/jabref/build.gradle
2025-01-11 12:30:11 +01:00

899 lines
35 KiB
Groovy

import org.gradle.internal.os.OperatingSystem
import org.gradle.nativeplatform.platform.internal.DefaultNativePlatform
import org.jabref.build.xjc.XjcPlugin
import org.jabref.build.xjc.XjcTask
plugins {
id 'application'
id 'com.github.andygoossens.modernizer' version '1.9.3'
id 'me.champeau.jmh' version '0.7.2'
// This is https://github.com/java9-modularity/gradle-modules-plugin/pull/282
id 'com.github.koppor.gradle-modules-plugin' version 'v1.8.15-cmd-1'
id 'org.openjfx.javafxplugin' version '0.1.0'
id 'org.beryx.jlink' version '3.0.1'
// nicer test outputs during running and completion
// Homepage: https://github.com/radarsh/gradle-test-logger-plugin
id 'com.adarshr.test-logger' version '4.0.0'
id 'jacoco'
id 'checkstyle'
id 'project-report'
id 'idea'
id 'org.openrewrite.rewrite' version '6.20.0'
}
// Enable following for debugging
// gradle.startParameter.showStacktrace = org.gradle.api.logging.configuration.ShowStacktrace.
apply plugin: XjcPlugin
apply from: 'eclipse.gradle'
group = "org.jabref"
version = project.findProperty('projVersion') ?: '100.0.0'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
// Workaround needed for Eclipse, probably because of https://github.com/gradle/gradle/issues/16922
// Should be removed as soon as Gradle 7.0.1 is released ( https://github.com/gradle/gradle/issues/16922#issuecomment-828217060 )
modularity.inferModulePath.set(false)
toolchain {
// If this is updated, also update
// - .gitpod.Dockerfile
// - .devcontainer/devcontainer.json#L34 and
// - .github/workflows/deployment-jdk-ea.yml#L53
languageVersion = JavaLanguageVersion.of(21)
// See https://docs.gradle.org/current/javadoc/org/gradle/jvm/toolchain/JvmVendorSpec.html for a full list
// vendor = JvmVendorSpec.AMAZON
}
}
application {
mainClass.set('org.jabref.Launcher')
mainModule.set('org.jabref')
applicationDefaultJvmArgs = [
// On a change here, also adapt
// 1. "run > moduleOptions"
// 2. "deployment.yml" (macOS part)
// 3. "deployment-arm64.yml"
// Note that the arguments are cleared for the "run" task to avoid messages like "WARNING: Unknown module: org.jabref.merged.module specified to --add-exports"
// Fix for https://github.com/JabRef/jabref/issues/11188
'--add-exports=javafx.base/com.sun.javafx.event=org.jabref.merged.module',
'--add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module',
// Fix for https://github.com/JabRef/jabref/issues/11198
'--add-opens=javafx.graphics/javafx.scene=org.jabref.merged.module',
'--add-opens=javafx.controls/javafx.scene.control=org.jabref.merged.module',
'--add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref.merged.module',
// fix for https://github.com/JabRef/jabref/issues/11426
'--add-opens=javafx.controls/javafx.scene.control.skin=org.jabref.merged.module',
// Fix for https://github.com/JabRef/jabref/issues/11225 on linux
'--add-opens=javafx.controls/javafx.scene.control=org.jabref',
'--add-exports=javafx.base/com.sun.javafx.event=org.jabref',
'--add-exports=javafx.controls/com.sun.javafx.scene.control=org.jabref',
'--add-opens=javafx.graphics/javafx.scene=org.jabref',
'--add-opens=javafx.controls/javafx.scene.control=org.jabref',
'--add-opens=javafx.controls/com.sun.javafx.scene.control=org.jabref',
'--add-opens=javafx.base/javafx.collections=org.jabref',
'--add-opens=javafx.base/javafx.collections.transformation=org.jabref'
]
}
// Workaround for https://github.com/openjfx/javafx-gradle-plugin/issues/89
// See also https://github.com/java9-modularity/gradle-modules-plugin/issues/165
modularity.disableEffectiveArgumentsAdjustment()
sourceSets {
main {
java {
// src-gen reasoning: https://stackoverflow.com/a/64612308/873282
srcDirs = ["src/main/java", "src-gen/main/java"]
}
resources {
srcDirs = ["src/main/java", "src/main/resources"]
}
}
test {
java {
srcDirs = ["src/test/java"]
}
resources {
srcDirs = ["src/test/resources"]
}
}
}
repositories {
mavenCentral()
maven { url 'https://s01.oss.sonatype.org/content/repositories/snapshots/' }
maven { url 'https://jitpack.io' }
maven { url 'https://oss.sonatype.org/content/groups/public' }
// Required for one.jpro.jproutils:tree-showing
maven { url 'https://sandec.jfrog.io/artifactory/repo' }
}
configurations {
antlr4
}
dependencyLocking {
lockAllConfigurations()
}
javafx {
version = "22.0.2"
modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.swing' ]
}
jacoco {
toolVersion = "0.8.10"
}
dependencies {
// Include all jar-files in the 'lib' folder as dependencies
implementation fileTree(dir: 'lib', includes: ['*.jar'])
def pdfbox = "3.0.3"
implementation ("org.apache.pdfbox:pdfbox:$pdfbox") {
exclude group: 'commons-logging'
}
implementation ("org.apache.pdfbox:fontbox:$pdfbox") {
exclude group: 'commons-logging'
}
implementation ("org.apache.pdfbox:xmpbox:$pdfbox") {
exclude group: 'org.junit.jupiter'
exclude group: 'commons-logging'
}
def luceneVersion = "9.11.1"
implementation "org.apache.lucene:lucene-core:$luceneVersion"
implementation "org.apache.lucene:lucene-queryparser:$luceneVersion"
implementation "org.apache.lucene:lucene-queries:$luceneVersion"
implementation "org.apache.lucene:lucene-analysis-common:$luceneVersion"
implementation "org.apache.lucene:lucene-highlighter:$luceneVersion"
implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.11.0'
implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.17.0'
implementation group: 'org.apache.commons', name: 'commons-text', version: '1.12.0'
implementation 'commons-logging:commons-logging:1.3.4'
implementation 'com.h2database:h2-mvstore:2.3.232'
// required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635
implementation 'org.bouncycastle:bcprov-jdk18on:1.78.1'
implementation 'commons-cli:commons-cli:1.9.0'
// region: LibreOffice
implementation 'org.libreoffice:unoloader:24.2.3'
implementation 'org.libreoffice:libreoffice:24.2.3'
// Required for ID generation
implementation 'io.github.thibaultmeyer:cuid:2.0.3'
// endregion
implementation 'io.github.java-diff-utils:java-diff-utils:4.12'
implementation 'info.debatty:java-string-similarity:2.0.0'
implementation 'com.github.javakeyring:java-keyring:1.0.4'
antlr4 'org.antlr:antlr4:4.13.2'
implementation 'org.antlr:antlr4-runtime:4.13.2'
implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.10.0.202406032230-r'
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.17.2'
implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.17.2'
implementation 'com.fasterxml:aalto-xml:1.3.3'
implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.9'
implementation 'org.postgresql:postgresql:42.7.4'
// Support unix socket connection types
implementation 'com.kohlschutter.junixsocket:junixsocket-core:2.10.0'
implementation 'com.kohlschutter.junixsocket:junixsocket-mysql:2.10.0'
implementation ('com.oracle.ojdbc:ojdbc10:19.3.0.0') {
// causing module issues
exclude module: 'oraclepki'
}
implementation ('com.google.guava:guava:33.1.0-jre') {
// TODO: Remove this as soon as https://github.com/google/guava/issues/2960 is fixed
exclude module: "jsr305"
}
implementation 'jakarta.annotation:jakarta.annotation-api:2.1.1'
implementation 'jakarta.inject:jakarta.inject-api:2.0.1'
implementation('org.jabref:afterburner.fx:2.0.0') {
exclude group: 'org.openjfx'
}
implementation 'org.kordamp.ikonli:ikonli-javafx:12.3.1'
implementation 'org.kordamp.ikonli:ikonli-materialdesign2-pack:12.3.1'
implementation 'com.github.sialcasa.mvvmFX:mvvmfx-validation:f195849ca9' //jitpack
implementation 'de.saxsys:mvvmfx:1.8.0'
implementation('org.jabref:easybind:2.2.1-SNAPSHOT') {
exclude group: 'org.openjfx'
}
implementation 'org.fxmisc.flowless:flowless:0.7.3'
implementation 'org.fxmisc.richtext:richtextfx:0.11.3'
implementation (group: 'com.dlsc.gemsfx', name: 'gemsfx', version: '2.43.0') {
exclude module: 'javax.inject' // Split package, use only jakarta.inject
exclude module: 'commons-lang3'
exclude group: 'org.apache.commons.validator'
exclude group: 'org.apache.commons.commons-logging'
exclude module: 'kotlin-stdlib-jdk8'
exclude group: 'com.squareup.retrofit2'
exclude group: 'org.openjfx'
exclude group: 'org.apache.logging.log4j'
exclude group: 'tech.units'
}
// Required by gemsfx
implementation 'tech.units:indriya:2.2'
implementation ('com.squareup.retrofit2:retrofit:2.11.0') {
exclude group: 'com.squareup.okhttp3'
}
implementation 'org.controlsfx:controlsfx:11.2.1'
implementation 'org.jsoup:jsoup:1.18.1'
implementation 'com.konghq:unirest-java-core:4.4.4'
implementation 'com.konghq:unirest-modules-gson:4.4.4'
implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'
implementation 'org.slf4j:slf4j-api:2.0.16'
implementation 'org.tinylog:tinylog-api:2.7.0'
implementation 'org.tinylog:slf4j-tinylog:2.7.0'
implementation 'org.tinylog:tinylog-impl:2.7.0'
// route all requests to java.util.logging to SLF4J (which in turn routes to tinylog)
implementation 'org.slf4j:jul-to-slf4j:2.0.13'
// route all requests to log4j to SLF4J
implementation 'org.apache.logging.log4j:log4j-to-slf4j:2.23.1'
implementation('de.undercouch:citeproc-java:3.1.0') {
exclude group: 'org.antlr'
}
// jakarta.activation is already dependency of glassfish
implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '4.0.2'
implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '4.0.3'
implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') {
exclude module: 'fastparse_2.13'
}
implementation "de.rototor.snuggletex:snuggletex:1.3.0"
implementation ("de.rototor.snuggletex:snuggletex-jeuclid:1.3.0") {
exclude group: "org.apache.xmlgraphics"
}
implementation 'com.vladsch.flexmark:flexmark:0.64.8'
implementation 'com.vladsch.flexmark:flexmark-html2md-converter:0.64.8'
implementation group: 'net.harawata', name: 'appdirs', version: '1.2.2'
implementation group: 'org.jooq', name: 'jool', version: '0.9.15'
// JAX-RS implemented by Jersey
// API
implementation 'jakarta.ws.rs:jakarta.ws.rs-api:4.0.0'
// Implementation of the API
implementation 'org.glassfish.jersey.core:jersey-server:3.1.8'
// injection framework
implementation 'org.glassfish.jersey.inject:jersey-hk2:3.1.8'
implementation 'org.glassfish.hk2:hk2-api:3.1.1'
// testImplementation 'org.glassfish.hk2:hk2-testing:3.0.4'
// implementation 'org.glassfish.hk2:hk2-testing-jersey:3.0.4'
// testImplementation 'org.glassfish.hk2:hk2-junitrunner:3.0.4'
// HTTP server
// implementation 'org.glassfish.jersey.containers:jersey-container-netty-http:3.1.1'
implementation 'org.glassfish.jersey.containers:jersey-container-grizzly2-http:3.1.8'
testImplementation 'org.glassfish.jersey.test-framework.providers:jersey-test-framework-provider-grizzly2:3.1.8'
// Allow objects "magically" to be mapped to JSON using GSON
// implementation 'org.glassfish.jersey.media:jersey-media-json-gson:3.1.1'
// Because of GraalVM quirks, we need to ship that. See https://github.com/jspecify/jspecify/issues/389#issuecomment-1661130973 for details
implementation 'org.jspecify:jspecify:1.0.0'
// parse plist files
implementation 'com.googlecode.plist:dd-plist:1.28'
// Parse lnk files
implementation 'com.github.vatbub:mslinks:1.0.6.2'
// YAML formatting
implementation 'org.yaml:snakeyaml:2.2'
// AI
implementation 'dev.langchain4j:langchain4j:0.33.0'
// Even though we use jvm-openai for LLM connection, we still need this package for tokenization.
implementation('dev.langchain4j:langchain4j-open-ai:0.33.0') {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
implementation('dev.langchain4j:langchain4j-mistral-ai:0.33.0')
implementation('dev.langchain4j:langchain4j-hugging-face:0.33.0')
implementation 'ai.djl:api:0.29.0'
implementation 'ai.djl.pytorch:pytorch-model-zoo:0.29.0'
implementation 'ai.djl.huggingface:tokenizers:0.29.0'
implementation 'io.github.stefanbratanov:jvm-openai:0.10.0'
// openai depends on okhttp, which needs kotlin - see https://github.com/square/okhttp/issues/5299 for details
implementation ('com.squareup.okhttp3:okhttp:4.12.0') {
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
}
// GemxFX also (transitively) depends on kotlin
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.0.20'
implementation 'commons-io:commons-io:2.16.1'
// Even if "compileOnly" is used, IntelliJ always adds to module-info.java. To avoid issues during committing, we use "implementation" instead of "compileOnly"
implementation 'io.github.adr:e-adr:2.0.0-SNAPSHOT'
testImplementation 'io.github.classgraph:classgraph:4.8.175'
testImplementation 'org.junit.jupiter:junit-jupiter:5.11.0'
testImplementation 'org.junit.platform:junit-platform-launcher:1.10.3'
testImplementation 'org.mockito:mockito-core:5.13.0'
testImplementation 'org.xmlunit:xmlunit-core:2.10.0'
testImplementation 'org.xmlunit:xmlunit-matchers:2.10.0'
testRuntimeOnly 'com.tngtech.archunit:archunit-junit5-engine:1.3.0'
testImplementation 'com.tngtech.archunit:archunit-junit5-api:1.3.0'
testImplementation "org.testfx:testfx-core:4.0.16-alpha"
testImplementation "org.testfx:testfx-junit5:4.0.16-alpha"
testImplementation "org.hamcrest:hamcrest-library:3.0"
checkstyle 'com.puppycrawl.tools:checkstyle:10.18.0'
// xjc needs the runtime as well for the ant task, otherwise it fails
xjc group: 'org.glassfish.jaxb', name: 'jaxb-xjc', version: '3.0.2'
xjc group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2'
rewrite(platform("org.openrewrite.recipe:rewrite-recipe-bom:2.17.0"))
rewrite("org.openrewrite.recipe:rewrite-static-analysis")
rewrite("org.openrewrite.recipe:rewrite-logging-frameworks")
rewrite("org.openrewrite.recipe:rewrite-testing-frameworks")
rewrite("org.openrewrite.recipe:rewrite-migrate-java")
configurations.checkstyle {
resolutionStrategy.capabilitiesResolution.withCapability("com.google.collections:google-collections") {
select("com.google.guava:guava:0")
}
}
configurations
.matching(c -> c.name.contains("downloadSources"))
.configureEach {
attributes {
attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage, Usage.JAVA_RUNTIME))
attribute(OperatingSystemFamily.OPERATING_SYSTEM_ATTRIBUTE, objects.named(OperatingSystemFamily, DefaultNativePlatform.getCurrentOperatingSystem().getName()))
attribute(MachineArchitecture.ARCHITECTURE_ATTRIBUTE, objects.named(MachineArchitecture, DefaultNativePlatform.getCurrentArchitecture().getName()))
}
}
}
clean {
delete "src/main/generated"
delete "src-gen"
}
processResources {
filteringCharset = 'UTF-8'
filesMatching("build.properties") {
expand(version: project.findProperty('projVersionInfo') ?: '100.0.0',
"year": String.valueOf(Calendar.getInstance().get(Calendar.YEAR)),
"maintainers": new File('MAINTAINERS').readLines().findAll { !it.startsWith("#") }.join(", "),
"azureInstrumentationKey": System.getenv('AzureInstrumentationKey') ? System.getenv('AzureInstrumentationKey') : '',
"springerNatureAPIKey": System.getenv('SpringerNatureAPIKey') ? System.getenv('SpringerNatureAPIKey') : '',
"astrophysicsDataSystemAPIKey": System.getenv('AstrophysicsDataSystemAPIKey') ? System.getenv('AstrophysicsDataSystemAPIKey') : '',
"ieeeAPIKey": System.getenv('IEEEAPIKey') ? System.getenv('IEEEAPIKey') : '',
"scienceDirectApiKey": System.getenv('SCIENCEDIRECTAPIKEY') ? System.getenv('SCIENCEDIRECTAPIKEY') : '',
"biodiversityHeritageApiKey": System.getenv('BiodiversityHeritageApiKey') ? System.getenv('BiodiversityHeritageApiKey') : '',
"semanticScholarApiKey": System.getenv('SemanticScholarApiKey') ? System.getenv("SemanticScholarApiKey") : ''
)
filteringCharset = 'UTF-8'
}
filesMatching(["resources/resource/ods/meta.xml", "resources/resource/openoffice/meta.xml"]) {
expand version: project.version
}
}
tasks.register('generateSource') {
dependsOn("generateBstGrammarSource",
"generateSearchGrammarSource",
"generateCitaviSource")
group = 'JabRef'
description 'Generates all necessary (Java) source files.'
}
tasks.register("generateBstGrammarSource", JavaExec) {
group = "JabRef"
description = 'Generates BstLexer.java and BstParser.java from the Bst.g grammar file using antlr4.'
classpath = configurations.antlr4
mainClass = "org.antlr.v4.Tool"
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
inputs.dir('src/main/antlr4/org/jabref/bst/')
outputs.dir("src-gen/main/java/org/jabref/logic/bst/")
args = ["-o", "src-gen/main/java/org/jabref/logic/bst/", "-visitor", "-no-listener", "-package", "org.jabref.logic.bst", "$projectDir/src/main/antlr4/org/jabref/bst/Bst.g4"]
}
tasks.register("generateSearchGrammarSource", JavaExec) {
group = 'JabRef'
description = "Generates java files for Search.g antlr4."
classpath = configurations.antlr4
mainClass = "org.antlr.v4.Tool"
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
inputs.dir("src/main/antlr4/org/jabref/search/")
outputs.dir("src-gen/main/java/org/jabref/search/")
args = ["-o","src-gen/main/java/org/jabref/search" , "-visitor", "-no-listener", "-package", "org.jabref.search", "$projectDir/src/main/antlr4/org/jabref/search/Search.g4"]
}
tasks.register("generateJournalListMV", JavaExec) {
group = "JabRef"
description = "Converts the comma-separated journal abbreviation file to a H2 MVStore"
classpath = sourceSets.main.runtimeClasspath
mainClass = "org.jabref.cli.JournalListMvGenerator"
javaLauncher.set(javaToolchains.launcherFor(java.toolchain))
onlyIf {
!file("build/resources/main/journals/journal-list.mv").exists()
}
}
jar.dependsOn("generateJournalListMV")
compileTestJava.dependsOn("generateJournalListMV")
tasks.register('generateCitaviSource', XjcTask) {
group = 'JabRef'
description = "Generates java files for the citavi importer."
schemaFile = "src/main/resources/xjc/citavi/citavi.xsd"
outputDirectory = "src-gen/main/java/"
javaPackage = "org.jabref.logic.importer.fileformat.citavi"
}
tasks.withType(JavaCompile).configureEach {
options.encoding = 'UTF-8'
// hint by https://docs.gradle.org/current/userguide/performance.html#run_the_compiler_as_a_separate_process
options.fork = true
}
compileJava {
options.compilerArgs << "-Xlint:none"
dependsOn "generateSource"
options.generatedSourceOutputDirectory.set(file("src-gen/main/java"))
moduleOptions {
addExports = [
// TODO: Remove access to internal api
'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
'org.controlsfx.controls/impl.org.controlsfx.skin' : 'org.jabref'
]
}
}
// Configures "application > run" task
run {
doFirst {
// Clear the default JVM arguments, to avoid messages like "WARNING: Unknown module: org.jabref.merged.module specified to --add-exports"
application.applicationDefaultJvmArgs = []
}
moduleOptions {
// On a change here, also adapt "application > applicationDefaultJvmArgs"
addExports = [
// TODO: Remove access to internal api
'javafx.base/com.sun.javafx.event' : 'org.jabref.merged.module',
'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
// We need to restate the ControlsFX exports, because we get following error otherwise:
// java.lang.IllegalAccessError:
// class org.controlsfx.control.textfield.AutoCompletionBinding (in module org.controlsfx.controls)
// cannot access class com.sun.javafx.event.EventHandlerManager (in module javafx.base) because
// module javafx.base does not export com.sun.javafx.event to module org.controlsfx.controls
// Taken from here: https://github.com/controlsfx/controlsfx/blob/9.0.0/build.gradle#L1
'javafx.graphics/com.sun.javafx.scene' : 'org.controlsfx.controls',
'javafx.graphics/com.sun.javafx.scene.traversal' : 'org.controlsfx.controls',
'javafx.graphics/com.sun.javafx.css' : 'org.controlsfx.controls',
'javafx.controls/com.sun.javafx.scene.control' : 'org.controlsfx.controls',
'javafx.controls/com.sun.javafx.scene.control.behavior' : 'org.controlsfx.controls',
'javafx.controls/com.sun.javafx.scene.control.inputmap' : 'org.controlsfx.controls',
'javafx.base/com.sun.javafx.event' : 'org.controlsfx.controls',
'javafx.base/com.sun.javafx.collections' : 'org.controlsfx.controls',
'javafx.base/com.sun.javafx.runtime': 'org.controlsfx.controls',
'javafx.web/com.sun.webkit' : 'org.controlsfx.controls',
]
addOpens = [
'javafx.controls/javafx.scene.control' : 'org.jabref',
'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
'org.controlsfx.controls/impl.org.controlsfx.skin' : 'org.jabref',
'org.controlsfx.controls/org.controlsfx.control.textfield' : 'org.jabref',
'javafx.controls/javafx.scene.control.skin' : 'org.controlsfx.controls',
'javafx.graphics/javafx.scene' : 'org.controlsfx.controls',
'javafx.base/javafx.collections' : 'org.jabref',
'javafx.base/javafx.collections.transformation' : 'org.jabref'
]
addModules = [
'jdk.incubator.vector'
]
createCommandLineArgumentFile = true
}
if (project.hasProperty('component')){
if (component == 'httpserver'){
main = 'org.jabref.http.server.Server'
}
}
}
javadoc {
options {
encoding = 'UTF-8'
version = false
author = false
addMultilineStringsOption("-add-exports").setValue([
'javafx.controls/com.sun.javafx.scene.control=org.jabref'
])
}
}
test {
useJUnitPlatform {
excludeTags 'DatabaseTest', 'FetcherTest', 'GUITest'
}
moduleOptions {
// TODO: Remove this as soon as ArchUnit is modularized
runOnClasspath = true
}
}
testlogger {
// See https://github.com/radarsh/gradle-test-logger-plugin#configuration for configuration options
theme 'standard'
showPassed false
showSkipped false
showCauses false
showStackTraces false
}
tasks.withType(Test).configureEach {
reports.html.outputLocation.set(file("${reporting.baseDir}/${name}"))
// Enable parallel tests (on desktop).
// See https://docs.gradle.org/8.1/userguide/performance.html#execute_tests_in_parallel for details.
if (!providers.environmentVariable("CI").isPresent()) {
maxParallelForks = Math.max(Runtime.runtime.availableProcessors() - 1, 1)
}
}
tasks.register('databaseTest', Test) {
useJUnitPlatform {
includeTags 'DatabaseTest'
}
testLogging {
// set options for log level LIFECYCLE
events = ["FAILED"]
exceptionFormat "full"
}
maxParallelForks = 1
}
tasks.register('fetcherTest', Test) {
useJUnitPlatform {
includeTags 'FetcherTest'
}
maxParallelForks = 1
}
tasks.register('guiTest', Test) {
useJUnitPlatform {
includeTags 'GUITest'
}
testLogging {
// set options for log level LIFECYCLE
events = ["FAILED"]
exceptionFormat "full"
}
maxParallelForks = 1
}
// Test result tasks
tasks.register('copyTestResources', Copy) {
from "${projectDir}/src/test/resources"
into "${buildDir}/classes/test"
}
processTestResources.dependsOn copyTestResources
tasks.register('jacocoPrepare') {
doFirst {
// Ignore failures of tests
tasks.withType(Test).tap {
configureEach {
ignoreFailures = true
}
}
}
}
test.mustRunAfter jacocoPrepare
databaseTest.mustRunAfter jacocoPrepare
fetcherTest.mustRunAfter jacocoPrepare
jacocoTestReport {
dependsOn jacocoPrepare, test, fetcherTest, databaseTest
executionData files(
layout.buildDirectory.file('jacoco/test.exec').get().asFile,
layout.buildDirectory.file('jacoco/fetcherTest.exec').get().asFile,
layout.buildDirectory.file('jacoco/databaseTest.exec').get().asFile)
reports {
csv.required = true
html.required = true
// coveralls plugin depends on xml format report
xml.required = true
}
}
// Code quality tasks
checkstyle {
// will only run when called explicitly from the command line
sourceSets = []
}
rewrite {
activeRecipe(
'org.jabref.config.rewrite.cleanup'
)
exclusion (
"build.gradle",
"buildSrc/build.gradle",
"eclipse.gradle",
"settings.gradle",
"src-gen/**",
"src/main/resources/**",
"src/test/resources/**",
"**/module-info.java",
"**/*.py",
"**/*.xml",
"**/*.yml"
)
plainTextMask("**/*.md")
failOnDryRunResults = true
}
modernizer {
failOnViolations = false
includeTestClasses = true
exclusions = [
'java/util/Optional.get:()Ljava/lang/Object;'
]
}
// Release tasks
tasks.register('deleteInstallerTemp', Delete) {
delete "$buildDir/installer"
}
jpackage.dependsOn deleteInstallerTemp
jlinkZip.dependsOn jpackage
jlink {
// https://github.com/beryx/badass-jlink-plugin/issues/61#issuecomment-504640018
addExtraDependencies("javafx")
addOptions('--strip-debug', '--compress', 'zip-6', '--no-header-files', '--no-man-pages')
launcher {
name = 'JabRef'
}
addOptions("--bind-services")
// TODO: Remove the following as soon as the dependencies are fixed (upstream)
// forceMerge is usually needed when some non-modular artifacts in the dependency graph use code that was previously part of the JDK
// but it was removed in the newer releases.
// The pom.xml associated with such a non-modular artifact does not mention that the artifact depends on the removed code
// (because the artifact was published when this code was still available in the JDK).
forceMerge "controlsfx", "bcprov", "jaxb", "istack", "stax"
// TODO: Remove the following correction to the merged module
// The module descriptor automatically generated by the plugin for the merged module contained some invalid entries.
// This is based on ./gradlew suggestMergedModuleInfo, sort, strip ";"", comment non-used modules, and include the suggested directives here.
// However, we need to fine-tune this manually (non-alphabetic order)
mergedModule {
requires 'javafx.base'
requires 'javafx.controls'
requires 'javafx.fxml'
requires 'javafx.graphics'
requires 'javafx.media'
requires 'javafx.swing'
requires 'java.compiler'
requires 'java.datatransfer'
requires 'java.desktop'
requires 'java.logging'
requires 'java.management'
requires 'java.naming'
requires 'java.net.http'
requires 'java.scripting'
requires 'java.security.jgss'
requires 'java.security.sasl'
requires 'java.sql'
requires 'java.sql.rowset'
requires 'java.transaction.xa'
requires 'java.rmi'
requires 'java.xml'
requires 'jdk.jsobject'
requires 'jdk.unsupported'
requires 'jdk.unsupported.desktop'
requires 'jdk.security.jgss'
requires 'jdk.xml.dom'
requires 'com.google.gson'
requires 'org.jsoup'
requires 'org.slf4j'
requires 'jakarta.xml.bind'
requires 'org.apache.commons.lang3'
requires 'org.apache.commons.text'
requires 'org.apache.commons.logging';
uses 'org.mariadb.jdbc.credential.CredentialPlugin'
uses 'org.mariadb.jdbc.authentication.AuthenticationPlugin'
uses 'org.mariadb.jdbc.tls.TlsSocketPlugin'
uses 'org.mariadb.jdbc.LocalInfileInterceptor'
uses 'org.eclipse.jgit.transport.SshSessionFactory'
uses 'org.eclipse.jgit.lib.GpgSigner'
uses 'kong.unirest.core.json.JsonEngine';
provides 'org.mariadb.jdbc.tls.TlsSocketPlugin' with 'org.mariadb.jdbc.internal.protocol.tls.DefaultTlsSocketPlugin'
provides 'java.sql.Driver' with 'org.postgresql.Driver'
provides 'org.mariadb.jdbc.authentication.AuthenticationPlugin' with 'org.mariadb.jdbc.internal.com.send.authentication.CachingSha2PasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.ClearPasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.Ed25519PasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.NativePasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.OldPasswordPlugin',
'org.mariadb.jdbc.internal.com.send.authentication.SendGssApiAuthPacket',
'org.mariadb.jdbc.internal.com.send.authentication.SendPamAuthPacket',
'org.mariadb.jdbc.internal.com.send.authentication.Sha256PasswordPlugin'
provides 'org.mariadb.jdbc.credential.CredentialPlugin' with 'org.mariadb.jdbc.credential.aws.AwsIamCredentialPlugin',
'org.mariadb.jdbc.credential.env.EnvCredentialPlugin',
'org.mariadb.jdbc.credential.system.PropertiesCredentialPlugin'
provides 'java.security.Provider' with 'org.bouncycastle.jce.provider.BouncyCastleProvider',
'org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider'
provides 'kong.unirest.core.json.JsonEngine' with 'kong.unirest.modules.gson.GsonEngine';
}
jpackage {
outputDir = "distribution"
if (OperatingSystem.current().isWindows()) {
// This requires WiX to be installed: https://github.com/wixtoolset/wix3/releases
installerType = "msi"
imageOptions = [
'--icon', "${projectDir}/src/main/resources/icons/jabref.ico",
]
installerOptions = [
'--vendor', 'JabRef',
'--app-version', "${project.version}",
'--verbose',
'--win-upgrade-uuid', 'd636b4ee-6f10-451e-bf57-c89656780e36',
'--win-dir-chooser',
'--win-shortcut',
'--win-menu',
'--win-menu-group', "JabRef",
'--temp', "$buildDir/installer",
'--resource-dir', "${projectDir}/buildres/windows",
'--license-file', "${projectDir}/buildres/LICENSE_with_Privacy.md",
'--file-associations', "${projectDir}/buildres/windows/bibtexAssociations.properties"
]
}
if (OperatingSystem.current().isLinux()) {
imageOptions = [
'--icon', "${projectDir}/src/main/resources/icons/JabRef-icon-64.png",
'--app-version', "${project.version}",
]
installerOptions = [
'--verbose',
'--vendor', 'JabRef',
'--app-version', "${project.version}",
// '--temp', "$buildDir/installer",
'--resource-dir', "${projectDir}/buildres/linux",
'--linux-menu-group', 'Office;',
'--linux-rpm-license-type', 'MIT',
// '--license-file', "${projectDir}/LICENSE.md",
'--description', 'JabRef is an open source bibliography reference manager. The native file format used by JabRef is BibTeX, the standard LaTeX bibliography format.',
'--linux-shortcut',
'--file-associations', "${projectDir}/buildres/linux/bibtexAssociations.properties"
]
}
if (OperatingSystem.current().isMacOsX()) {
imageOptions = [
'--icon', "${projectDir}/src/main/resources/icons/jabref.icns",
'--resource-dir', "${projectDir}/buildres/mac"
]
// Notarized mac images and packages are built on the pipeline only
skipInstaller = true
installerOptions = [
'--verbose',
'--vendor', 'JabRef',
'--mac-package-identifier', "JabRef",
'--mac-package-name', "JabRef",
'--app-version', "${project.version}",
'--file-associations', "${projectDir}/buildres/mac/bibtexAssociations.properties",
'--resource-dir', "${projectDir}/buildres/mac"
]
}
}
}
if (OperatingSystem.current().isWindows()) {
tasks.jpackageImage.doLast {
copy {
from("${projectDir}/buildres/windows") {
include "jabref-firefox.json", "jabref-chrome.json", "JabRefHost.bat", "JabRefHost.ps1"
}
into "$buildDir/distribution/JabRef"
}
}
}
if (OperatingSystem.current().isLinux()) {
tasks.jpackageImage.doLast {
copy {
from("${projectDir}/buildres/linux") {
include "native-messaging-host/**", "jabrefHost.py"
}
into "$buildDir/distribution/JabRef/lib"
}
}
}
if (OperatingSystem.current().isMacOsX()) {
tasks.jpackageImage.doLast {
copy {
from("${projectDir}/buildres/mac") {
include "native-messaging-host/**", "jabrefHost.py"
}
into "$buildDir/distribution/JabRef.app/Contents/Resources"
}
}
}
jmh {
warmupIterations = 5
iterations = 10
fork = 2
}