2024-01-15 14:09:48 +00:00
|
|
|
#!/bin/env bash
|
|
|
|
|
|
|
|
set -ex
|
|
|
|
|
|
|
|
# Make all cargo invocations verbose.
|
|
|
|
export CARGO_TERM_VERBOSE=true
|
|
|
|
|
|
|
|
main() {
|
|
|
|
crate="$1"
|
|
|
|
task="$2"
|
|
|
|
|
2024-02-01 01:01:43 +00:00
|
|
|
check_required_commands
|
|
|
|
|
|
|
|
cargo --version
|
|
|
|
rustc --version
|
|
|
|
/usr/bin/env bash --version
|
|
|
|
locale
|
|
|
|
env
|
|
|
|
|
2024-01-15 14:09:48 +00:00
|
|
|
cd "$crate"
|
|
|
|
|
|
|
|
# Building the fuzz crate is more-or-less just a sanity check.
|
|
|
|
if [ "$crate" == "fuzz" ]
|
|
|
|
then
|
|
|
|
cargo --locked build
|
|
|
|
exit 0
|
|
|
|
fi
|
|
|
|
|
|
|
|
# Every crate must define EXAMPLES.
|
|
|
|
. contrib/test_vars.sh || exit 1
|
|
|
|
|
|
|
|
case $task in
|
|
|
|
test)
|
|
|
|
do_test
|
|
|
|
;;
|
|
|
|
|
|
|
|
feature_matrix)
|
|
|
|
do_feature_matrix
|
|
|
|
;;
|
|
|
|
|
|
|
|
lint)
|
|
|
|
do_lint
|
|
|
|
;;
|
|
|
|
|
|
|
|
dup_deps)
|
|
|
|
do_dup_deps
|
|
|
|
;;
|
|
|
|
|
|
|
|
docs)
|
|
|
|
build_docs_with_stable_toolchain
|
|
|
|
;;
|
|
|
|
|
|
|
|
docsrs)
|
|
|
|
build_docs_with_nightly_toolchain
|
|
|
|
;;
|
|
|
|
|
|
|
|
wasm)
|
|
|
|
do_wasm
|
|
|
|
;;
|
|
|
|
|
|
|
|
asan)
|
|
|
|
do_asan
|
|
|
|
;;
|
|
|
|
|
|
|
|
bench)
|
|
|
|
do_bench
|
|
|
|
;;
|
|
|
|
|
|
|
|
schemars)
|
|
|
|
do_schemars
|
|
|
|
;;
|
|
|
|
*)
|
2024-02-01 01:01:43 +00:00
|
|
|
err "Error: unknown task $task"
|
2024-01-15 14:09:48 +00:00
|
|
|
;;
|
|
|
|
esac
|
|
|
|
}
|
|
|
|
|
|
|
|
do_test() {
|
|
|
|
# Use the current (recent/minimal) lock file.
|
|
|
|
local cargo="cargo --locked"
|
|
|
|
|
|
|
|
# Defaults / sanity checks
|
|
|
|
$cargo build
|
|
|
|
$cargo test
|
|
|
|
|
|
|
|
for example in $EXAMPLES; do
|
|
|
|
name="$(echo "$example" | cut -d ':' -f 1)"
|
|
|
|
features="$(echo "$example" | cut -d ':' -f 2)"
|
|
|
|
$cargo run --example "$name" --features="$features"
|
|
|
|
done
|
|
|
|
|
|
|
|
if [ -e ./contrib/extra_tests.sh ];
|
|
|
|
then
|
|
|
|
./contrib/extra_tests.sh
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Each crate defines its own feature matrix test so feature combinations
|
|
|
|
# can be better controlled.
|
|
|
|
do_feature_matrix() {
|
|
|
|
local cargo="cargo --locked"
|
|
|
|
|
|
|
|
$cargo build --no-default-features
|
|
|
|
$cargo test --no-default-features
|
|
|
|
|
|
|
|
# All crates have a "std" feature.
|
|
|
|
loop_features "std" "$FEATURES_WITH_STD"
|
|
|
|
|
|
|
|
# All but `bitcoin` crate have an "alloc" feature, this tests it
|
|
|
|
# along with any other features that should work with "std".
|
|
|
|
if [ -n "$FEATURES_WITHOUT_STD" ]
|
|
|
|
then
|
|
|
|
loop_features "" "$FEATURES_WITHOUT_STD"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Build with each feature as well as all combinations of two features.
|
|
|
|
#
|
|
|
|
# Usage: loop_features "std" "this-feature that-feature other"
|
|
|
|
loop_features() {
|
|
|
|
local use="$1"
|
|
|
|
local features="$2"
|
|
|
|
local cargo="cargo --locked"
|
|
|
|
|
|
|
|
# All the provided features including $use
|
|
|
|
$cargo build --no-default-features --features="$use $features"
|
|
|
|
$cargo test --no-default-features --features="$use $features"
|
|
|
|
|
|
|
|
read -r -a array <<< "$features"
|
|
|
|
local len="${#array[@]}"
|
|
|
|
|
|
|
|
if (( len > 1 )); then
|
|
|
|
for ((i = 0 ; i < len ; i++ ));
|
|
|
|
do
|
|
|
|
$cargo build --features="$use ${array[i]}"
|
|
|
|
$cargo test --features="$use ${array[i]}"
|
|
|
|
|
|
|
|
if (( i < len - 1 )); then
|
|
|
|
for ((j = i + 1 ; j < len ; j++ ));
|
|
|
|
do
|
|
|
|
$cargo build --features="$use ${array[i]} ${array[j]}"
|
|
|
|
$cargo test --features="$use ${array[i]} ${array[j]}"
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
done
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Lint the workspace then the individual crate examples.
|
|
|
|
do_lint() {
|
2024-02-20 16:58:25 +00:00
|
|
|
need_nightly
|
|
|
|
|
2024-01-15 14:09:48 +00:00
|
|
|
# Use the current (recent/minimal) lock file.
|
2024-02-20 16:58:25 +00:00
|
|
|
local cargo="cargo --locked"
|
2024-01-15 14:09:48 +00:00
|
|
|
|
|
|
|
$cargo clippy --workspace -- -D warnings
|
|
|
|
|
|
|
|
for example in $EXAMPLES; do
|
|
|
|
name=$(echo "$example" | cut -d ':' -f 1)
|
|
|
|
features=$(echo "$example" | cut -d ':' -f 2)
|
|
|
|
$cargo clippy --example "$name" --features="$features" -- -D warnings
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
# We should not have any duplicate dependencies. This catches mistakes made upgrading dependencies
|
|
|
|
# in one crate and not in another (e.g. upgrade bitcoin_hashes in bitcoin but not in secp).
|
|
|
|
do_dup_deps() {
|
|
|
|
duplicate_dependencies=$(
|
|
|
|
# Only show the actual duplicated deps, not their reverse tree, then
|
|
|
|
# whitelist the 'syn' crate which is duplicated but it's not our fault.
|
2024-03-21 00:46:31 +00:00
|
|
|
#
|
|
|
|
# Temporarily allow 2 versions of `hashes` and `hex` while we upgrade.
|
2024-01-15 14:09:48 +00:00
|
|
|
cargo tree --target=all --all-features --duplicates \
|
|
|
|
| grep '^[0-9A-Za-z]' \
|
|
|
|
| grep -v 'syn' \
|
2024-03-21 00:46:31 +00:00
|
|
|
| grep -v 'bitcoin_hashes' \
|
|
|
|
| grep -v 'hex-conservative' \
|
2024-01-15 14:09:48 +00:00
|
|
|
| wc -l
|
|
|
|
)
|
|
|
|
if [ "$duplicate_dependencies" -ne 0 ]; then
|
|
|
|
echo "Dependency tree is broken, contains duplicates"
|
|
|
|
cargo tree --target=all --all-features --duplicates
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
|
|
|
# Build the docs with a nightly toolchain, in unison with the function
|
|
|
|
# below this checks that we feature guarded docs imports correctly.
|
|
|
|
build_docs_with_nightly_toolchain() {
|
2024-02-20 16:58:25 +00:00
|
|
|
need_nightly
|
|
|
|
local cargo="cargo --locked"
|
2024-01-15 14:09:48 +00:00
|
|
|
|
|
|
|
RUSTDOCFLAGS="--cfg docsrs -D warnings -D rustdoc::broken-intra-doc-links" $cargo doc --all-features
|
|
|
|
}
|
|
|
|
|
|
|
|
# Build the docs with a stable toolchain, in unison with the function
|
|
|
|
# above this checks that we feature guarded docs imports correctly.
|
|
|
|
build_docs_with_stable_toolchain() {
|
|
|
|
local cargo="cargo +stable --locked"
|
|
|
|
|
|
|
|
RUSTDOCFLAGS="-D warnings" $cargo doc --all-features
|
|
|
|
}
|
|
|
|
|
|
|
|
do_wasm() {
|
|
|
|
clang --version &&
|
|
|
|
CARGO_TARGET_DIR=wasm cargo install --force wasm-pack &&
|
|
|
|
printf '\n[target.wasm32-unknown-unknown.dev-dependencies]\nwasm-bindgen-test = "0.3"\n' >> Cargo.toml &&
|
|
|
|
printf '\n[lib]\ncrate-type = ["cdylib", "rlib"]\n' >> Cargo.toml &&
|
|
|
|
CC=clang-9 wasm-pack build &&
|
|
|
|
CC=clang-9 wasm-pack test --node;
|
|
|
|
}
|
|
|
|
|
|
|
|
do_asan() {
|
|
|
|
cargo clean
|
|
|
|
CC='clang -fsanitize=address -fno-omit-frame-pointer' \
|
|
|
|
RUSTFLAGS='-Zsanitizer=address -Clinker=clang -Cforce-frame-pointers=yes' \
|
|
|
|
ASAN_OPTIONS='detect_leaks=1 detect_invalid_pointer_pairs=1 detect_stack_use_after_return=1' \
|
|
|
|
cargo test --lib --no-default-features --features="$ASAN_FEATURES" -Zbuild-std --target x86_64-unknown-linux-gnu
|
2024-03-14 22:44:38 +00:00
|
|
|
# There is currently a bug in the MemorySanitizer (MSAN) - disable the job for now.
|
|
|
|
#
|
|
|
|
# cargo clean
|
|
|
|
# CC='clang -fsanitize=memory -fno-omit-frame-pointer' \
|
|
|
|
# RUSTFLAGS='-Zsanitizer=memory -Zsanitizer-memory-track-origins -Cforce-frame-pointers=yes' \
|
|
|
|
# cargo test --lib --no-default-features --features="$ASAN_FEATURES" -Zbuild-std --target x86_64-unknown-linux-gnu
|
2024-01-15 14:09:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
# Bench only works with a non-stable toolchain (nightly, beta).
|
|
|
|
do_bench() {
|
|
|
|
RUSTFLAGS='--cfg=bench' cargo bench
|
|
|
|
}
|
|
|
|
|
|
|
|
# This is only relevant for hashes.
|
|
|
|
do_schemars() {
|
|
|
|
cd "extended_tests/schemars" > /dev/null
|
|
|
|
cargo test
|
|
|
|
}
|
|
|
|
|
2024-02-01 01:01:43 +00:00
|
|
|
# Check all the commands we use are present in the current environment.
|
|
|
|
check_required_commands() {
|
|
|
|
need_cmd cargo
|
|
|
|
need_cmd rustc
|
|
|
|
need_cmd jq
|
|
|
|
need_cmd cut
|
|
|
|
need_cmd grep
|
|
|
|
need_cmd wc
|
|
|
|
}
|
|
|
|
|
|
|
|
need_cmd() {
|
|
|
|
if ! command -v "$1" > /dev/null 2>&1
|
|
|
|
then err "need '$1' (command not found)"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2024-02-20 16:58:25 +00:00
|
|
|
need_nightly() {
|
|
|
|
cargo_ver=$(cargo --version)
|
|
|
|
if echo "$cargo_ver" | grep -q -v nightly; then
|
|
|
|
err "Need a nightly compiler; have $(cargo --version)"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2024-02-01 01:01:43 +00:00
|
|
|
err() {
|
|
|
|
echo "$1" >&2
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
2024-01-15 14:09:48 +00:00
|
|
|
#
|
|
|
|
# Main script
|
|
|
|
#
|
|
|
|
main "$@"
|
|
|
|
exit 0
|