ethers_hardhat_rs/
cmds.rs1use std::{
2 fs::{create_dir_all, remove_dir_all},
3 path::PathBuf,
4};
5
6use async_process::{Child, Command, ExitStatus, Stdio};
7use futures::{executor::block_on, io::BufReader, task::SpawnExt, AsyncBufReadExt, TryStreamExt};
8
9use crate::{
10 error::HardhatError,
11 utils::{thread_pool, HardhatCommand, HardhatCommandContext},
12};
13
14#[derive(Debug)]
17pub struct NetworkContext;
18
19#[async_trait::async_trait]
20impl HardhatCommandContext for NetworkContext {
21 fn init_command(_: PathBuf, c: &mut Command) -> anyhow::Result<()> {
22 c.arg("node").stdout(Stdio::piped()).stderr(Stdio::piped());
23
24 Ok(())
25 }
26
27 async fn start_command(child_process: &mut Child) -> anyhow::Result<()> {
28 let mut lines = BufReader::new(child_process.stdout.take().unwrap()).lines();
29
30 let mut waiting_started = false;
31
32 while let Some(line) = lines.try_next().await.expect("") {
33 if "Any funds sent to them on Mainnet or any other live network WILL BE LOST." == line {
34 log::info!("hardhat node started");
35 waiting_started = true;
36 break;
37 }
38 }
39
40 if !waiting_started {
42 let status = child_process.status().await?;
43
44 return Err(HardhatError::ChildProcess("npx hardhat node".to_string(), status).into());
45 }
46
47 thread_pool().spawn(async move {
48 while let Some(line) = lines.try_next().await.expect("") {
49 log::trace!(target:"hardhat node" ,"{}", line);
50 }
51 })?;
52
53 Ok(())
54 }
55}
56pub type HardhatNetwork = HardhatCommand<NetworkContext>;
58
59#[derive(Debug)]
61pub struct NewProjectContext;
62
63#[async_trait::async_trait]
64impl HardhatCommandContext for NewProjectContext {
65 fn init_command(hardhat_root: PathBuf, _c: &mut Command) -> anyhow::Result<()> {
66 if hardhat_root.exists() {
67 Err(HardhatError::ProjectExists(hardhat_root.to_string_lossy().into_owned()).into())
68 } else {
69 log::debug!(
70 "create hardhat project root dir,{}",
71 hardhat_root.to_string_lossy()
72 );
73
74 create_dir_all(hardhat_root)?;
75
76 Ok(())
77 }
78 }
79}
80
81pub type HardhatNewProject = HardhatCommand<NewProjectContext>;
83
84#[derive(Debug)]
88pub struct ForceNewProjectContext;
89
90#[async_trait::async_trait]
91impl HardhatCommandContext for ForceNewProjectContext {
92 fn init_command(hardhat_root: PathBuf, _c: &mut Command) -> anyhow::Result<()> {
93 if hardhat_root.exists() {
94 remove_dir_all(hardhat_root.clone())?;
95 }
96
97 create_dir_all(hardhat_root)?;
98
99 Ok(())
100 }
101}
102
103pub type HardhatForceNewProject = HardhatCommand<ForceNewProjectContext>;
105
106#[derive(Debug)]
107pub struct BuildProjectContext;
108
109#[async_trait::async_trait]
110impl HardhatCommandContext for BuildProjectContext {
111 fn init_command(hardhat_root: PathBuf, c: &mut Command) -> anyhow::Result<()> {
112 log::debug!(
113 "try build hardhat project {}",
114 hardhat_root.to_string_lossy()
115 );
116
117 c.arg("compile");
118
119 Ok(())
120 }
121}
122
123pub type HardhatBuildProject = HardhatCommand<BuildProjectContext>;
125
126pub fn block_run_build() -> anyhow::Result<ExitStatus> {
128 block_on(async {
129 let mut command = HardhatBuildProject::new()?;
130
131 command.start().await?;
132
133 Ok(command.status().await?)
134 })
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140
141 #[async_std::test]
142 async fn test_start_network() {
143 _ = pretty_env_logger::try_init();
144
145 let mut network =
146 HardhatNetwork::new().expect("Create default hardhat network helper command");
147
148 assert!(!network.is_started());
149
150 network.start().await.expect("Start hardhat network");
151 }
152
153 #[async_std::test]
154 async fn test_create_new_project() {
155 _ = pretty_env_logger::try_init();
156
157 let mut command =
158 HardhatForceNewProject::new().expect("Create default hardhat new project command");
159
160 assert!(!command.is_started());
161
162 command
163 .start()
164 .await
165 .expect("Start create new hardhat project");
166
167 assert!(command
168 .status()
169 .await
170 .expect("Create new project")
171 .success());
172
173 _ = HardhatNewProject::new().expect_err("Create new project in exists path, expect failed");
174 }
175}