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): add forge selectors cmd #5072

Merged
merged 7 commits into from
May 30, 2023
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 cli/src/cmd/forge/fourbyte.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use ethers::prelude::artifacts::output_selection::ContractOutputSelection;
use foundry_common::{
compile,
selectors::{import_selectors, SelectorImportData},
shell,
};
use yansi::Paint;

/// CLI arguments for `forge upload-selectors`.
#[derive(Debug, Clone, Parser)]
Expand All @@ -28,6 +30,8 @@ pub struct UploadSelectorsArgs {
impl UploadSelectorsArgs {
/// Builds a contract and uploads the ABI to selector database
pub async fn run(self) -> eyre::Result<()> {
shell::println(Paint::yellow("Warning! This command is deprecated and will be removed in v1, use `forge selectors upload` instead"))?;

let UploadSelectorsArgs { contract, all, project_paths } = self;

let build_args = CoreBuildArgs {
Expand Down
1 change: 1 addition & 0 deletions cli/src/cmd/forge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ pub mod install;
pub mod remappings;
pub mod remove;
pub mod script;
pub mod selectors;
pub mod snapshot;
pub mod test;
pub mod tree;
Expand Down
95 changes: 95 additions & 0 deletions cli/src/cmd/forge/selectors.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
use crate::{
cmd::forge::build::{CoreBuildArgs, ProjectPathsArgs},
opts::forge::CompilerArgs,
utils::FoundryPathExt,
};
use clap::Parser;
use ethers::prelude::artifacts::output_selection::ContractOutputSelection;
use foundry_common::{
compile,
selectors::{import_selectors, SelectorImportData},
};

/// CLI arguments for `forge selectors`.
#[derive(Debug, Clone, Parser)]
pub enum SelectorsSubcommands {
Copy link
Member

Choose a reason for hiding this comment

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

Let's leave some docs on what this is 🙏

/// Upload selectors to registry
#[clap(visible_alias = "up")]
Upload {
/// The name of the contract to upload selectors for.
#[clap(required_unless_present = "all")]
contract: Option<String>,

/// Upload selectors for all contracts in the project.
#[clap(long, required_unless_present = "contract")]
all: bool,

#[clap(flatten)]
project_paths: ProjectPathsArgs,
Copy link
Member

Choose a reason for hiding this comment

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

Let's also document this field

Copy link
Contributor Author

@lmanini lmanini May 29, 2023

Choose a reason for hiding this comment

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

tbf I don't really know how to document this field: it doesn't look settable by the user and it's not documented over on fourbytes.rs either..
any suggestions?

Copy link
Member

Choose a reason for hiding this comment

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

these will be flattened and will use the existing documentation

},
}

impl SelectorsSubcommands {
pub async fn run(self) -> eyre::Result<()> {
match self {
SelectorsSubcommands::Upload { contract, all, project_paths } => {
let build_args = CoreBuildArgs {
project_paths: project_paths.clone(),
compiler: CompilerArgs {
extra_output: vec![ContractOutputSelection::Abi],
..Default::default()
},
..Default::default()
};

let project = build_args.project()?;
let outcome = compile::suppress_compile(&project)?;
let artifacts = if all {
outcome
.into_artifacts_with_files()
.filter(|(file, _, _)| {
let is_sources_path = file
.starts_with(&project.paths.sources.to_string_lossy().to_string());
let is_test = file.is_sol_test();

is_sources_path && !is_test
})
.map(|(_, contract, artifact)| (contract, artifact))
.collect()
} else {
let contract = contract.unwrap();
let found_artifact = outcome.find_first(&contract);
let artifact = found_artifact
.ok_or_else(|| {
eyre::eyre!(
"Could not find artifact `{contract}` in the compiled artifacts"
)
})?
.clone();
vec![(contract, artifact)]
};

let mut artifacts = artifacts.into_iter().peekable();
while let Some((contract, artifact)) = artifacts.next() {
let abi = artifact.abi.ok_or(eyre::eyre!("Unable to fetch abi"))?;
if abi.abi.functions.is_empty() &&
abi.abi.events.is_empty() &&
abi.abi.errors.is_empty()
{
continue
}

println!("Uploading selectors for {contract}...");

// upload abi to selector database
import_selectors(SelectorImportData::Abi(vec![abi])).await?.describe();

if artifacts.peek().is_some() {
println!()
}
}
}
}
Ok(())
}
}
1 change: 1 addition & 0 deletions cli/src/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,6 @@ fn main() -> eyre::Result<()> {
Ok(())
}
Subcommands::Doc(cmd) => cmd.run(),
Subcommands::Selectors { command } => utils::block_on(command.run()),
}
}
8 changes: 8 additions & 0 deletions cli/src/opts/forge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::cmd::forge::{
remappings::RemappingArgs,
remove::RemoveArgs,
script::ScriptArgs,
selectors::SelectorsSubcommands,
snapshot, test, tree, update,
verify::{VerifyArgs, VerifyCheckArgs},
};
Expand Down Expand Up @@ -155,6 +156,13 @@ pub enum Subcommands {

/// Generate documentation for the project.
Doc(DocArgs),

/// Function selector utilities
#[clap(visible_alias = "se")]
Selectors {
#[clap(subcommand)]
command: SelectorsSubcommands,
},
}

// A set of solc compiler settings that can be set via command line arguments, which are intended
Expand Down