plugins { id 'java' id 'application' id 'com.github.johnrengelman.shadow' version '5.2.0' id "com.diffplug.gradle.spotless" version "3.28.0" id 'org.hidetake.ssh' version '2.10.1' id "jacoco" } apply from: 'versioningHelper.gradle' mainClassName = 'org.photonvision.Main' group 'org.photonvision' version versionString sourceCompatibility = 11 repositories { jcenter() mavenCentral() maven { url = "https://maven.photonvision.org/repository/internal/" } maven { url = 'https://frcmaven.wpi.edu:443/artifactory/development' } } ext { wpilibVersion = '2020.3.2-99-g9f4de91' joglVersion = '2.4.0-rc-20200307' openCVVersion = '3.4.7-2' } dependencies { implementation "io.javalin:javalin:3.7.0" implementation "com.fasterxml.jackson.core:jackson-annotations:2.10.0" implementation "com.fasterxml.jackson.core:jackson-core:2.10.0" implementation "com.fasterxml.jackson.core:jackson-databind:2.10.0" implementation "org.msgpack:msgpack-core:0.8.20" implementation "org.msgpack:jackson-dataformat-msgpack:0.8.20" implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.9' implementation "org.apache.commons:commons-math3:3.6.1" implementation group: 'commons-io', name: 'commons-io', version: '2.6' implementation group: 'commons-cli', name: 'commons-cli', version: '1.4' implementation "org.apache.commons:commons-collections4:4.4" implementation "org.apache.commons:commons-exec:1.3" // JOGL stuff (currently we only distribute for aarch64, which is Pi 4) implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion" implementation "org.jogamp.jogl:jogl-all:$joglVersion" // implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion:natives-linux-amd64" // implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion:natives-linux-armv6hf" implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion:natives-linux-aarch64" // implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion:natives-macosx-universal" // implementation "org.jogamp.gluegen:gluegen-rt:$joglVersion:natives-windows-amd64" // implementation "org.jogamp.jogl:jogl-all:$joglVersion:natives-linux-amd64" // implementation "org.jogamp.jogl:jogl-all:$joglVersion:natives-linux-armv6hf" implementation "org.jogamp.jogl:jogl-all:$joglVersion:natives-linux-aarch64" // implementation "org.jogamp.jogl:jogl-all:$joglVersion:natives-macosx-universal" // implementation "org.jogamp.jogl:jogl-all:$joglVersion:natives-windows-amd64" // WPILib stuff implementation "edu.wpi.first.wpiutil:wpiutil-java:$wpilibVersion" implementation "edu.wpi.first.cameraserver:cameraserver-java:$wpilibVersion" implementation "edu.wpi.first.cscore:cscore-java:$wpilibVersion" compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:linuxaarch64bionic" compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:linuxraspbian" compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:linuxx86-64" compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:osxx86-64" compile "edu.wpi.first.cscore:cscore-jni:$wpilibVersion:windowsx86-64" implementation "edu.wpi.first.ntcore:ntcore-java:$wpilibVersion" compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:linuxaarch64bionic" compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:linuxraspbian" compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:linuxx86-64" compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:osxx86-64" compile "edu.wpi.first.ntcore:ntcore-jni:$wpilibVersion:windowsx86-64" implementation "edu.wpi.first.thirdparty.frc2020.opencv:opencv-java:$openCVVersion" compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:linuxaarch64bionic" compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:linuxraspbian" compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:linuxx86-64" compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:osxx86-64" compile "edu.wpi.first.thirdparty.frc2020.opencv:opencv-jni:$openCVVersion:windowsx86-64" compile "org.slf4j:slf4j-simple:1.8.0-beta4" // Zip compile "org.zeroturnaround:zt-zip:1.14" // test stuff testImplementation('org.junit.jupiter:junit-jupiter:5.6.0') } shadowJar { configurations = [project.configurations.runtimeClasspath] archiveFileName.set("photonvision-${project.version}.jar") } test { useJUnitPlatform() testLogging { events "passed", "skipped", "failed", "standardOut", "standardError" } } task testHeadless(type: Test) { group = 'verification' systemProperty("java.awt.headless", "true") useJUnitPlatform() } task runNpmOnClient(type: Exec) { workingDir "${projectDir}/../photon-client" if (System.getProperty('os.name').toLowerCase(Locale.ROOT).contains('windows')) { commandLine 'cmd', '/c', 'npm run build' } else { commandLine 'npm', 'run', 'build' } } task copyClientUIToResources(type: Copy) { from "${projectDir}/../photon-client/dist/" into "${projectDir}/src/main/resources/web/" } task buildAndCopyUI {} buildAndCopyUI.dependsOn copyClientUIToResources copyClientUIToResources.dependsOn runNpmOnClient copyClientUIToResources.shouldRunAfter runNpmOnClient task generateJavaDocs(type: Javadoc) { source = sourceSets.main.allJava classpath = sourceSets.main.compileClasspath destinationDir = file("${projectDir}/build/docs") } spotless { java { googleJavaFormat() paddedCell() indentWithTabs(2) indentWithSpaces(4) removeUnusedImports() } java { target "src/*/java/org/**/*.java" licenseHeaderFile "$rootDir/LicenseHeader.txt" targetExclude("src/main/java/org/photonvision/PhotonVersion.java") } } run { if (project.hasProperty("profile")) { jvmArgs=[ "-Dcom.sun.management.jmxremote=true", "-Dcom.sun.management.jmxremote.ssl=false", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.port=5000", "-Djava.rmi.server.hostname=0.0.0.0", ] } } jacocoTestReport { dependsOn test // Tests are required to run before generating the report reports { xml.enabled true } afterEvaluate { classDirectories.setFrom(files(classDirectories.files.collect { fileTree(dir: it, exclude: 'edu/wpi/**' ) })) } } remotes { pi { host = 'photonvision.local' user = 'pi' password = 'raspberry' knownHosts = allowAnyHosts } gloworm { host = 'gloworm.local' user = 'pi' password = 'raspberry' knownHosts = allowAnyHosts } } import java.io.*; import java.net.*; task findDeployTarget { doLast { if(project.hasProperty('tgtIP')){ //If user specificed IP, default to using the PI profile // but adjust hostname to match the provided IP address findDeployTarget.ext.rmt = remotes.pi findDeployTarget.ext.rmt.host=tgtIP } else { findDeployTarget.ext.rmt = null for(testRmt in remotes){ println "Checking for " + testRmt.host boolean canContact = false; try { InetAddress testAddr = InetAddress.getByName(testRmt.host) canContact = testAddr.isReachable(5000) } catch(UnknownHostException e) { canContact = false; } if(canContact){ println "Found!" findDeployTarget.ext.rmt = testRmt break } else { println "Not Found." } } if(findDeployTarget.ext.rmt == null ){ throw new GradleException("Could not find a supported target for deployment!") } } } } task deploy { dependsOn assemble dependsOn findDeployTarget doLast { println 'Starting deployment to ' + findDeployTarget.rmt.host ssh.run{ session(findDeployTarget.rmt) { //Stop photonvision before manipulating its files execute 'sudo systemctl stop photonvision.service' // gerth2 - I was having issues with the .jar being in use still - waiting a tiny bit here seems to get rid of it on a pi4 execute 'sleep 3' // Copy into a folder owned by PI. Mostly because, as far as I can tell, the put command doesn't support sudo. put from: "${projectDir}/build/libs/photonvision-${project.version}.jar", into: "/tmp/photonvision.jar" //belt-and-suspenders. Make sure the old jar is gone first. execute 'sudo rm -f /opt/photonvision/photonvision.jar' //Copy in the new .jar and make sure it's executable execute 'sudo mv /tmp/photonvision.jar /opt/photonvision/photonvision.jar' execute 'sudo chmod +x /opt/photonvision/photonvision.jar' //Fire up photonvision again execute 'sudo systemctl start photonvision.service' //Cleanup execute 'sudo rm -f /tmp/photonvision.jar' } } } }