Skip to content

Commit 0b03f41

Browse files
committed
Merge branch 'master' into dev
2 parents 94a80d6 + 19b2f85 commit 0b03f41

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

crytic_compile/cryticparser/defaults.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
"buidler_cache_directory": "cache",
4141
"buidler_skip_directory_name_fix": False,
4242
"hardhat_ignore_compile": False,
43-
"hardhat_cache_directory": "cache",
44-
"hardhat_artifacts_directory": "artifacts",
43+
"hardhat_cache_directory": None,
44+
"hardhat_artifacts_directory": None,
4545
"foundry_ignore_compile": False,
4646
"foundry_out_directory": "out",
4747
"export_dir": "crytic-export",

crytic_compile/platform/hardhat.py

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import shutil
88
import subprocess
99
from pathlib import Path
10-
from typing import TYPE_CHECKING, List
10+
from typing import TYPE_CHECKING, Dict, List, Optional, Union
1111

1212
from crytic_compile.compiler.compiler import CompilerVersion
1313
from crytic_compile.platform.exceptions import InvalidCompilation
@@ -52,16 +52,20 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None:
5252
"ignore_compile", False
5353
)
5454

55-
build_directory = Path(
56-
self._target, kwargs.get("hardhat_artifacts_directory", "artifacts"), "build-info"
57-
)
58-
59-
hardhat_working_dir = kwargs.get("hardhat_working_dir", self._target)
60-
6155
base_cmd = ["hardhat"]
6256
if not kwargs.get("npx_disable", False):
6357
base_cmd = ["npx"] + base_cmd
6458

59+
detected_paths = self._get_hardhat_paths(base_cmd, kwargs)
60+
61+
build_directory = Path(
62+
self._target,
63+
detected_paths["artifacts"],
64+
"build-info",
65+
)
66+
67+
hardhat_working_dir = Path(self._target, detected_paths["root"])
68+
6569
if not hardhat_ignore_compile:
6670
cmd = base_cmd + ["compile", "--force"]
6771

@@ -217,3 +221,76 @@ def _guessed_tests(self) -> List[str]:
217221
List[str]: The guessed unit tests commands
218222
"""
219223
return ["hardhat test"]
224+
225+
def _get_hardhat_paths(
226+
self, base_cmd: List[str], args: Dict[str, str]
227+
) -> Dict[str, Union[Path, str]]:
228+
"""Obtain hardhat configuration paths, defaulting to the
229+
standard config if needed.
230+
231+
Args:
232+
base_cmd ([str]): hardhat command
233+
args (Dict[str, str]): crytic-compile options that may affect paths
234+
235+
Returns:
236+
Dict[str, str]: hardhat paths configuration
237+
"""
238+
target_path = Path(self._target)
239+
default_paths = {
240+
"root": target_path,
241+
"configFile": target_path.joinpath("hardhat.config.js"),
242+
"sources": target_path.joinpath("contracts"),
243+
"cache": target_path.joinpath("cache"),
244+
"artifacts": target_path.joinpath("artifacts"),
245+
"tests": target_path.joinpath("test"),
246+
}
247+
override_paths = {}
248+
249+
if args.get("hardhat_cache_directory", None):
250+
override_paths["cache"] = Path(target_path, args["hardhat_cache_directory"])
251+
252+
if args.get("hardhat_artifacts_directory", None):
253+
override_paths["artifacts"] = Path(target_path, args["hardhat_artifacts_directory"])
254+
255+
if args.get("hardhat_working_dir", None):
256+
override_paths["root"] = Path(target_path, args["hardhat_working_dir"])
257+
258+
print_paths = "console.log(JSON.stringify(config.paths))"
259+
config_str = self._run_hardhat_console(base_cmd, print_paths)
260+
261+
try:
262+
paths = json.loads(config_str or "{}")
263+
return {**default_paths, **paths, **override_paths}
264+
except ValueError as e:
265+
LOGGER.info("Problem deserializing hardhat configuration: %s", e)
266+
return {**default_paths, **override_paths}
267+
268+
def _run_hardhat_console(self, base_cmd: List[str], command: str) -> Optional[str]:
269+
"""Run a JS command in the hardhat console
270+
271+
Args:
272+
base_cmd ([str]): hardhat command
273+
command (str): console command to run
274+
275+
Returns:
276+
Optional[str]: command output if execution succeeds
277+
"""
278+
with subprocess.Popen(
279+
base_cmd + ["console", "--no-compile"],
280+
stdin=subprocess.PIPE,
281+
stdout=subprocess.PIPE,
282+
stderr=subprocess.PIPE,
283+
cwd=self._target,
284+
executable=shutil.which(base_cmd[0]),
285+
) as process:
286+
stdout_bytes, stderr_bytes = process.communicate(command.encode("utf-8"))
287+
stdout, stderr = (
288+
stdout_bytes.decode(),
289+
stderr_bytes.decode(),
290+
)
291+
292+
if stderr:
293+
LOGGER.info("Problem executing hardhat: %s", stderr)
294+
return None
295+
296+
return stdout

0 commit comments

Comments
 (0)