Skip to content

Commit

Permalink
Add scripts for magic number detection and CI workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
GreenTomato5 committed Dec 21, 2024
1 parent 3f9d22b commit 7122318
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 3 deletions.
105 changes: 105 additions & 0 deletions .github/scripts/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import re
import os
import sys

# List of files to excuse (constants and things we didnt make and stuff we wont use)
excused_files = ["Constants.java", "BuildConstants.java", "LocalADStarAK.java", "VisionUtil.java", "SwerveModule.java", "VisionIOSim.java"]

# Not really dirs becasue the full ones didnt work
excused_dirs = [
"bin",
"build",
"src/main/java/frc/robot/pioneersLib"
]

# Weird stuff that shouldn't go in constants, dont put function/var names in here theyre already checked
excused_cases = ["ModuleIOSparkMax", "case", "new Module(", "new BaseStatusSignal[", "BaseStatusSignal.waitForAll(", "new ModuleIOHybrid(", "Math.pow(", "+=", "drive.getRotation()", "autoChooser.addOption(", "static final", "getRealTimestamp", "antiJitterThreshold", "trackWidth", "i < 4", "SwerveModuleState[4]", "gearRatio", "Math.PI", "private final", "/ 360", "/360", "* 360", "*360", "DCMotor.get", "/60", "/ 60"]

def check_for_magic_numbers(file_path):
magic_numbers = []

# Number pattern makes sure number isnt in a var and detects all numbers that arent in a function/var
number_pattern = r'(?<!\w)-?(?:\d*\.\d+|\d+\.?)\b(?!\w)'
zero_pattern = r'^0*\.?0+$'

with open(file_path, 'r') as file:
lines = file.readlines()
in_comment_block = False

for line_number, line in enumerate(lines, 1):
line = line.strip()

# Skip empty lines
if not line:
continue

# Skip big comments
if '/*' in line:
in_comment_block = True
# If someone like put a thing after a multi-line comment end this wouldnt work but idk if you can even do that
if '*/' in line:
in_comment_block = False
continue
if in_comment_block:
continue

# Skip regular comments and imports
if line.startswith('//') or line.startswith('import'):
continue

# Skips excused cases
if any(case in line for case in excused_cases):
continue

numbers = re.findall(number_pattern, line)
for number in numbers:
# Skip for zeroes, they're fine as is
if re.match(zero_pattern, number):
continue
magic_numbers.append((number, line_number))
return magic_numbers

def is_file_excused(file_path, project_root):
filename = os.path.basename(file_path)
if filename in excused_files:
return True

relative_path = os.path.relpath(file_path, project_root)
for excluded_dir in excused_dirs:
if relative_path.startswith(excluded_dir) or excluded_dir in relative_path:
return True

return False

def scan_directory(directory):
magic_number_count = 0
for root, _, files in os.walk(directory):
for file in files:
if file.endswith('.java'):
file_path = os.path.join(root, file)
if not is_file_excused(file_path, directory):
magic_numbers = check_for_magic_numbers(file_path)
if magic_numbers:
print(f"In {file_path}:")
for number, line_number in magic_numbers:
print(f" Line {line_number}: Magic number {number}")
magic_number_count += 1
return magic_number_count

if __name__ == "__main__":
# Get scripts dir
script_dir = os.path.dirname(os.path.abspath(__file__))

# Move up 2 dirs to get the project root
project_root = os.path.dirname(os.path.dirname(script_dir))

print(f"Scanning directory: {project_root}")
total_magic_numbers = scan_directory(project_root)

# Fails if magic numbers are in any non excused locations
if total_magic_numbers > 0:
print(f"\nTotal magic numbers found: {total_magic_numbers}.\nPlease put these in Constanats.java!")
sys.exit(1)
else:
print("\nNo Magic Number Found")
sys.exit(0)
17 changes: 17 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
name: Build

on:
push:

jobs:
build:
name: Build
runs-on: ubuntu-latest
container: wpilib/roborio-cross-ubuntu:2024-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Grant execute permission
run: chmod +x gradlew
- name: Build robot code
run: ./gradlew build
20 changes: 20 additions & 0 deletions .github/workflows/constants.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Find Misplaced Constants

on:
pull_request:
push:
branches:
- main

jobs:
find-misplaced-constants:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v2
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.11'
- name: Run Python Script
run: python .github/scripts/constants.py
41 changes: 41 additions & 0 deletions .github/workflows/crash.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Crash

on:
push:

jobs:
Crash:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: '17'
- name: Grant execute permission
run: chmod +x gradlew
- name: Build robot code
run: ./gradlew build
- name: Run Simulation and Capture Logs
env:
CI_NAME: "Crash"
run: ./gradlew simulateJava | tee simulateJava.log

- name: Check for Errors in Logs
run: |
# Check for errors
if grep -qE "Exception|Error|NULL|NullPointerException" simulateJava.log; then
echo "Errors detected in simulation logs (See Crash for Details)."
exit 1
fi
# Check for modes
if grep -q "DISABLED" simulateJava.log && grep -q "TELEOP" simulateJava.log && grep -q "AUTONOMOUS" simulateJava.log && grep -q "TEST" simulateJava.log; then
echo "All modes found in simulation logs."
else
echo "One or more modes not found in simulation logs (See Crash for Details)."
exit 1
fi
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id "java"
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-2"
id "edu.wpi.first.GradleRIO" version "2025.1.1-beta-3"
}

java {
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public enum RobotMode {
TESTING,
SIM
}
public static final RobotMode ROBOT_MODE = RobotMode.SIM;
public static final RobotMode ROBOT_MODE = "Crash".equals(System.getenv("CI_NAME")) ? RobotMode.SIM : RobotMode.SIM;

public static class Controllers {
public static final XboxController DRIVER_CONTROLLER = new XboxController(0);
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/frc/robot/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
package frc.robot;

import edu.wpi.first.wpilibj.RobotBase;
import frc.robot.pioneersLib.CI.CrashCheck;

public final class Main {
private Main() {}

public static void main(String... args) {
RobotBase.startRobot(Robot::new);
RobotBase.startRobot("Crash".equals(System.getenv("CI_NAME")) ? CrashCheck::getInstance : Robot::new);
}
}

0 comments on commit 7122318

Please sign in to comment.