<NME> build.gradle
<BEF> import org.gradle.internal.os.OperatingSystem
import org.jabref.build.JournalAbbreviationConverter
import org.jabref.build.xjc.XjcPlugin
import org.jabref.build.xjc.XjcTask

plugins {
    id 'application'

    id 'com.github.andygoossens.modernizer' version '1.6.2'

apply plugin: "java"
apply plugin: "application"
apply plugin: "project-report"
apply plugin: "maven"
apply plugin: 'jacoco'
apply plugin: 'com.github.kt3k.coveralls'
apply from: 'eclipse.gradle'
    id 'org.beryx.jlink' version '2.25.0'

    // nicer test outputs during running and completion
    // Homepage: https://github.com/radarsh/gradle-test-logger-plugin
    id 'com.adarshr.test-logger' version '3.2.0'

    id 'jacoco'

    id 'checkstyle'

    id 'project-report'

    id 'idea'
}

// 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_18
    targetCompatibility = JavaVersion.VERSION_18

    // 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)
}

application {
    mainClass.set('org.jabref.cli.Launcher')
    mainModule.set('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 {
    mavenLocal()
    mavenCentral()
    maven { url 'https://oss.sonatype.org/content/groups/public' }
    maven { url 'https://jitpack.io' }
}

configurations {
    antlr4
    // TODO: Remove the following workaround for split error messages such as
    // error: module java.xml.bind reads package javax.annotation from both jsr305 and java.annotation
    compile {
        extendsFrom implementation
        exclude group: "javax.activation"
    }
}

dependencyLocking {
    lockAllConfigurations()
}

javafx {
    version = "19"
    modules = [ 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.swing' ]
}

jacoco {
    toolVersion = "0.8.8"
}

dependencies {
    // Include all jar-files in the 'lib' folder as dependencies
    implementation fileTree(dir: 'lib', includes: ['*.jar'])

    implementation 'org.apache.pdfbox:pdfbox:3.0.0-RC1'
    implementation 'org.apache.pdfbox:fontbox:3.0.0-RC1'
    implementation 'org.apache.pdfbox:xmpbox:3.0.0-RC1'

    implementation 'org.apache.lucene:lucene-core:9.4.1'
    implementation 'org.apache.lucene:lucene-queryparser:9.4.1'
    implementation 'org.apache.lucene:lucene-queries:9.4.1'
    implementation 'org.apache.lucene:lucene-analysis-common:9.4.1'
    implementation 'org.apache.lucene:lucene-highlighter:9.4.1'

    implementation group: 'org.apache.commons', name: 'commons-csv', version: '1.9.0'
    implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.12.0'
    implementation 'com.h2database:h2-mvstore:2.1.214'

    implementation group: 'org.apache.tika', name: 'tika-core', version: '2.5.0'

    // required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635
    implementation 'org.bouncycastle:bcprov-jdk18on:1.71.1'

    implementation 'commons-cli:commons-cli:1.5.0'

    implementation 'org.libreoffice:libreoffice:7.4.1'
    implementation 'org.libreoffice:unoloader:7.4.1'

    implementation 'io.github.java-diff-utils:java-diff-utils:4.12'
    implementation 'info.debatty:java-string-similarity:2.0.0'

    antlr4 'org.antlr:antlr4:4.9.3'
    implementation 'org.antlr:antlr4-runtime:4.9.3'

    implementation group: 'org.eclipse.jgit', name: 'org.eclipse.jgit', version: '6.3.0.202209071007-r'

    implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.13.4'
    implementation group: 'com.fasterxml.jackson.datatype', name: 'jackson-datatype-jsr310', version: '2.13.4'

    implementation group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: '2.7.6'

    implementation 'org.postgresql:postgresql:42.5.0'

    implementation ('com.oracle.ojdbc:ojdbc10:19.3.0.0') {
        // causing module issues
        exclude module: 'oraclepki'
    }

    implementation ('com.google.guava:guava:31.1-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 'com.github.JabRef:afterburner.fx:testmoduleinfo-SNAPSHOT'
    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 'com.tobiasdiez:easybind:2.2.1-SNAPSHOT'
    implementation 'org.fxmisc.flowless:flowless:0.6.10'
    implementation 'org.fxmisc.richtext:richtextfx:0.10.9'
    implementation 'com.jfoenix:jfoenix:9.0.10'
    implementation 'org.controlsfx:controlsfx:11.1.2'

    implementation 'org.jsoup:jsoup:1.15.3'
    implementation 'com.konghq:unirest-java:3.13.12'

    implementation 'org.slf4j:slf4j-api:2.0.3'
    implementation "org.tinylog:tinylog-api:2.5.0"
    implementation "org.tinylog:slf4j-tinylog:2.5.0"
    implementation "org.tinylog:tinylog-impl:2.5.0"

    implementation 'de.undercouch:citeproc-java:3.0.0-alpha.6'

    // jakarta.activation is already dependency of glassfish
    implementation group: 'jakarta.xml.bind', name: 'jakarta.xml.bind-api', version: '3.0.1'
    implementation group: 'org.glassfish.jaxb', name: 'jaxb-runtime', version: '3.0.2'

    implementation ('com.github.tomtung:latex2unicode_2.13:0.3.2') {
        exclude module: 'fastparse_2.13'
    }

    implementation group: 'com.microsoft.azure', name: 'applicationinsights-core', version: '2.4.1'
    implementation (group: 'com.microsoft.azure', name: 'applicationinsights-logging-log4j2', version: '2.4.1') {
        exclude module: "log4j-core"
    }

    implementation 'com.vladsch.flexmark:flexmark:0.64.0'
    implementation 'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.64.0'
    implementation 'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.64.0'

    implementation group: 'net.harawata', name: 'appdirs', version: '1.2.1'

    testImplementation 'io.github.classgraph:classgraph:4.8.149'
    testImplementation 'org.junit.jupiter:junit-jupiter:5.9.1'
    testImplementation 'org.junit.platform:junit-platform-launcher:1.9.1'

    testImplementation 'org.mockito:mockito-core:4.8.1'
    testImplementation 'org.xmlunit:xmlunit-core:2.9.0'
    testImplementation 'org.xmlunit:xmlunit-matchers:2.9.0'
    testRuntimeOnly 'com.tngtech.archunit:archunit-junit5-engine:1.0.0'
    testImplementation 'com.tngtech.archunit:archunit-junit5-api:1.0.0'
    testImplementation "org.testfx:testfx-core:4.0.16-alpha"
    testImplementation "org.testfx:testfx-junit5:4.0.16-alpha"
    testImplementation "org.hamcrest:hamcrest-library:2.2"

    checkstyle 'com.puppycrawl.tools:checkstyle:10.4'
    // 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'
}

clean {
    delete "src/main/generated"
    delete "src-gen"
}

processResources {
    gradle.taskGraph.whenReady {
        if (gradle.taskGraph.hasTask(":jpackage")) {
            logger.info('Adding buildres/csl to resources')
            from("buildres/csl")
            duplicatesStrategy = DuplicatesStrategy.EXCLUDE
        }
    }

    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') : ''
        )
        filteringCharset = 'UTF-8'
    }

    filesMatching(["resources/resource/ods/meta.xml", "resources/resource/openoffice/meta.xml"]) {
        expand version: project.version
    }
}

task generateSource(dependsOn: ["generateBstGrammarSource",
                                "generateSearchGrammarSource",
                                "generateMedlineSource",
                                "generateBibtexmlSource",
                                "generateEndnoteSource",
                                "generateModsSource",
                                "generateCitaviSource"]) {
    group = 'JabRef'
    description 'Generates all necessary (Java) source files.'
}

tasks.register("generateBstGrammarSource", JavaExec) {
    main = "org.antlr.v4.Tool"
    classpath = configurations.antlr4
    group = "JabRef"
    description = 'Generates BstLexer.java and BstParser.java from the Bst.g grammar file using antlr4.'

    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) {
    main = "org.antlr.v4.Tool"
    classpath = configurations.antlr4
    group = 'JabRef'
    description = "Generates java files for Search.g antlr4."

    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"]
}

task generateMedlineSource(type: XjcTask) {
    group = 'JabRef'
    description = "Generates java files for the medline importer."

    schemaFile = "src/main/resources/xjc/medline/medline.xsd"
    outputDirectory = "src-gen/main/java"
    javaPackage = "org.jabref.logic.importer.fileformat.medline"
}

task generateBibtexmlSource(type: XjcTask) {
    group = 'JabRef'
    description = "Generates java files for the bibtexml importer."

    schemaFile = "src/main/resources/xjc/bibtexml/bibtexml.xsd"
    outputDirectory = "src-gen/main/java/"
    javaPackage = "org.jabref.logic.importer.fileformat.bibtexml"
}

task generateEndnoteSource(type: XjcTask) {
    group = 'JabRef'
    description = "Generates java files for the endnote importer."

    schemaFile = "src/main/resources/xjc/endnote/endnote.xsd"
    outputDirectory = "src-gen/main/java/"
    javaPackage = "org.jabref.logic.importer.fileformat.endnote"
}

task generateCitaviSource(type: 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"
}

task generateModsSource(type: XjcTask) {
    group = 'JabRef'
    description = "Generates java files for the mods importer."

    schemaFile = "src/main/resources/xjc/mods/mods-3-7.xsd"
    bindingFile = "src/main/resources/xjc/mods/mods-binding.xjb"
    outputDirectory = "src-gen/main/java"
    javaPackage = "org.jabref.logic.importer.fileformat.mods"
    arguments = '-npa'
}

task generateJournalAbbreviationList(type: JournalAbbreviationConverter) {
    group = 'JabRef'
    description = "Converts the comma-separated journal abbreviation file to a H2 MVStore."

    // This directory is filled by "refresh-journal-lists.yml"
    // It takes the contents of https://github.com/JabRef/abbrv.jabref.org.git
    inputDir = file("build/journals")

    outputDir = file("src/main/resources/journals")
}

tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

compileJava {
    options.compilerArgs << "-Xlint:none"
    dependsOn "generateSource"

    options.generatedSourceOutputDirectory.set(file("src-gen/main/java"))

    moduleOptions {
        // TODO: Remove access to internal api
        addExports = [
                'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
                'org.controlsfx.controls/impl.org.controlsfx.skin' : 'org.jabref'
        ]
    }
}

run {
    // TODO: Remove access to internal api
    moduleOptions {
        addExports = [
                'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',
                'org.controlsfx.controls/impl.org.controlsfx.skin' : 'org.jabref',

                'javafx.controls/com.sun.javafx.scene.control.behavior' : 'com.jfoenix',

                // Not sure why we need to restate the controlfx exports
                // 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',
                'org.controlsfx.controls/org.controlsfx.control.textfield' : 'org.jabref',
                'javafx.controls/com.sun.javafx.scene.control' : 'org.jabref',

                'javafx.controls/javafx.scene.control.skin' : 'org.controlsfx.controls',
                'javafx.graphics/javafx.scene' : 'org.controlsfx.controls',

                'javafx.controls/com.sun.javafx.scene.control.behavior' : 'com.jfoenix',
                'javafx.base/com.sun.javafx.binding' : 'com.jfoenix',
                'javafx.graphics/com.sun.javafx.stage' : 'com.jfoenix',
                'javafx.base/com.sun.javafx.event' : 'com.jfoenix'
        ]
    }
}

javadoc {
    options {
        encoding = 'UTF-8'
        version = true
        author = true
         addMultilineStringsOption("-add-exports").setValue([
            'javafx.controls/com.sun.javafx.scene.control=org.jabref',
            'org.controlsfx.controls/impl.org.controlsfx.skin=org.jabref'
        ])
    }
}

test {
    useJUnitPlatform {
        excludeTags 'DatabaseTest', 'FetcherTest', 'GUITest'
    }

    moduleOptions {
        // TODO: Remove this as soon as archunit is modularized
        runOnClasspath = true
    }

    testLogging {
        // set options for log level LIFECYCLE
        // for debugging tests: add "STANDARD_OUT", "STANDARD_ERROR"
        events = ["FAILED"]
        exceptionFormat "full"
    }
}

testlogger {
    showPassed false
}

task databaseTest(type: Test) {
    useJUnitPlatform {
        includeTags 'DatabaseTest'
    }

    testLogging {
        // set options for log level LIFECYCLE
        events = ["FAILED"]
        exceptionFormat "full"
    }
}

task fetcherTest(type: Test) {
    useJUnitPlatform {
        includeTags 'FetcherTest'
    }

    testLogging {
        // set options for log level LIFECYCLE
        events = ["FAILED"]
        exceptionFormat "full"
    }
}

task guiTest(type: Test) {
    useJUnitPlatform {
        includeTags 'GUITest'
    }

    testLogging {
        // set options for log level LIFECYCLE
        events = ["FAILED"]
        exceptionFormat "full"
    }
}

// Test result tasks
task copyTestResources(type: Copy) {
    from "${projectDir}/src/test/resources"
    into "${buildDir}/classes/test"
}
processTestResources.dependsOn copyTestResources

tasks.withType(Test) {
    reports.html.outputLocation.set(file("${reporting.baseDir}/${name}"))
}

task jacocoPrepare() {
    doFirst {
        // Ignore failures of tests
        tasks.withType(Test) {
            ignoreFailures = true
        }
    }
}
test.mustRunAfter jacocoPrepare
databaseTest.mustRunAfter jacocoPrepare
fetcherTest.mustRunAfter jacocoPrepare

jacocoTestReport {
    executionData files(
            "$buildDir/jacoco/test.exec",
            "$buildDir/jacoco/databaseTest.exec",
            "$buildDir/jacoco/fetcherTest.exec").filter { it.exists() }
    dependsOn jacocoPrepare, test, databaseTest, fetcherTest

    reports {
        csv.getRequired().set(true)
        html.getRequired().set(true)
        xml.getRequired().set(true) // coveralls plugin depends on xml format report
    }
}

// Code quality tasks
checkstyle {
    // will only run when called explicitly from the command line
    sourceSets = []
}

// Release tasks
task deleteInstallerTemp(type: Delete) {
    delete "$buildDir/installer"
}

jpackage.dependsOn deleteInstallerTemp
jlink {
    addOptions('--strip-debug', '--compress', '2', '--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 "javafx"
    forceMerge "controlsfx", "bcprov", "jaxb", "istack", "stax", "log4j"

    // 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.
    // Execute ./gradlew suggestMergedModuleInfo and include the suggested directives here.
    mergedModule {
        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.slf4j'
        requires 'jakarta.xml.bind'
        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'
        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'    }

    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",
                    '--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"
            ]
            // Due to a signing bug in jpackage we have to first resign the created app and therefore build the dmg manually
            // See https://bugs.openjdk.java.net/browse/JDK-8251892 for details
            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
}

// Source: https://stackoverflow.com/a/44168582/873282
task downloadDependencies {
    description "Pre-downloads *most* dependencies"
    doLast {
        configurations.getAsMap().each { name, config ->
            println "Retrieving dependencies for $name"
            try {
                config.files
            } catch (e) {
                // some cannot be resolved, just log them
                project.logger.info e.message
            }
        }
    }
}

<MSG> Remove "maven" plugin as we currently don't publish maven artifacts

<DFF> @@ -11,7 +11,6 @@ plugins {
 apply plugin: "java"
 apply plugin: "application"
 apply plugin: "project-report"
-apply plugin: "maven"
 apply plugin: 'jacoco'
 apply plugin: 'com.github.kt3k.coveralls'
 apply from: 'eclipse.gradle'

{'commit': 'diff --git a/build.gradle b/build.gradle\nindex 067fdace1f..69e9d0eab0 100644\n--- a/build.gradle\n+++ b/build.gradle\n@@ -11,7 +11,6 @@ plugins {\n apply plugin: "java"\n apply plugin: "application"\n apply plugin: "project-report"\n-apply plugin: "maven"\n apply plugin: \'jacoco\'\n apply plugin: \'com.github.kt3k.coveralls\'\n apply from: \'eclipse.gradle\'\n', 'commit_subject': 'Remove "maven" plugin as we currently don\'t publish maven artifacts', 'repo_name': 'JabRef/jabref', 'committer': {'name': 'Oliver Kopp', 'email': '6e3b2ea5538f1752a10d3f04fddcdb11429e4200@gmail.com', 'time_sec': '1445821236', 'tz_offset': '60', 'date': {'seconds': '1445821236'}}, 'commit_tree': '8fc1d639ca3183f7a2d904d35d1035e03245bd1a', 'commit_message': 'Remove "maven" plugin as we currently don\'t publish maven artifacts\n', 'language_name': 'Ruby', 'license': 'mit', 'hunks': '@@ -11,7 +11,6 @@ plugins {\n apply plugin: "java"\n apply plugin: "application"\n apply plugin: "project-report"\n-apply plugin: "maven"\n apply plugin: \'jacoco\'\n apply plugin: \'com.github.kt3k.coveralls\'\n apply from: \'eclipse.gradle\'\n', 'addition_count': 0, 'deletion_count': 1, 'src_file': 'a/build.gradle', 'tgt_file': 'b/build.gradle', 'file_extension': '.gradle', 'before_file': 'import org.gradle.internal.os.OperatingSystem\nimport org.jabref.build.JournalAbbreviationConverter\nimport org.jabref.build.xjc.XjcPlugin\nimport org.jabref.build.xjc.XjcTask\n\nplugins {\n    id \'application\'\n\n    id \'com.github.andygoossens.modernizer\' version \'1.6.2\'\n\napply plugin: "java"\napply plugin: "application"\napply plugin: "project-report"\napply plugin: "maven"\napply plugin: \'jacoco\'\napply plugin: \'com.github.kt3k.coveralls\'\napply from: \'eclipse.gradle\'\n    id \'org.beryx.jlink\' version \'2.25.0\'\n\n    // nicer test outputs during running and completion\n    // Homepage: https://github.com/radarsh/gradle-test-logger-plugin\n    id \'com.adarshr.test-logger\' version \'3.2.0\'\n\n    id \'jacoco\'\n\n    id \'checkstyle\'\n\n    id \'project-report\'\n\n    id \'idea\'\n}\n\n// Enable following for debugging\n// gradle.startParameter.showStacktrace = org.gradle.api.logging.configuration.ShowStacktrace.\n\napply plugin: XjcPlugin\n\napply from: \'eclipse.gradle\'\n\ngroup = "org.jabref"\nversion = project.findProperty(\'projVersion\') ?: \'100.0.0\'\n\njava {\n    sourceCompatibility = JavaVersion.VERSION_18\n    targetCompatibility = JavaVersion.VERSION_18\n\n    // Workaround needed for Eclipse, probably because of https://github.com/gradle/gradle/issues/16922\n    // Should be removed as soon as Gradle 7.0.1 is released ( https://github.com/gradle/gradle/issues/16922#issuecomment-828217060 )\n    modularity.inferModulePath.set(false)\n}\n\napplication {\n    mainClass.set(\'org.jabref.cli.Launcher\')\n    mainModule.set(\'org.jabref\')\n}\n\n// Workaround for https://github.com/openjfx/javafx-gradle-plugin/issues/89\n// See also https://github.com/java9-modularity/gradle-modules-plugin/issues/165\nmodularity.disableEffectiveArgumentsAdjustment()\n\nsourceSets {\n    main {\n        java {\n            // src-gen reasoning: https://stackoverflow.com/a/64612308/873282\n            srcDirs = ["src/main/java", "src-gen/main/java"]\n        }\n        resources {\n            srcDirs = ["src/main/java", "src/main/resources"]\n        }\n    }\n    test {\n        java {\n            srcDirs = ["src/test/java"]\n        }\n        resources {\n            srcDirs = ["src/test/resources"]\n        }\n    }\n}\n\nrepositories {\n    mavenLocal()\n    mavenCentral()\n    maven { url \'https://oss.sonatype.org/content/groups/public\' }\n    maven { url \'https://jitpack.io\' }\n}\n\nconfigurations {\n    antlr4\n    // TODO: Remove the following workaround for split error messages such as\n    // error: module java.xml.bind reads package javax.annotation from both jsr305 and java.annotation\n    compile {\n        extendsFrom implementation\n        exclude group: "javax.activation"\n    }\n}\n\ndependencyLocking {\n    lockAllConfigurations()\n}\n\njavafx {\n    version = "19"\n    modules = [ \'javafx.controls\', \'javafx.fxml\', \'javafx.web\', \'javafx.swing\' ]\n}\n\njacoco {\n    toolVersion = "0.8.8"\n}\n\ndependencies {\n    // Include all jar-files in the \'lib\' folder as dependencies\n    implementation fileTree(dir: \'lib\', includes: [\'*.jar\'])\n\n    implementation \'org.apache.pdfbox:pdfbox:3.0.0-RC1\'\n    implementation \'org.apache.pdfbox:fontbox:3.0.0-RC1\'\n    implementation \'org.apache.pdfbox:xmpbox:3.0.0-RC1\'\n\n    implementation \'org.apache.lucene:lucene-core:9.4.1\'\n    implementation \'org.apache.lucene:lucene-queryparser:9.4.1\'\n    implementation \'org.apache.lucene:lucene-queries:9.4.1\'\n    implementation \'org.apache.lucene:lucene-analysis-common:9.4.1\'\n    implementation \'org.apache.lucene:lucene-highlighter:9.4.1\'\n\n    implementation group: \'org.apache.commons\', name: \'commons-csv\', version: \'1.9.0\'\n    implementation group: \'org.apache.commons\', name: \'commons-lang3\', version: \'3.12.0\'\n    implementation \'com.h2database:h2-mvstore:2.1.214\'\n\n    implementation group: \'org.apache.tika\', name: \'tika-core\', version: \'2.5.0\'\n\n    // required for reading write-protected PDFs - see https://github.com/JabRef/jabref/pull/942#issuecomment-209252635\n    implementation \'org.bouncycastle:bcprov-jdk18on:1.71.1\'\n\n    implementation \'commons-cli:commons-cli:1.5.0\'\n\n    implementation \'org.libreoffice:libreoffice:7.4.1\'\n    implementation \'org.libreoffice:unoloader:7.4.1\'\n\n    implementation \'io.github.java-diff-utils:java-diff-utils:4.12\'\n    implementation \'info.debatty:java-string-similarity:2.0.0\'\n\n    antlr4 \'org.antlr:antlr4:4.9.3\'\n    implementation \'org.antlr:antlr4-runtime:4.9.3\'\n\n    implementation group: \'org.eclipse.jgit\', name: \'org.eclipse.jgit\', version: \'6.3.0.202209071007-r\'\n\n    implementation group: \'com.fasterxml.jackson.dataformat\', name: \'jackson-dataformat-yaml\', version: \'2.13.4\'\n    implementation group: \'com.fasterxml.jackson.datatype\', name: \'jackson-datatype-jsr310\', version: \'2.13.4\'\n\n    implementation group: \'org.mariadb.jdbc\', name: \'mariadb-java-client\', version: \'2.7.6\'\n\n    implementation \'org.postgresql:postgresql:42.5.0\'\n\n    implementation (\'com.oracle.ojdbc:ojdbc10:19.3.0.0\') {\n        // causing module issues\n        exclude module: \'oraclepki\'\n    }\n\n    implementation (\'com.google.guava:guava:31.1-jre\') {\n        // TODO: Remove this as soon as https://github.com/google/guava/issues/2960 is fixed\n        exclude module: "jsr305"\n    }\n\n    implementation \'jakarta.annotation:jakarta.annotation-api:2.1.1\'\n    implementation \'jakarta.inject:jakarta.inject-api:2.0.1\'\n\n\n    implementation \'com.github.JabRef:afterburner.fx:testmoduleinfo-SNAPSHOT\'\n    implementation \'org.kordamp.ikonli:ikonli-javafx:12.3.1\'\n    implementation \'org.kordamp.ikonli:ikonli-materialdesign2-pack:12.3.1\'\n    implementation \'com.github.sialcasa.mvvmFX:mvvmfx-validation:f195849ca9\' //jitpack\n    implementation \'de.saxsys:mvvmfx:1.8.0\'\n    implementation \'com.tobiasdiez:easybind:2.2.1-SNAPSHOT\'\n    implementation \'org.fxmisc.flowless:flowless:0.6.10\'\n    implementation \'org.fxmisc.richtext:richtextfx:0.10.9\'\n    implementation \'com.jfoenix:jfoenix:9.0.10\'\n    implementation \'org.controlsfx:controlsfx:11.1.2\'\n\n    implementation \'org.jsoup:jsoup:1.15.3\'\n    implementation \'com.konghq:unirest-java:3.13.12\'\n\n    implementation \'org.slf4j:slf4j-api:2.0.3\'\n    implementation "org.tinylog:tinylog-api:2.5.0"\n    implementation "org.tinylog:slf4j-tinylog:2.5.0"\n    implementation "org.tinylog:tinylog-impl:2.5.0"\n\n    implementation \'de.undercouch:citeproc-java:3.0.0-alpha.6\'\n\n    // jakarta.activation is already dependency of glassfish\n    implementation group: \'jakarta.xml.bind\', name: \'jakarta.xml.bind-api\', version: \'3.0.1\'\n    implementation group: \'org.glassfish.jaxb\', name: \'jaxb-runtime\', version: \'3.0.2\'\n\n    implementation (\'com.github.tomtung:latex2unicode_2.13:0.3.2\') {\n        exclude module: \'fastparse_2.13\'\n    }\n\n    implementation group: \'com.microsoft.azure\', name: \'applicationinsights-core\', version: \'2.4.1\'\n    implementation (group: \'com.microsoft.azure\', name: \'applicationinsights-logging-log4j2\', version: \'2.4.1\') {\n        exclude module: "log4j-core"\n    }\n\n    implementation \'com.vladsch.flexmark:flexmark:0.64.0\'\n    implementation \'com.vladsch.flexmark:flexmark-ext-gfm-strikethrough:0.64.0\'\n    implementation \'com.vladsch.flexmark:flexmark-ext-gfm-tasklist:0.64.0\'\n\n    implementation group: \'net.harawata\', name: \'appdirs\', version: \'1.2.1\'\n\n    testImplementation \'io.github.classgraph:classgraph:4.8.149\'\n    testImplementation \'org.junit.jupiter:junit-jupiter:5.9.1\'\n    testImplementation \'org.junit.platform:junit-platform-launcher:1.9.1\'\n\n    testImplementation \'org.mockito:mockito-core:4.8.1\'\n    testImplementation \'org.xmlunit:xmlunit-core:2.9.0\'\n    testImplementation \'org.xmlunit:xmlunit-matchers:2.9.0\'\n    testRuntimeOnly \'com.tngtech.archunit:archunit-junit5-engine:1.0.0\'\n    testImplementation \'com.tngtech.archunit:archunit-junit5-api:1.0.0\'\n    testImplementation "org.testfx:testfx-core:4.0.16-alpha"\n    testImplementation "org.testfx:testfx-junit5:4.0.16-alpha"\n    testImplementation "org.hamcrest:hamcrest-library:2.2"\n\n    checkstyle \'com.puppycrawl.tools:checkstyle:10.4\'\n    // xjc needs the runtime as well for the ant task, otherwise it fails\n    xjc group: \'org.glassfish.jaxb\', name: \'jaxb-xjc\', version: \'3.0.2\'\n    xjc group: \'org.glassfish.jaxb\', name: \'jaxb-runtime\', version: \'3.0.2\'\n}\n\nclean {\n    delete "src/main/generated"\n    delete "src-gen"\n}\n\nprocessResources {\n    gradle.taskGraph.whenReady {\n        if (gradle.taskGraph.hasTask(":jpackage")) {\n            logger.info(\'Adding buildres/csl to resources\')\n            from("buildres/csl")\n            duplicatesStrategy = DuplicatesStrategy.EXCLUDE\n        }\n    }\n\n    filteringCharset = \'UTF-8\'\n\n    filesMatching("build.properties") {\n        expand(version: project.findProperty(\'projVersionInfo\') ?: \'100.0.0\',\n                "year": String.valueOf(Calendar.getInstance().get(Calendar.YEAR)),\n                "maintainers": new File(\'MAINTAINERS\').readLines().findAll { !it.startsWith("#") }.join(", "),\n                "azureInstrumentationKey": System.getenv(\'AzureInstrumentationKey\') ? System.getenv(\'AzureInstrumentationKey\') : \'\',\n                "springerNatureAPIKey": System.getenv(\'SpringerNatureAPIKey\') ? System.getenv(\'SpringerNatureAPIKey\') : \'\',\n                "astrophysicsDataSystemAPIKey": System.getenv(\'AstrophysicsDataSystemAPIKey\') ? System.getenv(\'AstrophysicsDataSystemAPIKey\') : \'\',\n                "ieeeAPIKey": System.getenv(\'IEEEAPIKey\') ? System.getenv(\'IEEEAPIKey\') : \'\',\n                "scienceDirectApiKey": System.getenv(\'SCIENCEDIRECTAPIKEY\') ? System.getenv(\'SCIENCEDIRECTAPIKEY\') : \'\',\n                "biodiversityHeritageApiKey": System.getenv(\'BiodiversityHeritageApiKey\') ? System.getenv(\'BiodiversityHeritageApiKey\') : \'\'\n        )\n        filteringCharset = \'UTF-8\'\n    }\n\n    filesMatching(["resources/resource/ods/meta.xml", "resources/resource/openoffice/meta.xml"]) {\n        expand version: project.version\n    }\n}\n\ntask generateSource(dependsOn: ["generateBstGrammarSource",\n                                "generateSearchGrammarSource",\n                                "generateMedlineSource",\n                                "generateBibtexmlSource",\n                                "generateEndnoteSource",\n                                "generateModsSource",\n                                "generateCitaviSource"]) {\n    group = \'JabRef\'\n    description \'Generates all necessary (Java) source files.\'\n}\n\ntasks.register("generateBstGrammarSource", JavaExec) {\n    main = "org.antlr.v4.Tool"\n    classpath = configurations.antlr4\n    group = "JabRef"\n    description = \'Generates BstLexer.java and BstParser.java from the Bst.g grammar file using antlr4.\'\n\n    inputs.dir(\'src/main/antlr4/org/jabref/bst/\')\n    outputs.dir("src-gen/main/java/org/jabref/logic/bst/")\n    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"]\n}\n\ntasks.register("generateSearchGrammarSource", JavaExec) {\n    main = "org.antlr.v4.Tool"\n    classpath = configurations.antlr4\n    group = \'JabRef\'\n    description = "Generates java files for Search.g antlr4."\n\n    inputs.dir("src/main/antlr4/org/jabref/search/")\n    outputs.dir("src-gen/main/java/org/jabref/search/")\n    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"]\n}\n\ntask generateMedlineSource(type: XjcTask) {\n    group = \'JabRef\'\n    description = "Generates java files for the medline importer."\n\n    schemaFile = "src/main/resources/xjc/medline/medline.xsd"\n    outputDirectory = "src-gen/main/java"\n    javaPackage = "org.jabref.logic.importer.fileformat.medline"\n}\n\ntask generateBibtexmlSource(type: XjcTask) {\n    group = \'JabRef\'\n    description = "Generates java files for the bibtexml importer."\n\n    schemaFile = "src/main/resources/xjc/bibtexml/bibtexml.xsd"\n    outputDirectory = "src-gen/main/java/"\n    javaPackage = "org.jabref.logic.importer.fileformat.bibtexml"\n}\n\ntask generateEndnoteSource(type: XjcTask) {\n    group = \'JabRef\'\n    description = "Generates java files for the endnote importer."\n\n    schemaFile = "src/main/resources/xjc/endnote/endnote.xsd"\n    outputDirectory = "src-gen/main/java/"\n    javaPackage = "org.jabref.logic.importer.fileformat.endnote"\n}\n\ntask generateCitaviSource(type: XjcTask) {\n    group = \'JabRef\'\n    description = "Generates java files for the citavi importer."\n\n    schemaFile = "src/main/resources/xjc/citavi/citavi.xsd"\n    outputDirectory = "src-gen/main/java/"\n    javaPackage = "org.jabref.logic.importer.fileformat.citavi"\n}\n\ntask generateModsSource(type: XjcTask) {\n    group = \'JabRef\'\n    description = "Generates java files for the mods importer."\n\n    schemaFile = "src/main/resources/xjc/mods/mods-3-7.xsd"\n    bindingFile = "src/main/resources/xjc/mods/mods-binding.xjb"\n    outputDirectory = "src-gen/main/java"\n    javaPackage = "org.jabref.logic.importer.fileformat.mods"\n    arguments = \'-npa\'\n}\n\ntask generateJournalAbbreviationList(type: JournalAbbreviationConverter) {\n    group = \'JabRef\'\n    description = "Converts the comma-separated journal abbreviation file to a H2 MVStore."\n\n    // This directory is filled by "refresh-journal-lists.yml"\n    // It takes the contents of https://github.com/JabRef/abbrv.jabref.org.git\n    inputDir = file("build/journals")\n\n    outputDir = file("src/main/resources/journals")\n}\n\ntasks.withType(JavaCompile) {\n    options.encoding = \'UTF-8\'\n}\n\ncompileJava {\n    options.compilerArgs << "-Xlint:none"\n    dependsOn "generateSource"\n\n    options.generatedSourceOutputDirectory.set(file("src-gen/main/java"))\n\n    moduleOptions {\n        // TODO: Remove access to internal api\n        addExports = [\n                \'javafx.controls/com.sun.javafx.scene.control\' : \'org.jabref\',\n                \'org.controlsfx.controls/impl.org.controlsfx.skin\' : \'org.jabref\'\n        ]\n    }\n}\n\nrun {\n    // TODO: Remove access to internal api\n    moduleOptions {\n        addExports = [\n                \'javafx.controls/com.sun.javafx.scene.control\' : \'org.jabref\',\n                \'org.controlsfx.controls/impl.org.controlsfx.skin\' : \'org.jabref\',\n\n                \'javafx.controls/com.sun.javafx.scene.control.behavior\' : \'com.jfoenix\',\n\n                // Not sure why we need to restate the controlfx exports\n                // Taken from here: https://github.com/controlsfx/controlsfx/blob/9.0.0/build.gradle#L1\n                \'javafx.graphics/com.sun.javafx.scene\' : \'org.controlsfx.controls\',\n                \'javafx.graphics/com.sun.javafx.scene.traversal\' : \'org.controlsfx.controls\',\n                \'javafx.graphics/com.sun.javafx.css\' : \'org.controlsfx.controls\',\n                \'javafx.controls/com.sun.javafx.scene.control\' : \'org.controlsfx.controls\',\n                \'javafx.controls/com.sun.javafx.scene.control.behavior\' : \'org.controlsfx.controls\',\n                \'javafx.controls/com.sun.javafx.scene.control.inputmap\' : \'org.controlsfx.controls\',\n                \'javafx.base/com.sun.javafx.event\' : \'org.controlsfx.controls\',\n                \'javafx.base/com.sun.javafx.collections\' : \'org.controlsfx.controls\',\n                \'javafx.base/com.sun.javafx.runtime\': \'org.controlsfx.controls\',\n                \'javafx.web/com.sun.webkit\' : \'org.controlsfx.controls\',\n        ]\n\n        addOpens = [\n                \'javafx.controls/javafx.scene.control\' : \'org.jabref\',\n                \'org.controlsfx.controls/org.controlsfx.control.textfield\' : \'org.jabref\',\n                \'javafx.controls/com.sun.javafx.scene.control\' : \'org.jabref\',\n\n                \'javafx.controls/javafx.scene.control.skin\' : \'org.controlsfx.controls\',\n                \'javafx.graphics/javafx.scene\' : \'org.controlsfx.controls\',\n\n                \'javafx.controls/com.sun.javafx.scene.control.behavior\' : \'com.jfoenix\',\n                \'javafx.base/com.sun.javafx.binding\' : \'com.jfoenix\',\n                \'javafx.graphics/com.sun.javafx.stage\' : \'com.jfoenix\',\n                \'javafx.base/com.sun.javafx.event\' : \'com.jfoenix\'\n        ]\n    }\n}\n\njavadoc {\n    options {\n        encoding = \'UTF-8\'\n        version = true\n        author = true\n         addMultilineStringsOption("-add-exports").setValue([\n            \'javafx.controls/com.sun.javafx.scene.control=org.jabref\',\n            \'org.controlsfx.controls/impl.org.controlsfx.skin=org.jabref\'\n        ])\n    }\n}\n\ntest {\n    useJUnitPlatform {\n        excludeTags \'DatabaseTest\', \'FetcherTest\', \'GUITest\'\n    }\n\n    moduleOptions {\n        // TODO: Remove this as soon as archunit is modularized\n        runOnClasspath = true\n    }\n\n    testLogging {\n        // set options for log level LIFECYCLE\n        // for debugging tests: add "STANDARD_OUT", "STANDARD_ERROR"\n        events = ["FAILED"]\n        exceptionFormat "full"\n    }\n}\n\ntestlogger {\n    showPassed false\n}\n\ntask databaseTest(type: Test) {\n    useJUnitPlatform {\n        includeTags \'DatabaseTest\'\n    }\n\n    testLogging {\n        // set options for log level LIFECYCLE\n        events = ["FAILED"]\n        exceptionFormat "full"\n    }\n}\n\ntask fetcherTest(type: Test) {\n    useJUnitPlatform {\n        includeTags \'FetcherTest\'\n    }\n\n    testLogging {\n        // set options for log level LIFECYCLE\n        events = ["FAILED"]\n        exceptionFormat "full"\n    }\n}\n\ntask guiTest(type: Test) {\n    useJUnitPlatform {\n        includeTags \'GUITest\'\n    }\n\n    testLogging {\n        // set options for log level LIFECYCLE\n        events = ["FAILED"]\n        exceptionFormat "full"\n    }\n}\n\n// Test result tasks\ntask copyTestResources(type: Copy) {\n    from "${projectDir}/src/test/resources"\n    into "${buildDir}/classes/test"\n}\nprocessTestResources.dependsOn copyTestResources\n\ntasks.withType(Test) {\n    reports.html.outputLocation.set(file("${reporting.baseDir}/${name}"))\n}\n\ntask jacocoPrepare() {\n    doFirst {\n        // Ignore failures of tests\n        tasks.withType(Test) {\n            ignoreFailures = true\n        }\n    }\n}\ntest.mustRunAfter jacocoPrepare\ndatabaseTest.mustRunAfter jacocoPrepare\nfetcherTest.mustRunAfter jacocoPrepare\n\njacocoTestReport {\n    executionData files(\n            "$buildDir/jacoco/test.exec",\n            "$buildDir/jacoco/databaseTest.exec",\n            "$buildDir/jacoco/fetcherTest.exec").filter { it.exists() }\n    dependsOn jacocoPrepare, test, databaseTest, fetcherTest\n\n    reports {\n        csv.getRequired().set(true)\n        html.getRequired().set(true)\n        xml.getRequired().set(true) // coveralls plugin depends on xml format report\n    }\n}\n\n// Code quality tasks\ncheckstyle {\n    // will only run when called explicitly from the command line\n    sourceSets = []\n}\n\n// Release tasks\ntask deleteInstallerTemp(type: Delete) {\n    delete "$buildDir/installer"\n}\n\njpackage.dependsOn deleteInstallerTemp\njlink {\n    addOptions(\'--strip-debug\', \'--compress\', \'2\', \'--no-header-files\', \'--no-man-pages\')\n    launcher {\n        name = \'JabRef\'\n    }\n\n    addOptions("--bind-services")\n\n    // TODO: Remove the following as soon as the dependencies are fixed (upstream)\n    // forceMerge is usually needed when some non-modular artifacts in the dependency graph use code that was previously part of the JDK\n    // but it was removed in the newer releases.\n    // The pom.xml associated with such a non-modular artifact does not mention that the artifact depends on the removed code\n    // (because the artifact was published when this code was still available in the JDK).\n    forceMerge "javafx"\n    forceMerge "controlsfx", "bcprov", "jaxb", "istack", "stax", "log4j"\n\n    // TODO: Remove the following correction to the merged module\n    // The module descriptor automatically generated by the plugin for the merged module contained some invalid entries.\n    // Execute ./gradlew suggestMergedModuleInfo and include the suggested directives here.\n    mergedModule {\n        requires \'java.compiler\'\n        requires \'java.datatransfer\'\n        requires \'java.desktop\'\n        requires \'java.logging\'\n        requires \'java.management\'\n        requires \'java.naming\'\n        requires \'java.net.http\'\n        requires \'java.scripting\'\n        requires \'java.security.jgss\'\n        requires \'java.security.sasl\'\n        requires \'java.sql\'\n        requires \'java.sql.rowset\'\n        requires \'java.transaction.xa\'\n        requires \'java.rmi\'\n        requires \'java.xml\'\n        requires \'jdk.jsobject\'\n        requires \'jdk.unsupported\'\n        requires \'jdk.unsupported.desktop\'\n        requires \'jdk.security.jgss\'\n        requires \'jdk.xml.dom\'\n        requires \'com.google.gson\'\n        requires \'org.slf4j\'\n        requires \'jakarta.xml.bind\'\n        uses \'org.mariadb.jdbc.credential.CredentialPlugin\'\n        uses \'org.mariadb.jdbc.authentication.AuthenticationPlugin\'\n        uses \'org.mariadb.jdbc.tls.TlsSocketPlugin\'\n        uses \'org.mariadb.jdbc.LocalInfileInterceptor\'\n        uses \'org.eclipse.jgit.transport.SshSessionFactory\'\n        uses \'org.eclipse.jgit.lib.GpgSigner\'\n        provides \'org.mariadb.jdbc.tls.TlsSocketPlugin\' with \'org.mariadb.jdbc.internal.protocol.tls.DefaultTlsSocketPlugin\'\n        provides \'java.sql.Driver\' with \'org.postgresql.Driver\'\n        provides \'org.mariadb.jdbc.authentication.AuthenticationPlugin\' with \'org.mariadb.jdbc.internal.com.send.authentication.CachingSha2PasswordPlugin\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.ClearPasswordPlugin\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.Ed25519PasswordPlugin\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.NativePasswordPlugin\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.OldPasswordPlugin\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.SendGssApiAuthPacket\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.SendPamAuthPacket\',\n                \'org.mariadb.jdbc.internal.com.send.authentication.Sha256PasswordPlugin\'\n        provides \'org.mariadb.jdbc.credential.CredentialPlugin\' with \'org.mariadb.jdbc.credential.aws.AwsIamCredentialPlugin\',\n                \'org.mariadb.jdbc.credential.env.EnvCredentialPlugin\',\n                \'org.mariadb.jdbc.credential.system.PropertiesCredentialPlugin\'\n        provides \'java.security.Provider\' with \'org.bouncycastle.jce.provider.BouncyCastleProvider\',\n                \'org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider\'    }\n\n    jpackage {\n        outputDir = "distribution"\n\n        if (OperatingSystem.current().isWindows()) {\n            // This requires WiX to be installed: https://github.com/wixtoolset/wix3/releases\n            installerType = "msi"\n            imageOptions = [\n                    \'--icon\', "${projectDir}/src/main/resources/icons/jabref.ico",\n            ]\n            installerOptions = [\n                    \'--vendor\', \'JabRef\',\n                    \'--app-version\', "${project.version}",\n                    \'--verbose\',\n                    \'--win-upgrade-uuid\', \'d636b4ee-6f10-451e-bf57-c89656780e36\',\n                    \'--win-dir-chooser\',\n                    \'--win-shortcut\',\n                    \'--win-menu\',\n                    \'--win-menu-group\', "JabRef",\n                    \'--temp\', "$buildDir/installer",\n                    \'--resource-dir\', "${projectDir}/buildres/windows",\n                    \'--file-associations\', "${projectDir}/buildres/windows/bibtexAssociations.properties"\n            ]\n        }\n\n        if (OperatingSystem.current().isLinux()) {\n            imageOptions = [\n                    \'--icon\', "${projectDir}/src/main/resources/icons/JabRef-icon-64.png",\n                    \'--app-version\', "${project.version}",\n            ]\n            installerOptions = [\n                    \'--verbose\',\n                    \'--vendor\', \'JabRef\',\n                    \'--app-version\', "${project.version}",\n                    // \'--temp\', "$buildDir/installer",\n                    \'--resource-dir\', "${projectDir}/buildres/linux",\n                    \'--linux-menu-group\', \'Office;\',\n                    \'--linux-rpm-license-type\', \'MIT\',\n                    // \'--license-file\', "${projectDir}/LICENSE.md",\n                    \'--description\', \'JabRef is an open source bibliography reference manager. The native file format used by JabRef is BibTeX, the standard LaTeX bibliography format.\',\n                    \'--linux-shortcut\',\n                    \'--file-associations\', "${projectDir}/buildres/linux/bibtexAssociations.properties"\n            ]\n        }\n\n        if (OperatingSystem.current().isMacOsX()) {\n            imageOptions = [\n                    \'--icon\', "${projectDir}/src/main/resources/icons/jabref.icns",\n                    \'--resource-dir\', "${projectDir}/buildres/mac"\n            ]\n            // Due to a signing bug in jpackage we have to first resign the created app and therefore build the dmg manually\n            // See https://bugs.openjdk.java.net/browse/JDK-8251892 for details\n            skipInstaller = true\n            installerOptions = [\n                    \'--verbose\',\n                    \'--vendor\', \'JabRef\',\n                    \'--mac-package-identifier\', "JabRef",\n                    \'--mac-package-name\', "JabRef",\n                    \'--app-version\', "${project.version}",\n                    \'--file-associations\', "${projectDir}/buildres/mac/bibtexAssociations.properties",\n                    \'--resource-dir\', "${projectDir}/buildres/mac"\n            ]\n        }\n    }\n}\n\nif (OperatingSystem.current().isWindows()) {\n    tasks.jpackageImage.doLast {\n        copy {\n            from("${projectDir}/buildres/windows") {\n                include "jabref-firefox.json", "jabref-chrome.json", "JabRefHost.bat", "JabRefHost.ps1"\n            }\n            into "$buildDir/distribution/JabRef"\n        }\n    }\n}\n\nif (OperatingSystem.current().isLinux()) {\n    tasks.jpackageImage.doLast {\n        copy {\n            from("${projectDir}/buildres/linux") {\n                include "native-messaging-host/**", "jabrefHost.py"\n            }\n            into "$buildDir/distribution/JabRef/lib"\n        }\n    }\n}\n\nif (OperatingSystem.current().isMacOsX()) {\n    tasks.jpackageImage.doLast {\n        copy {\n            from("${projectDir}/buildres/mac") {\n                include "native-messaging-host/**", "jabrefHost.py"\n            }\n            into "$buildDir/distribution/JabRef.app/Contents/Resources"\n        }\n    }\n}\njmh {\n    warmupIterations = 5\n    iterations = 10\n    fork = 2\n}\n\n// Source: https://stackoverflow.com/a/44168582/873282\ntask downloadDependencies {\n    description "Pre-downloads *most* dependencies"\n    doLast {\n        configurations.getAsMap().each { name, config ->\n            println "Retrieving dependencies for $name"\n            try {\n                config.files\n            } catch (e) {\n                // some cannot be resolved, just log them\n                project.logger.info e.message\n            }\n        }\n    }\n}\n', 'message': 'Remove "maven" plugin as we currently don\'t publish maven artifacts\n', 'author_name': 'Oliver Kopp', 'lang': 'gradle'}