Skip to content

Commit 97e2ebb

Browse files
authored
chore: version cmp cheatcodes clean up (foundry-rs#9914)
1 parent 7e8c6e9 commit 97e2ebb

File tree

3 files changed

+36
-40
lines changed

3 files changed

+36
-40
lines changed

crates/cheatcodes/assets/cheatcodes.json

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/cheatcodes/spec/src/vm.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -1677,21 +1677,27 @@ interface Vm {
16771677
string calldata error
16781678
) external pure;
16791679

1680-
/// Returns true if the current Foundry version is at least the given version.
1681-
/// Version string can be in the format `major.minor.patch`.
1680+
/// Returns true if the current Foundry version is greater than or equal to the given version.
1681+
/// The given version string must be in the format `major.minor.patch`.
1682+
///
1683+
/// This is equivalent to `foundryVersionCmp(version) >= 0`.
16821684
#[cheatcode(group = Testing, safety = Safe)]
16831685
function foundryVersionAtLeast(string calldata version) external view returns (bool);
16841686

16851687
/// Compares the current Foundry version with the given version string.
1686-
/// Version string can be in the format `major.minor.patch`.
1688+
/// The given version string must be in the format `major.minor.patch`.
1689+
///
16871690
/// Returns:
1688-
/// -1 if current version is less than the given version
1689-
/// 0 if current version equals the given version
1690-
/// 1 if current version is greater than the given version
1691+
/// -1 if current Foundry version is less than the given version
1692+
/// 0 if current Foundry version equals the given version
1693+
/// 1 if current Foundry version is greater than the given version
1694+
///
1695+
/// This result can then be used with a comparison operator against `0`.
1696+
/// For example, to check if the current Foundry version is greater than or equal to `1.0.0`:
1697+
/// `if (foundryVersionCmp("1.0.0") >= 0) { ... }`
16911698
#[cheatcode(group = Testing, safety = Safe)]
16921699
function foundryVersionCmp(string calldata version) external view returns (int256);
16931700

1694-
16951701
// ======== OS and Filesystem ========
16961702

16971703
// -------- Metadata --------

crates/cheatcodes/src/version.rs

+21-31
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,35 @@ use std::cmp::Ordering;
77
impl Cheatcode for foundryVersionCmpCall {
88
fn apply(&self, _state: &mut Cheatcodes) -> Result {
99
let Self { version } = self;
10-
11-
if version.contains("+") || version.contains("-") {
12-
return Err(fmt_err!("Version must be in only major.minor.patch format"));
13-
}
14-
15-
let parsed_version = Version::parse(version)
16-
.map_err(|e| fmt_err!("Invalid semver format '{}': {}", version, e))?;
17-
let current_semver = Version::parse(SEMVER_VERSION)
18-
.map_err(|_| fmt_err!("Invalid current version format"))?;
19-
20-
let current_version =
21-
Version::new(current_semver.major, current_semver.minor, current_semver.patch);
22-
// Note: returns -1 if current < provided, 0 if equal, 1 if current > provided.
23-
let cmp_result = match current_version.cmp(&parsed_version) {
24-
Ordering::Less => -1i32,
25-
Ordering::Equal => 0i32,
26-
Ordering::Greater => 1i32,
27-
};
28-
Ok(cmp_result.abi_encode())
10+
foundry_version_cmp(version).map(|cmp| (cmp as i8).abi_encode())
2911
}
3012
}
3113

3214
impl Cheatcode for foundryVersionAtLeastCall {
3315
fn apply(&self, _state: &mut Cheatcodes) -> Result {
3416
let Self { version } = self;
17+
foundry_version_cmp(version).map(|cmp| cmp.is_ge().abi_encode())
18+
}
19+
}
3520

36-
if version.contains("+") || version.contains("-") {
37-
return Err(fmt_err!("Version must be in only major.minor.patch format"));
38-
}
39-
40-
let parsed_version =
41-
Version::parse(version).map_err(|_| fmt_err!("Invalid version format"))?;
42-
let current_semver = Version::parse(SEMVER_VERSION)
43-
.map_err(|_| fmt_err!("Invalid current version format"))?;
21+
fn foundry_version_cmp(version: &str) -> Result<Ordering> {
22+
version_cmp(SEMVER_VERSION.split('-').next().unwrap(), version)
23+
}
4424

45-
let current_version =
46-
Version::new(current_semver.major, current_semver.minor, current_semver.patch);
25+
fn version_cmp(version_a: &str, version_b: &str) -> Result<Ordering> {
26+
let version_a = parse_version(version_a)?;
27+
let version_b = parse_version(version_b)?;
28+
Ok(version_a.cmp(&version_b))
29+
}
4730

48-
let at_least = current_version.cmp(&parsed_version) != Ordering::Less;
49-
Ok(at_least.abi_encode())
31+
fn parse_version(version: &str) -> Result<Version> {
32+
let version =
33+
Version::parse(version).map_err(|e| fmt_err!("invalid version `{version}`: {e}"))?;
34+
if !version.pre.is_empty() {
35+
return Err(fmt_err!("invalid version `{version}`: pre-release versions are not supported"));
36+
}
37+
if !version.build.is_empty() {
38+
return Err(fmt_err!("invalid version `{version}`: build metadata is not supported"));
5039
}
40+
Ok(version)
5141
}

0 commit comments

Comments
 (0)