svm/
lib.rs

1#![doc = include_str!("../README.md")]
2#![doc(
3    html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg",
4    html_favicon_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/favicon.ico"
5)]
6#![warn(rustdoc::all)]
7#![cfg_attr(
8    not(any(test, feature = "cli", feature = "solc")),
9    warn(unused_crate_dependencies)
10)]
11#![deny(unused_must_use, rust_2018_idioms)]
12#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
13
14use semver::Version;
15use std::fs;
16
17mod error;
18pub use error::SvmError;
19
20mod install;
21#[cfg(feature = "blocking")]
22pub use install::blocking_install;
23pub use install::install;
24
25mod paths;
26pub use paths::{data_dir, global_version_path, setup_data_dir, version_binary, version_path};
27
28mod platform;
29pub use platform::{platform, Platform};
30
31mod releases;
32pub use releases::{all_releases, BuildInfo, Releases};
33
34#[cfg(feature = "blocking")]
35pub use releases::blocking_all_releases;
36
37#[cfg(feature = "cli")]
38#[doc(hidden)]
39pub const VERSION_MESSAGE: &str = concat!(
40    env!("CARGO_PKG_VERSION"),
41    " (",
42    env!("VERGEN_GIT_SHA"),
43    " ",
44    env!("VERGEN_BUILD_DATE"),
45    ")"
46);
47
48/// Reads the currently set global version for Solc. Returns None if none has yet been set.
49pub fn get_global_version() -> Result<Option<Version>, SvmError> {
50    let v = fs::read_to_string(global_version_path())?;
51    Ok(Version::parse(v.trim_end_matches('\n')).ok())
52}
53
54/// Sets the provided version as the global version for Solc.
55pub fn set_global_version(version: &Version) -> Result<(), SvmError> {
56    fs::write(global_version_path(), version.to_string()).map_err(Into::into)
57}
58
59/// Unset the global version. This should be done if all versions are removed.
60pub fn unset_global_version() -> Result<(), SvmError> {
61    fs::write(global_version_path(), "").map_err(Into::into)
62}
63
64/// Reads the list of Solc versions that have been installed in the machine.
65/// The version list is sorted in ascending order.
66pub fn installed_versions() -> Result<Vec<Version>, SvmError> {
67    let mut versions = vec![];
68    for v in fs::read_dir(data_dir())? {
69        let v = v?;
70        let path = v.path();
71        let Some(file_name) = path.file_name() else {
72            continue;
73        };
74        let Some(file_name) = file_name.to_str() else {
75            continue;
76        };
77        if file_name == ".global-version" {
78            continue;
79        }
80        versions.push(Version::parse(file_name)?);
81    }
82    versions.sort();
83    Ok(versions)
84}
85
86/// Blocking version of [`all_versions`]
87#[cfg(feature = "blocking")]
88pub fn blocking_all_versions() -> Result<Vec<Version>, SvmError> {
89    Ok(releases::blocking_all_releases(platform::platform())?.into_versions())
90}
91
92/// Fetches the list of all the available versions of Solc. The list is platform dependent, so
93/// different versions can be found for macosx vs linux.
94pub async fn all_versions() -> Result<Vec<Version>, SvmError> {
95    Ok(releases::all_releases(platform::platform())
96        .await?
97        .into_versions())
98}
99
100/// Removes the provided version of Solc from the machine.
101pub fn remove_version(version: &Version) -> Result<(), SvmError> {
102    fs::remove_dir_all(version_path(version.to_string().as_str())).map_err(Into::into)
103}
104
105fn setup_version(version: &str) -> Result<(), SvmError> {
106    let v = version_path(version);
107    if !v.exists() {
108        fs::create_dir_all(v)?;
109    }
110    Ok(())
111}