Skip to content

Commit

Permalink
feat: always provide Default for MultiCompiler (#188)
Browse files Browse the repository at this point in the history
Closes #187
Closes #168

Updates `MultiCompiler` and makes solc compiler on it optional. If
`svm-solc` is not activated, it is attempted to initialize solc via
`Solc::new("solc")`, and if solc binary is not available in command
line, it is set to None.

We could also add `svm-solc` to default features as I think people would
often prefer enabling it as it's required to emulate foundry's default
behavior.
  • Loading branch information
klkvr authored Aug 18, 2024
1 parent 850de50 commit 3f08085
Show file tree
Hide file tree
Showing 8 changed files with 18 additions and 48 deletions.
6 changes: 0 additions & 6 deletions crates/compilers/src/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// If the cache file does not exist
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
///
Expand All @@ -127,7 +126,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
///
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
///
Expand Down Expand Up @@ -228,7 +226,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// `src/Greeter.sol` if `base` is `/Users/me/project`
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project,
Expand All @@ -254,7 +251,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// Returns the path to the artifact of the given `(file, contract)` pair
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
///
Expand All @@ -272,7 +268,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// [`Self::find_artifact_path()`]) and deserializes the artifact file as JSON.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project,
Expand Down Expand Up @@ -302,7 +297,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
/// Reads all cached artifacts from disk using the given ArtifactOutput handler
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::contract::CompactContractBytecode, cache::CompilerCache, solc::SolcSettings,
Expand Down
4 changes: 0 additions & 4 deletions crates/compilers/src/compile/output/contracts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ impl VersionedContracts {
/// Finds the _first_ contract with the given name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -61,7 +60,6 @@ impl VersionedContracts {
/// Finds the contract with matching path and name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -84,7 +82,6 @@ impl VersionedContracts {
/// Removes the _first_ contract with the given name from the set
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -111,7 +108,6 @@ impl VersionedContracts {
/// Removes the contract with matching path and name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand Down
19 changes: 0 additions & 19 deletions crates/compilers/src/compile/output/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// This returns a chained iterator of both cached and recompiled contract artifacts
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, ArtifactId, Project};
/// use std::collections::btree_map::BTreeMap;
Expand All @@ -131,7 +130,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// the contract name and the corresponding artifact
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project};
/// use std::collections::btree_map::BTreeMap;
Expand All @@ -149,7 +147,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// the contract name and the corresponding artifact with its version
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project};
/// use semver::Version;
Expand Down Expand Up @@ -192,7 +189,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// This returns a chained iterator of both cached and recompiled contract artifacts
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project};
/// use std::{collections::btree_map::BTreeMap, path::PathBuf};
Expand Down Expand Up @@ -237,7 +233,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// # Examples
///
/// Make all artifact files relative to the project's root directory
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand All @@ -254,7 +249,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// Returns a reference to the (merged) solc compiler output.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::contract::Contract, Project};
/// use std::collections::btree_map::BTreeMap;
Expand Down Expand Up @@ -329,7 +323,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// [`Self::remove_first`].
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, info::ContractInfo, Project};
///
Expand All @@ -351,7 +344,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// Finds the artifact with matching path and name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -378,7 +370,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// Finds the artifact with matching path and name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -397,7 +388,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// Removes the _first_ contract with the given name from the set
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -421,7 +411,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
///
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, info::ContractInfo, Project};
///
Expand All @@ -447,7 +436,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
/// [`foundry_compilers_artifacts::ConfigurableContractArtifact`]
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{
/// artifacts::contract::CompactContractBytecode, contracts::ArtifactContracts, ArtifactId,
Expand Down Expand Up @@ -631,7 +619,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// Finds the _first_ contract with the given name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -647,7 +634,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// Removes the _first_ contract with the given name from the set
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -663,7 +649,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// Removes the contract with matching path and name
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -683,7 +668,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// [Self::remove_first]
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, info::ContractInfo, Project};
///
Expand Down Expand Up @@ -747,7 +731,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// bytecode, runtime bytecode, and ABI.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -764,7 +747,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// provide several helper methods
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand Down Expand Up @@ -792,7 +774,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
/// # Examples
///
/// Make all sources and contracts relative to the project's root directory
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand Down
4 changes: 0 additions & 4 deletions crates/compilers/src/compile/output/sources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ impl VersionedSourceFiles {
/// Finds the _first_ source file with the given path.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand Down Expand Up @@ -85,7 +84,6 @@ impl VersionedSourceFiles {
/// Finds the _first_ source file with the given id
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -109,7 +107,6 @@ impl VersionedSourceFiles {
/// Removes the _first_ source_file with the given path from the set
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand All @@ -131,7 +128,6 @@ impl VersionedSourceFiles {
/// Removes the _first_ source_file with the given id from the set
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{artifacts::*, Project};
///
Expand Down
1 change: 0 additions & 1 deletion crates/compilers/src/compile/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ impl<'a, T: ArtifactOutput, C: Compiler> ProjectCompiler<'a, T, C> {
/// `Contract`s
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand Down
22 changes: 16 additions & 6 deletions crates/compilers/src/compilers/multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,25 @@ use std::{
/// Compiler capable of compiling both Solidity and Vyper sources.
#[derive(Clone, Debug)]
pub struct MultiCompiler {
pub solc: SolcCompiler,
pub solc: Option<SolcCompiler>,
pub vyper: Option<Vyper>,
}

#[cfg(feature = "svm-solc")]
impl Default for MultiCompiler {
fn default() -> Self {
let vyper = Vyper::new("vyper").ok();

Self { solc: SolcCompiler::default(), vyper }
#[cfg(feature = "svm-solc")]
let solc = Some(SolcCompiler::AutoDetect);
#[cfg(not(feature = "svm-solc"))]
let solc = crate::solc::Solc::new("solc").map(SolcCompiler::Specific).ok();

Self { solc, vyper }
}
}

impl MultiCompiler {
pub fn new(solc: SolcCompiler, vyper_path: Option<PathBuf>) -> Result<Self> {
pub fn new(solc: Option<SolcCompiler>, vyper_path: Option<PathBuf>) -> Result<Self> {
let vyper = vyper_path.map(Vyper::new).transpose()?;
Ok(Self { solc, vyper })
}
Expand Down Expand Up @@ -259,7 +263,11 @@ impl Compiler for MultiCompiler {
fn compile(&self, input: &Self::Input) -> Result<CompilerOutput<Self::CompilationError>> {
match input {
MultiCompilerInput::Solc(input) => {
self.solc.compile(input).map(|res| res.map_err(MultiCompilerError::Solc))
if let Some(solc) = &self.solc {
Compiler::compile(solc, input).map(|res| res.map_err(MultiCompilerError::Solc))
} else {
Err(SolcError::msg("solc compiler is not available"))
}
}
MultiCompilerInput::Vyper(input) => {
if let Some(vyper) = &self.vyper {
Expand All @@ -274,7 +282,9 @@ impl Compiler for MultiCompiler {

fn available_versions(&self, language: &Self::Language) -> Vec<CompilerVersion> {
match language {
MultiCompilerLanguage::Solc(language) => self.solc.available_versions(language),
MultiCompilerLanguage::Solc(language) => {
self.solc.as_ref().map(|s| s.available_versions(language)).unwrap_or_default()
}
MultiCompilerLanguage::Vyper(language) => {
self.vyper.as_ref().map(|v| v.available_versions(language)).unwrap_or_default()
}
Expand Down
7 changes: 0 additions & 7 deletions crates/compilers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ impl Project {
/// # Examples
///
/// Configure with [ConfigurableArtifacts] artifacts output and [MultiCompiler] compiler:
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand All @@ -119,7 +118,6 @@ impl Project {
/// ```
///
/// To configure any a project with any `ArtifactOutput` use either:
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand All @@ -128,7 +126,6 @@ impl Project {
/// ```
///
/// or use the builder directly:
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{multi::MultiCompiler, ConfigurableArtifacts, ProjectBuilder};
///
Expand Down Expand Up @@ -249,7 +246,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
/// Use this if you compile a project in a `build.rs` file.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::{Project, ProjectPathsConfig};
///
Expand All @@ -274,7 +270,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
/// Convenience function to compile a single solidity file with the project's settings.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand All @@ -292,7 +287,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
/// Same as [`Self::compile()`] but with the given `files` as input.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```no_run
/// use foundry_compilers::Project;
///
Expand All @@ -315,7 +309,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
/// If the cache file was the only file in the folder, this also removes the empty folder.
///
/// # Examples
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
/// ```
/// use foundry_compilers::Project;
///
Expand Down
3 changes: 2 additions & 1 deletion crates/compilers/tests/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3973,7 +3973,8 @@ fn test_can_compile_multi() {
solc: Default::default(),
};

let compiler = MultiCompiler { solc: SolcCompiler::default(), vyper: Some(VYPER.clone()) };
let compiler =
MultiCompiler { solc: Some(SolcCompiler::default()), vyper: Some(VYPER.clone()) };

let project = ProjectBuilder::<MultiCompiler>::new(Default::default())
.settings(settings)
Expand Down

0 comments on commit 3f08085

Please sign in to comment.