Files
FTC-Project-Gen/linux/lib.sh
2026-01-24 12:39:32 -06:00

290 lines
8.6 KiB
Bash
Executable File

#!/bin/bash
# FTC Project Generator - Shared Library Functions
# Copyright (c) 2026 Nexus Workshops LLC
# Licensed under MIT License
# Get the directory where this script lives
get_script_dir() {
echo "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
}
# Get generator version
get_generator_version() {
local script_dir="$(get_script_dir)"
local version_file="$script_dir/../VERSION"
if [ -f "$version_file" ]; then
cat "$version_file" | tr -d '\n\r'
else
echo "unknown"
fi
}
# Process template file, replacing placeholders
process_template() {
local input="$1"
local output="$2"
sed -e "s|{{PROJECT_NAME}}|${PROJECT_NAME}|g" \
-e "s|{{SDK_DIR}}|${FTC_SDK_DIR}|g" \
-e "s|{{FTC_VERSION}}|${FTC_VERSION}|g" \
-e "s|{{GENERATOR_VERSION}}|${GENERATOR_VERSION}|g" \
"$input" > "$output"
}
# Copy template file
copy_template() {
local src="$1"
local dest="$2"
cp "$src" "$dest"
}
# Create project structure
create_project_structure() {
local project_dir="$1"
mkdir -p "$project_dir"
cd "$project_dir"
mkdir -p src/main/java/robot/subsystems
mkdir -p src/main/java/robot/hardware
mkdir -p src/main/java/robot/opmodes
mkdir -p src/test/java/robot/subsystems
mkdir -p src/test/java/robot/hardware
mkdir -p gradle/wrapper
}
# Install all project templates
install_templates() {
local project_dir="$1"
local template_dir="$2"
cd "$project_dir"
copy_template "$template_dir/Pose2d.java" "src/main/java/robot/Pose2d.java"
copy_template "$template_dir/Drive.java" "src/main/java/robot/subsystems/Drive.java"
copy_template "$template_dir/MecanumDrive.java" "src/main/java/robot/hardware/MecanumDrive.java"
copy_template "$template_dir/TeleOp.java" "src/main/java/robot/opmodes/TeleOp.java"
copy_template "$template_dir/DriveTest.java" "src/test/java/robot/subsystems/DriveTest.java"
copy_template "$template_dir/build.gradle.kts" "build.gradle.kts"
process_template "$template_dir/settings.gradle.kts.template" "settings.gradle.kts"
process_template "$template_dir/gitignore.template" ".gitignore"
process_template "$template_dir/README.md.template" "README.md"
copy_template "$template_dir/build.sh" "build.sh"
chmod +x "build.sh"
create_deploy_script "$project_dir"
echo "${GENERATOR_VERSION}" > ".ftc-generator-version"
}
# Create deploy script
create_deploy_script() {
local project_dir="$1"
cat > "$project_dir/deploy-to-robot.sh" <<'ENDSCRIPT'
#!/bin/bash
set -e
CONTROL_HUB_IP="${CONTROL_HUB_IP:-192.168.43.1}"
CONTROL_HUB_PORT="5555"
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help) echo "Deploy to Control Hub"; echo "Usage: $0 [--usb|--wifi] [-i IP]"; exit 0 ;;
-i|--ip) CONTROL_HUB_IP="$2"; shift 2 ;;
*) shift ;;
esac
done
echo "Deploying to SDK..."
./gradlew deployToSDK || exit 1
echo "Building APK..."
cd "${HOME}/ftc-sdk" && ./gradlew build || exit 1
APK_PATH="${HOME}/ftc-sdk/FtcRobotController/build/outputs/apk/debug/FtcRobotController-debug.apk"
[ -f "$APK_PATH" ] || { echo "APK not found"; exit 1; }
echo "Installing..."
if adb devices | grep -q device; then
adb install -r "$APK_PATH" && echo "✓ Deployed!" || exit 1
else
adb connect "$CONTROL_HUB_IP:$CONTROL_HUB_PORT" && sleep 2
adb install -r "$APK_PATH" && echo "✓ Deployed!" || exit 1
fi
ENDSCRIPT
chmod +x "$project_dir/deploy-to-robot.sh"
}
# Setup Gradle wrapper
setup_gradle_wrapper() {
local project_dir="$1"
cd "$project_dir"
# Create gradle wrapper properties
mkdir -p gradle/wrapper
cat > gradle/wrapper/gradle-wrapper.properties <<EOF
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
EOF
# Check if gradle is available
if ! command -v gradle &> /dev/null; then
echo "Error: gradle command not found"
echo "Gradle must be installed to generate wrapper scripts"
echo ""
echo "Install:"
echo " Ubuntu/Debian: sudo apt install gradle"
echo " macOS: brew install gradle"
return 1
fi
echo "Generating Gradle wrapper..."
# Try with system gradle first
if gradle wrapper --gradle-version 8.9 --no-daemon 2>/dev/null; then
echo "✓ Gradle wrapper created"
else
echo ""
echo "System Gradle failed. Using fallback method..."
# Download wrapper jar directly
local wrapper_jar_url="https://raw.githubusercontent.com/gradle/gradle/v8.9.0/gradle/wrapper/gradle-wrapper.jar"
if command -v curl &> /dev/null; then
curl -sL "$wrapper_jar_url" -o gradle/wrapper/gradle-wrapper.jar 2>/dev/null
elif command -v wget &> /dev/null; then
wget -q "$wrapper_jar_url" -O gradle/wrapper/gradle-wrapper.jar 2>/dev/null
else
echo "Error: Need curl or wget to download wrapper jar"
return 1
fi
if [ ! -f "gradle/wrapper/gradle-wrapper.jar" ]; then
echo "Error: Failed to download gradle-wrapper.jar"
return 1
fi
# Create proper gradlew script
cat > gradlew <<'GRADLEW_END'
#!/bin/sh
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_BASE_NAME=${0##*/}
# Determine the Java command
if [ -n "$JAVA_HOME" ] ; then
JAVACMD=$JAVA_HOME/bin/java
else
JAVACMD=java
fi
# Check if Java is available
if ! "$JAVACMD" -version > /dev/null 2>&1; then
echo "ERROR: JAVA_HOME is not set and no 'java' command could be found"
exit 1
fi
# Execute Gradle
exec "$JAVACMD" -Xmx64m -Xms64m -Dorg.gradle.appname="$APP_BASE_NAME" -classpath "$(dirname "$0")/gradle/wrapper/gradle-wrapper.jar" org.gradle.wrapper.GradleWrapperMain "$@"
GRADLEW_END
chmod +x gradlew
# Create Windows batch file
cat > gradlew.bat <<'GRADLEWBAT_END'
@if "%DEBUG%" == "" @echo off
setlocal enabledelayedexpansion
set DIRNAME=%~dp0
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
set CLASSPATH=%APP_HOME%gradle\wrapper\gradle-wrapper.jar
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
goto execute
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%\bin\java.exe
:execute
"%JAVA_EXE%" -Xmx64m -Xms64m -Dorg.gradle.appname="%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
GRADLEWBAT_END
echo "✓ Gradle wrapper created (via fallback)"
fi
# Verify wrapper was created
if [ ! -f "gradlew" ]; then
echo "Error: gradlew script not created"
return 1
fi
}
# Check if project is a generator project
is_generator_project() {
local project_dir="$1"
[ -f "$project_dir/.ftc-generator-version" ]
}
# Get project generator version
get_project_generator_version() {
local project_dir="$1"
if [ -f "$project_dir/.ftc-generator-version" ]; then
cat "$project_dir/.ftc-generator-version" | tr -d '\n\r'
else
echo "unknown"
fi
}
# Upgrade project
upgrade_project() {
local project_dir="$1"
local template_dir="$2"
local old_version=$(get_project_generator_version "$project_dir")
echo "Upgrading project from $old_version to ${GENERATOR_VERSION}..."
cd "$project_dir"
copy_template "$template_dir/build.gradle.kts" "build.gradle.kts"
process_template "$template_dir/settings.gradle.kts.template" "settings.gradle.kts"
process_template "$template_dir/gitignore.template" ".gitignore"
copy_template "$template_dir/build.sh" "build.sh"
chmod +x "build.sh"
create_deploy_script "$project_dir"
echo "${GENERATOR_VERSION}" > ".ftc-generator-version"
echo "✓ Upgrade complete"
}
# Initialize git repo
init_git_repo() {
local project_dir="$1"
cd "$project_dir"
if [ ! -d ".git" ]; then
git init > /dev/null 2>&1
git add . > /dev/null 2>&1
git commit -m "Initial commit from FTC Project Generator v${GENERATOR_VERSION}" > /dev/null 2>&1
echo "✓ Git repository initialized"
fi
}
# Check prerequisites
check_prerequisites() {
local missing=()
command -v git &> /dev/null || missing+=("git")
command -v java &> /dev/null || missing+=("java")
command -v gradle &> /dev/null || missing+=("gradle")
if [ "${#missing[@]}" -gt 0 ]; then
echo "Error: Missing tools: ${missing[*]}"
echo "Install: sudo apt install ${missing[*]}"
return 1
fi
echo "✓ All prerequisites satisfied"
return 0
}