SwerveIO/build.gradle

336 lines
11 KiB
Groovy
Executable file

/*
* SwerveIO - A versatile open-source FRC swerve drive library.
*
* Copyright (C) 2019-2024 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.3',
'WPILib': '2023.4.3',
'OpenCV': '4.6.0-4',
'Jackson': '2.12.4'
]
/* 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 {
/* 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://github.wpilib.org/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 */
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/'
}
/* Vendor: KauaiLabs */
maven {
url 'https://dev.studica.com/maven/release/2023/'
}
}
/* 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.frc2023.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.frc2023.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
}
}