-
Notifications
You must be signed in to change notification settings - Fork 1
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(foundry-ignore-compile): read from ignore file and filter out al… #1
base: feature/foundry-ignore-compile
Are you sure you want to change the base?
Changes from 2 commits
6d5b833
92a42c5
7d046d7
9d1ead9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -16,7 +16,7 @@ use figment::{ | |||||||
value::{Dict, Map, Value}, | ||||||||
Error, Figment, Metadata, Profile, Provider, | ||||||||
}; | ||||||||
use filter::GlobMatcher; | ||||||||
use filter::{GlobMatcher, SkipBuildFilter}; | ||||||||
use foundry_compilers::{ | ||||||||
artifacts::{ | ||||||||
output_selection::{ContractOutputSelection, OutputSelection}, | ||||||||
|
@@ -44,7 +44,8 @@ use serde::{Deserialize, Serialize, Serializer}; | |||||||
use std::{ | ||||||||
borrow::Cow, | ||||||||
collections::HashMap, | ||||||||
fs, | ||||||||
fs::{self, File}, | ||||||||
io::{self, BufRead}, | ||||||||
path::{Path, PathBuf}, | ||||||||
str::FromStr, | ||||||||
}; | ||||||||
|
@@ -834,6 +835,21 @@ impl Config { | |||||||
.set_build_info(!no_artifacts && self.build_info) | ||||||||
.set_no_artifacts(no_artifacts); | ||||||||
|
||||||||
let foundry_ignored_paths: Vec<String> = self.get_ignore_paths()?; | ||||||||
|
||||||||
if foundry_ignored_paths.is_empty() { | ||||||||
println!("No ignored paths found"); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
} | ||||||||
|
||||||||
let ignore_pattern: Vec<GlobMatcher> = foundry_ignored_paths | ||||||||
.iter() | ||||||||
.filter_map(|path| GlobMatcher::from_str(path).ok()) | ||||||||
.collect(); | ||||||||
|
||||||||
let ignore_filter: SkipBuildFilters = | ||||||||
SkipBuildFilters::new(ignore_pattern.clone(), self.root.0.clone()); | ||||||||
builder = builder.sparse_output(ignore_filter); | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Group these lines in to a fn There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
|
||||||||
if !self.skip.is_empty() { | ||||||||
let filter = SkipBuildFilters::new(self.skip.clone(), self.root.0.clone()); | ||||||||
builder = builder.sparse_output(filter); | ||||||||
|
@@ -886,7 +902,7 @@ impl Config { | |||||||
if self.offline { | ||||||||
return Err(SolcError::msg(format!( | ||||||||
"can't install missing solc {version} in offline mode" | ||||||||
))) | ||||||||
))); | ||||||||
} | ||||||||
Solc::blocking_install(version)? | ||||||||
} | ||||||||
|
@@ -896,12 +912,12 @@ impl Config { | |||||||
return Err(SolcError::msg(format!( | ||||||||
"`solc` {} does not exist", | ||||||||
solc.display() | ||||||||
))) | ||||||||
))); | ||||||||
} | ||||||||
Solc::new(solc)? | ||||||||
} | ||||||||
}; | ||||||||
return Ok(Some(solc)) | ||||||||
return Ok(Some(solc)); | ||||||||
} | ||||||||
|
||||||||
Ok(None) | ||||||||
|
@@ -919,16 +935,16 @@ impl Config { | |||||||
/// `auto_detect_solc` | ||||||||
pub fn is_auto_detect(&self) -> bool { | ||||||||
if self.solc.is_some() { | ||||||||
return false | ||||||||
return false; | ||||||||
} | ||||||||
self.auto_detect_solc | ||||||||
} | ||||||||
|
||||||||
/// Whether caching should be enabled for the given chain id | ||||||||
pub fn enable_caching(&self, endpoint: &str, chain_id: impl Into<u64>) -> bool { | ||||||||
!self.no_storage_caching && | ||||||||
self.rpc_storage_caching.enable_for_chain_id(chain_id.into()) && | ||||||||
self.rpc_storage_caching.enable_for_endpoint(endpoint) | ||||||||
!self.no_storage_caching | ||||||||
&& self.rpc_storage_caching.enable_for_chain_id(chain_id.into()) | ||||||||
&& self.rpc_storage_caching.enable_for_endpoint(endpoint) | ||||||||
} | ||||||||
|
||||||||
/// Returns the `ProjectPathsConfig` sub set of the config. | ||||||||
|
@@ -978,7 +994,7 @@ impl Config { | |||||||
pub fn vyper_compiler(&self) -> Result<Option<Vyper>, SolcError> { | ||||||||
// Only instantiate Vyper if there are any Vyper files in the project. | ||||||||
if self.project_paths::<VyperLanguage>().input_files_iter().next().is_none() { | ||||||||
return Ok(None) | ||||||||
return Ok(None); | ||||||||
} | ||||||||
let vyper = if let Some(path) = &self.vyper.path { | ||||||||
Some(Vyper::new(path)?) | ||||||||
|
@@ -1063,6 +1079,25 @@ impl Config { | |||||||
} | ||||||||
} | ||||||||
|
||||||||
pub fn get_ignore_paths(&self) -> Result<Vec<String>, SolcError> { | ||||||||
let path = Path::new("foundry.ignore"); | ||||||||
if !path.exists() { | ||||||||
return Ok(Vec::new()); | ||||||||
} | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Return more clear error, to differentiate "file not found", and "file not contains items" |
||||||||
let file = File::open(&path).unwrap(); | ||||||||
let reader = io::BufReader::new(file); | ||||||||
let mut entries: Vec<String> = Vec::new(); | ||||||||
for line in reader.lines() { | ||||||||
let line = line.map_err(|e| SolcError::msg(format!("Failed to read line: {}", e)))?; | ||||||||
let trimmed = line.trim(); | ||||||||
if !trimmed.is_empty() && !trimmed.starts_with('#') { | ||||||||
entries.push(trimmed.to_string()); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
Ok(entries) | ||||||||
} | ||||||||
|
||||||||
/// Resolves the given alias to a matching rpc url | ||||||||
/// | ||||||||
/// Returns: | ||||||||
|
@@ -1160,7 +1195,7 @@ impl Config { | |||||||
) -> Result<Option<ResolvedEtherscanConfig>, EtherscanConfigError> { | ||||||||
if let Some(maybe_alias) = self.etherscan_api_key.as_ref().or(self.eth_rpc_url.as_ref()) { | ||||||||
if self.etherscan.contains_key(maybe_alias) { | ||||||||
return self.etherscan.clone().resolved().remove(maybe_alias).transpose() | ||||||||
return self.etherscan.clone().resolved().remove(maybe_alias).transpose(); | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
|
@@ -1174,7 +1209,7 @@ impl Config { | |||||||
// we update the key, because if an etherscan_api_key is set, it should take | ||||||||
// precedence over the entry, since this is usually set via env var or CLI args. | ||||||||
config.key.clone_from(key); | ||||||||
return Ok(Some(config)) | ||||||||
return Ok(Some(config)); | ||||||||
} | ||||||||
(Ok(config), None) => return Ok(Some(config)), | ||||||||
(Err(err), None) => return Err(err), | ||||||||
|
@@ -1187,7 +1222,7 @@ impl Config { | |||||||
// etherscan fallback via API key | ||||||||
if let Some(key) = self.etherscan_api_key.as_ref() { | ||||||||
let chain = chain.or(self.chain).unwrap_or_default(); | ||||||||
return Ok(ResolvedEtherscanConfig::create(key, chain)) | ||||||||
return Ok(ResolvedEtherscanConfig::create(key, chain)); | ||||||||
} | ||||||||
|
||||||||
Ok(None) | ||||||||
|
@@ -1471,7 +1506,7 @@ impl Config { | |||||||
{ | ||||||||
let file_path = self.get_config_path(); | ||||||||
if !file_path.exists() { | ||||||||
return Ok(()) | ||||||||
return Ok(()); | ||||||||
} | ||||||||
let contents = fs::read_to_string(&file_path)?; | ||||||||
let mut doc = contents.parse::<toml_edit::DocumentMut>()?; | ||||||||
|
@@ -1633,14 +1668,14 @@ impl Config { | |||||||
return match path.is_file() { | ||||||||
true => Some(path.to_path_buf()), | ||||||||
false => None, | ||||||||
} | ||||||||
}; | ||||||||
} | ||||||||
let cwd = std::env::current_dir().ok()?; | ||||||||
let mut cwd = cwd.as_path(); | ||||||||
loop { | ||||||||
let file_path = cwd.join(path); | ||||||||
if file_path.is_file() { | ||||||||
return Some(file_path) | ||||||||
return Some(file_path); | ||||||||
} | ||||||||
cwd = cwd.parent()?; | ||||||||
} | ||||||||
|
@@ -1714,7 +1749,7 @@ impl Config { | |||||||
if let Some(cache_dir) = Self::foundry_rpc_cache_dir() { | ||||||||
let mut cache = Cache { chains: vec![] }; | ||||||||
if !cache_dir.exists() { | ||||||||
return Ok(cache) | ||||||||
return Ok(cache); | ||||||||
} | ||||||||
if let Ok(entries) = cache_dir.as_path().read_dir() { | ||||||||
for entry in entries.flatten().filter(|x| x.path().is_dir()) { | ||||||||
|
@@ -1758,19 +1793,19 @@ impl Config { | |||||||
fn get_cached_blocks(chain_path: &Path) -> eyre::Result<Vec<(String, u64)>> { | ||||||||
let mut blocks = vec![]; | ||||||||
if !chain_path.exists() { | ||||||||
return Ok(blocks) | ||||||||
return Ok(blocks); | ||||||||
} | ||||||||
for block in chain_path.read_dir()?.flatten() { | ||||||||
let file_type = block.file_type()?; | ||||||||
let file_name = block.file_name(); | ||||||||
let filepath = if file_type.is_dir() { | ||||||||
block.path().join("storage.json") | ||||||||
} else if file_type.is_file() && | ||||||||
file_name.to_string_lossy().chars().all(char::is_numeric) | ||||||||
} else if file_type.is_file() | ||||||||
&& file_name.to_string_lossy().chars().all(char::is_numeric) | ||||||||
{ | ||||||||
block.path() | ||||||||
} else { | ||||||||
continue | ||||||||
continue; | ||||||||
}; | ||||||||
blocks.push((file_name.to_string_lossy().into_owned(), fs::metadata(filepath)?.len())); | ||||||||
} | ||||||||
|
@@ -1780,7 +1815,7 @@ impl Config { | |||||||
/// The path provided to this function should point to the etherscan cache for a chain. | ||||||||
fn get_cached_block_explorer_data(chain_path: &Path) -> eyre::Result<u64> { | ||||||||
if !chain_path.exists() { | ||||||||
return Ok(0) | ||||||||
return Ok(0); | ||||||||
} | ||||||||
|
||||||||
fn dir_size_recursive(mut dir: fs::ReadDir) -> eyre::Result<u64> { | ||||||||
|
@@ -1956,7 +1991,7 @@ pub(crate) mod from_opt_glob { | |||||||
{ | ||||||||
let s: Option<String> = Option::deserialize(deserializer)?; | ||||||||
if let Some(s) = s { | ||||||||
return Ok(Some(globset::Glob::new(&s).map_err(serde::de::Error::custom)?)) | ||||||||
return Ok(Some(globset::Glob::new(&s).map_err(serde::de::Error::custom)?)); | ||||||||
} | ||||||||
Ok(None) | ||||||||
} | ||||||||
|
@@ -2238,7 +2273,7 @@ impl TomlFileProvider { | |||||||
if let Some(file) = self.env_val() { | ||||||||
let path = Path::new(&file); | ||||||||
if !path.exists() { | ||||||||
return true | ||||||||
return true; | ||||||||
} | ||||||||
} | ||||||||
false | ||||||||
|
@@ -2258,7 +2293,7 @@ impl TomlFileProvider { | |||||||
"Config file `{}` set in env var `{}` does not exist", | ||||||||
file, | ||||||||
self.env_var.unwrap() | ||||||||
))) | ||||||||
))); | ||||||||
} | ||||||||
Toml::file(file) | ||||||||
} else { | ||||||||
|
@@ -2302,7 +2337,7 @@ impl<P: Provider> Provider for ForcedSnakeCaseData<P> { | |||||||
if Config::STANDALONE_SECTIONS.contains(&profile.as_ref()) { | ||||||||
// don't force snake case for keys in standalone sections | ||||||||
map.insert(profile, dict); | ||||||||
continue | ||||||||
continue; | ||||||||
} | ||||||||
map.insert(profile, dict.into_iter().map(|(k, v)| (k.to_snake_case(), v)).collect()); | ||||||||
} | ||||||||
|
@@ -2442,7 +2477,7 @@ impl Provider for DappEnvCompatProvider { | |||||||
if val > 1 { | ||||||||
return Err( | ||||||||
format!("Invalid $DAPP_BUILD_OPTIMIZE value `{val}`, expected 0 or 1").into() | ||||||||
) | ||||||||
); | ||||||||
} | ||||||||
dict.insert("optimizer".to_string(), (val == 1).into()); | ||||||||
} | ||||||||
|
@@ -2508,7 +2543,7 @@ impl<P: Provider> Provider for RenameProfileProvider<P> { | |||||||
fn data(&self) -> Result<Map<Profile, Dict>, Error> { | ||||||||
let mut data = self.provider.data()?; | ||||||||
if let Some(data) = data.remove(&self.from) { | ||||||||
return Ok(Map::from([(self.to.clone(), data)])) | ||||||||
return Ok(Map::from([(self.to.clone(), data)])); | ||||||||
} | ||||||||
Ok(Default::default()) | ||||||||
} | ||||||||
|
@@ -2554,7 +2589,7 @@ impl<P: Provider> Provider for UnwrapProfileProvider<P> { | |||||||
for (profile_str, profile_val) in profiles { | ||||||||
let profile = Profile::new(&profile_str); | ||||||||
if profile != self.profile { | ||||||||
continue | ||||||||
continue; | ||||||||
} | ||||||||
match profile_val { | ||||||||
Value::Dict(_, dict) => return Ok(profile.collect(dict)), | ||||||||
|
@@ -2565,7 +2600,7 @@ impl<P: Provider> Provider for UnwrapProfileProvider<P> { | |||||||
)); | ||||||||
err.metadata = Some(self.provider.metadata()); | ||||||||
err.profile = Some(self.profile.clone()); | ||||||||
return Err(err) | ||||||||
return Err(err); | ||||||||
} | ||||||||
} | ||||||||
} | ||||||||
|
@@ -2677,7 +2712,7 @@ impl<P: Provider> Provider for OptionalStrictProfileProvider<P> { | |||||||
// provider and can't map the metadata to the error. Therefor we return the root error | ||||||||
// if this error originated in the provider's data. | ||||||||
if let Err(root_err) = self.provider.data() { | ||||||||
return root_err | ||||||||
return root_err; | ||||||||
} | ||||||||
err | ||||||||
}) | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer use
warning
here