@@ -8,15 +8,19 @@ use foundry_compilers::{
88} ;
99use foundry_config:: {
1010 cache:: { CachedChains , CachedEndpoints , StorageCachingConfig } ,
11+ filter:: GlobMatcher ,
1112 fs_permissions:: { FsAccessPermission , PathPermission } ,
12- Config , FsPermissions , FuzzConfig , InvariantConfig , SolcReq ,
13+ CompilationRestrictions , Config , FsPermissions , FuzzConfig , InvariantConfig , SettingsOverrides ,
14+ SolcReq ,
1315} ;
1416use foundry_evm:: opts:: EvmOpts ;
1517use foundry_test_utils:: {
1618 foundry_compilers:: artifacts:: { remappings:: Remapping , EvmVersion } ,
1719 util:: { pretty_err, OutputExt , TestCommand , OTHER_SOLC_VERSION } ,
1820} ;
1921use path_slash:: PathBufExt ;
22+ use semver:: VersionReq ;
23+ use serde_json:: Value ;
2024use similar_asserts:: assert_eq;
2125use std:: {
2226 fs,
@@ -1631,3 +1635,161 @@ contract GasSnapshotEmitTest is DSTest {
16311635 // Assert that snapshots were not emitted to disk.
16321636 assert!( !prj. root( ) . join( "snapshots/GasSnapshotEmitTest.json" ) . exists( ) ) ;
16331637} ) ;
1638+
1639+ // Tests compilation restrictions enables optimizer if optimizer runs set to a value higher than 0.
1640+ forgetest_init ! ( test_additional_compiler_profiles, |prj, cmd| {
1641+ prj. add_source(
1642+ "v1/Counter.sol" ,
1643+ r#"
1644+ contract Counter {
1645+ }
1646+ "# ,
1647+ )
1648+ . unwrap( ) ;
1649+
1650+ prj. add_source(
1651+ "v2/Counter.sol" ,
1652+ r#"
1653+ contract Counter {
1654+ }
1655+ "# ,
1656+ )
1657+ . unwrap( ) ;
1658+
1659+ prj. add_source(
1660+ "v3/Counter.sol" ,
1661+ r#"
1662+ contract Counter {
1663+ }
1664+ "# ,
1665+ )
1666+ . unwrap( ) ;
1667+
1668+ // Additional profiles are defined with optimizer runs but without explicitly enabling
1669+ // optimizer
1670+ //
1671+ // additional_compiler_profiles = [
1672+ // { name = "v1", optimizer_runs = 44444444, via_ir = true, evm_version = "cancun" },
1673+ // { name = "v2", optimizer_runs = 111, via_ir = true },
1674+ // { name = "v3", optimizer_runs = 800, evm_version = "istanbul", via_ir = false },
1675+ // ]
1676+ //
1677+ // compilation_restrictions = [
1678+ // # v1
1679+ // { paths = "src/v1/[!i]*.sol", version = "0.8.16", optimizer_runs = 44444444 },
1680+ // # v2
1681+ // { paths = "src/v2/{Counter}.sol", optimizer_runs = 111 },
1682+ // # v3
1683+ // { paths = "src/v3/*", optimizer_runs = 800 },
1684+ // ]
1685+ let v1_profile = SettingsOverrides {
1686+ name: "v1" . to_string( ) ,
1687+ via_ir: Some ( true ) ,
1688+ evm_version: Some ( EvmVersion :: Cancun ) ,
1689+ optimizer: None ,
1690+ optimizer_runs: Some ( 44444444 ) ,
1691+ bytecode_hash: None ,
1692+ } ;
1693+ let v1_restrictions = CompilationRestrictions {
1694+ paths: GlobMatcher :: from_str( "src/v1/[!i]*.sol" ) . unwrap( ) ,
1695+ version: Some ( VersionReq :: from_str( "0.8.16" ) . unwrap( ) ) ,
1696+ via_ir: None ,
1697+ bytecode_hash: None ,
1698+ min_optimizer_runs: None ,
1699+ optimizer_runs: Some ( 44444444 ) ,
1700+ max_optimizer_runs: None ,
1701+ min_evm_version: None ,
1702+ evm_version: None ,
1703+ max_evm_version: None ,
1704+ } ;
1705+ let v2_profile = SettingsOverrides {
1706+ name: "v2" . to_string( ) ,
1707+ via_ir: Some ( true ) ,
1708+ evm_version: None ,
1709+ optimizer: None ,
1710+ optimizer_runs: Some ( 111 ) ,
1711+ bytecode_hash: None ,
1712+ } ;
1713+ let v2_restrictions = CompilationRestrictions {
1714+ paths: GlobMatcher :: from_str( "src/v2/{Counter}.sol" ) . unwrap( ) ,
1715+ version: None ,
1716+ via_ir: None ,
1717+ bytecode_hash: None ,
1718+ min_optimizer_runs: None ,
1719+ optimizer_runs: Some ( 111 ) ,
1720+ max_optimizer_runs: None ,
1721+ min_evm_version: None ,
1722+ evm_version: None ,
1723+ max_evm_version: None ,
1724+ } ;
1725+ let v3_profile = SettingsOverrides {
1726+ name: "v3" . to_string( ) ,
1727+ via_ir: Some ( false ) ,
1728+ evm_version: Some ( EvmVersion :: Istanbul ) ,
1729+ optimizer: None ,
1730+ optimizer_runs: Some ( 800 ) ,
1731+ bytecode_hash: None ,
1732+ } ;
1733+ let v3_restrictions = CompilationRestrictions {
1734+ paths: GlobMatcher :: from_str( "src/v3/*" ) . unwrap( ) ,
1735+ version: None ,
1736+ via_ir: None ,
1737+ bytecode_hash: None ,
1738+ min_optimizer_runs: None ,
1739+ optimizer_runs: Some ( 800 ) ,
1740+ max_optimizer_runs: None ,
1741+ min_evm_version: None ,
1742+ evm_version: None ,
1743+ max_evm_version: None ,
1744+ } ;
1745+ let additional_compiler_profiles = vec![ v1_profile, v2_profile, v3_profile] ;
1746+ let compilation_restrictions = vec![ v1_restrictions, v2_restrictions, v3_restrictions] ;
1747+ prj. update_config( |config| {
1748+ config. additional_compiler_profiles = additional_compiler_profiles;
1749+ config. compilation_restrictions = compilation_restrictions;
1750+ } ) ;
1751+ // Should find and build all profiles satisfying settings restrictions.
1752+ cmd. forge_fuse( ) . args( [ "build" ] ) . assert_success( ) ;
1753+ prj. assert_artifacts_dir_exists( ) ;
1754+
1755+ let artifact_settings =
1756+ |artifact| -> ( Option <Value >, Option <Value >, Option <Value >, Option <Value >) {
1757+ let artifact: serde_json:: Value = serde_json:: from_reader(
1758+ fs:: File :: open( prj. artifacts( ) . join( artifact) ) . expect( "no artifact" ) ,
1759+ )
1760+ . expect( "invalid artifact" ) ;
1761+ let settings =
1762+ artifact. get( "metadata" ) . unwrap( ) . get( "settings" ) . unwrap( ) . as_object( ) . unwrap( ) ;
1763+ let optimizer = settings. get( "optimizer" ) . unwrap( ) ;
1764+ (
1765+ settings. get( "viaIR" ) . cloned( ) ,
1766+ settings. get( "evmVersion" ) . cloned( ) ,
1767+ optimizer. get( "enabled" ) . cloned( ) ,
1768+ optimizer. get( "runs" ) . cloned( ) ,
1769+ )
1770+ } ;
1771+
1772+ let ( via_ir, evm_version, enabled, runs) = artifact_settings( "Counter.sol/Counter.json" ) ;
1773+ assert_eq!( None , via_ir) ;
1774+ assert_eq!( "\" cancun\" " , evm_version. unwrap( ) . to_string( ) ) ;
1775+ assert_eq!( "false" , enabled. unwrap( ) . to_string( ) ) ;
1776+ assert_eq!( "200" , runs. unwrap( ) . to_string( ) ) ;
1777+
1778+ let ( via_ir, evm_version, enabled, runs) = artifact_settings( "v1/Counter.sol/Counter.json" ) ;
1779+ assert_eq!( "true" , via_ir. unwrap( ) . to_string( ) ) ;
1780+ assert_eq!( "\" cancun\" " , evm_version. unwrap( ) . to_string( ) ) ;
1781+ assert_eq!( "true" , enabled. unwrap( ) . to_string( ) ) ;
1782+ assert_eq!( "44444444" , runs. unwrap( ) . to_string( ) ) ;
1783+
1784+ let ( via_ir, evm_version, enabled, runs) = artifact_settings( "v2/Counter.sol/Counter.json" ) ;
1785+ assert_eq!( "true" , via_ir. unwrap( ) . to_string( ) ) ;
1786+ assert_eq!( "\" cancun\" " , evm_version. unwrap( ) . to_string( ) ) ;
1787+ assert_eq!( "true" , enabled. unwrap( ) . to_string( ) ) ;
1788+ assert_eq!( "111" , runs. unwrap( ) . to_string( ) ) ;
1789+
1790+ let ( via_ir, evm_version, enabled, runs) = artifact_settings( "v3/Counter.sol/Counter.json" ) ;
1791+ assert_eq!( None , via_ir) ;
1792+ assert_eq!( "\" istanbul\" " , evm_version. unwrap( ) . to_string( ) ) ;
1793+ assert_eq!( "true" , enabled. unwrap( ) . to_string( ) ) ;
1794+ assert_eq!( "800" , runs. unwrap( ) . to_string( ) ) ;
1795+ } ) ;
0 commit comments