Skip to content

Commit

Permalink
feat(cli): autostart dev container if "run-locally = true" (#176)
Browse files Browse the repository at this point in the history
  • Loading branch information
BlaineHeffron authored Dec 17, 2024
1 parent e0d97be commit c1ad01a
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 3 deletions.
144 changes: 144 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/loam-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ sha2 = { workspace = true }

clap-cargo-extra = "0.3.0"

reqwest = { version = "0.12.9", features = ["json"] }
thiserror = "1.0.31"
serde = "1.0.82"
serde_derive = "1.0.82"
Expand Down
2 changes: 1 addition & 1 deletion crates/loam-cli/src/commands/build/env_toml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub struct Network {
pub rpc_url: Option<String>,
pub network_passphrase: Option<String>,
pub rpc_headers: Option<Vec<(String, String)>>,
// run_locally: Option<bool>,
pub run_locally: Option<bool>,
}

#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
Expand Down
56 changes: 56 additions & 0 deletions crates/loam-cli/src/commands/dev/docker.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use soroban_cli::{commands as cli, CommandParser};
use std::error::Error;

pub async fn start_local_stellar() -> Result<(), Box<dyn Error>> {
let result = cli::container::StartCmd::parse_arg_vec(&["local"])?
.run(&soroban_cli::commands::global::Args::default())
.await;

match result {
Ok(()) => {
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
}
Err(e) => {
if e.to_string().contains("already in use")
|| e.to_string().contains("port is already allocated")
{
eprintln!("Container is already running, proceeding to health check...");
} else {
return Err(Box::new(e));
}
}
}

wait_for_stellar_health().await?;
Ok(())
}
async fn wait_for_stellar_health() -> Result<(), Box<dyn Error>> {
let client = reqwest::Client::new();
let start_time = std::time::Instant::now();
let timeout = std::time::Duration::from_secs(60);
loop {
let elapsed_time = start_time.elapsed();
if elapsed_time > timeout {
eprintln!("Timeout reached: stopping health checks.");
return Err("Health check timed out".into());
}
let res = client
.post("http://localhost:8000/rpc")
.header("Content-Type", "application/json")
.body(r#"{"jsonrpc": "2.0", "id": 1, "method": "getHealth"}"#)
.send()
.await?;
if res.status().is_success() {
let health_status: serde_json::Value = res.json().await?;
if health_status["result"]["status"] == "healthy" {
break;
}
eprintln!("Stellar status is not healthy: {health_status:?}");
} else {
eprintln!("Health check request failed with status: {}", res.status());
}
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
eprintln!("Retrying health check.");
}
Ok(())
}
22 changes: 20 additions & 2 deletions crates/loam-cli/src/commands/dev/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ use tokio::sync::mpsc;
use tokio::sync::Mutex;
use tokio::time;

use crate::commands::build;
use crate::commands::build::{self, env_toml};

use super::build::clients::LoamEnv;
use super::build::env_toml::ENV_FILE;

pub mod docker;

pub enum Message {
FileChanged,
}
Expand All @@ -34,6 +36,10 @@ pub enum Error {
Build(#[from] build::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error(transparent)]
Env(#[from] env_toml::Error),
#[error("Failed to start docker container")]
DockerStart,
}

fn canonicalize_path(path: &Path) -> PathBuf {
Expand Down Expand Up @@ -137,7 +143,19 @@ impl Cmd {
.parent()
.unwrap_or_else(|| Path::new("."));
let env_toml_dir = workspace_root;

let Some(current_env) =
env_toml::Environment::get(workspace_root, &LoamEnv::Development.to_string())?
else {
return Ok(());
};
if current_env.network.run_locally.unwrap_or(false) {
eprintln!("Starting local Stellar Docker container...");
docker::start_local_stellar().await.map_err(|e| {
eprintln!("Failed to start Stellar Docker container: {e:?}");
Error::DockerStart
})?;
eprintln!("Local Stellar network is healthy and running.");
}
let packages = self
.build_cmd
.list_packages()?
Expand Down
Loading

0 comments on commit c1ad01a

Please sign in to comment.