Skip to content

Commit

Permalink
feat(cheatcodes): add vm.getFoundryVersion() (#8530)
Browse files Browse the repository at this point in the history
* feat: implement `vm.getFoundryVersion`

* test: implement dummy test for `vm.getFoundryVersion`

* chore: modify implementation to return cargo version and build timestamp

* test: modify test

* docs: add sample output

* chore: cargo cheats

* fix: failing test and vergen setup

* test: update getFoundryVersion

* docs: mention built timestamps issue

---------

Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
leovct and mattsse authored Jul 27, 2024
1 parent df5f45c commit a416c10
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 9 additions & 1 deletion crates/cheatcodes/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ exclude.workspace = true
[lints]
workspace = true

[build-dependencies]
vergen = { workspace = true, default-features = false, features = [
"build",
"git",
"gitcl",
] }

[dependencies]
foundry-cheatcodes-spec.workspace = true
foundry-common.workspace = true
Expand Down Expand Up @@ -54,6 +61,7 @@ semver.workspace = true
rustc-hash.workspace = true
dialoguer = "0.11.0"
rand = "0.8"
chrono.workspace = true

[dev-dependencies]
proptest.workspace = true
proptest.workspace = true
20 changes: 20 additions & 0 deletions crates/cheatcodes/assets/cheatcodes.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/cheatcodes/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
fn main() {
vergen::EmitBuilder::builder().build_timestamp().git_sha(true).emit().unwrap();
}
9 changes: 9 additions & 0 deletions crates/cheatcodes/spec/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,15 @@ interface Vm {
#[cheatcode(group = Testing, safety = Safe)]
function breakpoint(string calldata char, bool value) external;

/// Returns the Foundry version.
/// Format: <cargo_version>+<git_sha>+<build_timestamp>
/// Sample output: 0.2.0+faa94c384+202407110019
/// Note: Build timestamps may vary slightly across platforms due to separate CI jobs.
/// For reliable version comparisons, use YYYYMMDD0000 format (e.g., >= 202407110000)
/// to compare timestamps while ignoring minor time differences.
#[cheatcode(group = Testing, safety = Safe)]
function getFoundryVersion() external view returns (string memory version);

/// Returns the RPC url for the given alias.
#[cheatcode(group = Testing, safety = Safe)]
function rpcUrl(string calldata rpcAlias) external view returns (string memory json);
Expand Down
17 changes: 17 additions & 0 deletions crates/cheatcodes/src/test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
//! Implementations of [`Testing`](spec::Group::Testing) cheatcodes.
use chrono::DateTime;
use std::env;

use crate::{Cheatcode, Cheatcodes, CheatsCtxt, DatabaseExt, Error, Result, Vm::*};
use alloy_primitives::Address;
use alloy_sol_types::SolValue;
Expand Down Expand Up @@ -33,6 +36,20 @@ impl Cheatcode for breakpoint_1Call {
}
}

impl Cheatcode for getFoundryVersionCall {
fn apply(&self, _state: &mut Cheatcodes) -> Result {
let Self {} = self;
let cargo_version = env!("CARGO_PKG_VERSION");
let git_sha = env!("VERGEN_GIT_SHA");
let build_timestamp = DateTime::parse_from_rfc3339(env!("VERGEN_BUILD_TIMESTAMP"))
.expect("Invalid build timestamp format")
.format("%Y%m%d%H%M")
.to_string();
let foundry_version = format!("{cargo_version}+{git_sha}+{build_timestamp}");
Ok(foundry_version.abi_encode())
}
}

impl Cheatcode for rpcUrlCall {
fn apply(&self, state: &mut Cheatcodes) -> Result {
let Self { rpcAlias } = self;
Expand Down
1 change: 1 addition & 0 deletions testdata/cheats/Vm.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions testdata/default/cheats/GetFoundryVersion.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
pragma solidity 0.8.18;

import "ds-test/test.sol";
import "cheats/Vm.sol";

contract GetFoundryVersionTest is DSTest {
Vm constant vm = Vm(HEVM_ADDRESS);

function testGetFoundryVersion() public view {
string memory fullVersionString = vm.getFoundryVersion();

string[] memory versionComponents = vm.split(fullVersionString, "+");
require(versionComponents.length == 3, "Invalid version format");

string memory semanticVersion = versionComponents[0];
require(bytes(semanticVersion).length > 0, "Semantic version is empty");

string memory commitHash = versionComponents[1];
require(bytes(commitHash).length > 0, "Commit hash is empty");

uint256 buildUnixTimestamp = vm.parseUint(versionComponents[2]);
uint256 minimumAcceptableTimestamp = 202406111234;
require(buildUnixTimestamp >= minimumAcceptableTimestamp, "Build timestamp is too old");
}
}

0 comments on commit a416c10

Please sign in to comment.