diff --git a/checkBuild.sh b/checkBuild.sh index 570a93b4cd..deeafaf5fb 100755 --- a/checkBuild.sh +++ b/checkBuild.sh @@ -1,6 +1,10 @@ -#!/bin/bash +#!/bin/sh -if [[ $# -eq 0 ]] ; then +set -euf + +die () { echo "Error: $*"; exit 1; } + +if [ $# -eq 0 ]; then printf "No arguments supplied.\nUsage: ./checkBuild.sh FILE REVISION [RETRIES]\n\n \ FILE The apk you want to verify, without extension. mbw-prodnet-release for example\n \ REVISION The git revision, tag or branch. v2.12.0.19 for example.\n \ @@ -16,90 +20,99 @@ revision=$2 # with every iteration. Pick how many retries you want to run: retries=${3:-0} -if [[ ! -f "./${releaseFile}.apk" ]] +if [ ! -f "./${releaseFile}.apk" ] then - echo "./${releaseFile}.apk not found. Put the file you want to test into this folder and reference it omitting the \".apk\"." - exit 1 + die "./${releaseFile}.apk not found. Put the file you want to test into this folder and reference it omitting the \".apk\"." fi -if [[ ! -f "apktool.jar" ]] +if [ ! -f "apktool.jar" ] then - echo "apktool.jar not found. Put the file into this folder. You can get it from https://ibotpeaches.github.io/Apktool/ or https://github.com/iBotPeaches/Apktool" - exit 1 + die "apktool.jar not found. Put the file into this folder. You can get it from https://ibotpeaches.github.io/Apktool/ or https://github.com/iBotPeaches/Apktool" fi workdir=/tmp/mbwDeterministicBuild/ -mkdir -p $workdir +mkdir -p -- "$workdir" || die "Cannot create directory $workdir" -printf "Checking $releaseFile against revision $revision with $retries retries if verification fails.\n \ -You can monitor progress in ${workdir}progress.log\n" | tee ${workdir}progress.log +printf "%s\n%s\n" "Checking $releaseFile against revision $revision with $retries retries if verification fails." \ +"You can monitor progress in ${workdir}progress.log" | tee "${workdir}progress.log" -cp -r . $workdir -cd $workdir +if ! cp -r -- . "$workdir" || ! cd -- "$workdir" +then + die "Error: Cannot cp and cd to $workdir (maybe no disk space?)" +fi -rm local.properties # this doesn't work in docker and shouldn't be needed outside of docker. +rm -f -- local.properties || true # this doesn't work in docker and shouldn't be needed outside of docker. -java -jar apktool.jar d --output original $releaseFile.apk +java -jar apktool.jar d --output original "$releaseFile.apk" git config user.email "only@thistmprepo.com" git config user.name "only temporary" git stash -git checkout $revision +git checkout -- "$revision" || die "Invalid commit." sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules -git submodule update --init --recursive +git submodule update --init --recursive || die "Cannot initialize submodules." # these files are either irrelevant (apktool.yml is created by the akp extractor) or not reproducible signature/meta data (CERT, MANIFEST) ignoreFiles="apktool.yml\|original/META-INF/CERT.RSA\|original/META-INF/CERT.SF\|original/META-INF/MANIFEST.MF" ./gradlew clean :mbw:assProdRel -cp ./mbw/build/outputs/apk/prodnet/release/mbw-prodnet-release.apk candidate.apk +cp ./mbw/build/outputs/apk/prodnet/release/mbw-prodnet-release.apk candidate.apk || + die "Cannot copy a file (maybe no disk space?)" if [ ! -e candidate.apk ] then - echo "Unexpected error: candidate.apk doesn't exist. Possibly the build failed. Check and try again." - exit 1 + die "Unexpected error: candidate.apk doesn't exist. Possibly the build failed. Check and try again." fi java -jar apktool.jar d candidate.apk +set +x diff --brief --recursive original/ candidate/ > 0.diff +set -x mv candidate/ 0/ # store the list of relevant differing files in remaining.diff -cat 0.diff | grep -v "$ignoreFiles" > remaining.diff +set +x +grep -v -- "$ignoreFiles" 0.diff > remaining.diff +set -x checkFinished() { # if remaining.diff is empty, we are done. if [ ! -s remaining.diff ] then - printf "$releaseFile matches $revision!\n" >> progress.log + printf "%s\n" "$releaseFile matches $revision!" >> progress.log cat progress.log exit 0 else - printf "$(cat remaining.diff | wc -l) files differ. Trying harder to find matches.\n \ - Remaining files:\n$(cat remaining.diff)\n\n" >> progress.log + printf "%s\n%s\n%s\n\n" "$(wc -l remaining.diff) files differ. Trying harder to find matches." \ + "Remaining files:" "$(cat remaining.diff)" >> progress.log fi } checkFinished -for i in $( seq 1 $retries ) ; do - printf "Deterministic build failed. Attempt $i to still confirm all files individually under not totally deterministic conditions.\n" >> progress.log +for i in $( seq 1 "$retries" ) ; do + printf "%s\n" "Deterministic build failed. Attempt $i to still confirm all files individually under not totally deterministic conditions." >> progress.log ./gradlew clean :mbw:assProdRel - cp ./mbw/build/outputs/apk/prodnet/release/mbw-prodnet-release.apk candidate.apk + cp ./mbw/build/outputs/apk/prodnet/release/mbw-prodnet-release.apk candidate.apk || + die "Cannot copy a file (maybe no disk space?)" java -jar apktool.jar d candidate.apk # join remaining filenames to a grep filter. Only these file names are relevant. - relevantFilesFilter=$(cat remaining.diff | paste -sd "|" - | sed 's/|/\\\|/g') + relevantFilesFilter="$(paste -sd "|" remaining.diff | sed 's/|/\\\|/g')" # diff, only listing files that differ - diff --brief --recursive original/ candidate/ > $i.diff - mv candidate/ $i/ + set +x + diff --brief --recursive original/ candidate/ > "$i.diff" + set -x + mv -- candidate/ "$i/" # diff lines that were present in all prior diffs get stored in remaining.diff - cat $i.diff | grep "$relevantFilesFilter" > remaining.diff + set +x + grep -- "$relevantFilesFilter" "$i.diff" > remaining.diff + set -x checkFinished done -printf "Error: The following files could not be verified:\n \ -$( cat remaining.diff ) \ -Error: Giving up after $retries retries. Please manually check if the differing files are acceptable using meld or any other folder diff tool.\n \ -Not every tiny diff is a red flag. Maybe this script is broken. Maybe a tool compiles in a non-deterministic way. Both happened before." \ +printf "%s\n%s%s\n%s" "Error: The following files could not be verified:" \ +"$(cat remaining.diff)" \ +"Error: Giving up after $retries retries. Please manually check if the differing files are acceptable using meld or any other folder diff tool." \ +"Not every tiny diff is a red flag. Maybe this script is broken. Maybe a tool compiles in a non-deterministic way. Both happened before." \ | tee -a progress.log exit 1 diff --git a/collectApks.sh b/collectApks.sh index 2bfabcdc0c..bbf931b818 100755 --- a/collectApks.sh +++ b/collectApks.sh @@ -2,12 +2,19 @@ # this script helps wrap up the currently 8 apks into 2 zips, named containing the versionName -releasefolder="/tmp/release_mbw/comp_"$(date +"%s")"/" -mbwVersion=$( grep "versionName '" mbw/build.gradle | sed "s/.*versionName //g" | sed "s/'//g" ) -mkdir -p $releasefolder -for f in $( find . -name *.apk ); do - echo $f - cp $f $releasefolder -done -zip $releasefolder"release_mbw_${mbwVersion}.zip" ${releasefolder}mbw*.apk >/dev/null 2>&1 -echo done +set -euf + +releasefolder="/tmp/release_mbw/comp_$(date +%s)/" +mbwVersion="$( grep "versionName '" mbw/build.gradle | sed "s/.*versionName //g" | sed "s/'//g" )" +mkdir -p -- "$releasefolder" +if ! find . -name "*.apk" -exec echo {} \; -exec cp -- {} "$releasefolder" \; ; then + printf "Error: Cannot copy a file (maybe no disk space?)" + exit 1 +fi + +if ! zip "${releasefolder}release_mbw_${mbwVersion}.zip" "${releasefolder}mbw*.apk" >/dev/null 2>&1; then + printf "Error: Cannot zip a file (maybe no disk space?)" + exit 1 +fi + +printf "Done\n" diff --git a/gradlew b/gradlew index 4453ccea33..dc5a40bea3 100755 --- a/gradlew +++ b/gradlew @@ -1,4 +1,4 @@ -#!/usr/bin/env sh +#!/bin/sh ############################################################################## ## @@ -6,26 +6,35 @@ ## ############################################################################## +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +set -euf + # Attempt to set APP_HOME # Resolve links: $0 may be a link PRG="$0" # Need this for relative symlinks. while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` + ls="$(ls -ld "$PRG")" + link="$(expr "$ls" : '.*-> \(.*\)$')" if expr "$link" : '/.*' > /dev/null; then PRG="$link" else - PRG=`dirname "$PRG"`"/$link" + PRG="$(dirname "$PRG")/${link}" fi done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null +SAVED="$(pwd)" +cd "$(dirname "$PRG")/" || die "Error: Cannot cd to $(dirname "$PRG")/" +APP_HOME="$(pwd -P)" +cd "$SAVED" || die "Error: Cannot cd to $SAVED" APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME="$(basename "$0")" # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS="" @@ -37,19 +46,12 @@ warn ( ) { echo "$*" } -die ( ) { - echo - echo "$*" - echo - exit 1 -} - # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in +case "$(uname)" in CYGWIN* ) cygwin=true ;; @@ -64,7 +66,7 @@ case "`uname`" in ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="$APP_HOME/gradle/wrapper/gradle-wrapper.jar" # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then @@ -89,14 +91,12 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then +if [ "$cygwin" = "false" ] && [ "$darwin" = "false" ] && [ "$nonstop" = "false" ] ; then + if MAX_FD_LIMIT="$(ulimit -H -n)"; then + if [ "$MAX_FD" = "maximum" ] || [ "$MAX_FD" = "max" ] ; then MAX_FD="$MAX_FD_LIMIT" fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then + if ! ulimit -n "$MAX_FD"; then warn "Could not set maximum file descriptor limit: $MAX_FD" fi else @@ -105,18 +105,18 @@ if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then fi # For Darwin, add options to specify how the application appears in the dock -if $darwin; then +if [ "$darwin" = "true" ]; then GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" fi # For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` +if [ "$cygwin" = "true" ]; then + APP_HOME="$(cygpath --path --mixed "$APP_HOME")" + CLASSPATH="$(cygpath --path --mixed "$CLASSPATH")" + JAVACMD="$(cygpath --unix "$JAVACMD")" # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + ROOTDIRSRAW="$(find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null)" SEP="" for dir in $ROOTDIRSRAW ; do ROOTDIRS="$ROOTDIRS$SEP$dir" @@ -124,19 +124,19 @@ if $cygwin ; then done OURCYGPATTERN="(^($ROOTDIRS))" # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then + if [ -n "$GRADLE_CYGPATTERN" ] ; then OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" fi # Now convert the arguments - kludge to limit ourselves to /bin/sh i=0 for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + CHECK="$(echo "$arg"|grep -E -c "$OURCYGPATTERN" -)" + CHECK2="$(echo "$arg"|grep -E -c "^-")" ### Determine if an option - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + if [ "$CHECK" != "0" ] && [ "$CHECK2" = "0" ] ; then ### Added a condition + eval "args${i}"="$(cygpath --path --ignore --mixed "${arg}")" else - eval `echo args$i`="\"$arg\"" + eval "args${i}"="${arg}" fi i=$((i+1)) done @@ -159,10 +159,10 @@ save ( ) { for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done echo " " } -APP_ARGS=$(save "$@") +APP_ARGS="$(save "$@")" # Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" +eval "set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"-Dorg.gradle.appname=$APP_BASE_NAME\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain $APP_ARGS" # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then diff --git a/mbw/res-sources/updateDrawables.sh b/mbw/res-sources/updateDrawables.sh index 5b98965200..582a62d28c 100755 --- a/mbw/res-sources/updateDrawables.sh +++ b/mbw/res-sources/updateDrawables.sh @@ -1,36 +1,33 @@ #!/bin/bash +set -euf -o pipefail + +die () { echo "Error: $*"; exit 1; } + sizeNames=(ldpi mdpi hdpi xhdpi xxhdpi) sizes=(360 480 720 960 1800) fileIn=localTraderLocalOnly.png fileOut=lt_local_only_warning.png -for ((n=0; n <= 4; n++)) -do - fOut="../src/main/res/drawable-"${sizeNames[n]}"/"$fileOut - convert -background none -resize ${sizes[n]}"x" $fileIn - | \ - pngquant --force 64 > $fOut -done +conv_function () { + for ((n=0; n <= 4; n++)) + do + fOut="../src/main/res/drawable-${sizeNames[n]}/${fileOut}" + convert -background none -resize "${sizes[n]}x" "$fileIn" - | \ + pngquant --force 64 > "$fOut" || die "Command failed." + done +} +conv_function || die "Command failed." sizes=(100 133 200 267 400) fileIn=creditCard.png fileOut=credit_card_buy.png -for ((n=0; n <= 4; n++)) -do - fOut="../src/main/res/drawable-"${sizeNames[n]}"/"$fileOut - convert -background none -resize ${sizes[n]}"x" $fileIn - | \ - pngquant --force 64 > $fOut -done +conv_function || die "Command failed." sizes=(100 133 200 267 400) fileIn=mycelium_logo_transp.png fileOut=mycelium_logo_transp.png -for ((n=0; n <= 4; n++)) -do - fOut="../src/main/res/drawable-"${sizeNames[n]}"/"$fileOut - convert -background none -resize ${sizes[n]}"x" $fileIn - | \ - pngquant --force 64 > $fOut -done \ No newline at end of file +conv_function || die "Command failed." diff --git a/mbw/updateTranslations.sh b/mbw/updateTranslations.sh index abee78555d..f4218792fc 100755 --- a/mbw/updateTranslations.sh +++ b/mbw/updateTranslations.sh @@ -1,17 +1,28 @@ #!/bin/sh -APIKEY=`cat ~/.mycelium_crowdin_api` +set -euf -cwd=`pwd` +die () { echo "Error: $*"; exit 1; } + +APIKEY="$(cat ~/.mycelium_crowdin_api)" + +cwd="$(pwd)" dir=/tmp/translation -rm -r ${dir} -mkdir -p ${dir} || exit -echo " " > $dir/1.xml -echo " " > $dir/2.xml -cd ${dir} || exit -rm -f mycelium-bitcoin-wallet.zip -wget -O all.zip https://api.crowdin.com/api/project/mycelium-bitcoin-wallet/download/all.zip?key=$APIKEY || exit -unzip -q all.zip -d ${dir} || exit +rm -rf -- "$dir" || die "Cannot remove $dir" +mkdir -p -- "$dir" || die "Cannot create directory $dir" +echo " " > "$dir/1.xml" +echo " " > "$dir/2.xml" +cd -- "$dir" || die "Cannot cd to $dir" +rm -f mycelium-bitcoin-wallet.zip || die "Cannot remove mycelium-bitcoin-wallet.zip" +url="https://api.crowdin.com/api/project/mycelium-bitcoin-wallet/download/all.zip?key=$APIKEY" +if command -v curl; then +curl -LfS --tlsv1.2 --output all.zip -- "$url" || die "Cannot curl url $url" +elif command -v wget; then + wget --secure-protocol=TLSv1_2 -O all.zip -- "$url" || die "Cannot wget url $url" +else + die "Please install either curl or wget." +fi +unzip -q all.zip -d "$dir" || die "Cannot unzip all.zip" UpdateOne () { # arg 1: source folder as in ../${1}/strings.xml @@ -19,13 +30,16 @@ UpdateOne () { # arg 3: Language name in language itself echo "Updating language ${1}" if [ "$1" != "en" ]; then - mkdir -p ${cwd}/src/main/res/values-${2} && cp -f ${dir}/${1}/strings.xml ${cwd}/src/main/res/values-${2} || echo "Failed to update language ${1}" + if ! mkdir -p -- "${cwd}/src/main/res/values-${2}" || + ! cp -f -- "${dir}/${1}/strings.xml" "${cwd}/src/main/res/values-${2}"; then + die "Failed to update language ${1}" + fi fi - echo " ${2}" >> $dir/1.xml - echo " ${3}" >> $dir/2.xml + echo " ${2}" >> "$dir/1.xml" + echo " ${3}" >> "$dir/2.xml" } -mkdir -p ${cwd}/res/values || exit +mkdir -p -- "${cwd}/res/values" || die "Cannot create directory ${cwd}/res/values" UpdateOne bg bg Български Bulgarian-Bulgaria UpdateOne cs cs čeština Czech @@ -54,8 +68,8 @@ UpdateOne vi vi "Tiếng Việt" Vietnamese-Vietnam UpdateOne zh-CN zh 简体中文 Chinese-China UpdateOne zh-TW zh-rTW 繁体中文 Chinese-Taiwan -echo " " >> $dir/1.xml -echo " " >> $dir/2.xml +echo " " >> "$dir/1.xml" +echo " " >> "$dir/2.xml" echo "Add or update the following in your strings_nolocale.xml. The zh-rTW might have to be zh-TW though:" -cat $dir/1.xml $dir/2.xml +cat -- "$dir/1.xml" "$dir/2.xml" diff --git a/trezor/build_pb.sh b/trezor/build_pb.sh index be45c319c8..fe40b3fd20 100755 --- a/trezor/build_pb.sh +++ b/trezor/build_pb.sh @@ -1,13 +1,19 @@ -#!/bin/bash +#!/bin/sh # create directory ../trezor-common by running # git clone https://github.com/trezor/trezor-common -CURDIR=$(pwd) +set -euf -cd $CURDIR/../trezor-common/protob +CURDIR="$(pwd)" + +if ! cd "$CURDIR/../trezor-common/protob"; then + printf "Cannot cd to %s\n" "$CURDIR/../trezor-common/protob" + exit 1 +fi for i in messages types ; do - echo $i - protoc --java_out=$CURDIR/src/ $i.proto + printf "%s\n" "$i" + protoc --java_out="$CURDIR/src/" "$i.proto" || + printf "Command %s failed\n" "protoc --java_out=\"$CURDIR/src/\" \"$i.proto\"" done