Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(forge compile): print compiled contract names #682

Merged
merged 5 commits into from
Mar 1, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
8 changes: 7 additions & 1 deletion cli/src/cmd/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@ pub struct BuildArgs {
#[serde(flatten)]
pub compiler: CompilerArgs,

#[clap(help = "print compiled contract names", long = "names")]
pub names: bool,

#[clap(help = "print compiled contract sizes", long = "sizes")]
pub sizes: bool,

#[clap(help = "ignore warnings with specific error codes", long)]
#[serde(skip_serializing_if = "Vec::is_empty")]
pub ignored_error_codes: Vec<u64>,
Expand Down Expand Up @@ -155,7 +161,7 @@ impl Cmd for BuildArgs {
type Output = ProjectCompileOutput;
fn run(self) -> eyre::Result<Self::Output> {
let project = self.project()?;
super::compile(&project)
super::compile(&project, self.names, self.sizes)
}
}

Expand Down
2 changes: 1 addition & 1 deletion cli/src/cmd/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl Cmd for CreateArgs {
fn run(self) -> Result<Self::Output> {
// Find Project & Compile
let project = self.opts.project()?;
let compiled = super::compile(&project)?;
let compiled = super::compile(&project, self.opts.names, self.opts.sizes)?;

// Get ABI and BIN
let (abi, bin, _) = super::read_artifact(&project, compiled, self.contract.clone())?;
Expand Down
2 changes: 2 additions & 0 deletions cli/src/cmd/flatten.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ impl Cmd for FlattenArgs {
lib_paths,
out_path: None,
compiler: Default::default(),
names: false,
sizes: false,
ignored_error_codes: vec![],
no_auto_detect: false,
offline: false,
Expand Down
48 changes: 46 additions & 2 deletions cli/src/cmd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ use ethers::{
prelude::artifacts::{CompactBytecode, CompactDeployedBytecode},
solc::cache::SolFilesCache,
};
use std::path::PathBuf;
use std::{collections::BTreeMap, path::PathBuf};

/// Common trait for all cli commands
pub trait Cmd: clap::Parser + Sized {
Expand All @@ -67,9 +67,15 @@ pub trait Cmd: clap::Parser + Sized {

use ethers::solc::{artifacts::CompactContractBytecode, Project, ProjectCompileOutput};

use foundry_utils::to_table;

/// Compiles the provided [`Project`], throws if there's any compiler error and logs whether
/// compilation was successful or if there was a cache hit.
pub fn compile(project: &Project) -> eyre::Result<ProjectCompileOutput> {
pub fn compile(
project: &Project,
print_names: bool,
print_sizes: bool,
) -> eyre::Result<ProjectCompileOutput> {
if !project.paths.sources.exists() {
eyre::bail!(
r#"no contracts to compile, contracts folder "{}" does not exist.
Expand All @@ -88,9 +94,47 @@ If you are in a subdirectory in a Git repository, try adding `--root .`"#,
} else if output.is_unchanged() {
println!("no files changed, compilation skipped.");
} else {
if print_names {
let compiled_contracts = output.compiled_contracts_by_compiler_version();
println!("compiled contracts:");
for (version, contracts) in compiled_contracts.into_iter() {
println!(
" compiler version: {}.{}.{}",
version.major, version.minor, version.patch
);
for (name, _) in contracts {
println!(" - {}", name);
}
}
}
if print_sizes {
let compiled_contracts = output.compiled_contracts_by_compiler_version();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code could be modularized and reused in the future for foundry sizes

let mut sizes = BTreeMap::new();
for (_, contracts) in compiled_contracts.into_iter() {
for (name, contract) in contracts {
let bytecode: CompactContractBytecode = contract.into();
let size = if let Some(code) = bytecode.bytecode {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to always be 0 for libraries

if let Some(object) = code.object.as_bytes() {
object.to_vec().len()
} else {
0
}
} else {
0
};
sizes.insert(name, size);
}
}
let json = serde_json::to_value(&sizes)?;
println!("name size (bytes)");
println!("-----------------------------");
println!("{}", to_table(json));
}

println!("{}", output);
println!("success.");
}

Ok(output)
}

Expand Down
6 changes: 6 additions & 0 deletions config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ pub struct Config {
/// by proptest, to be encountered during usage of `vm.assume`
/// cheatcode.
pub fuzz_max_global_rejects: u32,
/// Print the names of the compiled contracts
pub names: bool,
/// Print the sizes of the compiled contracts
pub sizes: bool,
/// The root path where the config detection started from, `Config::with_root`
#[doc(hidden)]
// We're skipping serialization here, so it won't be included in the [`Config::to_string()`]
Expand Down Expand Up @@ -800,6 +804,8 @@ impl Default for Config {
optimizer_details: None,
extra_output: Default::default(),
extra_output_files: Default::default(),
names: false,
sizes: false,
fuzz_runs: 256,
fuzz_max_local_rejects: 1024,
fuzz_max_global_rejects: 65536,
Expand Down