Skip to content

Commit 3f08085

Browse files
authored
feat: always provide Default for MultiCompiler (#188)
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.
1 parent 850de50 commit 3f08085

File tree

8 files changed

+18
-48
lines changed

8 files changed

+18
-48
lines changed

crates/compilers/src/cache.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
101101
/// If the cache file does not exist
102102
///
103103
/// # Examples
104-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
105104
/// ```no_run
106105
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
107106
///
@@ -127,7 +126,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
127126
///
128127
///
129128
/// # Examples
130-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
131129
/// ```no_run
132130
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
133131
///
@@ -228,7 +226,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
228226
/// `src/Greeter.sol` if `base` is `/Users/me/project`
229227
///
230228
/// # Examples
231-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
232229
/// ```no_run
233230
/// use foundry_compilers::{
234231
/// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project,
@@ -254,7 +251,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
254251
/// Returns the path to the artifact of the given `(file, contract)` pair
255252
///
256253
/// # Examples
257-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
258254
/// ```no_run
259255
/// use foundry_compilers::{cache::CompilerCache, solc::SolcSettings, Project};
260256
///
@@ -272,7 +268,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
272268
/// [`Self::find_artifact_path()`]) and deserializes the artifact file as JSON.
273269
///
274270
/// # Examples
275-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
276271
/// ```no_run
277272
/// use foundry_compilers::{
278273
/// artifacts::contract::CompactContract, cache::CompilerCache, solc::SolcSettings, Project,
@@ -302,7 +297,6 @@ impl<S: CompilerSettings> CompilerCache<S> {
302297
/// Reads all cached artifacts from disk using the given ArtifactOutput handler
303298
///
304299
/// # Examples
305-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
306300
/// ```no_run
307301
/// use foundry_compilers::{
308302
/// artifacts::contract::CompactContractBytecode, cache::CompilerCache, solc::SolcSettings,

crates/compilers/src/compile/output/contracts.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ impl VersionedContracts {
4343
/// Finds the _first_ contract with the given name
4444
///
4545
/// # Examples
46-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
4746
/// ```no_run
4847
/// use foundry_compilers::{artifacts::*, Project};
4948
///
@@ -61,7 +60,6 @@ impl VersionedContracts {
6160
/// Finds the contract with matching path and name
6261
///
6362
/// # Examples
64-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
6563
/// ```no_run
6664
/// use foundry_compilers::{artifacts::*, Project};
6765
///
@@ -84,7 +82,6 @@ impl VersionedContracts {
8482
/// Removes the _first_ contract with the given name from the set
8583
///
8684
/// # Examples
87-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
8885
/// ```no_run
8986
/// use foundry_compilers::{artifacts::*, Project};
9087
///
@@ -111,7 +108,6 @@ impl VersionedContracts {
111108
/// Removes the contract with matching path and name
112109
///
113110
/// # Examples
114-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
115111
/// ```no_run
116112
/// use foundry_compilers::{artifacts::*, Project};
117113
///

crates/compilers/src/compile/output/mod.rs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
112112
/// This returns a chained iterator of both cached and recompiled contract artifacts
113113
///
114114
/// # Examples
115-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
116115
/// ```no_run
117116
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, ArtifactId, Project};
118117
/// use std::collections::btree_map::BTreeMap;
@@ -131,7 +130,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
131130
/// the contract name and the corresponding artifact
132131
///
133132
/// # Examples
134-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
135133
/// ```no_run
136134
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project};
137135
/// use std::collections::btree_map::BTreeMap;
@@ -149,7 +147,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
149147
/// the contract name and the corresponding artifact with its version
150148
///
151149
/// # Examples
152-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
153150
/// ```no_run
154151
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project};
155152
/// use semver::Version;
@@ -192,7 +189,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
192189
/// This returns a chained iterator of both cached and recompiled contract artifacts
193190
///
194191
/// # Examples
195-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
196192
/// ```no_run
197193
/// use foundry_compilers::{artifacts::ConfigurableContractArtifact, Project};
198194
/// use std::{collections::btree_map::BTreeMap, path::PathBuf};
@@ -237,7 +233,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
237233
/// # Examples
238234
///
239235
/// Make all artifact files relative to the project's root directory
240-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
241236
/// ```no_run
242237
/// use foundry_compilers::Project;
243238
///
@@ -254,7 +249,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
254249
/// Returns a reference to the (merged) solc compiler output.
255250
///
256251
/// # Examples
257-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
258252
/// ```no_run
259253
/// use foundry_compilers::{artifacts::contract::Contract, Project};
260254
/// use std::collections::btree_map::BTreeMap;
@@ -329,7 +323,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
329323
/// [`Self::remove_first`].
330324
///
331325
/// # Examples
332-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
333326
/// ```no_run
334327
/// use foundry_compilers::{artifacts::*, info::ContractInfo, Project};
335328
///
@@ -351,7 +344,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
351344
/// Finds the artifact with matching path and name
352345
///
353346
/// # Examples
354-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
355347
/// ```no_run
356348
/// use foundry_compilers::{artifacts::*, Project};
357349
///
@@ -378,7 +370,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
378370
/// Finds the artifact with matching path and name
379371
///
380372
/// # Examples
381-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
382373
/// ```no_run
383374
/// use foundry_compilers::{artifacts::*, Project};
384375
///
@@ -397,7 +388,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
397388
/// Removes the _first_ contract with the given name from the set
398389
///
399390
/// # Examples
400-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
401391
/// ```no_run
402392
/// use foundry_compilers::{artifacts::*, Project};
403393
///
@@ -421,7 +411,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
421411
///
422412
///
423413
/// # Examples
424-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
425414
/// ```no_run
426415
/// use foundry_compilers::{artifacts::*, info::ContractInfo, Project};
427416
///
@@ -447,7 +436,6 @@ impl<T: ArtifactOutput, C: Compiler> ProjectCompileOutput<C, T> {
447436
/// [`foundry_compilers_artifacts::ConfigurableContractArtifact`]
448437
///
449438
/// # Examples
450-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
451439
/// ```no_run
452440
/// use foundry_compilers::{
453441
/// artifacts::contract::CompactContractBytecode, contracts::ArtifactContracts, ArtifactId,
@@ -631,7 +619,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
631619
/// Finds the _first_ contract with the given name
632620
///
633621
/// # Examples
634-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
635622
/// ```no_run
636623
/// use foundry_compilers::{artifacts::*, Project};
637624
///
@@ -647,7 +634,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
647634
/// Removes the _first_ contract with the given name from the set
648635
///
649636
/// # Examples
650-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
651637
/// ```no_run
652638
/// use foundry_compilers::{artifacts::*, Project};
653639
///
@@ -663,7 +649,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
663649
/// Removes the contract with matching path and name
664650
///
665651
/// # Examples
666-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
667652
/// ```no_run
668653
/// use foundry_compilers::{artifacts::*, Project};
669654
///
@@ -683,7 +668,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
683668
/// [Self::remove_first]
684669
///
685670
/// # Examples
686-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
687671
/// ```no_run
688672
/// use foundry_compilers::{artifacts::*, info::ContractInfo, Project};
689673
///
@@ -747,7 +731,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
747731
/// bytecode, runtime bytecode, and ABI.
748732
///
749733
/// # Examples
750-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
751734
/// ```no_run
752735
/// use foundry_compilers::{artifacts::*, Project};
753736
///
@@ -764,7 +747,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
764747
/// provide several helper methods
765748
///
766749
/// # Examples
767-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
768750
/// ```no_run
769751
/// use foundry_compilers::Project;
770752
///
@@ -792,7 +774,6 @@ impl<C: Compiler> AggregatedCompilerOutput<C> {
792774
/// # Examples
793775
///
794776
/// Make all sources and contracts relative to the project's root directory
795-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
796777
/// ```no_run
797778
/// use foundry_compilers::Project;
798779
///

crates/compilers/src/compile/output/sources.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ impl VersionedSourceFiles {
5656
/// Finds the _first_ source file with the given path.
5757
///
5858
/// # Examples
59-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
6059
/// ```no_run
6160
/// use foundry_compilers::{artifacts::*, Project};
6261
///
@@ -85,7 +84,6 @@ impl VersionedSourceFiles {
8584
/// Finds the _first_ source file with the given id
8685
///
8786
/// # Examples
88-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
8987
/// ```no_run
9088
/// use foundry_compilers::{artifacts::*, Project};
9189
///
@@ -109,7 +107,6 @@ impl VersionedSourceFiles {
109107
/// Removes the _first_ source_file with the given path from the set
110108
///
111109
/// # Examples
112-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
113110
/// ```no_run
114111
/// use foundry_compilers::{artifacts::*, Project};
115112
///
@@ -131,7 +128,6 @@ impl VersionedSourceFiles {
131128
/// Removes the _first_ source_file with the given id from the set
132129
///
133130
/// # Examples
134-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
135131
/// ```no_run
136132
/// use foundry_compilers::{artifacts::*, Project};
137133
///

crates/compilers/src/compile/project.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ impl<'a, T: ArtifactOutput, C: Compiler> ProjectCompiler<'a, T, C> {
171171
/// `Contract`s
172172
///
173173
/// # Examples
174-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
175174
/// ```no_run
176175
/// use foundry_compilers::Project;
177176
///

crates/compilers/src/compilers/multi.rs

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,25 @@ use std::{
3232
/// Compiler capable of compiling both Solidity and Vyper sources.
3333
#[derive(Clone, Debug)]
3434
pub struct MultiCompiler {
35-
pub solc: SolcCompiler,
35+
pub solc: Option<SolcCompiler>,
3636
pub vyper: Option<Vyper>,
3737
}
3838

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

44-
Self { solc: SolcCompiler::default(), vyper }
43+
#[cfg(feature = "svm-solc")]
44+
let solc = Some(SolcCompiler::AutoDetect);
45+
#[cfg(not(feature = "svm-solc"))]
46+
let solc = crate::solc::Solc::new("solc").map(SolcCompiler::Specific).ok();
47+
48+
Self { solc, vyper }
4549
}
4650
}
4751

4852
impl MultiCompiler {
49-
pub fn new(solc: SolcCompiler, vyper_path: Option<PathBuf>) -> Result<Self> {
53+
pub fn new(solc: Option<SolcCompiler>, vyper_path: Option<PathBuf>) -> Result<Self> {
5054
let vyper = vyper_path.map(Vyper::new).transpose()?;
5155
Ok(Self { solc, vyper })
5256
}
@@ -259,7 +263,11 @@ impl Compiler for MultiCompiler {
259263
fn compile(&self, input: &Self::Input) -> Result<CompilerOutput<Self::CompilationError>> {
260264
match input {
261265
MultiCompilerInput::Solc(input) => {
262-
self.solc.compile(input).map(|res| res.map_err(MultiCompilerError::Solc))
266+
if let Some(solc) = &self.solc {
267+
Compiler::compile(solc, input).map(|res| res.map_err(MultiCompilerError::Solc))
268+
} else {
269+
Err(SolcError::msg("solc compiler is not available"))
270+
}
263271
}
264272
MultiCompilerInput::Vyper(input) => {
265273
if let Some(vyper) = &self.vyper {
@@ -274,7 +282,9 @@ impl Compiler for MultiCompiler {
274282

275283
fn available_versions(&self, language: &Self::Language) -> Vec<CompilerVersion> {
276284
match language {
277-
MultiCompilerLanguage::Solc(language) => self.solc.available_versions(language),
285+
MultiCompilerLanguage::Solc(language) => {
286+
self.solc.as_ref().map(|s| s.available_versions(language)).unwrap_or_default()
287+
}
278288
MultiCompilerLanguage::Vyper(language) => {
279289
self.vyper.as_ref().map(|v| v.available_versions(language)).unwrap_or_default()
280290
}

crates/compilers/src/lib.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ impl Project {
110110
/// # Examples
111111
///
112112
/// Configure with [ConfigurableArtifacts] artifacts output and [MultiCompiler] compiler:
113-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
114113
/// ```no_run
115114
/// use foundry_compilers::Project;
116115
///
@@ -119,7 +118,6 @@ impl Project {
119118
/// ```
120119
///
121120
/// To configure any a project with any `ArtifactOutput` use either:
122-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
123121
/// ```no_run
124122
/// use foundry_compilers::Project;
125123
///
@@ -128,7 +126,6 @@ impl Project {
128126
/// ```
129127
///
130128
/// or use the builder directly:
131-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
132129
/// ```no_run
133130
/// use foundry_compilers::{multi::MultiCompiler, ConfigurableArtifacts, ProjectBuilder};
134131
///
@@ -249,7 +246,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
249246
/// Use this if you compile a project in a `build.rs` file.
250247
///
251248
/// # Examples
252-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
253249
/// ```no_run
254250
/// use foundry_compilers::{Project, ProjectPathsConfig};
255251
///
@@ -274,7 +270,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
274270
/// Convenience function to compile a single solidity file with the project's settings.
275271
///
276272
/// # Examples
277-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
278273
/// ```no_run
279274
/// use foundry_compilers::Project;
280275
///
@@ -292,7 +287,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
292287
/// Same as [`Self::compile()`] but with the given `files` as input.
293288
///
294289
/// # Examples
295-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
296290
/// ```no_run
297291
/// use foundry_compilers::Project;
298292
///
@@ -315,7 +309,6 @@ impl<T: ArtifactOutput, C: Compiler> Project<C, T> {
315309
/// If the cache file was the only file in the folder, this also removes the empty folder.
316310
///
317311
/// # Examples
318-
#[cfg_attr(not(feature = "svm-solc"), doc = "```ignore")]
319312
/// ```
320313
/// use foundry_compilers::Project;
321314
///

crates/compilers/tests/project.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3973,7 +3973,8 @@ fn test_can_compile_multi() {
39733973
solc: Default::default(),
39743974
};
39753975

3976-
let compiler = MultiCompiler { solc: SolcCompiler::default(), vyper: Some(VYPER.clone()) };
3976+
let compiler =
3977+
MultiCompiler { solc: Some(SolcCompiler::default()), vyper: Some(VYPER.clone()) };
39773978

39783979
let project = ProjectBuilder::<MultiCompiler>::new(Default::default())
39793980
.settings(settings)

0 commit comments

Comments
 (0)