diff --git a/build.gradle b/build.gradle index 20ee360e81f..41514ca2040 100644 --- a/build.gradle +++ b/build.gradle @@ -1,26 +1,19 @@ import java.security.MessageDigest -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'com.android.tools.build:gradle:0.9.+' - } +plugins { + id 'java' + id 'maven-publish' } -configurations { - provided - compile +// Use version from Git if no version is provided (using `-Pversion=buildXXXXX`) +if (version == DEFAULT_VERSION) { + version = versionFromGit } -apply plugin: 'java' -apply plugin: 'maven-publish' - repositories { flatDir { dirs uri("${projectDir}/lib") } maven { - url 'https://mvn.freenetproject.org' + url = 'https://mvn.freenetproject.org' metadataSources { artifact() } @@ -28,275 +21,236 @@ repositories { mavenCentral() } -sourceSets { - main.compileClasspath += configurations.provided - test.compileClasspath += configurations.provided +dependencies { + implementation 'org.bouncycastle:bcprov-jdk15on:1.59' + implementation 'net.java.dev.jna:jna:4.5.2' + implementation 'net.java.dev.jna:jna-platform:4.5.2' + implementation 'org.freenetproject:freenet-ext:29' + implementation 'io.pebbletemplates:pebble:3.1.5' + // dependencies of pebble + implementation 'org.unbescape:unbescape:1.1.6.RELEASE' + implementation 'org.slf4j:slf4j-api:1.7.25' + + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.mockito:mockito-core:1.9.5' + testImplementation 'org.hamcrest:hamcrest:3.0' + testImplementation 'org.objenesis:objenesis:1.0' } -def version_buildir = file("$projectDir/build/tmp/compileVersion/") -def version_src = 'freenet/node/Version.java' +publishing { + publications { + mavenJava(MavenPublication) { + groupId = 'org.freenetproject' + artifactId = 'fred' + from components.java + } + } + repositories { + maven { + url = 's3://mvn.freenetproject.org/' + credentials(AwsCredentials) { + accessKey = System.getenv('AWS_ACCESS_KEY_ID') + secretKey = System.getenv('AWS_SECRET_ACCESS_KEY') + } + } + } +} + +def versionJavaFile = 'freenet/node/Version.java' sourceSets { main { java { - srcDir 'src/' + srcDirs 'src' + include '**/*.java' + exclude versionJavaFile + } + resources { + srcDirs 'src' + exclude '**/*.java' } } test { java { - srcDir 'test/' + srcDirs 'test' + include '**/*.java' + } + resources { + srcDirs 'test' + exclude '**/*.java' } - } -} - -def gitrev -task buildInfo { - try { - def cmd = "git describe --always --abbrev=4 --dirty" - def proc = cmd.execute([], project.rootDir) - gitrev = proc.text.trim() - } catch (IOException ignored) { - gitrev = "@unknown@" } } java { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 + withSourcesJar() + withJavadocJar() } -tasks.withType(JavaCompile) { - options.encoding = "UTF-8" -} - -tasks.withType(Javadoc) { - options.encoding = "UTF-8" -} - -task generateVersionSource(type: Copy) { - dependsOn buildInfo +tasks.register('versionSource', Copy) { + inputs.property('version', version) from(sourceSets.main.java.srcDirs) { - include version_src - filter { - String line -> line.replaceAll('@custom@', gitrev) - } - } - into version_buildir -} - -task compileVersion (type: JavaCompile) { - dependsOn generateVersionSource, compileJava - sourceCompatibility = 1.8 - targetCompatibility = 1.8 - source = version_buildir - include version_src - classpath = files(sourceSets.main.compileClasspath, sourceSets.main.output.classesDirs) - destinationDirectory.set(layout.buildDirectory.dir("java/version/").get()) -} - -task buildJar(type: Jar) { - dependsOn compileVersion, processResources - from(processResources) - from(compileJava.destinationDirectory) { - exclude 'freenet/node/Version.class' - exclude 'freenet/node/Version$1.class' + include versionJavaFile } - from(compileVersion.destinationDirectory) - preserveFileTimestamps = false - reproducibleFileOrder = true - duplicatesStrategy = DuplicatesStrategy.FAIL - archivesBaseName = "freenet" - manifest { - attributes("Permissions": "all-permissions") - attributes("Application-Name": "Freenet REference Daemon") - attributes("Required-Ext-Version": 29) - attributes("Recommended-Ext-Version": 29) - attributes("Compiled-With": "${System.getProperty('java.version')} (${System.getProperty('java.vendor')})") - attributes([ - "Specification-Title": "Freenet", - "Specification-Version": "0.7.5", - "Specification-Vendor": "freenetproject.org", - "Implementation-Title": "Freenet", - "Implementation-Version": "0.7.5 ${gitrev}", - "Implementation-Vendor": "freenetproject.org", - ], "common") + filteringCharset = 'UTF-8' + filter { + line -> line.replaceAll('@custom@', inputs.properties.version as String) } + into temporaryDir } -jar.enabled = false -jar.dependsOn buildJar - -task sourcesJar(type: Jar) { - dependsOn generateVersionSource - archiveClassifier = 'sources' - preserveFileTimestamps = false - reproducibleFileOrder = true - from(sourceSets.main.allSource) { - exclude 'freenet/node/Version.java' - } - from(compileVersion.source) +extendSourceDirectorySet(sourceSets.main.java, 'version') { + // Add the generated version file + srcDirs versionSource + include versionJavaFile } -def jars = [] -gradle.addListener(new TaskExecutionListener() { -void afterExecute(Task task, TaskState state) { - if(task in AbstractArchiveTask && task.enabled) { - jars << task.outputs.files.singleFile - } +extendSourceDirectorySet(sourceSets.main.resources, 'dependencies') { + // Add `dependencies.properties` from the project root + srcDirs projectDir + include 'dependencies.properties' } -void beforeExecute(Task task) { } -}) -gradle.addBuildListener(new BuildAdapter() { - void buildFinished(BuildResult result) { - if(jars) { - def hash = { - File file -> def sha256 = MessageDigest.getInstance('SHA-256') - file.eachByte(1024 * 4) { buffer, len -> sha256.update(buffer, 0, len) } - println "SHA-256 of ${file.name}: ${sha256.digest().encodeHex().toString()}" - } - - jars.each { hash(it) } - } - } -}) - -task copyResourcesToClasses2 { - inputs.files sourceSets.main.allSource - outputs.dir layout.buildDirectory.dir("classes/java/main/") - doLast { - copy { - from sourceSets.main.allSource - into layout.buildDirectory.dir("classes/java/main/") - include 'freenet/l10n/*properties' - include 'freenet/l10n/iso-*.tab' - include 'freenet/clients/http/staticfiles/**' - include 'freenet/clients/http/templates/**' - include '../dependencies.properties' - } - copy { - from "${projectDir}/" - into layout.buildDirectory.dir("classes/java/main/") - include 'dependencies.properties' - } +compileJava { + options.encoding = 'UTF-8' + if (!version.endsWith('-dirty')) { + // Make sure incremental compilation is disabled on release builds due to reproducibility issues. + logger.lifecycle('Potential release build (project version not dirty). Incremental compilation disabled.') + options.incremental = false } } -processResources.dependsOn copyResourcesToClasses2 -compileVersion.dependsOn copyResourcesToClasses2 -task copyTestResourcesToClasses2 { - inputs.files sourceSets.test.allSource - outputs.dir layout.buildDirectory.dir("classes/java/test/") - doLast { - copy { - from sourceSets.test.allSource - into layout.buildDirectory.dir("classes/java/test/") - include 'freenet/client/filter/*/**' - include 'freenet/crypt/ciphers/rijndael-gladman-test-data/**' - include 'freenet/l10n/*properties' - include 'freenet/clients/http/templates/**' - } - } +compileTestJava { + options.encoding = 'UTF-8' } -compileTestJava.dependsOn copyResourcesToClasses2 -compileTestJava.dependsOn copyTestResourcesToClasses2 test { - if(JavaVersion.current() >= JavaVersion.VERSION_1_9) { + if (JavaVersion.current() >= JavaVersion.VERSION_1_9) { jvmArgs '--add-opens=java.base/java.lang=ALL-UNNAMED' jvmArgs '--add-opens=java.base/java.util=ALL-UNNAMED' jvmArgs '--add-opens=java.base/java.io=ALL-UNNAMED' jvmArgs '--add-opens=java.base/java.util.zip=ALL-UNNAMED' } - minHeapSize = "128m" - maxHeapSize = "512m" - // no inner class + useJUnit() + minHeapSize = '128m' + maxHeapSize = '512m' + // Do not run inner classes, they are registered as part of a Suite include 'freenet/**/*Test.class' exclude 'freenet/**/*$*Test.class' scanForTestClasses = false - systemProperties += [ -// "test.extensive": -// "test.verbose": -// "test.benchmark": - ] } -tasks.withType(Test) { - enableAssertions = false +javadoc { + title = "Freenet REference Daemon ${version}" + options { + encoding = 'UTF-8' + source = java.sourceCompatibility + // Ignore Javadoc linting errors + addBooleanOption('Xdoclint:none', true) + } } -publishing { - publications { - mavenJava(MavenPublication) { - groupId 'org.freenetproject' - artifactId "fred" - version gitrev - from components.java - } - } - repositories { - maven { - url "s3://mvn.freenetproject.org/" - credentials(AwsCredentials) { - accessKey System.getenv('AWS_ACCESS_KEY_ID') - secretKey System.getenv('AWS_SECRET_ACCESS_KEY') - } - } +jar { + archiveFileName = 'freenet.jar' + manifest { + attributes 'Permissions': 'all-permissions' + attributes 'Application-Name': 'Freenet REference Daemon' + attributes 'Required-Ext-Version': 29 + attributes 'Recommended-Ext-Version': 29 + attributes 'Compiled-With': "${System.getProperty('java.version')} (${System.getProperty('java.vendor')})" + attributes([ + 'Specification-Title' : 'Freenet', + 'Specification-Version' : '0.7.5', + 'Specification-Vendor' : 'freenetproject.org', + 'Implementation-Title' : 'Freenet', + 'Implementation-Version': "0.7.5 ${version}", + 'Implementation-Vendor' : 'freenetproject.org', + ], 'common') } } -task copyRuntimeLibs(type: Copy) { - into "${buildDir}/output/" +sourcesJar { + archiveFileName = 'freenet-sources.jar' +} + +javadocJar { + archiveFileName = 'freenet-javadoc.jar' +} + +tasks.register('copyRuntimeLibs', Copy) { + description = 'Collect all runtime artifacts and dependencies.' + group = 'Build' + + into layout.buildDirectory.dir('output') from configurations.runtimeClasspath from jar } -copyRuntimeLibs.dependsOn jar - -// In this section you declare the dependencies for your production and test code -dependencies { - implementation "org.bouncycastle:bcprov-jdk15on:1.59" - implementation "net.java.dev.jna:jna:4.5.2" - implementation "net.java.dev.jna:jna-platform:4.5.2" - implementation "org.freenetproject:freenet-ext:29" - implementation "io.pebbletemplates:pebble:3.1.5" - // dependencies of pebble - implementation "org.unbescape:unbescape:1.1.6.RELEASE" - implementation "org.slf4j:slf4j-api:1.7.25" - testImplementation 'junit:junit:4.13.2' - testImplementation "org.mockito:mockito-core:1.9.5" - testImplementation "org.hamcrest:hamcrest:3.0" - testImplementation "org.objenesis:objenesis:1.0" +assemble { + // Add copyRuntimeLibs so `gradlew assemble` collects all build artifacts. + // Note: jar, sourcesJar, javadocJar are added as dependency by default. + dependsOn copyRuntimeLibs } -task tar(type: Tar) { - description = "Build a source release, specifically excluding the build directories and gradle wrapper files" - compression = Compression.BZIP2 +tasks.register('archiveDigests') { + description = 'Display SHA-256 digests of all archives that were created.' + group = 'Help' - archiveBaseName = "freenet-sources" + // Do not declare dependencies, we'll print whatever is available + def artifacts = configurations.archives.artifacts - from(project.rootDir) { - exclude '**/build' - exclude 'build' - exclude '.gradle' - } + // Run this task at the end of the build + shouldRunAfter tasks - into(archiveBaseName) + // Print SHA256 digests of all available archive artifacts + doLast { + def sha256 = MessageDigest.getInstance('SHA-256') + artifacts.files.files.findAll { + it.canRead() + }.each { file -> + file.eachByte(1024 * 4) { buffer, len -> sha256.update(buffer, 0, len) } + logger.lifecycle('SHA-256 of {}: {}', file.name, sha256.digest().encodeHex()) + } + } +} - preserveFileTimestamps = true - reproducibleFileOrder = true +tasks.withType(AbstractArchiveTask).configureEach { + // Ensure reproducible archives + preserveFileTimestamps = false + reproducibleFileOrder = true - // Set destination directory. - destinationDirectory = file("${project.buildDir}") + // Fail the build if any file would be overwritten due to duplicates + duplicatesStrategy = DuplicatesStrategy.FAIL - archiveFileName = "${archiveBaseName}.tgz" - doLast { // generate md5 checksum - ant.checksum file:"$destinationDirectory/$archiveFileName" - } + // Register the archive for displaying digests at the end of the build + artifacts.archives archiveFile + finalizedBy archiveDigests } -javadoc { - doLast { - failOnError false +/** + * Try to obtain the version description from `git describe`. + */ +String getVersionFromGit() { + try { + def process = 'git describe --always --abbrev=4 --dirty'.execute([], project.rootDir) + if (process.waitFor() != 0) { + throw new IOException("exit code ${process.exitValue()}") + } + return process.text.trim() + } catch (IOException e) { + logger.warn('Cannot determine version from git: {}', e.message) + return '@unknown@' } } + +/** + * Add additional sources to a existing source directory. The additional sources can specify their own inclusion/ + * exclusion patterns independently from the existing sources. + */ +void extendSourceDirectorySet(SourceDirectorySet parent, String name, @DelegatesTo(value = SourceDirectorySet) Closure cl) { + def child = objects.sourceDirectorySet(name, parent.name) + cl.rehydrate(child, cl.owner, cl.thisObject).call() + parent.source child +} diff --git a/debian/rules b/debian/rules index 60026f8d707..9c487a9dfbe 100755 --- a/debian/rules +++ b/debian/rules @@ -32,7 +32,6 @@ clean: rm -rf .gradle gradle/wrapper/dists debian/freenet override_dh_auto_build: build_seed_file - ./gradlew jar; \ ./gradlew copyRuntimeLibs sed -e 's/@version@/$(FREENET_VERSION)/' -e 's/@build@/$(FREENET_BUILD)/' $(CURDIR)/debian/freenet.service.params | \