Skip to content

Commit 4f1d461

Browse files
authored
Return correct error instead of panicking if requested resolc version doesn't exist (#23)
* fix foundry-rs#126
1 parent 069136c commit 4f1d461

1 file changed

Lines changed: 76 additions & 17 deletions

File tree

crates/compilers/src/compilers/resolc/compiler.rs

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -142,14 +142,31 @@ impl Resolc {
142142
let version_manager = rvm::VersionManager::new(false)
143143
.map_err(|e| SolcError::Message(e.to_string()))?;
144144

145-
let versions: Vec<Binary> = version_manager
146-
.list_available(_solc_version.clone())
147-
.map_err(|e| SolcError::Message(e.to_string()))?
148-
.into_iter()
149-
.filter(|x| _resolc_version.is_none_or(|version| version == x.version()))
150-
.collect();
151-
152-
let binary = versions.into_iter().next_back().expect("Can't be empty");
145+
let binary = {
146+
if let Some(resolc_version) = _resolc_version {
147+
if version_manager.is_installed(resolc_version) {
148+
version_manager
149+
.get(resolc_version, _solc_version.clone())
150+
.map_err(|e| SolcError::Message(e.to_string()))?
151+
} else {
152+
version_manager
153+
.get_or_install(resolc_version, _solc_version.clone())
154+
.map_err(|e| SolcError::Message(e.to_string()))?
155+
}
156+
} else {
157+
let versions: Vec<Binary> = version_manager
158+
.list_available(_solc_version.clone())
159+
.map_err(|e| SolcError::Message(e.to_string()))?
160+
.into_iter()
161+
.collect();
162+
163+
let Some(binary) = versions.into_iter().next_back() else {
164+
let message = "No `resolc` versions available.".to_string();
165+
return Err(SolcError::Message(message));
166+
};
167+
binary
168+
}
169+
};
153170

154171
let binary_info = match binary {
155172
Binary::Remote(binary_info) => binary_info,
@@ -223,15 +240,21 @@ impl Resolc {
223240
{
224241
let version_manager =
225242
rvm::VersionManager::new(true).map_err(|e| SolcError::Message(e.to_string()))?;
243+
let binary = if let Some(resolc_version) = _resolc_version {
244+
if version_manager.is_installed(resolc_version) {
245+
version_manager.get(resolc_version, _solc_version.clone()).ok()
246+
} else {
247+
None
248+
}
249+
} else {
250+
let versions: Vec<Binary> = version_manager
251+
.list_available(_solc_version.clone())
252+
.map_err(|e| SolcError::Message(e.to_string()))?
253+
.into_iter()
254+
.collect();
226255

227-
let versions: Vec<Binary> = version_manager
228-
.list_available(_solc_version)
229-
.map_err(|e| SolcError::Message(e.to_string()))?
230-
.into_iter()
231-
.filter(|x| _resolc_version.is_none_or(|version| version == x.version()))
232-
.collect();
233-
234-
let binary = versions.into_iter().next_back();
256+
versions.into_iter().next_back()
257+
};
235258

236259
if let Some(binary) = binary {
237260
match binary {
@@ -346,7 +369,9 @@ impl Resolc {
346369
cmd.arg(&solc.solc);
347370
cmd.arg("--standard-json");
348371
let mut child = cmd.spawn().map_err(map_io_err(&self.resolc))?;
349-
let mut stdin = io::BufWriter::new(child.stdin.take().unwrap());
372+
let mut stdin = io::BufWriter::new(
373+
child.stdin.take().ok_or(SolcError::msg("`resolc` `stdin` closed"))?,
374+
);
350375
serde_json::to_writer(&mut stdin, &input)?;
351376
stdin.flush().map_err(map_io_err(&self.resolc))?;
352377
child
@@ -414,3 +439,37 @@ fn compile_output(output: Output) -> Result<Vec<u8>> {
414439
Err(SolcError::solc_output(&output))
415440
}
416441
}
442+
443+
#[cfg(test)]
444+
#[cfg(feature = "full")]
445+
mod test {
446+
use super::Resolc;
447+
use crate::solc::Solc;
448+
449+
#[test]
450+
fn not_existing_version() {
451+
let result = Resolc::install(
452+
semver::Version::parse("0.1.0-dev.33").ok().as_ref(),
453+
crate::solc::SolcCompiler::AutoDetect,
454+
)
455+
.expect_err("should fail");
456+
assert_eq!(result.to_string(), "Unknown version of Resolc v0.1.0-dev.33.")
457+
}
458+
459+
fn solc_with_version() -> Solc {
460+
Solc::blocking_install(&semver::Version::parse("0.4.14").unwrap()).unwrap()
461+
}
462+
463+
#[test]
464+
fn not_existing_solc() {
465+
let result = Resolc::install(
466+
semver::Version::parse("0.1.0-dev.13").ok().as_ref(),
467+
crate::solc::SolcCompiler::Specific(solc_with_version()),
468+
)
469+
.expect_err("should fail");
470+
assert_eq!(
471+
result.to_string(),
472+
"Unsupported version of `solc` - v0.4.14 for Resolc v0.1.0-dev.13. Only versions \">=0.8.0, <=0.8.29\" is supported by this version of Resolc"
473+
)
474+
}
475+
}

0 commit comments

Comments
 (0)