From 826758e2cceaa5350181ea76c0e79bb0a7ab3fd5 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Mon, 6 Nov 2023 22:31:45 -0600 Subject: [PATCH 1/5] fix: use target to get config, drop toml for json --- crytic_compile/platform/foundry.py | 104 ++++++++++++++--------------- setup.py | 2 +- 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/crytic_compile/platform/foundry.py b/crytic_compile/platform/foundry.py index 47c3a890..b4424770 100755 --- a/crytic_compile/platform/foundry.py +++ b/crytic_compile/platform/foundry.py @@ -7,7 +7,7 @@ from pathlib import Path from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar -import toml +import json from crytic_compile.platform.abstract_platform import AbstractPlatform, PlatformConfig from crytic_compile.platform.types import Type @@ -63,7 +63,7 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: compile_all = kwargs.get("foundry_compile_all", False) if not compile_all: - foundry_config = self.config(str(crytic_compile.working_dir.absolute())) + foundry_config = self.config(self._target) if foundry_config: compilation_command += [ "--skip", @@ -118,68 +118,62 @@ def is_supported(target: str, **kwargs: str) -> bool: return os.path.isfile(os.path.join(target, "foundry.toml")) @staticmethod - def config(working_dir: str) -> Optional[PlatformConfig]: + def config(target: str) -> Optional[PlatformConfig]: """Return configuration data that should be passed to solc, such as remappings. Args: - working_dir (str): path to the working directory + target (str): path to the target Returns: Optional[PlatformConfig]: Platform configuration data such as optimization, remappings... """ result = PlatformConfig() - result.remappings = ( - subprocess.run(["forge", "remappings"], stdout=subprocess.PIPE, check=True) - .stdout.decode("utf-8") - .replace("\n", " ") - .strip() + LOGGER.info("'forge config --json' running") + json_config = json.loads( + subprocess.run(["forge", "config", "--json"], stdout=subprocess.PIPE, check=True).stdout ) - with open("foundry.toml", "r", encoding="utf-8") as f: - foundry_toml = toml.loads(f.read()) - default_profile = foundry_toml["profile"]["default"] - - def lookup_by_keys(keys: List[str], dictionary: Dict[str, T]) -> Optional[T]: - for key in keys: - if key in dictionary: - return dictionary[key] - return None - - # Foundry supports snake and kebab case. - result.solc_version = lookup_by_keys( - ["solc", "solc_version", "solc-version"], default_profile - ) - via_ir = lookup_by_keys(["via_ir", "via-ir"], default_profile) - if via_ir: - result.via_ir = via_ir - result.allow_paths = lookup_by_keys(["allow_paths", "allow-paths"], default_profile) - - if "offline" in default_profile: - result.offline = default_profile["offline"] - if "optimizer" in default_profile: - result.optimizer = default_profile["optimizer"] - else: - # Default to true - result.optimizer = True - optimizer_runs = lookup_by_keys(["optimizer_runs", "optimizer-runs"], default_profile) - if optimizer_runs is None: - # Default to 200 - result.optimizer_runs = 200 - else: - result.optimizer_runs = optimizer_runs - evm_version = lookup_by_keys(["evm_version", "evm-version"], default_profile) - if evm_version is None: - result.evm_version = evm_version - else: - # Default to london - result.evm_version = "london" - if "src" in default_profile: - result.src_path = default_profile["src"] - if "test" in default_profile: - result.tests_path = default_profile["test"] - if "libs" in default_profile: - result.libs_path = default_profile["libs"] - if "script" in default_profile: - result.scripts_path = default_profile["script"] + result.remappings = json_config["remappings"] + + def lookup_by_keys(keys: List[str], dictionary: Dict[str, T]) -> Optional[T]: + for key in keys: + if key in dictionary: + return dictionary[key] + return None + + # Foundry supports snake and kebab case. + result.solc_version = lookup_by_keys(["solc", "solc_version", "solc-version"], json_config) + via_ir = lookup_by_keys(["via_ir", "via-ir"], json_config) + if via_ir: + result.via_ir = via_ir + result.allow_paths = lookup_by_keys(["allow_paths", "allow-paths"], json_config) + + if "offline" in json_config: + result.offline = json_config["offline"] + if "optimizer" in json_config: + result.optimizer = json_config["optimizer"] + else: + # Default to true + result.optimizer = True + optimizer_runs = lookup_by_keys(["optimizer_runs", "optimizer-runs"], json_config) + if optimizer_runs is None: + # Default to 200 + result.optimizer_runs = 200 + else: + result.optimizer_runs = optimizer_runs + evm_version = lookup_by_keys(["evm_version", "evm-version"], json_config) + if evm_version is None: + result.evm_version = evm_version + else: + # Default to london + result.evm_version = "london" + if "src" in json_config: + result.src_path = json_config["src"] + if "test" in json_config: + result.tests_path = json_config["test"] + if "libs" in json_config: + result.libs_path = json_config["libs"] + if "script" in json_config: + result.scripts_path = json_config["script"] return result diff --git a/setup.py b/setup.py index fe021686..e96d7533 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ version="0.3.4", packages=find_packages(), python_requires=">=3.8", - install_requires=["pycryptodome>=3.4.6", "cbor2", "solc-select>=v1.0.4", "toml>=0.10.2"], + install_requires=["pycryptodome>=3.4.6", "cbor2", "solc-select>=v1.0.4"], extras_require={ "test": [ "pytest", From 066bd1c05c3ef906da99953a8909e703cd32dfbc Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Wed, 10 Jan 2024 22:19:33 -0600 Subject: [PATCH 2/5] remove snakecase and use get() --- crytic_compile/platform/foundry.py | 58 +++++++++--------------------- 1 file changed, 16 insertions(+), 42 deletions(-) diff --git a/crytic_compile/platform/foundry.py b/crytic_compile/platform/foundry.py index b4424770..849ce22c 100755 --- a/crytic_compile/platform/foundry.py +++ b/crytic_compile/platform/foundry.py @@ -132,48 +132,22 @@ def config(target: str) -> Optional[PlatformConfig]: json_config = json.loads( subprocess.run(["forge", "config", "--json"], stdout=subprocess.PIPE, check=True).stdout ) - result.remappings = json_config["remappings"] - - def lookup_by_keys(keys: List[str], dictionary: Dict[str, T]) -> Optional[T]: - for key in keys: - if key in dictionary: - return dictionary[key] - return None - - # Foundry supports snake and kebab case. - result.solc_version = lookup_by_keys(["solc", "solc_version", "solc-version"], json_config) - via_ir = lookup_by_keys(["via_ir", "via-ir"], json_config) - if via_ir: - result.via_ir = via_ir - result.allow_paths = lookup_by_keys(["allow_paths", "allow-paths"], json_config) - - if "offline" in json_config: - result.offline = json_config["offline"] - if "optimizer" in json_config: - result.optimizer = json_config["optimizer"] - else: - # Default to true - result.optimizer = True - optimizer_runs = lookup_by_keys(["optimizer_runs", "optimizer-runs"], json_config) - if optimizer_runs is None: - # Default to 200 - result.optimizer_runs = 200 - else: - result.optimizer_runs = optimizer_runs - evm_version = lookup_by_keys(["evm_version", "evm-version"], json_config) - if evm_version is None: - result.evm_version = evm_version - else: - # Default to london - result.evm_version = "london" - if "src" in json_config: - result.src_path = json_config["src"] - if "test" in json_config: - result.tests_path = json_config["test"] - if "libs" in json_config: - result.libs_path = json_config["libs"] - if "script" in json_config: - result.scripts_path = json_config["script"] + + # Solc configurations + result.solc_version = json_config.get("solc") + result.via_ir = json_config.get("via_ir") + result.allow_paths = json_config.get("allow_paths") + result.offline = json_config.get("offline") + result.evm_version = json_config.get("evm_version") + result.optimizer = json_config.get("optimizer") + result.optimizer_runs = json_config.get("optimizer_runs") + result.remappings = json_config.get("remappings") + + # Foundry project configurations + result.src_path = json_config.get("src") + result.tests_path = json_config.get("test") + result.libs_path = json_config.get("libs") + result.scripts_path = json_config.get("script") return result From e55843f355e838aea78413255346cb60db97a27c Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 11 Jan 2024 11:59:03 -0600 Subject: [PATCH 3/5] lint --- crytic_compile/platform/foundry.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crytic_compile/platform/foundry.py b/crytic_compile/platform/foundry.py index 849ce22c..8d54ffc0 100755 --- a/crytic_compile/platform/foundry.py +++ b/crytic_compile/platform/foundry.py @@ -118,11 +118,11 @@ def is_supported(target: str, **kwargs: str) -> bool: return os.path.isfile(os.path.join(target, "foundry.toml")) @staticmethod - def config(target: str) -> Optional[PlatformConfig]: + def config(working_dir: str) -> Optional[PlatformConfig]: """Return configuration data that should be passed to solc, such as remappings. Args: - target (str): path to the target + working_dir (str): path to the working_dir Returns: Optional[PlatformConfig]: Platform configuration data such as optimization, remappings... @@ -130,7 +130,9 @@ def config(target: str) -> Optional[PlatformConfig]: result = PlatformConfig() LOGGER.info("'forge config --json' running") json_config = json.loads( - subprocess.run(["forge", "config", "--json"], stdout=subprocess.PIPE, check=True).stdout + subprocess.run( + ["forge", "config", "--json"], cwd=working_dir, stdout=subprocess.PIPE, check=True + ).stdout ) # Solc configurations From 289a35881faf1b1a1df1cf81d97a0ed7bd7c0840 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Thu, 11 Jan 2024 12:13:22 -0600 Subject: [PATCH 4/5] unused import --- crytic_compile/platform/foundry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crytic_compile/platform/foundry.py b/crytic_compile/platform/foundry.py index 8d54ffc0..2ea66a96 100755 --- a/crytic_compile/platform/foundry.py +++ b/crytic_compile/platform/foundry.py @@ -5,7 +5,7 @@ import os import subprocess from pathlib import Path -from typing import TYPE_CHECKING, List, Optional, Dict, TypeVar +from typing import TYPE_CHECKING, List, Optional, TypeVar import json From 2b1526a236faba732c922466b9a95af552bbed04 Mon Sep 17 00:00:00 2001 From: alpharush <0xalpharush@protonmail.com> Date: Tue, 16 Jan 2024 10:05:55 -0600 Subject: [PATCH 5/5] add test for fix --- scripts/ci_test_foundry.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/scripts/ci_test_foundry.sh b/scripts/ci_test_foundry.sh index 726134fc..6e240e4a 100755 --- a/scripts/ci_test_foundry.sh +++ b/scripts/ci_test_foundry.sh @@ -12,6 +12,15 @@ forge init --no-commit crytic-compile . if [ $? -ne 0 ] then - echo "foundry test failed" + echo "foundry test 1 failed" exit 255 fi + +mkdir /tmp/forge_test/test_2 +rsync -a --exclude='test_2' ./ /tmp/forge_test/test_2/ +crytic-compile ./test_2 +if [ $? -ne 0 ] +then + echo "foundry test 2 failed" + exit 255 +fi \ No newline at end of file