Skip to content

Commit

Permalink
feat(solc): support rustup-like version specifiers (+x.y.z) (#125)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaniPopes authored Apr 9, 2024
1 parent ed8ac4a commit 7338c05
Showing 1 changed file with 48 additions and 8 deletions.
56 changes: 48 additions & 8 deletions crates/svm-rs/src/bin/solc/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Simple Solc wrapper that delegates everything to the global [`svm`] version.
//! Simple Solc wrapper that delegates everything to a specified or the global [`svm`] Solc version.

#![doc(
html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg",
Expand All @@ -8,17 +8,57 @@
#![deny(unused_must_use, rust_2018_idioms)]
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]

use anyhow::Context;
use std::process::{Command, Stdio};

fn main() -> anyhow::Result<()> {
let version = svm::get_global_version()?.ok_or(svm::SvmError::GlobalVersionNotSet)?;
let program = svm::version_binary(&version.to_string());
let status = Command::new(program)
.args(std::env::args_os().skip(1))
fn main() {
let code = match main_() {
Ok(code) => code,
Err(err) => {
eprintln!("svm: error: {err:?}");
1
}
};
std::process::exit(code);
}

fn main_() -> anyhow::Result<i32> {
let mut args = std::env::args_os().skip(1).peekable();
let version = 'v: {
// Try to parse the first argument as a version specifier `+x.y.z`.
if let Some(arg) = args.peek() {
if let Some(arg) = arg.to_str() {
if let Some(stripped) = arg.strip_prefix('+') {
let version = stripped
.parse::<semver::Version>()
.context("failed to parse version specifier")?;
if !version.build.is_empty() || !version.pre.is_empty() {
anyhow::bail!(
"version specifier must not have pre-release or build metadata"
);
}
args.next();
break 'v version;
}
}
}
// Fallback to the global version if one is not specified.
svm::get_global_version()?.ok_or(svm::SvmError::GlobalVersionNotSet)?
};

let bin = svm::version_binary(&version.to_string());
if !bin.exists() {
anyhow::bail!(
"Solc version {version} is not installed or does not exist; looked at {}",
bin.display()
);
}

let status = Command::new(bin)
.args(args)
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()?;
let code = status.code().unwrap_or(-1);
std::process::exit(code);
Ok(status.code().unwrap_or(-1))
}

0 comments on commit 7338c05

Please sign in to comment.