Skip to content

Commit b58a60f

Browse files
committed
rewrite ./vendor-libsecp.sh
This rewrite: * Fixes some shellcheck issues (bad quoting, use of | instead of || near the beginning of the file) * Automatically computes the version prefix, depend directory, etc., and provides instructions to override this with env vars if the user really wants to do this. * Detects when it would be destructive and refuses to run unless passed the -f flag, rather than prompting the user for a yes/no * Adds the capability to use cp rather than git clone, which I need to run this from within Nix. * Whitelists CHANGELOG.md which shouldn't get substituted.
1 parent b7e38eb commit b58a60f

File tree

1 file changed

+96
-49
lines changed

1 file changed

+96
-49
lines changed

secp256k1-sys/vendor-libsecp.sh

Lines changed: 96 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,92 @@
1-
#!/bin/bash
1+
#!/usr/bin/env bash
22
set -e
33

4+
# Set default variables
5+
: "${SECP_VENDOR_GIT_ROOT:=$(git rev-parse --show-toplevel)}"
6+
SECP_SYS="$SECP_VENDOR_GIT_ROOT"/secp256k1-sys
7+
DEFAULT_VERSION_CODE=$(grep version "$SECP_SYS/Cargo.toml" | sed 's/\./_/g' | sed 's/.*"\(.*\)".*/\1/')
8+
DEFAULT_DEPEND_DIR="$SECP_SYS/depend"
9+
DEFAULT_SECP_REPO=https://github.com/bitcoin-core/secp256k1.git
410

5-
if [ -z "$1" ] | [ -z "$2" ]; then
6-
echo "\$1 parameter must be the rust-secp256k1-sys depend directory"
7-
echo "\$2 parameter must be the rust-secp256k1-sys version code (M_m_p format)"
8-
echo "\$3 parameter (optional) can be the revision to check out"
9-
exit 1
10-
fi
11+
: "${SECP_VENDOR_VERSION_CODE:=$DEFAULT_VERSION_CODE}"
12+
: "${SECP_VENDOR_DEPEND_DIR:=$DEFAULT_DEPEND_DIR}"
13+
: "${SECP_VENDOR_SECP_REPO:=$DEFAULT_SECP_REPO}"
14+
# CP_NOT_CLONE lets us just copy a directory rather than git cloning.
15+
# This is usually a bad idea, since it will bring in build artifacts or any other
16+
# junk from the source directory, but may be useful during development or CI.
17+
: "${SECP_VENDOR_CP_NOT_CLONE:=no}"
18+
19+
echo "Using version code $SECP_VENDOR_VERSION_CODE. Set SECP_VENDOR_VERSION_CODE to override."
20+
echo "Using depend directory $SECP_VENDOR_DEPEND_DIR. Set SECP_VENDOR_DEPEND_DIR to override."
21+
echo "Using secp repository $SECP_VENDOR_SECP_REPO. Set SECP_VENDOR_SECP_REPO to override."
1122

12-
PARENT_DIR=$1
13-
VERSIONCODE=$2
14-
REV=$3
15-
DIR=secp256k1
16-
ORIGDIR=$(pwd)
17-
18-
while true; do
19-
read -r -p "$PARENT_DIR/$DIR will be deleted [yn]: " yn
20-
case $yn in
21-
[Yy]* ) break;;
22-
[Nn]* ) exit;;
23-
* ) echo "Please answer yes or no.";;
23+
# Parse command-line options
24+
SECP_REV=""
25+
FORCE=no
26+
while (( "$#" )); do
27+
case "$1" in
28+
-f)
29+
FORCE=yes
30+
;;
31+
*)
32+
if [ -z "$SECP_REV" ]; then
33+
echo "Using secp256k1 revision $SECP_REV."
34+
SECP_REV="$1"
35+
else
36+
echo "WARNING: ignoring unknown command-line argument $1"
37+
fi
38+
;;
2439
esac
40+
shift
2541
done
2642

27-
cd "$PARENT_DIR" || exit 1
28-
rm -rf "$DIR"
29-
git clone https://github.com/bitcoin-core/secp256k1.git "$DIR"
30-
cd "$DIR"
31-
if [ -n "$REV" ]; then
32-
git checkout "$REV"
43+
if [ -z "$SECP_REV" ]; then
44+
echo "WARNING: No secp256k1 revision specified. Will use whatever we find at the git repo."
45+
fi
46+
echo
47+
48+
# Check if we will do anything destructive.
49+
50+
if [ "$FORCE" == "no" ]; then
51+
if ! git diff --quiet -- "*.rs"; then
52+
echo "ERROR: There appear to be modified source files. Check these in or pass -f (some source files will be modified to have symbols renamed)."
53+
exit 2
54+
fi
55+
if ! git diff --quiet -- "$SECP_VENDOR_DEPEND_DIR"; then
56+
echo "ERROR: The depend directory appears to be modified. Check it in or pass -f (this directory will be deleted)."
57+
exit 2
58+
fi
59+
fi
60+
61+
DIR=./secp256k1
62+
63+
pushd "$SECP_VENDOR_DEPEND_DIR" > /dev/null
64+
rm -rf "$DIR" || true
65+
66+
# Clone the repo. As a special case, if the repo is a local path and we have
67+
# not specified a revision, just copy the directory rather than using 'git clone'.
68+
# This lets us use non-git repos or dirty source trees as secp sources.
69+
if [ "$SECP_VENDOR_CP_NOT_CLONE" == "yes" ]; then
70+
cp -r "$SECP_VENDOR_SECP_REPO" "$DIR"
71+
chmod -R +w "$DIR" # cp preserves write perms, which if missing will cause patch to fail
72+
else
73+
git clone "$SECP_VENDOR_SECP_REPO" "$DIR"
74+
fi
75+
76+
# Check out specified revision
77+
pushd "$DIR" > /dev/null
78+
if [ -n "$SECP_REV" ]; then
79+
git checkout "$SECP_REV"
3380
fi
34-
HEAD=$(git rev-parse HEAD)
35-
cd ..
81+
SOURCE_REV=$(git rev-parse HEAD || echo "[unknown revision from $SECP_VENDOR_SECP_REPO]")
82+
rm -rf .git/ || true
83+
popd
84+
85+
# Record revision
3686
echo "# This file was automatically created by $0" > ./secp256k1-HEAD-revision.txt
37-
echo "$HEAD" >> ./secp256k1-HEAD-revision.txt
87+
echo "$SOURCE_REV" >> ./secp256k1-HEAD-revision.txt
3888

39-
# We need to make some source changes to the files.
89+
# Patch source files
4090

4191
# To support compiling for WASM, we need to remove all methods that use malloc.
4292
# To compensate, the secp_context_create and _destroy methods are redefined in Rust.
@@ -46,28 +96,25 @@ patch "$DIR/src/scratch_impl.h" "./scratch_impl.h.patch"
4696
patch "$DIR/src/util.h" "./util.h.patch"
4797

4898
# Prefix all methods with rustsecp and a version prefix
49-
find "$DIR" -not -path '*/\.*' -type f -print0 | xargs -0 sed -i "/^#include/! s/secp256k1_/rustsecp256k1_v${VERSIONCODE}_/g"
50-
99+
find "$DIR" \
100+
-not -path '*/\.*' \
101+
-not -name "CHANGELOG.md" \
102+
-type f \
103+
-print0 | xargs -0 sed -i "/^#include/! s/secp256k1_/rustsecp256k1_v${SECP_VENDOR_VERSION_CODE}_/g"
51104
# special rule for a method that is not prefixed in libsecp
52-
find "$DIR" -not -path '*/\.*' -type f -print0 | xargs -0 sed -i "/^#include/! s/ecdsa_signature_parse_der_lax/rustsecp256k1_v${VERSIONCODE}_ecdsa_signature_parse_der_lax/g"
53-
54-
# TODO: can be removed once 496c5b43b lands in secp-zkp
55-
find "$DIR" -not -path '*/\.*' -type f -print0 | xargs -0 sed -i 's/^const int CURVE_B/static const int CURVE_B/g'
56-
57-
while true; do
58-
read -r -p "Update Rust extern references and Cargo.toml as well? [yn]: " yn
59-
case $yn in
60-
[Yy]* ) break;;
61-
[Nn]* ) exit;;
62-
* ) echo "Please answer yes or no.";;
63-
esac
64-
done
65-
66-
cd "$ORIGDIR"
105+
find "$DIR" \
106+
-not -path '*/\.*' \
107+
-type f \
108+
-print0 | xargs -0 sed -i "/^#include/! s/ecdsa_signature_parse_der_lax/rustsecp256k1_v${SECP_VENDOR_VERSION_CODE}_ecdsa_signature_parse_der_lax/g"
67109

110+
cd "$SECP_SYS"
68111
# Update the `links = ` in the manifest file.
69-
sed -i -r "s/^links = \".*\"$/links = \"rustsecp256k1_v${VERSIONCODE}\"/" Cargo.toml
70-
112+
sed -i -r "s/^links = \".*\"$/links = \"rustsecp256k1_v${SECP_VENDOR_VERSION_CODE}\"/" Cargo.toml
71113
# Update the extern references in the Rust FFI source files.
72-
find "./src/" -name "*.rs" -type f -print0 | xargs -0 sed -i -r "s/rustsecp256k1_v[0-9]+_[0-9]+_[0-9]+_(.*)([\"\(])/rustsecp256k1_v${VERSIONCODE}_\1\2/g"
114+
find "./src/" \
115+
-name "*.rs" \
116+
-type f \
117+
-print0 | xargs -0 sed -i -r "s/rustsecp256k1_v[0-9]+_[0-9]+_[0-9]+_(.*)([\"\(])/rustsecp256k1_v${SECP_VENDOR_VERSION_CODE}_\1\2/g"
118+
119+
popd > /dev/null
73120

0 commit comments

Comments
 (0)