feat: add proxy support for SDK downloads (v1.1.0)
Add --proxy and --no-proxy global flags to control HTTP/HTTPS proxy usage for all network operations (SDK installs, FTC SDK clone/fetch, Android SDK download). Proxy resolution priority: 1. --no-proxy → go direct, ignore everything 2. --proxy <url> → use the specified proxy 3. HTTPS_PROXY / HTTP_PROXY env vars (auto-detected) 4. Nothing → go direct Key implementation details: - reqwest client is always built through ProxyConfig::client() rather than Client::new(), so --no-proxy actively suppresses env-var auto-detection instead of just being a no-op. - git2/libgit2 has its own HTTP transport that doesn't use reqwest. GitProxyGuard is an RAII guard that temporarily sets/clears the HTTPS_PROXY env vars around clone and fetch operations, then restores the previous state on drop. This avoids mutating ~/.gitconfig. - Gradle wrapper reads HTTPS_PROXY natively; no programmatic intervention needed. - All network failure paths now print offline/air-gapped installation instructions automatically, covering manual SDK installs and Gradle distribution download. Closes: v1.1.0 proxy support milestone
This commit is contained in:
@@ -4,18 +4,19 @@ use std::process::Command;
|
||||
use colored::*;
|
||||
|
||||
use crate::sdk::SdkConfig;
|
||||
use crate::sdk::proxy::ProxyConfig;
|
||||
use crate::project::ProjectConfig;
|
||||
|
||||
/// Setup development environment - either system-wide or for a specific project
|
||||
pub fn setup_environment(project_path: Option<&str>) -> Result<()> {
|
||||
pub fn setup_environment(project_path: Option<&str>, proxy: &ProxyConfig) -> Result<()> {
|
||||
match project_path {
|
||||
Some(path) => setup_project(path),
|
||||
None => setup_system(),
|
||||
Some(path) => setup_project(path, proxy),
|
||||
None => setup_system(proxy),
|
||||
}
|
||||
}
|
||||
|
||||
/// Setup system-wide development environment with default SDKs
|
||||
fn setup_system() -> Result<()> {
|
||||
fn setup_system(proxy: &ProxyConfig) -> Result<()> {
|
||||
println!("{}", "═══════════════════════════════════════════════════════════".bright_cyan());
|
||||
println!("{}", " System Setup - Preparing FTC Development Environment".bright_cyan().bold());
|
||||
println!("{}", "═══════════════════════════════════════════════════════════".bright_cyan());
|
||||
@@ -57,7 +58,7 @@ fn setup_system() -> Result<()> {
|
||||
}
|
||||
Err(_) => {
|
||||
println!("{} FTC SDK found but incomplete, reinstalling...", "⚠".yellow());
|
||||
crate::sdk::ftc::install(&sdk_config.ftc_sdk_path, &sdk_config.android_sdk_path)?;
|
||||
crate::sdk::ftc::install(&sdk_config.ftc_sdk_path, &sdk_config.android_sdk_path, proxy)?;
|
||||
let version = crate::sdk::ftc::get_version(&sdk_config.ftc_sdk_path)
|
||||
.unwrap_or_else(|_| "unknown".to_string());
|
||||
installed.push(format!("FTC SDK {} (installed)", version));
|
||||
@@ -65,7 +66,7 @@ fn setup_system() -> Result<()> {
|
||||
}
|
||||
} else {
|
||||
println!("FTC SDK not found. Installing...");
|
||||
crate::sdk::ftc::install(&sdk_config.ftc_sdk_path, &sdk_config.android_sdk_path)?;
|
||||
crate::sdk::ftc::install(&sdk_config.ftc_sdk_path, &sdk_config.android_sdk_path, proxy)?;
|
||||
let version = crate::sdk::ftc::get_version(&sdk_config.ftc_sdk_path)
|
||||
.unwrap_or_else(|_| "unknown".to_string());
|
||||
installed.push(format!("FTC SDK {} (installed)", version));
|
||||
@@ -85,13 +86,13 @@ fn setup_system() -> Result<()> {
|
||||
}
|
||||
Err(_) => {
|
||||
println!("{} Android SDK found but incomplete, reinstalling...", "⚠".yellow());
|
||||
crate::sdk::android::install(&sdk_config.android_sdk_path)?;
|
||||
crate::sdk::android::install(&sdk_config.android_sdk_path, proxy)?;
|
||||
installed.push("Android SDK (installed)".to_string());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Android SDK not found. Installing...");
|
||||
crate::sdk::android::install(&sdk_config.android_sdk_path)?;
|
||||
crate::sdk::android::install(&sdk_config.android_sdk_path, proxy)?;
|
||||
installed.push("Android SDK (installed)".to_string());
|
||||
}
|
||||
println!();
|
||||
@@ -132,7 +133,7 @@ fn setup_system() -> Result<()> {
|
||||
}
|
||||
|
||||
/// Setup dependencies for a specific project by reading its .weevil.toml
|
||||
fn setup_project(project_path: &str) -> Result<()> {
|
||||
fn setup_project(project_path: &str, proxy: &ProxyConfig) -> Result<()> {
|
||||
let project_path = PathBuf::from(project_path);
|
||||
|
||||
if !project_path.exists() {
|
||||
@@ -214,7 +215,7 @@ fn setup_project(project_path: &str) -> Result<()> {
|
||||
|
||||
// Try to install it automatically
|
||||
println!("{}", "Attempting automatic installation...".bright_yellow());
|
||||
match crate::sdk::ftc::install(&config.ftc_sdk_path, &config.android_sdk_path) {
|
||||
match crate::sdk::ftc::install(&config.ftc_sdk_path, &config.android_sdk_path, proxy) {
|
||||
Ok(_) => {
|
||||
println!("{} FTC SDK {} installed successfully",
|
||||
"✓".green(),
|
||||
@@ -249,13 +250,13 @@ fn setup_project(project_path: &str) -> Result<()> {
|
||||
}
|
||||
Err(_) => {
|
||||
println!("{} Android SDK found but incomplete, reinstalling...", "⚠".yellow());
|
||||
crate::sdk::android::install(&config.android_sdk_path)?;
|
||||
crate::sdk::android::install(&config.android_sdk_path, proxy)?;
|
||||
installed.push("Android SDK (installed)".to_string());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("Android SDK not found. Installing...");
|
||||
crate::sdk::android::install(&config.android_sdk_path)?;
|
||||
crate::sdk::android::install(&config.android_sdk_path, proxy)?;
|
||||
installed.push("Android SDK (installed)".to_string());
|
||||
}
|
||||
println!();
|
||||
|
||||
Reference in New Issue
Block a user