3
3
"""
4
4
import logging
5
5
import os
6
+ import subprocess
6
7
from pathlib import Path
7
- from typing import TYPE_CHECKING , List
8
+ from typing import TYPE_CHECKING , List , Optional
9
+ import toml
8
10
9
- from crytic_compile .platform .abstract_platform import AbstractPlatform
11
+ from crytic_compile .platform .abstract_platform import AbstractPlatform , PlatformConfig
10
12
from crytic_compile .platform .types import Type
11
13
from crytic_compile .platform .hardhat import hardhat_like_parsing
12
14
from crytic_compile .utils .subprocess import run
@@ -24,7 +26,7 @@ class Foundry(AbstractPlatform):
24
26
"""
25
27
26
28
NAME = "Foundry"
27
- PROJECT_URL = "https://github.com/gakonst /foundry"
29
+ PROJECT_URL = "https://github.com/foundry-rs /foundry"
28
30
TYPE = Type .FOUNDRY
29
31
30
32
# pylint: disable=too-many-locals,too-many-statements,too-many-branches
@@ -49,12 +51,26 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
49
51
)
50
52
51
53
if not ignore_compile :
54
+ compilation_command = [
55
+ "forge" ,
56
+ "build" ,
57
+ "--build-info" ,
58
+ ]
59
+
60
+ compile_all = kwargs .get ("foundry_compile_all" , False )
61
+
62
+ if not compile_all :
63
+ foundry_config = self .config (str (crytic_compile .working_dir .absolute ()))
64
+ if foundry_config :
65
+ compilation_command += [
66
+ "--skip" ,
67
+ f"*/{ foundry_config .tests_path } /**" ,
68
+ f"*/{ foundry_config .scripts_path } /**" ,
69
+ "--force" ,
70
+ ]
71
+
52
72
run (
53
- [
54
- "forge" ,
55
- "build" ,
56
- "--build-info" ,
57
- ],
73
+ compilation_command ,
58
74
cwd = self ._target ,
59
75
)
60
76
@@ -98,6 +114,61 @@ def is_supported(target: str, **kwargs: str) -> bool:
98
114
99
115
return os .path .isfile (os .path .join (target , "foundry.toml" ))
100
116
117
+ @staticmethod
118
+ def config (working_dir : str ) -> Optional [PlatformConfig ]:
119
+ """Return configuration data that should be passed to solc, such as remappings.
120
+
121
+ Args:
122
+ working_dir (str): path to the working directory
123
+
124
+ Returns:
125
+ Optional[PlatformConfig]: Platform configuration data such as optimization, remappings...
126
+ """
127
+ result = PlatformConfig ()
128
+ result .remappings = (
129
+ subprocess .run (["forge" , "remappings" ], stdout = subprocess .PIPE , check = True )
130
+ .stdout .decode ("utf-8" )
131
+ .replace ("\n " , " " )
132
+ .strip ()
133
+ )
134
+ with open ("foundry.toml" , "r" , encoding = "utf-8" ) as f :
135
+ foundry_toml = toml .loads (f .read ())
136
+ default_profile = foundry_toml ["profile" ]["default" ]
137
+
138
+ if "solc_version" in default_profile :
139
+ result .solc_version = default_profile ["solc_version" ]
140
+ if "offline" in default_profile :
141
+ result .offline = default_profile ["offline" ]
142
+ if "optimizer" in default_profile :
143
+ result .optimizer = default_profile ["optimizer" ]
144
+ else :
145
+ # Default to true
146
+ result .optimizer = True
147
+ if "optimizer_runs" in default_profile :
148
+ result .optimizer_runs = default_profile ["optimizer_runs" ]
149
+ else :
150
+ # Default to 200
151
+ result .optimizer_runs = 200
152
+ if "via_ir" in default_profile :
153
+ result .via_ir = default_profile ["via_ir" ]
154
+ if "allow_paths" in default_profile :
155
+ result .allow_paths = default_profile ["allow_paths" ]
156
+ if "evm_version" in default_profile :
157
+ result .evm_version = default_profile ["evm_version" ]
158
+ else :
159
+ # Default to london
160
+ result .evm_version = "london"
161
+ if "src" in default_profile :
162
+ result .src_path = default_profile ["src" ]
163
+ if "test" in default_profile :
164
+ result .tests_path = default_profile ["test" ]
165
+ if "libs" in default_profile :
166
+ result .libs_path = default_profile ["libs" ]
167
+ if "script" in default_profile :
168
+ result .scripts_path = default_profile ["script" ]
169
+
170
+ return result
171
+
101
172
# pylint: disable=no-self-use
102
173
def is_dependency (self , path : str ) -> bool :
103
174
"""Check if the path is a dependency
0 commit comments