holochain_cli_sandbox/
lib.rs1#![warn(missing_docs)]
2
3use std::path::Path;
22
23use holochain_conductor_api::conductor::paths::ConfigRootPath;
24use holochain_conductor_api::{AdminRequest, AdminResponse};
25use holochain_websocket::{WebsocketResult, WebsocketSender};
26use ports::get_admin_api;
27
28pub use ports::force_admin_port;
29
30macro_rules! msg {
33 ($($arg:tt)*) => ({
34 use ansi_term::Color::*;
35 print!("{} ", Blue.bold().paint("hc-sandbox:"));
36 println!($($arg)*);
37 })
38}
39
40pub mod bundles;
41pub mod calls;
42pub mod cli;
43#[doc(hidden)]
44pub mod cmds;
45pub mod run;
46pub mod sandbox;
47pub mod save;
48pub use cli::HcSandbox;
49use holochain_trace::Output;
50
51mod ports;
52mod zome_call;
53
54pub struct CmdRunner {
56 client: WebsocketSender,
57 task: tokio::task::JoinHandle<()>,
58}
59
60impl Drop for CmdRunner {
61 fn drop(&mut self) {
62 self.task.abort();
63 }
64}
65
66impl CmdRunner {
67 const HOLOCHAIN_PATH: &'static str = "holochain";
68 pub async fn new(port: u16) -> Self {
71 Self::try_new(port)
72 .await
73 .expect("Failed to create CmdRunner because admin port failed to connect")
74 }
75
76 pub async fn try_new(port: u16) -> WebsocketResult<Self> {
78 let (client, task) = get_admin_api(port).await?;
79 Ok(Self { client, task })
80 }
81
82 pub async fn from_sandbox(
85 sandbox_path: ConfigRootPath,
86 ) -> anyhow::Result<(Self, tokio::process::Child)> {
87 Self::from_sandbox_with_bin_path(Path::new(Self::HOLOCHAIN_PATH), sandbox_path).await
88 }
89
90 pub async fn from_sandbox_with_bin_path(
93 holochain_bin_path: &Path,
94 sandbox_path: ConfigRootPath,
95 ) -> anyhow::Result<(Self, tokio::process::Child)> {
96 let conductor = run::run_async(holochain_bin_path, sandbox_path, None, Output::Log).await?;
97 let cmd = CmdRunner::try_new(conductor.0).await?;
98 Ok((cmd, conductor.1))
99 }
100
101 pub async fn command(&mut self, cmd: AdminRequest) -> anyhow::Result<AdminResponse> {
103 let response: Result<AdminResponse, _> = self.client.request(cmd).await;
104 Ok(response?)
105 }
106}
107
108#[macro_export]
109macro_rules! expect_variant {
111 ($var:expr => $variant:path, $error_msg:expr) => {
112 match $var {
113 $variant(v) => v,
114 _ => panic!(format!("{}: Expected {} but got {:?}", $error_msg, stringify!($variant), $var)),
115 }
116 };
117 ($var:expr => $variant:path) => {
118 expect_variant!($var => $variant, "")
119 };
120}
121
122#[macro_export]
123macro_rules! expect_match {
125 ($var:expr => $variant:path, $error_msg:expr) => {
126 match $var {
127 $variant(v) => v,
128 _ => anyhow::bail!("{}: Expected {} but got {:?}", $error_msg, stringify!($variant), $var),
129 }
130 };
131 ($var:expr => $variant:path) => {
132 expect_variant!($var => $variant, "")
133 };
134}