Compare commits
4 Commits
v1.0.0
...
7420f8bda4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7420f8bda4 | ||
|
|
eca488f703 | ||
|
|
bcdf62ffa9 | ||
|
|
2419334f72 |
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,17 +0,0 @@
|
|||||||
# Changelog
|
|
||||||
|
|
||||||
## [1.0.0] - 2026-01-27
|
|
||||||
|
|
||||||
First stable release! 🎉
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Complete Windows deployment support
|
|
||||||
- Android SDK path in project configuration
|
|
||||||
- Robust cross-platform build and deployment scripts
|
|
||||||
- Project upgrade command with config migration
|
|
||||||
- Comprehensive test suite
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Windows APK discovery and deployment
|
|
||||||
- Batch file path parsing (quote handling)
|
|
||||||
- ADB integration and error reporting
|
|
||||||
@@ -511,7 +511,7 @@ Built with frustration at unnecessarily complex robotics frameworks, and hope th
|
|||||||
|
|
||||||
## Project Status
|
## Project Status
|
||||||
|
|
||||||
**Current Version:** 1.0.0
|
**Current Version:** 1.0.0-rc1
|
||||||
|
|
||||||
**What Works:**
|
**What Works:**
|
||||||
- ✅ Project generation
|
- ✅ Project generation
|
||||||
@@ -532,7 +532,7 @@ Built with frustration at unnecessarily complex robotics frameworks, and hope th
|
|||||||
|
|
||||||
**Questions? Issues? Suggestions?**
|
**Questions? Issues? Suggestions?**
|
||||||
|
|
||||||
📧 Email: [eric@nxlearn.net](mailto:eric@nxlearn.net)
|
📧 Email: [eric@nxws.dev](mailto:eric@nxws.dev)
|
||||||
🐛 Issues: Open an issue on the repository
|
🐛 Issues: Open an issue on the repository
|
||||||
|
|
||||||
Building better tools so you can build better robots. 🤖
|
Building better tools so you can build better robots. 🤖
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
This document outlines the planned feature development for Weevil across multiple versions. Features are subject to change based on user feedback, technical constraints, and market needs.
|
This document outlines the planned feature development for Weevil across multiple versions. Features are subject to change based on user feedback, technical constraints, and market needs.
|
||||||
|
|
||||||
|
**Current Version:** 1.0.0-rc1
|
||||||
|
**Next Release:** 1.1.0 (Target: TBD)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Version 1.1.0 - Core Stability & Team Adoption
|
## Version 1.1.0 - Core Stability & Team Adoption
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ pub fn upgrade_project(path: &str) -> Result<()> {
|
|||||||
let project_name = project_path.file_name()
|
let project_name = project_path.file_name()
|
||||||
.and_then(|n| n.to_str())
|
.and_then(|n| n.to_str())
|
||||||
.unwrap_or("unknown");
|
.unwrap_or("unknown");
|
||||||
crate::project::ProjectConfig::new(project_name, sdk_config.ftc_sdk_path.clone(), sdk_config.android_sdk_path.clone())?
|
crate::project::ProjectConfig::new(project_name, sdk_config.ftc_sdk_path.clone())?
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("Current SDK: {}", project_config.ftc_sdk_path.display());
|
println!("Current SDK: {}", project_config.ftc_sdk_path.display());
|
||||||
|
|||||||
@@ -9,16 +9,10 @@ pub struct ProjectConfig {
|
|||||||
pub weevil_version: String,
|
pub weevil_version: String,
|
||||||
pub ftc_sdk_path: PathBuf,
|
pub ftc_sdk_path: PathBuf,
|
||||||
pub ftc_sdk_version: String,
|
pub ftc_sdk_version: String,
|
||||||
#[serde(default = "default_android_sdk_path")]
|
|
||||||
pub android_sdk_path: PathBuf,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn default_android_sdk_path() -> PathBuf {
|
|
||||||
PathBuf::new()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectConfig {
|
impl ProjectConfig {
|
||||||
pub fn new(project_name: &str, ftc_sdk_path: PathBuf, android_sdk_path: PathBuf) -> Result<Self> {
|
pub fn new(project_name: &str, ftc_sdk_path: PathBuf) -> Result<Self> {
|
||||||
let ftc_sdk_version = crate::sdk::ftc::get_version(&ftc_sdk_path)
|
let ftc_sdk_version = crate::sdk::ftc::get_version(&ftc_sdk_path)
|
||||||
.unwrap_or_else(|_| "unknown".to_string());
|
.unwrap_or_else(|_| "unknown".to_string());
|
||||||
|
|
||||||
@@ -27,7 +21,6 @@ impl ProjectConfig {
|
|||||||
weevil_version: "1.0.0".to_string(),
|
weevil_version: "1.0.0".to_string(),
|
||||||
ftc_sdk_path,
|
ftc_sdk_path,
|
||||||
ftc_sdk_version,
|
ftc_sdk_version,
|
||||||
android_sdk_path,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,15 +34,9 @@ impl ProjectConfig {
|
|||||||
let contents = fs::read_to_string(&config_path)
|
let contents = fs::read_to_string(&config_path)
|
||||||
.context("Failed to read .weevil.toml")?;
|
.context("Failed to read .weevil.toml")?;
|
||||||
|
|
||||||
let mut config: ProjectConfig = toml::from_str(&contents)
|
let config: ProjectConfig = toml::from_str(&contents)
|
||||||
.context("Failed to parse .weevil.toml")?;
|
.context("Failed to parse .weevil.toml")?;
|
||||||
|
|
||||||
// Migrate old configs that don't have android_sdk_path
|
|
||||||
if config.android_sdk_path.as_os_str().is_empty() {
|
|
||||||
let sdk_config = crate::sdk::SdkConfig::new()?;
|
|
||||||
config.android_sdk_path = sdk_config.android_sdk_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(config)
|
Ok(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +77,6 @@ impl ProjectConfig {
|
|||||||
println!();
|
println!();
|
||||||
println!("{:.<20} {}", "FTC SDK Path", self.ftc_sdk_path.display().to_string().bright_white());
|
println!("{:.<20} {}", "FTC SDK Path", self.ftc_sdk_path.display().to_string().bright_white());
|
||||||
println!("{:.<20} {}", "FTC SDK Version", self.ftc_sdk_version.bright_white());
|
println!("{:.<20} {}", "FTC SDK Version", self.ftc_sdk_version.bright_white());
|
||||||
println!("{:.<20} {}", "Android SDK Path", self.android_sdk_path.display().to_string().bright_white());
|
|
||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ impl ProjectBuilder {
|
|||||||
|
|
||||||
fn create_project_files(&self, project_path: &Path, sdk_config: &SdkConfig) -> Result<()> {
|
fn create_project_files(&self, project_path: &Path, sdk_config: &SdkConfig) -> Result<()> {
|
||||||
// Create .weevil.toml config
|
// Create .weevil.toml config
|
||||||
let project_config = ProjectConfig::new(&self.name, sdk_config.ftc_sdk_path.clone(), sdk_config.android_sdk_path.clone())?;
|
let project_config = ProjectConfig::new(&self.name, sdk_config.ftc_sdk_path.clone())?;
|
||||||
project_config.save(project_path)?;
|
project_config.save(project_path)?;
|
||||||
|
|
||||||
// README.md
|
// README.md
|
||||||
@@ -334,62 +334,47 @@ echo "✓ Deployed!"
|
|||||||
let deploy_bat = r#"@echo off
|
let deploy_bat = r#"@echo off
|
||||||
setlocal enabledelayedexpansion
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
REM Read SDK paths from config
|
REM Read SDK path from config
|
||||||
for /f "tokens=2 delims==" %%a in ('findstr /c:"ftc_sdk_path" .weevil.toml') do set SDK_DIR=%%a
|
for /f "tokens=2 delims==" %%a in ('findstr /c:"ftc_sdk_path" .weevil.toml') do (
|
||||||
for /f "tokens=2 delims==" %%a in ('findstr /c:"android_sdk_path" .weevil.toml') do set ANDROID_SDK=%%a
|
set SDK_DIR=%%a
|
||||||
|
)
|
||||||
|
|
||||||
REM Strip all quotes (both single and double)
|
REM Strip all quotes (both single and double)
|
||||||
set SDK_DIR=%SDK_DIR:"=%
|
set SDK_DIR=%SDK_DIR:"=%
|
||||||
set SDK_DIR=%SDK_DIR:'=%
|
set SDK_DIR=%SDK_DIR:'=%
|
||||||
set SDK_DIR=%SDK_DIR: =%
|
set SDK_DIR=%SDK_DIR: =%
|
||||||
set ANDROID_SDK=%ANDROID_SDK:"=%
|
|
||||||
set ANDROID_SDK=%ANDROID_SDK:'=%
|
|
||||||
set ANDROID_SDK=%ANDROID_SDK: =%
|
|
||||||
|
|
||||||
if not defined SDK_DIR (
|
if not defined SDK_DIR (
|
||||||
echo Error: Could not read FTC SDK path from .weevil.toml
|
echo Error: Could not read FTC SDK path from .weevil.toml
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
if not defined ANDROID_SDK (
|
|
||||||
echo Error: Could not read Android SDK path from .weevil.toml
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM Set ADB path
|
|
||||||
set ADB_PATH=%ANDROID_SDK%\platform-tools\adb.exe
|
|
||||||
|
|
||||||
echo Building APK...
|
echo Building APK...
|
||||||
call gradlew.bat buildApk
|
call gradlew.bat buildApk
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Deploying to Control Hub...
|
echo Deploying to Control Hub...
|
||||||
|
echo.
|
||||||
|
echo DEBUG: SDK_DIR = %SDK_DIR%
|
||||||
|
echo DEBUG: Searching for: %SDK_DIR%\TeamCode-debug.apk
|
||||||
|
echo.
|
||||||
|
|
||||||
REM Find APK - look for TeamCode-debug.apk
|
REM Find APK - look for TeamCode-debug.apk
|
||||||
for /f "delims=" %%i in ('dir /s /b "%SDK_DIR%\TeamCode-debug.apk" 2^>nul') do set APK=%%i
|
for /f "delims=" %%i in ('dir /s /b "%SDK_DIR%\TeamCode-debug.apk" 2^>nul') do set APK=%%i
|
||||||
|
|
||||||
if not defined APK (
|
if not defined APK (
|
||||||
echo Error: APK not found
|
echo Error: APK not found
|
||||||
|
echo.
|
||||||
|
echo DEBUG: Tried searching in: %SDK_DIR%
|
||||||
|
echo DEBUG: Let's see what APKs exist:
|
||||||
|
dir /s /b "%SDK_DIR%\*.apk" 2>nul
|
||||||
|
echo.
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
echo Found APK: %APK%
|
echo Found APK: %APK%
|
||||||
|
|
||||||
REM Check for adb
|
|
||||||
if not exist "%ADB_PATH%" (
|
|
||||||
echo Error: adb not found at %ADB_PATH%
|
|
||||||
echo Run: weevil sdk install
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
echo Installing: %APK%
|
echo Installing: %APK%
|
||||||
"%ADB_PATH%" install -r "%APK%"
|
adb install -r "%APK%"
|
||||||
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo.
|
|
||||||
echo Deployment failed!
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo Deployed!
|
echo Deployed!
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ use weevil::sdk::SdkConfig;
|
|||||||
fn test_config_create_and_save() {
|
fn test_config_create_and_save() {
|
||||||
let temp_dir = TempDir::new().unwrap();
|
let temp_dir = TempDir::new().unwrap();
|
||||||
let sdk_path = temp_dir.path().join("mock-sdk");
|
let sdk_path = temp_dir.path().join("mock-sdk");
|
||||||
let android_sdk_path = temp_dir.path().join("android-sdk");
|
|
||||||
|
|
||||||
// Create minimal SDK structure
|
// Create minimal SDK structure
|
||||||
fs::create_dir_all(sdk_path.join("TeamCode/src/main/java")).unwrap();
|
fs::create_dir_all(sdk_path.join("TeamCode/src/main/java")).unwrap();
|
||||||
@@ -21,11 +20,10 @@ fn test_config_create_and_save() {
|
|||||||
fs::write(sdk_path.join("build.gradle"), "// test").unwrap();
|
fs::write(sdk_path.join("build.gradle"), "// test").unwrap();
|
||||||
fs::write(sdk_path.join(".version"), "v10.1.1").unwrap();
|
fs::write(sdk_path.join(".version"), "v10.1.1").unwrap();
|
||||||
|
|
||||||
let config = ProjectConfig::new("test-robot", sdk_path.clone(), android_sdk_path.clone()).unwrap();
|
let config = ProjectConfig::new("test-robot", sdk_path.clone()).unwrap();
|
||||||
|
|
||||||
assert_eq!(config.project_name, "test-robot");
|
assert_eq!(config.project_name, "test-robot");
|
||||||
assert_eq!(config.ftc_sdk_path, sdk_path);
|
assert_eq!(config.ftc_sdk_path, sdk_path);
|
||||||
assert_eq!(config.android_sdk_path, android_sdk_path);
|
|
||||||
assert_eq!(config.weevil_version, "1.0.0");
|
assert_eq!(config.weevil_version, "1.0.0");
|
||||||
|
|
||||||
// Save and reload
|
// Save and reload
|
||||||
@@ -36,14 +34,12 @@ fn test_config_create_and_save() {
|
|||||||
let loaded = ProjectConfig::load(&project_path).unwrap();
|
let loaded = ProjectConfig::load(&project_path).unwrap();
|
||||||
assert_eq!(loaded.project_name, config.project_name);
|
assert_eq!(loaded.project_name, config.project_name);
|
||||||
assert_eq!(loaded.ftc_sdk_path, config.ftc_sdk_path);
|
assert_eq!(loaded.ftc_sdk_path, config.ftc_sdk_path);
|
||||||
assert_eq!(loaded.android_sdk_path, config.android_sdk_path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_config_toml_format() {
|
fn test_config_toml_format() {
|
||||||
let temp_dir = TempDir::new().unwrap();
|
let temp_dir = TempDir::new().unwrap();
|
||||||
let sdk_path = temp_dir.path().join("sdk");
|
let sdk_path = temp_dir.path().join("sdk");
|
||||||
let android_sdk_path = temp_dir.path().join("android-sdk");
|
|
||||||
|
|
||||||
// Create minimal SDK
|
// Create minimal SDK
|
||||||
fs::create_dir_all(sdk_path.join("TeamCode/src/main/java")).unwrap();
|
fs::create_dir_all(sdk_path.join("TeamCode/src/main/java")).unwrap();
|
||||||
@@ -51,7 +47,7 @@ fn test_config_toml_format() {
|
|||||||
fs::write(sdk_path.join("build.gradle"), "// test").unwrap();
|
fs::write(sdk_path.join("build.gradle"), "// test").unwrap();
|
||||||
fs::write(sdk_path.join(".version"), "v10.1.1").unwrap();
|
fs::write(sdk_path.join(".version"), "v10.1.1").unwrap();
|
||||||
|
|
||||||
let config = ProjectConfig::new("my-robot", sdk_path, android_sdk_path).unwrap();
|
let config = ProjectConfig::new("my-robot", sdk_path).unwrap();
|
||||||
|
|
||||||
let project_path = temp_dir.path().join("project");
|
let project_path = temp_dir.path().join("project");
|
||||||
fs::create_dir_all(&project_path).unwrap();
|
fs::create_dir_all(&project_path).unwrap();
|
||||||
@@ -63,7 +59,6 @@ fn test_config_toml_format() {
|
|||||||
assert!(content.contains("weevil_version = \"1.0.0\""));
|
assert!(content.contains("weevil_version = \"1.0.0\""));
|
||||||
assert!(content.contains("ftc_sdk_path"));
|
assert!(content.contains("ftc_sdk_path"));
|
||||||
assert!(content.contains("ftc_sdk_version"));
|
assert!(content.contains("ftc_sdk_version"));
|
||||||
assert!(content.contains("android_sdk_path"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user