From 0f4c43014adc384b104ea20fd7d980a38f7ec38a Mon Sep 17 00:00:00 2001 From: nathan Date: Sun, 17 Mar 2019 23:06:01 +0100 Subject: [PATCH] Build converted to kotlin script --- build.gradle.kts | 404 ++++++++++++++++++++++++++------------------ settings.gradle.kts | 11 -- 2 files changed, 238 insertions(+), 177 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3d10744..ccde1e9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,273 +14,345 @@ * limitations under the License. */ - -import java.nio.file.Paths +import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask import java.time.Instant +import java.util.* +import kotlin.reflect.KMutableProperty +import kotlin.reflect.full.declaredMemberProperties -buildscript { - // load properties from custom location - def propsFile = Paths.get("${projectDir}/../../gradle.properties").normalize().toFile() - if (propsFile.canRead()) { - println("Loading custom property data from: ${propsFile}") +/////////////////////////////// +////// PUBLISH TO SONATYPE / MAVEN CENTRAL +////// +////// TESTING : local maven repo +////// +////// RELEASE : sonatype / maven central, then +/////////////////////////////// - def props = new Properties() - propsFile.withInputStream {props.load(it)} - props.each {key, val -> project.ext.set(key, val)} - } - else { - ext.sonatypeUsername = "" - ext.sonatypePassword = "" - } - - // for plugin publishing and license sources - repositories { - maven {url "https://plugins.gradle.org/m2/"} - } - dependencies { - // this is the only way to also get the source code for IDE auto-complete - classpath "gradle.plugin.com.dorkbox:Licensing:1.2.2" - classpath "gradle.plugin.com.dorkbox:Licensing:1.2.2:sources" - } -} +println("\tGradle ${project.gradle.gradleVersion}") plugins { - id 'java' - id 'maven-publish' - id 'signing' + java + signing + `maven-publish` // close and release on sonatype - id 'io.codearte.nexus-staging' version '0.11.0' + id("io.codearte.nexus-staging") version "0.20.0" - id "com.dorkbox.CrossCompile" version "1.0.1" - id "com.dorkbox.VersionUpdate" version "1.2" + id("com.dorkbox.CrossCompile") version "1.0.1" + id("com.dorkbox.Licensing") version "1.4" + id("com.dorkbox.VersionUpdate") version "1.4.1" - // setup checking for the latest version of a plugin or dependency (and updating the gradle build) - id "se.patrikerdes.use-latest-versions" version "0.2.3" - id 'com.github.ben-manes.versions' version '0.16.0' + // setup checking for the latest version of a plugin or dependency + id("com.github.ben-manes.versions") version "0.21.0" + + kotlin("jvm") version "1.3.21" } -// this is the only way to also get the source code for IDE auto-complete -apply plugin: "com.dorkbox.Licensing" +object Extras { + // set for the project + const val description = "Windows PE (Portable Executable) file parser for Java 6+" + const val group = "com.dorkbox" + const val version = "2.14" -// give us access to api/implementation differences for building java libraries -apply plugin: 'java-library' + // set as project.ext + const val name = "PeParser" + const val id = "PeParser" + const val vendor = "Dorkbox LLC" + const val url = "https://git.dorkbox.com/dorkbox/PeParser" + val buildDate = Instant.now().toString() + val JAVA_VERSION = JavaVersion.VERSION_1_6.toString() -project.description = 'Windows PE (Portable Executable) file parser for Java 6+' -project.group = 'com.dorkbox' -project.version = '2.14' + var sonatypeUserName = "" + var sonatypePassword = "" +} -project.ext.name = 'PeParser' -project.ext.url = 'https://git.dorkbox.com/dorkbox/PeParser' +/////////////////////////////// +///// assign 'Extras' +/////////////////////////////// +description = Extras.description +group = Extras.group +version = Extras.version +val propsFile = File("$projectDir/../../gradle.properties").normalize() +if (propsFile.canRead()) { + println("\tLoading custom property data from: [$propsFile]") -sourceCompatibility = JavaVersion.VERSION_1_6 -targetCompatibility = JavaVersion.VERSION_1_6 + val props = Properties() + propsFile.inputStream().use { + props.load(it) + } + + val extraProperties = Extras::class.declaredMemberProperties.filterIsInstance>() + props.forEach { (k, v) -> run { + val key = k as String + val value = v as String + + val member = extraProperties.find { it.name == key } + if (member != null) { + member.setter.call(Extras::class.objectInstance, value) + } + else { + project.extra.set(k, v) + } + }} +} licensing { - license(License.APACHE_2) { - author 'dorkbox, llc' - url project.ext.url - note project.description + license(License.BSD_3) { + author(Extras.vendor) + author("Nathan Sweet") + author("Dan Brown") + url(Extras.url) + url("https://github.com/EsotericSoftware/minlog") + note(Extras.description) } - license('jOOU - Unsigned Numbers for Java', License.APACHE_2) { - copyright 2013 - author 'Lukas Eder, lukas.eder@gmail.com' - url 'https://github.com/jOOQ/jOOU' + + license("jOOU - Unsigned Numbers for Java", License.APACHE_2) { + copyright(2013) + author("Lukas Eder, lukas.eder@gmail.com") + url("https://github.com/jOOQ/jOOU") } } sourceSets { main { java { - setSrcDirs Collections.singletonList('src') + setSrcDirs(listOf("src")) + + // want to include java files for the source. 'setSrcDirs' resets includes... + include("**/*.java") } } } - repositories { mavenLocal() // this must be first! jcenter() } - -dependencies { - // utilities dependencies compile only - compileOnly(project('Utilities')) - - // our main dependencies are ALSO the same as the limited utilities (they are not automatically pulled in from other sourceSets) - // needed by the utilities (custom since we don't want to include everything). IntelliJ includes everything, but our builds do not -} - - /////////////////////////////// -////// Task defaults +////// UTILITIES COMPILE /////////////////////////////// -tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' -} -tasks.withType(Jar) { - duplicatesStrategy DuplicatesStrategy.FAIL +// as long as the 'Utilities' project is ALSO imported into IntelliJ, class resolution will work (add the sources in the intellij project) +val utils : Configuration by configurations.creating - manifest { - attributes['Implementation-Version'] = version - attributes['Build-Date'] = Instant.now().toString() - attributes['Automatic-Module-Name'] = project.ext.name.toString() - } -} +fun javaFile(vararg fileNames: String): Iterable { + val fileList = ArrayList(fileNames.size) -/////////////////////////////// -////// UTILITIES COMPILE (for inclusion into jars) -/////////////////////////////// -static String[] utilFiles(String... fileNames) { - def fileList = [] as ArrayList - - for (name in fileNames) { - def fixed = name.replace('.', '/') + '.java' - fileList.add(fixed) + fileNames.forEach { name -> + fileList.add(name.replace('.', '/') + ".java") } return fileList } -task compileUtils(type: JavaCompile) { + +task("compileUtils") { // we don't want the default include of **/*.java - getIncludes().clear() + includes.clear() - source = Collections.singletonList('../Utilities/src') + source = fileTree("../Utilities/src") + include(javaFile( + "dorkbox.util.OS", + "dorkbox.util.OSType", - include utilFiles('dorkbox.util.bytes.LittleEndian', - 'dorkbox.util.bytes.UByte', - 'dorkbox.util.bytes.UInteger', - 'dorkbox.util.bytes.ULong', - 'dorkbox.util.bytes.Unsigned', - 'dorkbox.util.bytes.UNumber', - 'dorkbox.util.bytes.UShort') + "dorkbox.util.bytes.LittleEndian", + "dorkbox.util.bytes.UByte", + "dorkbox.util.bytes.UInteger", + "dorkbox.util.bytes.ULong", + "dorkbox.util.bytes.Unsigned", + "dorkbox.util.bytes.UNumber", + "dorkbox.util.bytes.UShort" + )) - classpath = sourceSets.main.compileClasspath + classpath = files(utils) destinationDir = file("$rootDir/build/classes_utilities") } -jar { - dependsOn compileUtils +/////////////////////////////// +////// Task defaults +/////////////////////////////// +tasks.withType { + options.encoding = "UTF-8" - // include applicable class files from subset of Utilities project - from compileUtils.destinationDir + sourceCompatibility = Extras.JAVA_VERSION + targetCompatibility = Extras.JAVA_VERSION } -///////////////////////////// -//// Maven Publishing + Release -///////////////////////////// -task sourceJar(type: Jar) { +tasks.withType { + duplicatesStrategy = DuplicatesStrategy.FAIL +} + +tasks.jar.get().apply { + // include applicable class files from subset of Utilities project + from((tasks["compileUtils"] as JavaCompile).outputs) + + manifest { + // https://docs.oracle.com/javase/tutorial/deployment/jar/packageman.html + attributes["Name"] = Extras.name + + attributes["Specification-Title"] = Extras.name + attributes["Specification-Version"] = Extras.version + attributes["Specification-Vendor"] = Extras.vendor + + attributes["Implementation-Title"] = "${Extras.group}.${Extras.id}" + attributes["Implementation-Version"] = Extras.buildDate + attributes["Implementation-Vendor"] = Extras.vendor + } +} + +tasks.compileJava.get().apply { + println("\tCompiling classes to Java $sourceCompatibility") +} + + +dependencies { + api("com.dorkbox:TweenEngine:8.3") + + // add compile utils to dependencies + implementation(files((tasks["compileUtils"] as JavaCompile).outputs)) +} + +/////////////////////////////// +////// PUBLISH TO SONATYPE / MAVEN CENTRAL +////// +////// TESTING : local maven repo +////// +////// RELEASE : sonatype / maven central, then +/////////////////////////////// +val sourceJar = task("sourceJar") { description = "Creates a JAR that contains the source code." - from sourceSets.main.java + from(sourceSets["main"].java) - classifier = "sources" + archiveClassifier.set("sources") } -task javaDocJar(type: Jar) { +val javaDocJar = task("javaDocJar") { description = "Creates a JAR that contains the javadocs." - classifier = "javadoc" + archiveClassifier.set("javadoc") } -// for testing, we don't publish to maven central, but only to local maven publishing { publications { - maven(MavenPublication) { - from components.java + create("maven") { + groupId = Extras.group + artifactId = Extras.id + version = Extras.version + + from(components["java"]) - artifact(javaDocJar) artifact(sourceJar) - - groupId project.group - artifactId project.ext.name - version project.version + artifact(javaDocJar) pom { - name = project.ext.name - url = project.ext.url - description = project.description + name.set(Extras.name) + description.set(Extras.description) + url.set(Extras.url) issueManagement { - url = "${project.ext.url}/issues".toString() - system = 'Gitea Issues' + url.set("${Extras.url}/issues") + system.set("Gitea Issues") } - organization { - name = 'dorkbox, llc' - url = 'https://dorkbox.com' + name.set(Extras.vendor) + url.set("https://dorkbox.com") } - developers { developer { - name = 'dorkbox, llc' - email = 'email@dorkbox.com' + id.set("dorkbox") + name.set(Extras.vendor) + email.set("email@dorkbox.com") } } - scm { - url = project.ext.url - connection = "scm:${project.ext.url}.git".toString() + url.set(Extras.url) + connection.set("scm:${Extras.url}.git") } } + + } + } + + + repositories { + maven { + setUrl("https://oss.sonatype.org/service/local/staging/deploy/maven2") + credentials { + username = Extras.sonatypeUserName + password = Extras.sonatypePassword + } } } - repositories { - maven { - url "https://oss.sonatype.org/service/local/staging/deploy/maven2" - credentials { - username sonatypeUsername - password sonatypePassword - } + + tasks.withType { + onlyIf { + publication == publishing.publications["maven"] && repository == publishing.repositories["maven"] } } + + tasks.withType { + onlyIf { + publication == publishing.publications["maven"] + } + } + + // output the release URL in the console + tasks["releaseRepository"].doLast { + val url = "https://oss.sonatype.org/content/repositories/releases/" + val projectName = Extras.group.replace('.', '/') + val name = Extras.name + val version = Extras.version + + println("Maven URL: $url$projectName/$name/$version/") + } } nexusStaging { - username sonatypeUsername - password sonatypePassword + username = Extras.sonatypeUserName + password = Extras.sonatypePassword } signing { - sign publishing.publications.maven + sign(publishing.publications["maven"]) } -// output the release URL in the console -releaseRepository.doLast { - def URL = 'https://oss.sonatype.org/content/repositories/releases/' - def projectName = project.group.toString().replaceAll('\\.', '/') - def name = project.ext.name - def version = project.version - println("Maven URL: ${URL}${projectName}/${name}/${version}/") -} -// we don't use maven with the plugin (it's uploaded separately to gradle plugins) -tasks.withType(PublishToMavenRepository) { - onlyIf { - repository == publishing.repositories.maven && publication == publishing.publications.maven - } -} -tasks.withType(PublishToMavenLocal) { - onlyIf { - publication == publishing.publications.maven +/////////////////////////////// +///// Prevent anything other than a release from showing version updates +//// https://github.com/ben-manes/gradle-versions-plugin/blob/master/README.md +/////////////////////////////// +tasks.named("dependencyUpdates") { + resolutionStrategy { + componentSelection { + all { + val rejected = listOf("alpha", "beta", "rc", "cr", "m", "preview") + .map { qualifier -> Regex("(?i).*[.-]$qualifier[.\\d-]*") } + .any { it.matches(candidate.version) } + if (rejected) { + reject("Release candidate") + } + } + } } + + // optional parameters + checkForGradleUpdate = true } -///////////////////////////// -//// Gradle Wrapper Configuration. -/// Run this task, then refresh the gradle project -///////////////////////////// -task updateWrapper(type: Wrapper) { - gradleVersion = '4.10.2' + +/////////////////////////////// +////// Gradle Wrapper Configuration. +///// Run this task, then refresh the gradle project +/////////////////////////////// +val wrapperUpdate by tasks.creating(Wrapper::class) { + gradleVersion = "5.2.1" distributionUrl = distributionUrl.replace("bin", "all") - setDistributionType(Wrapper.DistributionType.ALL) } diff --git a/settings.gradle.kts b/settings.gradle.kts index d9d8f9f..cce9d6c 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -13,14 +13,3 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -include("Utilities") - -for (project in rootProject.children) { - project.projectDir = file("../$project.name") - project.buildFileName = "utilities.gradle" - - assert (project.projectDir.directory) - assert (project.buildFile.file) -} - -enableFeaturePreview('STABLE_PUBLISHING')