ethers-rs/ethers-core/src/utils/ganache.rs

83 lines
2.4 KiB
Rust
Raw Normal View History

use std::process::{Child, Command};
/// A ganache CLI instance. Will close the instance when dropped.
2020-06-10 07:33:51 +00:00
///
/// Construct this using [`Ganache`](./struct.Ganache.html)
pub struct GanacheInstance(Child);
2020-06-10 07:33:51 +00:00
impl Drop for GanacheInstance {
fn drop(&mut self) {
self.0.kill().expect("could not kill ganache");
}
}
/// Builder for launching `ganache-cli`.
///
/// # Panics
///
/// If `spawn` is called without `ganache-cli` being available in the user's $PATH
///
/// # Example
///
2020-06-10 07:33:51 +00:00
/// ```no_run
/// use ethers_core::utils::Ganache;
///
/// let port = 8545u64;
/// let url = format!("http://localhost:{}", port).to_string();
///
2020-06-10 07:33:51 +00:00
/// let ganache = Ganache::new()
/// .port(port)
/// .mnemonic("abstract vacuum mammal awkward pudding scene penalty purchase dinner depart evoke puzzle")
/// .spawn();
///
/// drop(ganache); // this will kill the instance
/// ```
#[derive(Clone, Default)]
2020-06-10 07:33:51 +00:00
pub struct Ganache {
port: Option<u64>,
mnemonic: Option<String>,
}
2020-06-10 07:33:51 +00:00
impl Ganache {
/// Creates an empty Ganache builder.
/// The default port is 8545. The mnemonic is chosen randomly.
pub fn new() -> Self {
Self::default()
}
/// Sets the port which will be used when the `ganache-cli` instance is launched.
pub fn port<T: Into<u64>>(mut self, port: T) -> Self {
self.port = Some(port.into());
self
}
/// Sets the mnemonic which will be used when the `ganache-cli` instance is launched.
pub fn mnemonic<T: Into<String>>(mut self, mnemonic: T) -> Self {
self.mnemonic = Some(mnemonic.into());
self
}
/// Consumes the builder and spawns `ganache-cli` with stdout redirected
/// to /dev/null. This takes ~2 seconds to execute as it blocks while
/// waiting for `ganache-cli` to launch.
2020-06-10 07:33:51 +00:00
pub fn spawn(self) -> GanacheInstance {
let mut cmd = Command::new("ganache-cli");
cmd.stdout(std::process::Stdio::null());
if let Some(port) = self.port {
cmd.arg("-p").arg(port.to_string());
}
if let Some(mnemonic) = self.mnemonic {
cmd.arg("-m").arg(mnemonic);
}
let ganache_pid = cmd.spawn().expect("couldnt start ganache-cli");
// wait a couple of seconds for ganache to boot up
// TODO: Change this to poll for `port`
let sleep_time = std::time::Duration::from_secs(2);
std::thread::sleep(sleep_time);
2020-06-10 07:33:51 +00:00
GanacheInstance(ganache_pid)
}
}