diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 81478ad..55e5318 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: Build Robot Code +name: Build on: push: diff --git a/.github/workflows/spotless.yml b/.github/workflows/spotless.yml new file mode 100644 index 0000000..b39e67d --- /dev/null +++ b/.github/workflows/spotless.yml @@ -0,0 +1,18 @@ +name: Spotless + +on: [push] + +jobs: + spotless: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: actions/setup-java@v4 + with: + distribution: 'zulu' + java-version: 17 + - name: Make gradlew executable + run: chmod +x gradlew + - run: ./gradlew spotlessCheck diff --git a/build.gradle b/build.gradle index 0e20304..1919287 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ plugins { id "java" id "edu.wpi.first.GradleRIO" version "2025.3.2" + id "com.diffplug.spotless" version "8.1.0" } java { @@ -37,7 +38,7 @@ deploy { final MAX_JAVA_HEAP_SIZE_MB = 100; jvmArgs.add("-Xmx" + MAX_JAVA_HEAP_SIZE_MB + "M") jvmArgs.add("-Xms" + MAX_JAVA_HEAP_SIZE_MB + "M") - jvmArgs.add("-XX:+AlwaysPreTouch") + jvmArgs.add("-XX:+AlwaysPreTouch") } // Static files artifact @@ -45,7 +46,7 @@ deploy { files = project.fileTree('src/main/deploy') directory = '/home/lvuser/deploy' deleteOldFiles = false // Change to true to delete files on roboRIO that no - // longer exist in deploy directory of this project + // longer exist in deploy directory of this project } } } @@ -98,7 +99,11 @@ wpi.sim.addDriverstation() // in order to make them all available at runtime. Also adding the manifest so WPILib // knows where to look for our Robot Class. jar { - from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } + from { + configurations.runtimeClasspath.collect { + it.isDirectory() ? it : zipTree(it) + } + } from sourceSets.main.allSource manifest edu.wpi.first.gradlerio.GradleRIOPlugin.javaManifest(ROBOT_MAIN_CLASS) duplicatesStrategy = DuplicatesStrategy.INCLUDE @@ -109,7 +114,95 @@ deployArtifact.jarTask = jar wpi.java.configureExecutableTasks(jar) wpi.java.configureTestTasks(test) +tasks.named('compileJava').configure { + finalizedBy tasks.named('spotlessCheck') +} + // Configure string concat to always inline compile tasks.withType(JavaCompile) { options.compilerArgs.add '-XDstringConcat=inline' } + +// Configure Spotless code formatter +spotless { + // Violations are found but build does not fail + enforceCheck = false + + java { + target fileTree('.') { + include '**/*.java' + exclude '**/build/**', '**/build-*/**', '**/bin/**' + } + toggleOffOn() + googleJavaFormat('1.28.0') + removeUnusedImports() + leadingTabsToSpaces(2) + trimTrailingWhitespace() + endWithNewline() + } + groovyGradle { + target fileTree('.') { + include '**/*.gradle' + exclude '**/build/**', '**/build-*/**' + } + greclipse() + leadingTabsToSpaces(4) + trimTrailingWhitespace() + endWithNewline() + } + format 'xml', { + target fileTree('.') { + include '**/*.xml' + exclude '**/build/**', '**/build-*/**' + } + eclipseWtp('xml') + leadingTabsToSpaces(2) + trimTrailingWhitespace() + endWithNewline() + } + format 'misc', { + target fileTree('.') { + include '**/*.md', '**/.gitignore' + exclude '**/build/**', '**/build-*/**' + } + leadingTabsToSpaces(2) + trimTrailingWhitespace() + endWithNewline() + } +} + +// Configure all Spotless check tasks to show warnings but not fail the build +gradle.taskGraph.whenReady { graph -> + graph.allTasks.each { task -> + if (task.name.startsWith('spotless') && task.name.endsWith('Check')) { + def originalActions = new ArrayList(task.actions) + task.actions.clear() + task.ext.spotlessViolationsFound = false + + originalActions.each { originalAction -> + task.doLast { + try { + originalAction.execute(task) + } catch (Exception e) { + task.ext.spotlessViolationsFound = true + def formatName = task.name.replace('spotless', '').replace('Check', '') + if (formatName.isEmpty()) { + formatName = "code" + } + logger.warn("") + logger.warn("═══════════════════════════════════════════════════════════") + logger.warn("\u001B[1;31mSpotless found formatting violations in ${formatName}!\u001B[0m") + logger.warn("") + logger.warn("1. Open the \u001B[36mWPILib Command Palette\u001B[0m") + logger.warn("2. Select \u001B[36mWPILib: Run a command with Gradle\u001B[0m") + logger.warn("") + logger.warn("Run \u001B[36mspotlessCheck\u001B[0m to see the violations") + logger.warn("Run \u001B[36mspotlessApply\u001B[0m to automatically fix violations") + logger.warn("═══════════════════════════════════════════════════════════") + logger.warn("") + } + } + } + } + } +} diff --git a/src/main/java/frc/robot/subsystems/DriveTrain.java b/src/main/java/frc/robot/subsystems/DriveTrain.java index e51da1a..2275156 100644 --- a/src/main/java/frc/robot/subsystems/DriveTrain.java +++ b/src/main/java/frc/robot/subsystems/DriveTrain.java @@ -5,8 +5,6 @@ package frc.robot.subsystems; import com.ctre.phoenix6.StatusSignal; -// import com.ctre.phoenix6.configs.Pigeon2Configuration; -// import com.ctre.phoenix6.configs.Pigeon2Configurator; import com.ctre.phoenix6.hardware.Pigeon2; import edu.wpi.first.math.Matrix; @@ -51,12 +49,6 @@ import java.util.ArrayList; import java.util.List; - -// Vision imports -// import org.photonvision.EstimatedRobotPose; -// import org.photonvision.targeting.PhotonPipelineResult; -// import org.photonvision.targeting.PhotonTrackedTarget; - import java.util.Optional; import org.photonvision.EstimatedRobotPose;