Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions assets/ContractTemplate.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.10;

contract Contract {}
6 changes: 6 additions & 0 deletions assets/ContractTemplate.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// SPDX-License-Identifier: Unlicense
pragma solidity 0.8.10;

contract ContractTest {
function setUp() public {}
}
49 changes: 49 additions & 0 deletions cli/src/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,55 @@ fn main() -> eyre::Result<()> {
.collect();
remappings.iter().for_each(|x| println!("{}", x));
}
Subcommands::Init { root, template } => {
let root = root.unwrap_or_else(|| std::env::current_dir().unwrap());
// create the root dir if it does not exist
if !root.exists() {
std::fs::create_dir_all(&root)?;
}
let root = std::fs::canonicalize(root)?;

// if a template is provided, then this command is just an alias to `git clone <url>
// <path>`
if let Some(ref template) = template {
println!("Initializing {} from {}...", root.display(), template);
std::process::Command::new("git")
.args(&["clone", template, &root.display().to_string()])
.spawn()?
.wait()?;
} else {
println!("Initializing {}...", root.display());

// make the dirs
let src = root.join("src");
let test = src.join("test");
std::fs::create_dir_all(&test)?;
let lib = root.join("lib");
std::fs::create_dir(&lib)?;

// write the contract file
let contract_path = src.join("Contract.sol");
std::fs::write(contract_path, include_str!("../../assets/ContractTemplate.sol"))?;
// write the tests
let contract_path = test.join("Contract.t.sol");
std::fs::write(contract_path, include_str!("../../assets/ContractTemplate.t.sol"))?;

// sets up git
std::process::Command::new("git").arg("init").current_dir(&root).spawn()?.wait()?;
std::process::Command::new("git")
.args(&["add", "."])
.current_dir(&root)
.spawn()?
.wait()?;
std::process::Command::new("git")
.args(&["commit", "-m", "chore: forge init"])
.current_dir(&root)
.spawn()?
.wait()?;
}

println!("Done.");
}
}

Ok(())
Expand Down
7 changes: 7 additions & 0 deletions cli/src/forge_opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ pub enum Subcommands {
#[structopt(long, help = "verify on Etherscan")]
verify: bool,
},
#[structopt(alias = "i", about = "initializes a new forge repository")]
Init {
#[structopt(help = "the project's root path, default being the current directory")]
root: Option<PathBuf>,
#[structopt(help = "optional solidity template to start from", long, short)]
template: Option<String>,
},
}

/// Represents the common dapp argument pattern for `<path>:<contractname>` where `<path>:` is
Expand Down