diff --git a/.github/workflows/black.yml b/.github/workflows/black.yml index 25cb38b8..32838fde 100644 --- a/.github/workflows/black.yml +++ b/.github/workflows/black.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 30954646..2c47d87a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,40 +21,35 @@ jobs: strategy: fail-fast: false matrix: - os: ["ubuntu-latest", "windows-2022"] - python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.12"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11", "3.12"]') }} + os: ["ubuntu-latest", "windows-2025"] + python: ${{ (github.event_name == 'pull_request' && fromJSON('["3.8", "3.13"]')) || fromJSON('["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]') }} type: ["brownie", "buidler", "dapp", "embark", "hardhat", "solc", "truffle", "waffle", "foundry", "standard", "vyper", "solc_multi_file", "hardhat_multi_file"] + include: + # buidler requires older NodeJS + - type: buidler + node-version: 12 exclude: # Currently broken, tries to pull git:// which is blocked by GH - type: embark # Requires nix - - os: windows-2022 + - os: windows-2025 type: dapp # Explore foundry support in windows - - os: windows-2022 + - os: windows-2025 type: foundry - # brownie does not install correctly with Python 3.10 - - python: 3.10 - type: brownie - # brownie does not install correctly with Python 3.11 - - python: 3.11 - type: brownie - # brownie does not install correctly with Python 3.12 - - python: 3.12 - type: brownie steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up shell if: runner.os == 'Windows' run: | echo 'C:\msys64\mingw64\bin' >> "$GITHUB_PATH" echo 'C:\msys64\usr\bin' >> "$GITHUB_PATH" - name: Set up Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: - node-version: 18.15 + node-version: ${{ matrix.node-version || '18.15' }} - name: Set up Python ${{ matrix.python }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.python }} - name: Install dependencies diff --git a/.github/workflows/darglint.yml b/.github/workflows/darglint.yml index 624b1d07..f97a3932 100644 --- a/.github/workflows/darglint.yml +++ b/.github/workflows/darglint.yml @@ -17,9 +17,9 @@ jobs: tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 - name: Run Tests diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml index 35ff04cf..27d5903c 100644 --- a/.github/workflows/doc.yml +++ b/.github/workflows/doc.yml @@ -28,16 +28,16 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Setup Pages uses: actions/configure-pages@v5 - - uses: actions/setup-python@v5 + - uses: actions/setup-python@v6 with: python-version: '3.8' - run: pip install -e ".[doc]" - run: pdoc -o html/ crytic_compile - name: Upload artifact - uses: actions/upload-pages-artifact@v3 + uses: actions/upload-pages-artifact@v4 with: # Upload the doc path: './html/' diff --git a/.github/workflows/etherscan.yml b/.github/workflows/etherscan.yml index 680630c5..f64ee7da 100644 --- a/.github/workflows/etherscan.yml +++ b/.github/workflows/etherscan.yml @@ -21,17 +21,17 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: ["ubuntu-latest", "windows-2022"] + os: ["ubuntu-latest", "windows-2025"] type: ["etherscan"] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up shell if: runner.os == 'Windows' run: | echo 'C:\msys64\mingw64\bin' >> "$GITHUB_PATH" echo 'C:\msys64\usr\bin' >> "$GITHUB_PATH" - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 - name: Install dependencies diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index ff9fe507..805f6377 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml index 80973bf3..6a456010 100644 --- a/.github/workflows/mypy.yml +++ b/.github/workflows/mypy.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index d1f67dbb..633a95b0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -10,10 +10,10 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: '3.x' @@ -24,7 +24,7 @@ jobs: python -m build - name: Upload distributions - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: crytic-compile-dists path: dist/ @@ -39,16 +39,16 @@ jobs: - build-release steps: - name: fetch dists - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v6 with: name: crytic-compile-dists path: dist/ - name: publish - uses: pypa/gh-action-pypi-publish@v1.12.4 + uses: pypa/gh-action-pypi-publish@v1.13.0 - name: sign - uses: sigstore/gh-action-sigstore-python@v3.0.0 + uses: sigstore/gh-action-sigstore-python@v3.1.0 with: inputs: ./dist/*.tar.gz ./dist/*.whl release-signing-artifacts: true diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index 17a0b529..3977f932 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index be6eea2f..ca930085 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -26,9 +26,9 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - name: Set up Python 3.8 - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: 3.8 cache: "pip" diff --git a/crytic_compile/cryticparser/defaults.py b/crytic_compile/cryticparser/defaults.py index 9635f365..f6719149 100755 --- a/crytic_compile/cryticparser/defaults.py +++ b/crytic_compile/cryticparser/defaults.py @@ -44,7 +44,7 @@ "hardhat_cache_directory": None, "hardhat_artifacts_directory": None, "foundry_ignore_compile": False, - "foundry_out_directory": "out", + "foundry_out_directory": None, "foundry_compile_all": False, "export_dir": "crytic-export", "compile_libraries": None, diff --git a/crytic_compile/platform/abstract_platform.py b/crytic_compile/platform/abstract_platform.py index b369e155..500dd58f 100644 --- a/crytic_compile/platform/abstract_platform.py +++ b/crytic_compile/platform/abstract_platform.py @@ -42,6 +42,7 @@ class PlatformConfig: tests_path: str = "test" libs_path: List[str] = field(default_factory=lambda: ["lib"]) scripts_path: str = "script" + out_path: str = "out" class AbstractPlatform(metaclass=abc.ABCMeta): diff --git a/crytic_compile/platform/etherscan.py b/crytic_compile/platform/etherscan.py index 72f67def..245c1a51 100644 --- a/crytic_compile/platform/etherscan.py +++ b/crytic_compile/platform/etherscan.py @@ -49,12 +49,11 @@ "mainnet": ("1", "etherscan.io"), "sepolia": ("11155111", "sepolia.etherscan.io"), "holesky": ("17000", "holesky.etherscan.io"), + "hoodi": ("560048", "hoodi.etherscan.io"), "bsc": ("56", "bscscan.com"), "testnet.bsc": ("97", "testnet.bscscan.com"), "poly": ("137", "polygonscan.com"), "amoy.poly": ("80002", "amoy.polygonscan.com"), - "polyzk": ("1101", "zkevm.polygonscan.com"), - "cardona.polyzk": ("2442", "cardona-zkevm.polygonscan.com"), "base": ("8453", "basescan.org"), "sepolia.base": ("84532", "sepolia.basescan.org"), "arbi": ("42161", "arbiscan.io"), @@ -62,8 +61,6 @@ "sepolia.arbi": ("421614", "sepolia.arbiscan.io"), "linea": ("59144", "lineascan.build"), "sepolia.linea": ("59141", "sepolia.lineascan.build"), - "ftm": ("250", "ftmscan.com"), - "testnet.ftm": ("4002", "testnet.ftmscan.com"), "blast": ("81457", "blastscan.io"), "sepolia.blast": ("168587773", "sepolia.blastscan.io"), "optim": ("10", "optimistic.etherscan.io"), @@ -71,17 +68,15 @@ "avax": ("43114", "snowscan.xyz"), "testnet.avax": ("43113", "testnet.snowscan.xyz"), "bttc": ("199", "bttcscan.com"), - "testnet.bttc": ("1028", "testnet.bttcscan.com"), + "testnet.bttc": ("1029", "testnet.bttcscan.com"), "celo": ("42220", "celoscan.io"), - "alfajores.celo": ("44787", "alfajores.celoscan.io"), - "cronos": ("25", "cronoscan.com"), + "sepolia.celo": ("11142220", "sepolia.celoscan.io"), "frax": ("252", "fraxscan.com"), - "holesky.frax": ("2522", "holesky.fraxscan.com"), + "hoodi.frax": ("2523", "hoodi.fraxscan.com"), "gno": ("100", "gnosisscan.io"), - "kroma": ("255", "kromascan.com"), - "sepolia.kroma": ("2358", "sepolia.kromascan.com"), "mantle": ("5000", "mantlescan.xyz"), "sepolia.mantle": ("5003", "sepolia.mantlescan.xyz"), + "memecore": ("43521", "testnet.memecorescan.io"), "moonbeam": ("1284", "moonbeam.moonscan.io"), "moonriver": ("1285", "moonriver.moonscan.io"), "moonbase": ("1287", "moonbase.moonscan.io"), @@ -90,13 +85,9 @@ "scroll": ("534352", "scrollscan.com"), "sepolia.scroll": ("534351", "sepolia.scrollscan.com"), "taiko": ("167000", "taikoscan.io"), - "hekla.taiko": ("167009", "hekla.taikoscan.io"), - "wemix": ("1111", "wemixscan.com"), - "testnet.wemix": ("1112", "testnet.wemixscan.com"), + "hoodi.taiko": ("167013", "hoodi.taikoscan.io"), "era.zksync": ("324", "era.zksync.network"), "sepoliaera.zksync": ("300", "sepolia-era.zksync.network"), - "xai": ("660279", "xaiscan.io"), - "sepolia.xai": ("37714555429", "sepolia.xaiscan.io"), "xdc": ("50", "xdcscan.com"), "testnet.xdc": ("51", "testnet.xdcscan.com"), "apechain": ("33139", "apescan.io"), @@ -106,12 +97,21 @@ "sophon": ("50104", "sophscan.xyz"), "testnet.sophon": ("531050104", "testnet.sophscan.xyz"), "sonic": ("146", "sonicscan.org"), - "testnet.sonic": ("57054", "testnet.sonicscan.org"), + "testnet.sonic": ("14601", "testnet.sonicscan.org"), "unichain": ("130", "uniscan.xyz"), "sepolia.unichain": ("1301", "sepolia.uniscan.xyz"), "abstract": ("2741", "abscan.org"), "sepolia.abstract": ("11124", "sepolia.abscan.org"), "berachain": ("80094", "berascan.com"), + "testnet.berachain": ("80069", "testnet.berascan.com"), + "swellchain": ("1923", "swellchainscan.io"), + "testnet.swellchain": ("1924", "sepolia.swellchainscan.io"), + "testnet.monad": ("10143", "testnet.monadscan.com"), + "hyperevm": ("999", "hyperevmscan.io"), + "katana": ("747474", "katanascan.com"), + "bokuto.katana": ("737373", "bokuto.katanascan.com"), + "sei": ("1329", "seiscan.io"), + "testnet.sei": ("1328", "testnet.seiscan.io"), } SUPPORTED_NETWORK = {**SUPPORTED_NETWORK_V1, **SUPPORTED_NETWORK_V2} diff --git a/crytic_compile/platform/foundry.py b/crytic_compile/platform/foundry.py index 79c418b4..2feb4aea 100755 --- a/crytic_compile/platform/foundry.py +++ b/crytic_compile/platform/foundry.py @@ -2,10 +2,9 @@ Foundry platform """ import logging -import os import subprocess from pathlib import Path -from typing import TYPE_CHECKING, List, Optional, TypeVar +from typing import TYPE_CHECKING, List, Optional, TypeVar, Union import json @@ -32,6 +31,14 @@ class Foundry(AbstractPlatform): PROJECT_URL = "https://github.com/foundry-rs/foundry" TYPE = Type.FOUNDRY + def __init__(self, target: str, **_kwargs: str): + super().__init__(target, **_kwargs) + + project_root = Foundry.locate_project_root(target) + # if we are initializing this, it is indeed a foundry project and thus has a root path + assert project_root is not None + self._project_root: Path = project_root + # pylint: disable=too-many-locals,too-many-statements,too-many-branches def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: """Compile @@ -46,44 +53,55 @@ def compile(self, crytic_compile: "CryticCompile", **kwargs: str) -> None: "ignore_compile", False ) - out_directory = kwargs.get("foundry_out_directory", "out") + foundry_config = None if ignore_compile: LOGGER.info( "--ignore-compile used, if something goes wrong, consider removing the ignore compile flag" ) - - if not ignore_compile: + else: compilation_command = [ "forge", "build", "--build-info", ] + targeted_build = not self._project_root.samefile(self._target) + if targeted_build: + compilation_command += [ + str(Path(self._target).resolve().relative_to(self._project_root)) + ] + compile_all = kwargs.get("foundry_compile_all", False) - if not compile_all: - foundry_config = self.config(self._target) - if foundry_config: - compilation_command += [ - "--skip", - f"*/{foundry_config.tests_path}/**", - f"*/{foundry_config.scripts_path}/**", - "--force", - ] + foundry_config = self.config(self._project_root) + + if not targeted_build and not compile_all and foundry_config: + compilation_command += [ + "--skip", + f"./{foundry_config.tests_path}/**", + f"./{foundry_config.scripts_path}/**", + "--force", + ] run( compilation_command, - cwd=self._target, + cwd=self._project_root, ) + out_directory_detected = foundry_config.out_path if foundry_config else "out" + out_directory_config = kwargs.get("foundry_out_directory", None) + out_directory = out_directory_config if out_directory_config else out_directory_detected + build_directory = Path( - self._target, + self._project_root, out_directory, "build-info", ) - hardhat_like_parsing(crytic_compile, self._target, build_directory, self._target) + hardhat_like_parsing( + crytic_compile, str(self._target), build_directory, str(self._project_root) + ) def clean(self, **kwargs: str) -> None: """Clean compilation artifacts @@ -99,7 +117,38 @@ def clean(self, **kwargs: str) -> None: if ignore_compile: return - run(["forge", "clean"], cwd=self._target) + run(["forge", "clean"], cwd=self._project_root) + + @staticmethod + def locate_project_root(file_or_dir: str) -> Optional[Path]: + """Determine the project root (if the target is a Foundry project) + + Foundry projects are detected through the presence of their + configuration file. See the following for reference: + + https://github.com/foundry-rs/foundry/blob/6983a938580a1eb25d9dbd61eb8cad8cd137a86d/crates/config/README.md#foundrytoml + + Args: + file_or_dir (str): path to the target + + Returns: + Optional[Path]: path to the project root, if found + """ + + target = Path(file_or_dir).resolve() + + # if the target is a directory, see if it has a foundry config + if target.is_dir() and (target / "foundry.toml").is_file(): + return target + + # if the target is a file, it might be a specific contract + # within a foundry project. Look in parent directories for a + # config file + for p in target.parents: + if (p / "foundry.toml").is_file(): + return p + + return None @staticmethod def is_supported(target: str, **kwargs: str) -> bool: @@ -115,10 +164,10 @@ def is_supported(target: str, **kwargs: str) -> bool: if kwargs.get("foundry_ignore", False): return False - return os.path.isfile(os.path.join(target, "foundry.toml")) + return Foundry.locate_project_root(target) is not None @staticmethod - def config(working_dir: str) -> Optional[PlatformConfig]: + def config(working_dir: Union[str, Path]) -> Optional[PlatformConfig]: """Return configuration data that should be passed to solc, such as remappings. Args: @@ -150,6 +199,7 @@ def config(working_dir: str) -> Optional[PlatformConfig]: result.tests_path = json_config.get("test") result.libs_path = json_config.get("libs") result.scripts_path = json_config.get("script") + result.out_path = json_config.get("out") return result diff --git a/scripts/ci_darglint.sh b/scripts/ci_darglint.sh index 6d98fcc8..f340f967 100755 --- a/scripts/ci_darglint.sh +++ b/scripts/ci_darglint.sh @@ -1,10 +1,9 @@ #!/usr/bin/env bash +set -euo pipefail pip install darglint -darglint . - -if [ $? -ne 0 ] +if ! darglint . then echo "Darglint failed. Please fix the above issues" exit 255 diff --git a/scripts/ci_test_brownie.sh b/scripts/ci_test_brownie.sh index ebfd9413..b28c9174 100755 --- a/scripts/ci_test_brownie.sh +++ b/scripts/ci_test_brownie.sh @@ -1,12 +1,14 @@ #!/usr/bin/env bash +set -euo pipefail + +# https://github.com/eth-brownie/brownie/pull/1873#issuecomment-2927669459 +pip install -U setuptools pip install eth-brownie brownie bake token cd token || exit 255 -crytic-compile . --compile-force-framework Brownie - -if [ $? -ne 0 ] +if ! crytic-compile . --compile-force-framework Brownie then echo "Brownie test failed" exit 255 diff --git a/scripts/ci_test_buidler.sh b/scripts/ci_test_buidler.sh index e37c8a15..225f70c6 100755 --- a/scripts/ci_test_buidler.sh +++ b/scripts/ci_test_buidler.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test buidler integration @@ -6,8 +7,7 @@ cd tests/buidler || exit 255 npm install --save-dev @nomiclabs/buidler -crytic-compile . -if [ $? -ne 0 ] +if ! crytic-compile . then echo "buidler test failed" exit 255 diff --git a/scripts/ci_test_dapp.sh b/scripts/ci_test_dapp.sh index bc258178..935c165f 100755 --- a/scripts/ci_test_dapp.sh +++ b/scripts/ci_test_dapp.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test dapp integration @@ -24,8 +25,7 @@ dapp init PROJECT="$PWD" echo "::group::Dapp + cwd target" -crytic-compile . --compile-remove-metadata -if [ $? -ne 0 ] +if ! crytic-compile . --compile-remove-metadata then echo "dapp test failed" exit 255 @@ -35,8 +35,7 @@ echo "::endgroup::" cd /tmp || exit 255 echo "::group::Dapp + different target" -crytic-compile "$PROJECT" --compile-remove-metadata -if [ $? -ne 0 ] +if ! crytic-compile "$PROJECT" --compile-remove-metadata then echo "dapp test with different target failed" exit 255 @@ -45,8 +44,7 @@ echo "::endgroup::" echo "::group::Dapp + different target + ignore compile" -crytic-compile "$PROJECT" --compile-remove-metadata --ignore-compile -if [ $? -ne 0 ] +if ! crytic-compile "$PROJECT" --compile-remove-metadata --ignore-compile then echo "dapp test with different target + ignore compile failed" exit 255 diff --git a/scripts/ci_test_embark.sh b/scripts/ci_test_embark.sh index e6756be6..ac0d6b42 100755 --- a/scripts/ci_test_embark.sh +++ b/scripts/ci_test_embark.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test embark integration @@ -13,9 +14,8 @@ npm install -g embark@4.2.0 embark demo cd /tmp/embark_demo || exit 255 npm install -crytic-compile . --embark-overwrite-config --compile-remove-metadata -if [ $? -ne 0 ] +if ! crytic-compile . --embark-overwrite-config --compile-remove-metadata then echo "Embark test failed" exit 255 diff --git a/scripts/ci_test_etherlime.sh b/scripts/ci_test_etherlime.sh index fc151802..10328111 100755 --- a/scripts/ci_test_etherlime.sh +++ b/scripts/ci_test_etherlime.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test etherlime integration @@ -7,9 +8,8 @@ cd "$DIR" || exit 255 npm i -g etherlime etherlime init -crytic-compile . --compile-remove-metadata -if [ $? -ne 0 ] +if ! crytic-compile . --compile-remove-metadata then echo "Etherlime test failed" exit 255 diff --git a/scripts/ci_test_etherscan.sh b/scripts/ci_test_etherscan.sh index 631b1f90..5e6b5a1b 100755 --- a/scripts/ci_test_etherscan.sh +++ b/scripts/ci_test_etherscan.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test etherscan integration @@ -14,9 +15,7 @@ if [ "$ETHERSCAN_API_KEY" = "" ]; then fi echo "::group::Etherscan mainnet" -crytic-compile 0x7F37f78cBD74481E593F9C737776F7113d76B315 --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" - -if [ $? -ne 0 ] +if ! crytic-compile 0x7F37f78cBD74481E593F9C737776F7113d76B315 --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" then echo "Etherscan mainnet test failed" exit 255 @@ -26,9 +25,7 @@ echo "::endgroup::" # From crytic/slither#1154 # Try without an explicit API key argument, to verify reading `ETHERSCAN_API_KEY` from env works fine echo "::group::Etherscan #3" -crytic-compile 0xcfc1E0968CA08aEe88CbF664D4A1f8B881d90f37 --compile-remove-metadata - -if [ $? -ne 0 ] +if ! crytic-compile 0xcfc1E0968CA08aEe88CbF664D4A1f8B881d90f37 --compile-remove-metadata then echo "Etherscan #3 test failed" exit 255 @@ -37,9 +34,7 @@ echo "::endgroup::" # From crytic/crytic-compile#415 echo "::group::Etherscan #4" -crytic-compile 0x19c7d0fbf906c282dedb5543d098f43dfe9f856f --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" - -if [ $? -ne 0 ] +if ! crytic-compile 0x19c7d0fbf906c282dedb5543d098f43dfe9f856f --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" then echo "Etherscan #4 test failed" exit 255 @@ -48,9 +43,7 @@ echo "::endgroup::" # From crytic/crytic-compile#150 echo "::group::Etherscan #5" -crytic-compile 0x2a311e451491091d2a1d3c43f4f5744bdb4e773a --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" - -if [ $? -ne 0 ] +if ! crytic-compile 0x2a311e451491091d2a1d3c43f4f5744bdb4e773a --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" then echo "Etherscan #5 test failed" case "$(uname -sr)" in @@ -66,9 +59,7 @@ echo "::endgroup::" # From crytic/crytic-compile#151 echo "::group::Etherscan #6" -crytic-compile 0x4c808e3c011514d5016536af11218eec537eb6f5 --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" - -if [ $? -ne 0 ] +if ! crytic-compile 0x4c808e3c011514d5016536af11218eec537eb6f5 --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" then echo "Etherscan #6 test failed" exit 255 @@ -77,9 +68,7 @@ echo "::endgroup::" # via-ir test for crytic/crytic-compile#517 echo "::group::Etherscan #7" -crytic-compile 0x9AB6b21cDF116f611110b048987E58894786C244 --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" - -if [ $? -ne 0 ] +if ! crytic-compile 0x9AB6b21cDF116f611110b048987E58894786C244 --compile-remove-metadata --etherscan-apikey "$ETHERSCAN_API_KEY" then echo "Etherscan #7 test failed" exit 255 @@ -88,9 +77,7 @@ echo "::endgroup::" # From crytic/crytic-compile#544 echo "::group::Etherscan #8" -crytic-compile 0x9AB6b21cDF116f611110b048987E58894786C244 --etherscan-apikey "$ETHERSCAN_API_KEY" - -if [ $? -ne 0 ] +if ! crytic-compile 0x9AB6b21cDF116f611110b048987E58894786C244 --etherscan-apikey "$ETHERSCAN_API_KEY" then echo "Etherscan #8 test failed" exit 255 @@ -105,9 +92,7 @@ if [ ! -f crytic_compile.config.json ]; then fi # TODO: Globbing at crytic_compile.py:720 to run with '.' -crytic-compile 'contracts/InterestRates/InterestRatePositionManager.f.sol' --config-file crytic_compile.config.json - -if [ $? -ne 0 ] +if ! crytic-compile 'contracts/InterestRates/InterestRatePositionManager.f.sol' --config-file crytic_compile.config.json then echo "crytic-compile command failed" exit 255 diff --git a/scripts/ci_test_foundry.sh b/scripts/ci_test_foundry.sh index 6e240e4a..682a36db 100755 --- a/scripts/ci_test_foundry.sh +++ b/scripts/ci_test_foundry.sh @@ -1,26 +1,48 @@ #!/usr/bin/env bash - ### Test foundry integration +set -Eeuxo pipefail -cd /tmp || exit 255 +## test 1 - same folder +cd /tmp || exit 255 mkdir forge_test cd forge_test || exit 255 -forge init --no-commit +forge init -crytic-compile . -if [ $? -ne 0 ] +if ! crytic-compile . then 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 ] + +## test 2 - same folder, different out dir + +cd /tmp || exit 255 +mkdir forge_test2 +cd forge_test2 || exit 255 +forge init + +sed -i 's/^out\s*=.*$/out = "foobar"/' foundry.toml + +if ! crytic-compile . then echo "foundry test 2 failed" exit 255 -fi \ No newline at end of file +fi + +## test 3 - different folder + +cd /tmp || exit 255 +mkdir forge_test3 +cd forge_test3 || exit 255 +forge init + +cd /tmp || exit 255 + +if ! crytic-compile ./forge_test3 +then + echo "foundry test 3 failed" + exit 255 +fi diff --git a/scripts/ci_test_hardhat.sh b/scripts/ci_test_hardhat.sh index 28f74b80..7d21dee6 100755 --- a/scripts/ci_test_hardhat.sh +++ b/scripts/ci_test_hardhat.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail echo "Testing hardhat integration of $(realpath "$(which crytic-compile)")" diff --git a/scripts/ci_test_hardhat_multi_file.sh b/scripts/ci_test_hardhat_multi_file.sh index 074be214..81995a6c 100755 --- a/scripts/ci_test_hardhat_multi_file.sh +++ b/scripts/ci_test_hardhat_multi_file.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail DIR=$(mktemp -d) diff --git a/scripts/ci_test_monorepo.sh b/scripts/ci_test_monorepo.sh index 10ca98cd..16aa5e0c 100755 --- a/scripts/ci_test_monorepo.sh +++ b/scripts/ci_test_monorepo.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail echo "Testing monorepo integration of $(realpath "$(which crytic-compile)")" diff --git a/scripts/ci_test_solc.sh b/scripts/ci_test_solc.sh index 3d04c394..60785266 100755 --- a/scripts/ci_test_solc.sh +++ b/scripts/ci_test_solc.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail DIR=$(mktemp -d) diff --git a/scripts/ci_test_solc_multi_file.sh b/scripts/ci_test_solc_multi_file.sh index 55624e90..582b1167 100755 --- a/scripts/ci_test_solc_multi_file.sh +++ b/scripts/ci_test_solc_multi_file.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail DIR=$(mktemp -d) diff --git a/scripts/ci_test_standard.sh b/scripts/ci_test_standard.sh index 281087f4..54358033 100755 --- a/scripts/ci_test_standard.sh +++ b/scripts/ci_test_standard.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail DIR=$(mktemp -d) @@ -8,34 +9,25 @@ cd "$DIR" || exit 255 solc-select use 0.8.0 --always-install -crytic-compile contract_with_toplevel.sol --export-format archive - -if [ $? -ne 0 ] +if ! crytic-compile contract_with_toplevel.sol --export-format archive then echo "Standard test failed" exit 255 fi -crytic-compile crytic-export/contract_with_toplevel.sol_export_archive.json - -if [ $? -ne 0 ] +if ! crytic-compile crytic-export/contract_with_toplevel.sol_export_archive.json then echo "Standard test failed" exit 255 fi - -crytic-compile contract_with_toplevel.sol --export-zip test.zip - -if [ $? -ne 0 ] +if ! crytic-compile contract_with_toplevel.sol --export-zip test.zip then echo "Standard test failed" exit 255 fi -crytic-compile test.zip - -if [ $? -ne 0 ] +if ! crytic-compile test.zip then echo "Standard test failed" exit 255 diff --git a/scripts/ci_test_truffle.sh b/scripts/ci_test_truffle.sh index 816fbab3..03f47268 100755 --- a/scripts/ci_test_truffle.sh +++ b/scripts/ci_test_truffle.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test truffle integration @@ -7,9 +8,8 @@ cd "$DIR" || exit 255 npm install -g truffle truffle unbox metacoin -crytic-compile . --compile-remove-metadata -if [ $? -ne 0 ] +if ! crytic-compile . --compile-remove-metadata then echo "Truffle test failed" exit 255 diff --git a/scripts/ci_test_vyper.sh b/scripts/ci_test_vyper.sh index 6afe62da..7ee64904 100755 --- a/scripts/ci_test_vyper.sh +++ b/scripts/ci_test_vyper.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test vyper integration diff --git a/scripts/ci_test_waffle.sh b/scripts/ci_test_waffle.sh index a27436e4..34f53a44 100755 --- a/scripts/ci_test_waffle.sh +++ b/scripts/ci_test_waffle.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +set -euo pipefail ### Test waffle integration @@ -15,9 +16,7 @@ echo 'contract Test { cd .. -crytic-compile . --compile-remove-metadata --compile-force-framework Waffle - -if [ $? -ne 0 ] +if ! crytic-compile . --compile-remove-metadata --compile-force-framework Waffle then echo "Waffle test failed" exit 255 diff --git a/setup.py b/setup.py index d0bd5049..2088f598 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ description="Util to facilitate smart contracts compilation.", url="https://github.com/crytic/crytic-compile", author="Trail of Bits", - version="0.3.10", + version="0.3.11", packages=find_packages(), # Python 3.12.0 on Windows suffers from https://github.com/python/cpython/issues/109590 # breaking some of our integrations. The issue is fixed in 3.12.1