329 lines
11 KiB
Groovy
329 lines
11 KiB
Groovy
|
/*
|
||
|
* SwerveIO - A versatile open-source FRC swerve drive library.
|
||
|
*
|
||
|
* Copyright (C) 2019-2022 Jordan Bancino <jordan@bancino.net>
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published with this
|
||
|
* source code. You should have received a copy of the GNU General Public
|
||
|
* License with this program. If you did not, contact the distributors of
|
||
|
* this program and view it here: https://bancino.net/licenses/gpl-3.0.txt
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||
|
* more details.
|
||
|
*/
|
||
|
/*
|
||
|
* SwerveIO core build script. This is the master build script that holds the common
|
||
|
* project configuration for all SwerveIO subprojects, as well as the main SwerveIO
|
||
|
* core project.
|
||
|
*/
|
||
|
import org.apache.tools.ant.taskdefs.condition.Os
|
||
|
|
||
|
def versions = [
|
||
|
'SwerveIO': '8.0.2',
|
||
|
'WPILib': '2022.1.1',
|
||
|
'OpenCV': '4.5.2-1',
|
||
|
'Jackson': '2.10.0'
|
||
|
]
|
||
|
|
||
|
/* Not all "projects" are actual projects. This filters out the ones that aren't. */
|
||
|
def matchProject = { Project proj ->
|
||
|
return file("${proj.getProjectDir()}/build.gradle").exists()
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Check if there is an internet connection. This is used to dynamically
|
||
|
* disable build functionality that requires a connection, because those
|
||
|
* functions will fail when we are at a competition.
|
||
|
*
|
||
|
* This function checks if the --offline was specified before attempting to
|
||
|
* establish a connection.
|
||
|
*/
|
||
|
def isOnline = {
|
||
|
/* If we know we're in offline mode, we already know the answer. */
|
||
|
if (project.getGradle().startParameter.isOffline()) {
|
||
|
return false
|
||
|
} else {
|
||
|
/* There may or may not be an available internet connection. */
|
||
|
try {
|
||
|
final URL url = new URL("http://wpilib.org")
|
||
|
final URLConnection conn = url.openConnection()
|
||
|
conn.connect()
|
||
|
conn.getInputStream().close()
|
||
|
return true
|
||
|
} catch (MalformedURLException e) {
|
||
|
throw new RuntimeException(e)
|
||
|
} catch (IOException e) {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Add external javadoc links if an internet connection is available. */
|
||
|
def javadocAddLinks = { Project proj, String... urls ->
|
||
|
if (isOnline()) {
|
||
|
configure (proj) {
|
||
|
javadoc {
|
||
|
for (String url : urls) {
|
||
|
options.getLinks().add(url)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Execute a command on the operating system. */
|
||
|
def osExec = { String command, List arguments ->
|
||
|
new ByteArrayOutputStream().withStream { OutputStream os ->
|
||
|
exec {
|
||
|
executable = command
|
||
|
args = arguments
|
||
|
standardOutput = os
|
||
|
}
|
||
|
return os.toString()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
def lsRecursive
|
||
|
lsRecursive = {File dir, String matches ->
|
||
|
def list = []
|
||
|
dir.listFiles().sort().each { File file ->
|
||
|
if (file.isFile()) {
|
||
|
if (file.getName().matches(matches)) {
|
||
|
list += file
|
||
|
}
|
||
|
} else {
|
||
|
list += lsRecursive(file, matches)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return list
|
||
|
}
|
||
|
|
||
|
/* Export methods and variables to subprojects. */
|
||
|
rootProject.ext.versions = versions
|
||
|
|
||
|
rootProject.ext.isOnline = isOnline
|
||
|
rootProject.ext.javadocAddLinks = javadocAddLinks
|
||
|
|
||
|
/* Root project tasks */
|
||
|
task updateHeaders() {
|
||
|
doLast {
|
||
|
def header = file("${projectDir}/header.txt")
|
||
|
def patch = file("${projectDir}/header.patch")
|
||
|
|
||
|
patch.text = osExec('git', ['diff', "$header"])
|
||
|
|
||
|
if (!patch.text.isEmpty()) {
|
||
|
def patchFiles = lsRecursive(file("${projectDir}"), '^.*\\.(gradle|java)$')
|
||
|
for (File file : patchFiles) {
|
||
|
println "Patching '$file'..."
|
||
|
osExec('patch', ["$file", "$patch"])
|
||
|
}
|
||
|
def deleteFiles = lsRecursive(file("${projectDir}"), '^.*\\.orig$')
|
||
|
for (File file : deleteFiles) {
|
||
|
file.delete()
|
||
|
}
|
||
|
osExec('git', ['commit', "$header", '-m', 'Update header.'])
|
||
|
} else {
|
||
|
println "Headers up to date."
|
||
|
}
|
||
|
patch.delete()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Common configuration for all projects. */
|
||
|
configure(allprojects.findAll { matchProject(it) }) {
|
||
|
/* Java plugins */
|
||
|
apply plugin: 'java-library'
|
||
|
apply plugin: 'maven-publish'
|
||
|
|
||
|
/* Maven metadata */
|
||
|
group = 'net.bancino.robotics'
|
||
|
version = versions.SwerveIO
|
||
|
|
||
|
/* Java 11 */
|
||
|
sourceCompatibility = 11
|
||
|
targetCompatibility = 11
|
||
|
|
||
|
/*
|
||
|
* SwerveIO doesn't need any of this stuff without internet. This
|
||
|
* will dramatically speed up the time it takes to build SwerveIO,
|
||
|
* which can be helpful at competitions when things need to happen
|
||
|
* quickly.
|
||
|
*/
|
||
|
if (isOnline()) {
|
||
|
/* Maven jars - for documentation and IDE support. */
|
||
|
java {
|
||
|
withJavadocJar()
|
||
|
withSourcesJar()
|
||
|
}
|
||
|
|
||
|
/* All Javadocs should link to the standard Javadoc, and the WPILib Javadoc */
|
||
|
javadocAddLinks(project,
|
||
|
'https://docs.oracle.com/en/java/javase/11/docs/api/',
|
||
|
'https://first.wpi.edu/wpilib/allwpilib/docs/release/java/'
|
||
|
)
|
||
|
}
|
||
|
|
||
|
/* All artifacts go to the root repo. */
|
||
|
def repoUrl = "${rootProject.buildDir}/repo"
|
||
|
|
||
|
/* Publish to a local repo that can be published separately. */
|
||
|
publishing {
|
||
|
publications {
|
||
|
/* Artifact is derived from the project name. */
|
||
|
mavenJava(MavenPublication) {
|
||
|
artifactId = project.getName()
|
||
|
from project.components.java
|
||
|
}
|
||
|
}
|
||
|
|
||
|
repositories {
|
||
|
maven {
|
||
|
url = repoUrl
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Common Javadoc configuration. */
|
||
|
javadoc {
|
||
|
options.overview = "${projectDir}/src/javadoc/overview.html"
|
||
|
options.setWindowTitle("${project.getName()} ${project.version} User Documentation")
|
||
|
/* All javadocs go to the root directory. */
|
||
|
options.destinationDirectory(file("${rootProject.docsDir}/${project.getName()}"))
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Dependency repositories. All repositories must be shared across all projects so that they can include
|
||
|
* each other without duplicating the repository requirements.
|
||
|
*/
|
||
|
repositories {
|
||
|
/* Jackson XML & Vendor: KauaiLabs */
|
||
|
mavenCentral()
|
||
|
|
||
|
/* WPILib */
|
||
|
maven {
|
||
|
url 'https://frcmaven.wpi.edu/artifactory/release'
|
||
|
}
|
||
|
|
||
|
/* Vendor: CTRE */
|
||
|
maven {
|
||
|
url 'https://maven.ctr-electronics.com/release'
|
||
|
}
|
||
|
|
||
|
/* Vendor: RevRobotics */
|
||
|
maven {
|
||
|
url 'https://maven.revrobotics.com/'
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Generate GradleRIO vendor Json files that can be dropped into vendordeps/ */
|
||
|
task generateVendorJson() {
|
||
|
def jsonFile = "${project.getName()}.json"
|
||
|
def repoList = {
|
||
|
def str = ""
|
||
|
repositories.each {
|
||
|
str += "\"${it.url}\", "
|
||
|
}
|
||
|
return str.substring(0, str.length() - 2)
|
||
|
}
|
||
|
def outputDir = file(repoUrl)
|
||
|
doLast {
|
||
|
outputDir.mkdirs()
|
||
|
file("${outputDir}/${jsonFile}").text =
|
||
|
"""{
|
||
|
"cppDependencies": [],
|
||
|
"fileName": "${jsonFile}",
|
||
|
"javaDependencies": [
|
||
|
{
|
||
|
"artifactId": "${project.getName()}",
|
||
|
"groupId": "${project.group}",
|
||
|
"version": "${version}"
|
||
|
}
|
||
|
],
|
||
|
"jniDependencies": [],
|
||
|
"jsonUrl": "",
|
||
|
"mavenUrls": [
|
||
|
${repoList()}
|
||
|
],
|
||
|
"name": "${project.getName()}",
|
||
|
"uuid": "${project.group}:${project.getName()}",
|
||
|
"version": "${version}"
|
||
|
}
|
||
|
"""
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* When publishing Maven artifacts, also generate vendor JSON. */
|
||
|
publish.dependsOn generateVendorJson
|
||
|
|
||
|
/* All common dependencies go here. */
|
||
|
dependencies {
|
||
|
/* WPILib */
|
||
|
api "edu.wpi.first.wpilibj:wpilibj-java:${versions.WPILib}"
|
||
|
api "edu.wpi.first.wpilibNewCommands:wpilibNewCommands-java:${versions.WPILib}"
|
||
|
api "edu.wpi.first.wpimath:wpimath-java:${versions.WPILib}"
|
||
|
|
||
|
/*
|
||
|
* The SwerveIO core itself doesn't use these artifacts, but the vendor dependencies,
|
||
|
* included in the subprojects may, so we include them here to ensure that they are the
|
||
|
* same version across the board. I noticed, for example, that the NavX library would
|
||
|
* pull older versions of these artifacts than what SwerveIO was using, so we do this to
|
||
|
* make everything line up.
|
||
|
*/
|
||
|
|
||
|
api "edu.wpi.first.cscore:cscore-java:${versions.WPILib}"
|
||
|
api "edu.wpi.first.cameraserver:cameraserver-java:${versions.WPILib}"
|
||
|
api "edu.wpi.first.ntcore:ntcore-java:${versions.WPILib}"
|
||
|
api "edu.wpi.first.wpiutil:wpiutil-java:${versions.WPILib}"
|
||
|
api "edu.wpi.first.hal:hal-java:${versions.WPILib}"
|
||
|
|
||
|
/* Required by WPILib - Make sure this lines up with the version specified by WPILib */
|
||
|
api "edu.wpi.first.thirdparty.frc2022.opencv:opencv-java:${versions.OpenCV}"
|
||
|
|
||
|
/* Required by WPILib - Gradle emits warnings if this isn't included. */
|
||
|
implementation "com.fasterxml.jackson.core:jackson-annotations:${versions.Jackson}"
|
||
|
|
||
|
/* Unit testing */
|
||
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:+'
|
||
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:+'
|
||
|
|
||
|
/* Convert OS into WPILib platform */
|
||
|
def platform
|
||
|
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||
|
platform = 'windowsx86-64'
|
||
|
} else if (Os.isFamily(Os.FAMILY_MAC)) {
|
||
|
platform = 'osxx86-64'
|
||
|
} else if (Os.isFamily(Os.FAMILY_UNIX)) {
|
||
|
platform = 'linuxx86-64'
|
||
|
} else {
|
||
|
throw new GradleException("Unrecognized operating system.")
|
||
|
}
|
||
|
|
||
|
/* JNI stuff so WPILib can run on the desktop. */
|
||
|
testImplementation "edu.wpi.first.thirdparty.frc2022.opencv:opencv-jni:${versions.OpenCV}:${platform}@jar"
|
||
|
testImplementation "edu.wpi.first.hal:hal-jni:${versions.WPILib}:${platform}@jar"
|
||
|
testImplementation "edu.wpi.first.wpiutil:wpiutil-jni:${versions.WPILib}:${platform}@jar"
|
||
|
testImplementation "edu.wpi.first.ntcore:ntcore-jni:${versions.WPILib}:${platform}@jar"
|
||
|
testImplementation "edu.wpi.first.cscore:cscore-jni:${versions.WPILib}:${platform}@jar"
|
||
|
}
|
||
|
|
||
|
test {
|
||
|
useJUnitPlatform()
|
||
|
testLogging {
|
||
|
showStandardStreams = true
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Common configuration for subprojects only. */
|
||
|
configure(subprojects.findAll { matchProject(it) }) {
|
||
|
/* All subprojects depend on the core SwerveIO project */
|
||
|
dependencies {
|
||
|
api rootProject
|
||
|
}
|
||
|
}
|