foundry2echidna/cli/
mod.rs1use crate::deserialization::deserialize_broadcast;
2use crate::file_handling::{read_broadcast_file, write_transformed_broadcast_to_file};
3use crate::serialization::{add_account_created_events, serialize_broadcast};
4use clap::Parser;
5use glob::glob;
6use std::{fs::create_dir_all, path::Path};
7
8pub fn transform_broadcast(input_path: &str, output_path: &str) -> Result<(), String> {
24 let broadcast_to_deserialize = read_broadcast_file(input_path)?;
25 let broadcast = deserialize_broadcast(&broadcast_to_deserialize)?;
26 let broadcast = serialize_broadcast(broadcast)?;
27 let etheno_like_broadcast = add_account_created_events(broadcast)?;
28 write_transformed_broadcast_to_file(ðeno_like_broadcast, output_path)?;
29 Ok(())
30}
31
32#[derive(Parser, Debug)]
33#[command(author, version, about, long_about = None )]
34pub struct Args {
35 #[clap(
36 short,
37 long,
38 help = r#"Path to the Foundry broadcast file to be transformed.
39If not provided, the default path is `broadcast/*.s.sol/31337/run-latest.json`.
40Please note that if you have a couple of directories in the `broadcast` dir,
41the first one found will be used by default."#
42 )]
43 pub input_path: Option<String>,
44
45 #[clap(
46 short,
47 long,
48 help = "Path to a file where you want to save the transformed broadcast. If not provided, the default path is `src/crytic/init.json`."
49 )]
50 pub output_path: Option<String>,
51}
52
53impl Args {
54 pub fn new() -> Result<Self, String> {
55 let mut args = Self::parse();
56 if args.input_path.is_none() {
57 let glob_pattern = "broadcast/*.s.sol/31337/run-latest.json";
58 let mut paths = match glob(glob_pattern) {
59 Ok(paths) => paths,
60 Err(e) => return Err(e.to_string()),
61 };
62 let path = match paths.next() {
63 Some(path) => path,
64 None => return Err("No matching input paths found".to_string()),
65 };
66 args.input_path = Some(match path.unwrap().to_str() {
67 Some(s) => s.to_string(),
68 None => return Err("Failed to convert input path to string".to_string()),
69 });
70 }
71 if args.output_path.is_none() {
72 let output_dir = Path::new("src/crytic");
73 match create_dir_all(output_dir) {
74 Ok(_) => {}
75 Err(e) => return Err(e.to_string()),
76 };
77 args.output_path = Some(match output_dir.join("init.json").to_str() {
78 Some(s) => s.to_string(),
79 None => return Err("Failed to convert output path to string".to_string()),
80 });
81 } else {
82 let output_path = match Path::new(args.output_path.as_ref().unwrap()).parent() {
83 Some(p) => p,
84 None => {
85 return Err("Failed to extract parent directory from output path".to_string())
86 }
87 };
88 match create_dir_all(output_path) {
89 Ok(_) => {}
90 Err(e) => return Err(e.to_string()),
91 };
92 }
93 Ok(args)
94 }
95}