Skip to content

Instantly share code, notes, and snippets.

@quezak
Created March 15, 2021 14:15
Show Gist options
  • Save quezak/b0cd46ec2d378a34edf0734505a5725e to your computer and use it in GitHub Desktop.
Save quezak/b0cd46ec2d378a34edf0734505a5725e to your computer and use it in GitHub Desktop.
Run waffle & typechain only if contract files changed

Helper scripts to compile contract ABIs and generate contract interfaces only if the solidity files are changed.

The scripts assume using waffle for solidity compilation and ethers for blockchain interaction, but you can easily update them to use different tools.

Full build is done by yarn compile, defined as follows in package.json scripts section:

{
  "scripts": {
    "compile:sol": "./scripts/compile-contracts.sh",
    "compile:typechain": "./scripts/compile-typechain.sh",
    "compile:ts": "tsc -b",
    "compile": "yarn compile:sol && yarn compile:typechain && yarn compile:ts",
    ...
  }
}
#!/bin/bash
# Run waffle, but only if any contracts were changed -- to save time on hot reloading.
CONTRACTS_BUILD_DIR="set path to your contract ABI jsons directory here (or read from script args)"
CONTRACTS_SOURCES_DIR="set path to your solidity files directory here"
found_updates=false
for contract_file in $(find "$CONTRACTS_SOURCES_DIR" -name '*.sol'); do
# grep on alpine images doesn't support PCRE (grep -P switch), use awk instead
# for contract_name in $(grep -Poh '(?<=^contract )\w+' "$contract_file"); do
for contract_name in \
$(awk '/^contract/{ print $2 }' "$contract_file") \
$(awk '/^abstract contract/{ print $3 }' "$contract_file")
do
contract_json="${CONTRACTS_BUILD_DIR}/$contract_name.json"
if [ ! -s "$contract_json" ] || [ "$contract_file" -nt "$contract_json" ]; then
echo "contract needs update: $contract_name"
found_updates=true
break
else
echo "contract up to date: $contract_name"
fi
done
if $found_updates; then break; fi
done
if $found_updates; then
rm -rf ${CONTRACTS_BUILD_DIR}
mkdir -p ${CONTRACTS_BUILD_DIR}
yarn waffle './waffle-config'
else
echo "Contracts unchanged, skipping waffle"
fi
#!/bin/bash
# Run typechain, but only if any contract ABI jsons were changed -- to save time on hot reloading.
# Currently typechain doesn't recognize unchanged files, and the whole process takes a few seconds.
CONTRACTS_BUILD_DIR="set path to your contract ABI jsons directory here (or read from script args)"
TYPECHAIN_OUT_DIR="set path to your typechain destination directory here"
found_updates=false
for contract_json in ${CONTRACTS_BUILD_DIR}/*.json; do
contract_name="$(basename $contract_json .json)"
contract_ts="${TYPECHAIN_OUT_DIR}/${contract_name}.d.ts"
if grep -q '"abi": \[\]' $contract_json; then
echo "skipping contract with no ABI: $contract_name"
elif [ ! -s "$contract_ts" ] || [ "$contract_json" -nt "$contract_ts" ]; then
echo "contract typings need update: $contract_name"
found_updates=true
break
else
echo "contract typings up to date: $contract_name"
fi
done
if $found_updates; then
# NOTE: typechain expects a glob, not a file list, so it must be quoted
yarn typechain --target ethers-v5 --outDir="$TYPECHAIN_OUT_DIR" "$CONTRACTS_BUILD_DIR/*.json"
else
echo "Contracts unchanged, skipping typechain generation"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment