From ff4a0b5dab6b2a05066dfbda64f01c337f53efbb Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 31 Aug 2023 15:19:31 +0100 Subject: [PATCH] Script to check if a `integration-test` manifest is a contract (#1893) * Add is_contract.sh script to detect if a crate is probably a contract * Add heuristic docs * Try using is_contract script in examples-contract-build * Fix * Use in examples-docs * conditional-compilation build release. * Fmt * Clippy * Fix UI tests * Find * Disable all find tests * Revert "Disable all find tests" This reverts commit 626f1b63a8f332520ffc0271ce58eecc083ba8e3. * Comment out tests using find command * Try examples-fmt * Split find lines * Restore examples-clippy * Restore examples-clippy-wasm * Restore examples-contract-build * Restore examples-docs * Attempt to fix up examples-docs * Comment out examples-docs * Restore examples-docs * examples-contract-build-riscv * Try just running tests on all contracts * Remove env vars * Run static buffer integration tests --- .gitlab-ci.yml | 167 ++++-------------- .../fail/message-returns-non-codec.stderr | 2 +- .../fail/message_output_non_codec.stderr | 2 +- scripts/is_contract.sh | 41 +++++ 4 files changed, 78 insertions(+), 134 deletions(-) create mode 100755 scripts/is_contract.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d31c9290b91..ec434e75b84 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,9 +30,6 @@ variables: PURELY_STD_CRATES: "ink/codegen metadata engine e2e e2e/macro ink/ir" ALSO_WASM_CRATES: "env storage storage/traits allocator prelude primitives ink ink/macro" ALL_CRATES: "${PURELY_STD_CRATES} ${ALSO_WASM_CRATES}" - MULTI_CONTRACT_CALLER_SUBCONTRACTS: "accumulator adder subber" - LANG_ERR_INTEGRATION_CONTRACTS: "integration-flipper call-builder contract-ref constructors-return-value" - UPGRADEABLE_CONTRACTS: "delegator set-code-hash" # TODO `cargo clippy --verbose --all-targets --all-features` for this crate # currently fails on `stable`, but succeeds on `nightly`. This is due to # this fix not yet in stable: https://github.com/rust-lang/rust-clippy/issues/8895. @@ -118,21 +115,9 @@ examples-fmt: <<: *docker-env <<: *test-refs script: - # Note that we disable the license header check for the examples, since they are unlicensed. - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - cargo +nightly fmt --verbose --manifest-path ${example}/Cargo.toml -- --check; - done - - for contract in ${MULTI_CONTRACT_CALLER_SUBCONTRACTS}; do - cargo +nightly fmt --verbose --manifest-path ./integration-tests/multi-contract-caller/${contract}/Cargo.toml -- --check; - done - - for contract in ${UPGRADEABLE_CONTRACTS}; do - cargo +nightly fmt --verbose --manifest-path ./integration-tests/upgradeable-contracts/${contract}/Cargo.toml -- --check; - done - - for contract in ${LANG_ERR_INTEGRATION_CONTRACTS}; do - cargo +nightly fmt --verbose --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml -- --check; - done + - find integration-tests -name "Cargo.toml" + -exec scripts/is_contract.sh {} \; + -exec cargo +nightly fmt --verbose --manifest-path {} -- --check \; # This file is not a part of the cargo project, so it wouldn't be formatted the usual way - rustfmt +nightly --verbose --check ./integration-tests/psp22-extension/runtime/psp22-extension-example.rs allow_failure: true @@ -161,20 +146,9 @@ examples-clippy-std: <<: *docker-env <<: *test-refs script: - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - cargo clippy --verbose --all-targets --manifest-path ${example}/Cargo.toml -- -D warnings -A $CLIPPY_ALLOWED; - done - - for contract in ${MULTI_CONTRACT_CALLER_SUBCONTRACTS}; do - cargo clippy --verbose --all-targets --manifest-path ./integration-tests/multi-contract-caller/${contract}/Cargo.toml -- -D warnings -A $CLIPPY_ALLOWED; - done - - for contract in ${UPGRADEABLE_CONTRACTS}; do - cargo clippy --verbose --manifest-path ./integration-tests/upgradeable-contracts/${contract}/Cargo.toml -- -D warnings -A $CLIPPY_ALLOWED; - done - - for contract in ${LANG_ERR_INTEGRATION_CONTRACTS}; do - cargo clippy --verbose --all-targets --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml -- -D warnings -A $CLIPPY_ALLOWED; - done + - find integration-tests -name "Cargo.toml" + -exec scripts/is_contract.sh {} \; + -exec cargo clippy --verbose --all-targets --manifest-path {} -- -D warnings -A $CLIPPY_ALLOWED \; allow_failure: true examples-clippy-wasm: @@ -182,21 +156,9 @@ examples-clippy-wasm: <<: *docker-env <<: *test-refs script: - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - cargo clippy --verbose --manifest-path ${example}/Cargo.toml --no-default-features --target wasm32-unknown-unknown -- -D warnings -A $CLIPPY_ALLOWED; - done - - for contract in ${MULTI_CONTRACT_CALLER_SUBCONTRACTS}; do - cargo clippy --verbose --manifest-path ./integration-tests/multi-contract-caller/${contract}/Cargo.toml --no-default-features --target wasm32-unknown-unknown -- -D warnings -A $CLIPPY_ALLOWED; - done - - for contract in ${UPGRADEABLE_CONTRACTS}; do - cargo clippy --verbose --manifest-path ./integration-tests/upgradeable-contracts/${contract}/Cargo.toml --no-default-features --target wasm32-unknown-unknown -- -D warnings -A $CLIPPY_ALLOWED; - done - - for contract in ${LANG_ERR_INTEGRATION_CONTRACTS}; do - cargo clippy --verbose --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml --no-default-features --target wasm32-unknown-unknown -- -D warnings -A $CLIPPY_ALLOWED; - done - - cargo clippy --verbose --manifest-path ./integration-tests/upgradeable-contracts/set-code-hash/updated-incrementer/Cargo.toml --no-default-features --target wasm32-unknown-unknown -- -D warnings -A $CLIPPY_ALLOWED; + - find integration-tests -name "Cargo.toml" + -exec scripts/is_contract.sh {} \; + -exec cargo clippy --verbose --manifest-path {} --no-default-features --target wasm32-unknown-unknown -- -D warnings -A $CLIPPY_ALLOWED \; allow_failure: true @@ -387,36 +349,13 @@ examples-test: # Fix linking of `linkme`: https://github.com/dtolnay/linkme/issues/49 RUSTFLAGS: "-Clink-arg=-z -Clink-arg=nostart-stop-gc" script: - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - if [ "$example" = "integration-tests/conditional-compilation/" ]; then - cargo test --verbose --manifest-path ${example}/Cargo.toml --features "foo"; - cargo test --verbose --manifest-path ${example}/Cargo.toml --features "bar"; - cargo test --verbose --manifest-path ${example}/Cargo.toml --features "foo, bar"; - fi; - if grep -q "e2e-tests = \[\]" "${example}/Cargo.toml"; then - if [ "$example" = "integration-tests/static-buffer/" ]; then - cargo clean && INK_STATIC_BUFFER_SIZE=30 cargo test --verbose --manifest-path ${example}/Cargo.toml --features e2e-tests && cargo clean; - else - cargo test --verbose --manifest-path ${example}/Cargo.toml --features e2e-tests; - fi; - else - cargo test --verbose --manifest-path ${example}/Cargo.toml; - fi; - done - - for contract in ${MULTI_CONTRACT_CALLER_SUBCONTRACTS}; do - cargo test --verbose --manifest-path ./integration-tests/multi-contract-caller/${contract}/Cargo.toml; - done - - for contract in ${UPGRADEABLE_CONTRACTS}; do - cargo test --verbose --manifest-path ./integration-tests/upgradeable-contracts/${contract}/Cargo.toml --features e2e-tests; - done - # TODO (#1502): We need to clean before running, otherwise the CI fails with a - # linking error. - - for contract in ${LANG_ERR_INTEGRATION_CONTRACTS}; do - cargo clean --verbose --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml; - cargo test --verbose --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml --features e2e-tests; - done + # run the static buffer test with a custom buffer size + - cargo clean --manifest-path integration-tests/static-buffer/Cargo.toml + - INK_STATIC_BUFFER_SIZE=30 cargo test --verbose --manifest-path integration-tests/static-buffer/Cargo.toml --all-features + # run all tests with --all-features, which will run the e2e-tests feature if present + - find integration-tests -name "Cargo.toml" + -exec scripts/is_contract.sh {} \; + -exec cargo test --verbose --manifest-path {} --all-features \; examples-contract-build: stage: examples @@ -428,33 +367,18 @@ examples-contract-build: script: - rustup component add rust-src --toolchain stable - cargo contract -V - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - if [ "$example" = "integration-tests/conditional-compilation/" ]; then - pushd $example && - cargo contract build --features "foo" && - popd; - pushd $example && - cargo contract build --features "bar" && - popd; - pushd $example && - cargo contract build --features "foo, bar" && - popd; - fi; - pushd $example && - cargo contract build && - popd; - done - - pushd ./integration-tests/multi-contract-caller/ && ./build-all.sh && popd - - for contract in ${LANG_ERR_INTEGRATION_CONTRACTS}; do - cargo contract build --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml; - done - - for contract in ${UPGRADEABLE_CONTRACTS}; do - cargo contract build --manifest-path ./integration-tests/upgradeable-contracts/${contract}/Cargo.toml; - done - -# TODO: Use cargo contract as soon as it has RISC-V support + # Build all examples + - find integration-tests -name "Cargo.toml" + -exec scripts/is_contract.sh {} \; + -exec cargo contract build --release --manifest-path {} \; + # Build the different features for the conditional compilation example + - pushd ./integration-tests/conditional-compilation + - cargo contract build --release --features "foo" + - cargo contract build --release --features "bar" + - cargo contract build --release --features "foo, bar" + - popd + +## TODO: Use cargo contract as soon as it has RISC-V support examples-contract-build-riscv: stage: examples <<: *docker-env @@ -465,22 +389,14 @@ examples-contract-build-riscv: - rustup component add rust-src --toolchain stable - cargo contract -V # We skip some examples for those reasons: - # There are no manifests in those two directories and hence it would fall back to the workspace. - # - lang-err-integration-tests - # - upgradeable-contracts # This uses dlmalloc which is only supported on select targets. # - custom_allocator # Pulls in sp-std which needlessly requires atomic pointers (TODO: Fix sp-std and enable this example) # - call-runtime - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - if [ "$example" = "integration-tests/custom-allocator/" ]; then continue; fi; - if [ "$example" = "integration-tests/call-runtime/" ]; then continue; fi; - pushd $example && - cargo build --no-default-features --target $RISCV_TARGET -Zbuild-std="core,alloc" && - popd; - done + - find integration-tests -name "Cargo.toml" + -not \( -path '*/custom-allocator/*' -o -path '*/call-runtime/*' \) + -exec scripts/is_contract.sh {} \; + -exec cargo build --manifest-path {} --no-default-features --target $RISCV_TARGET -Zbuild-std="core,alloc" \; examples-docs: stage: examples @@ -493,22 +409,9 @@ examples-docs: # puts the contract functions in a private module. # Once https://github.com/paritytech/ink/issues/336 has been implemented we can get rid # of this flag. - - for example in integration-tests/*/; do - if [ "$example" = "integration-tests/lang-err-integration-tests/" ]; then continue; fi; - if [ "$example" = "integration-tests/upgradeable-contracts/" ]; then continue; fi; - cargo doc --manifest-path ${example}/Cargo.toml --document-private-items --verbose --no-deps; - done - - for contract in ${MULTI_CONTRACT_CALLER_SUBCONTRACTS}; do - cargo doc --manifest-path ./integration-tests/multi-contract-caller/${contract}/Cargo.toml --document-private-items --verbose --no-deps; - done - - for contract in ${UPGRADEABLE_CONTRACTS}; do - cargo doc --manifest-path ./integration-tests/upgradeable-contracts/${contract}/Cargo.toml --document-private-items --verbose --no-deps; - done - - for contract in ${LANG_ERR_INTEGRATION_CONTRACTS}; do - cargo doc --manifest-path ./integration-tests/lang-err-integration-tests/${contract}/Cargo.toml --document-private-items --verbose --no-deps; - done - - cargo doc --manifest-path ./integration-tests/upgradeable-contracts/set-code-hash/updated-incrementer/Cargo.toml --document-private-items --verbose --no-deps - + - find integration-tests -name "Cargo.toml" + -exec scripts/is_contract.sh {} \; + -exec cargo doc --manifest-path {} --document-private-items --verbose --no-deps \; #### stage: ink-waterfall diff --git a/crates/ink/tests/ui/contract/fail/message-returns-non-codec.stderr b/crates/ink/tests/ui/contract/fail/message-returns-non-codec.stderr index 877500181fa..b1b22479ad7 100644 --- a/crates/ink/tests/ui/contract/fail/message-returns-non-codec.stderr +++ b/crates/ink/tests/ui/contract/fail/message-returns-non-codec.stderr @@ -52,7 +52,7 @@ error[E0599]: the method `try_invoke` exists for struct `CallBuilder $CARGO/parity-scale-codec-3.6.4/src/codec.rs + --> $CARGO/parity-scale-codec-3.6.5/src/codec.rs | | pub trait Decode: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/crates/ink/tests/ui/trait_def/fail/message_output_non_codec.stderr b/crates/ink/tests/ui/trait_def/fail/message_output_non_codec.stderr index f2321903953..27ce117e512 100644 --- a/crates/ink/tests/ui/trait_def/fail/message_output_non_codec.stderr +++ b/crates/ink/tests/ui/trait_def/fail/message_output_non_codec.stderr @@ -36,7 +36,7 @@ error[E0599]: the method `try_invoke` exists for struct `CallBuilder $CARGO/parity-scale-codec-3.6.4/src/codec.rs + --> $CARGO/parity-scale-codec-3.6.5/src/codec.rs | | pub trait Decode: Sized { | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/scripts/is_contract.sh b/scripts/is_contract.sh new file mode 100755 index 00000000000..98dd795044c --- /dev/null +++ b/scripts/is_contract.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +SCRIPT_NAME="${BASH_SOURCE[0]}" +MANIFEST_PATH=$1 + +function usage { + cat << EOF +Usage: ${SCRIPT_NAME} MANIFEST_PATH + +Succeeds if the crate at MANIFEST_PATH is *probably* contract crate, fails otherwise. The heuristic used is: + - Find the root package of the crate + - Find the source file of the root package that is a lib + - Check for the presence of the `#[ink::contract]` attribute macro + +MANIFEST_PATH + Path to the Cargo.toml manifest file for a possible contract project + +EXAMPLES + ${SCRIPT_NAME} ./Cargo.toml + +EOF +} + +if [ -z "$MANIFEST_PATH" ]; then + usage + exit 1 +fi + +ROOT_PACKAGE=$(cargo metadata --format-version=1 --manifest-path "$MANIFEST_PATH" | + jq -r '.resolve.root') +SOURCE_PATH=$(cargo metadata --format-version=1 --manifest-path "$MANIFEST_PATH" | + jq -r --arg ROOT_PACKAGE "$ROOT_PACKAGE" ' + .packages[] + | select(.id == $ROOT_PACKAGE).targets[] + | select(.kind[] | contains("lib")).src_path') + +if grep -q '^#\[ink::contract\]' $SOURCE_PATH; then + exit 0 +else + exit 1 +fi