foundry_cheatcodes/version.rs
1use crate::{Cheatcode, Cheatcodes, Result, Vm::*};
2use alloy_sol_types::SolValue;
3use foundry_common::version::SEMVER_VERSION;
4use foundry_evm_core::evm::FoundryEvmNetwork;
5use semver::Version;
6use std::cmp::Ordering;
7
8impl Cheatcode for foundryVersionCmpCall {
9 fn apply<FEN: FoundryEvmNetwork>(&self, _state: &mut Cheatcodes<FEN>) -> Result {
10 let Self { version } = self;
11 foundry_version_cmp(version).map(|cmp| (cmp as i8).abi_encode())
12 }
13}
14
15impl Cheatcode for foundryVersionAtLeastCall {
16 fn apply<FEN: FoundryEvmNetwork>(&self, _state: &mut Cheatcodes<FEN>) -> Result {
17 let Self { version } = self;
18 foundry_version_cmp(version).map(|cmp| cmp.is_ge().abi_encode())
19 }
20}
21
22fn foundry_version_cmp(version: &str) -> Result<Ordering> {
23 version_cmp(SEMVER_VERSION.split('-').next().unwrap(), version)
24}
25
26fn version_cmp(version_a: &str, version_b: &str) -> Result<Ordering> {
27 let version_a = parse_version(version_a)?;
28 let version_b = parse_version(version_b)?;
29 Ok(version_a.cmp(&version_b))
30}
31
32fn parse_version(version: &str) -> Result<Version> {
33 let version =
34 Version::parse(version).map_err(|e| fmt_err!("invalid version `{version}`: {e}"))?;
35 if !version.pre.is_empty() {
36 return Err(fmt_err!(
37 "invalid version `{version}`: pre-release versions are not supported"
38 ));
39 }
40 if !version.build.is_empty() {
41 return Err(fmt_err!("invalid version `{version}`: build metadata is not supported"));
42 }
43 Ok(version)
44}