1 Commits

Author SHA1 Message Date
Eric Ratliff
20bac7322d This might work with Android now 2026-02-01 20:07:11 -06:00
2 changed files with 144 additions and 0 deletions

View File

@@ -52,6 +52,13 @@ pub fn upgrade_project(path: &str) -> Result<()> {
"gradle/wrapper/gradle-wrapper.properties", "gradle/wrapper/gradle-wrapper.properties",
"gradle/wrapper/gradle-wrapper.jar", "gradle/wrapper/gradle-wrapper.jar",
".gitignore", ".gitignore",
// Android Studio integration — regenerated so run configs stay in
// sync if deploy.sh flags or script names ever change.
".idea/workspace.xml",
".idea/runConfigurations/Deploy (auto).xml",
".idea/runConfigurations/Deploy (USB).xml",
".idea/runConfigurations/Deploy (WiFi).xml",
".idea/runConfigurations/Test.xml",
]; ];
println!("{}", "Updating infrastructure files...".bright_yellow()); println!("{}", "Updating infrastructure files...".bright_yellow());

View File

@@ -55,6 +55,7 @@ impl ProjectBuilder {
"src/test/java/robot", "src/test/java/robot",
"src/test/java/robot/subsystems", "src/test/java/robot/subsystems",
"gradle/wrapper", "gradle/wrapper",
".idea/runConfigurations",
]; ];
for dir in dirs { for dir in dirs {
@@ -416,9 +417,145 @@ class BasicTest {
test_file test_file
)?; )?;
// Android Studio integration: .idea/ files
self.generate_idea_files(project_path)?;
Ok(()) Ok(())
} }
/// Generate .idea/ files for Android Studio integration.
///
/// The goal is for students to open the project in Android Studio and see
/// a clean file tree (just src/ and the scripts) with Run configurations
/// that invoke Weevil's shell scripts directly. All the internal plumbing
/// (sdk/, .gradle/, build/) is hidden from the IDE view.
///
/// Android Studio uses IntelliJ's run configuration XML format. The
/// ShellScript type invokes a script relative to the project root — exactly
/// what we want since deploy.sh and build.sh already live there.
fn generate_idea_files(&self, project_path: &Path) -> Result<()> {
// workspace.xml — controls the file-tree view and hides internals.
// We use a ProjectViewPane exclude pattern list rather than touching
// the module's source roots, so this works regardless of whether the
// student has opened the project before.
let workspace_xml = r#"<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectViewManager">
<state>
<navigator currentProjector="ProjectFiles" hideEmptyMiddlePackages="true" sortByType="true">
<state>
<expand>
<file url="file://$PROJECT_DIR$/src" />
<file url="file://$PROJECT_DIR$/src/main" />
<file url="file://$PROJECT_DIR$/src/main/java" />
<file url="file://$PROJECT_DIR$/src/main/java/robot" />
<file url="file://$PROJECT_DIR$/src/test" />
<file url="file://$PROJECT_DIR$/src/test/java" />
<file url="file://$PROJECT_DIR$/src/test/java/robot" />
</expand>
</state>
</navigator>
</state>
</component>
<component name="ExcludedFiles">
<file url="file://$PROJECT_DIR$/build" reason="Build output" />
<file url="file://$PROJECT_DIR$/.gradle" reason="Gradle cache" />
<file url="file://$PROJECT_DIR$/gradle" reason="Gradle wrapper internals" />
</component>
</project>
"#;
fs::write(project_path.join(".idea/workspace.xml"), workspace_xml)?;
// Run configurations. Each is a ShellScript type that invokes one of
// Weevil's scripts. Android Studio shows these in the Run dropdown
// at the top of the IDE — no configuration needed by the student.
//
// We generate platform-specific configs: .sh on Unix, .bat on Windows.
// The SCRIPT element uses $PROJECT_DIR$ so it's location-independent.
// Deploy (auto) — no flags, deploy.sh auto-detects USB vs WiFi
let deploy_auto_xml = r#"<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Deploy (auto)" type="ShellScript" factoryName="Shell script">
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/deploy.sh" />
<option name="SCRIPT_OPTIONS" value="" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<envs />
<EXTENSION ID="net.ash.shed.shell-script.run-configuration.DefaultRunConfigurationExtension" />
<method v="2">
<option name="RUN_SCRIPT_TASK" enabled="true" />
</method>
</configuration>
</component>
"#;
fs::write(
project_path.join(".idea/runConfigurations/Deploy (auto).xml"),
deploy_auto_xml,
)?;
// Deploy (USB) — forces USB connection
let deploy_usb_xml = r#"<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Deploy (USB)" type="ShellScript" factoryName="Shell script">
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/deploy.sh" />
<option name="SCRIPT_OPTIONS" value="--usb" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<envs />
<EXTENSION ID="net.ash.shed.shell-script.run-configuration.DefaultRunConfigurationExtension" />
<method v="2">
<option name="RUN_SCRIPT_TASK" enabled="true" />
</method>
</configuration>
</component>
"#;
fs::write(
project_path.join(".idea/runConfigurations/Deploy (USB).xml"),
deploy_usb_xml,
)?;
// Deploy (WiFi) — forces WiFi connection to default 192.168.43.1
let deploy_wifi_xml = r#"<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Deploy (WiFi)" type="ShellScript" factoryName="Shell script">
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/deploy.sh" />
<option name="SCRIPT_OPTIONS" value="--wifi" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<envs />
<EXTENSION ID="net.ash.shed.shell-script.run-configuration.DefaultRunConfigurationExtension" />
<method v="2">
<option name="RUN_SCRIPT_TASK" enabled="true" />
</method>
</configuration>
</component>
"#;
fs::write(
project_path.join(".idea/runConfigurations/Deploy (WiFi).xml"),
deploy_wifi_xml,
)?;
// Test — runs the unit test suite via Gradle
let test_xml = r#"<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Test" type="ShellScript" factoryName="Shell script">
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/gradlew" />
<option name="SCRIPT_OPTIONS" value="test" />
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$" />
<option name="INTERPRETER_PATH" value="/bin/bash" />
<envs />
<EXTENSION ID="net.ash.shed.shell-script.run-configuration.DefaultRunConfigurationExtension" />
<method v="2">
<option name="RUN_SCRIPT_TASK" enabled="true" />
</method>
</configuration>
</component>
"#;
fs::write(
project_path.join(".idea/runConfigurations/Test.xml"),
test_xml,
)?;
Ok(())
}
fn setup_gradle(&self, project_path: &Path) -> Result<()> { fn setup_gradle(&self, project_path: &Path) -> Result<()> {
println!("Setting up Gradle wrapper..."); println!("Setting up Gradle wrapper...");
crate::sdk::gradle::setup_wrapper(project_path)?; crate::sdk::gradle::setup_wrapper(project_path)?;