diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 87f4982..e8a3ff8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -30,6 +30,6 @@ jobs: checkout_dir=$PWD chmod -R a+r "$checkout_dir" find "$checkout_dir" -executable -type f -exec chmod a+x {} \; - sudo -u yugabyte-ci -E /bin/bash -c "cd '$checkout_dir' && ./build-and-release.sh" + sudo -u yugabyte-ci -E /bin/bash -c "cd '$checkout_dir' && ./test.sh && ./build-and-release.sh" env: GITHUB_TOKEN: $(yugabyte.githubToken) diff --git a/brew-build.sh b/brew-build.sh index 66a80e8..d2e2d3f 100755 --- a/brew-build.sh +++ b/brew-build.sh @@ -15,29 +15,73 @@ set -euo pipefail -COMMON_SH="${0%/*}/brew-common.sh" +readonly COMMON_SH="${0%/*}/brew-common.sh" . "$COMMON_SH" +# ------------------------------------------------------------------------------------------------- +# Constants +# ------------------------------------------------------------------------------------------------- + +readonly YB_USE_SSE4=${YB_USE_SSE4:-1} export HOMEBREW_NO_AUTO_UPDATE=1 +BREW_FROM_SRC_PACKAGES=( + autoconf + automake + bzip2 + flex + gcc + icu4c + libtool + libuuid + ninja + openssl + readline + s3cmd +) -[[ -x ./bin/brew ]] || fatal "This script should be run inside Homebrew/Linuxbrew directory." +BREW_BIN_PACKAGES=( + gcc@8 +) + +# ------------------------------------------------------------------------------------------------- +# Functions +# ------------------------------------------------------------------------------------------------- + +brew_install_packages() { + local package + for package in "$@"; do + if ( set -x; ./bin/brew install $install_args "$package" ); then + successful_packages+=( "$package" ) + else + log "Failed to install package: $package" + failed_packages+=( "$package" ) + fi + done +} + +# ------------------------------------------------------------------------------------------------- +# Main script +# ------------------------------------------------------------------------------------------------- + +if [[ ! -x ./bin/brew ]]; then + fatal "This script should be run inside Homebrew/Linuxbrew directory." +fi -YB_USE_SSE4=${YB_USE_SSE4:-1} +cd "$(realpath .)" +BREW_HOME=$PWD echo echo "============================================================================================" -echo "Building Homebrew/Linuxbrew in $PWD" +echo "Building Homebrew/Linuxbrew in $BREW_HOME" echo "YB_USE_SSE4=$YB_USE_SSE4" echo "============================================================================================" echo -cd "$(realpath .)" -BREW_HOME=$PWD - LEN=${#BREW_HOME} -[[ $LEN -eq $ABS_PATH_LIMIT ]] || +if [[ $LEN -ne $ABS_PATH_LIMIT ]]; then fatal "Homebrew absolute path should be exactly $ABS_PATH_LIMIT bytes, but actual length is" \ "$LEN bytes: $BREW_HOME" +fi openssl_formula=./Library/Taps/homebrew/homebrew-core/Formula/openssl.rb openssl_orig=./Library/Taps/homebrew/homebrew-core/Formula/openssl.rb.orig @@ -48,7 +92,6 @@ if [[ ! -e "$openssl_orig" ]]; then cp "$openssl_formula" "$openssl_orig" fi -install_args="--build-from-source" sse4_flags="" if [[ $YB_USE_SSE4 == "0" ]]; then echo "YB_USE_SSE4=$YB_USE_SSE4, disabling use of SSE4" @@ -96,51 +139,32 @@ EOF fi unset sse4_flags -BREW_PACKAGES=( - autoconf - automake - bzip2 - flex - gcc - icu4c - libtool - libuuid - ninja - openssl - readline - s3cmd -) +# ------------------------------------------------------------------------------------------------- +# Package installation +# ------------------------------------------------------------------------------------------------- -BREW_BIN_PACKAGES=( - gcc@8 -) +if [[ ${YB_BREW_BUILD_UNIT_TEST_MODE:-0} == "1" ]]; then + BREW_FROM_SRC_PACKAGES=() + BREW_BIN_PACKAGES=( patchelf ) +fi successful_packages=() failed_packages=() -for package in "${BREW_PACKAGES[@]}"; do - if ( set -x; ./bin/brew install $install_args "$package" ); then - successful_packages+=( "$package" ) - else - echo >&2 "Failed to install package: $package" - failed_packages+=( "$package" ) - fi -done - -for package in "${BREW_BIN_PACKAGES[@]}"; do - if ( set -x; ./bin/brew install "$package" ); then - successful_packages+=( "$package" ) - else - echo >&2 "Failed to install package: $package" - failed_packages+=( "$package" ) - fi -done +install_args="" +if [[ ${#BREW_BIN_PACKAGES[@]} -gt 0 ]]; then + brew_install_packages "${BREW_BIN_PACKAGES[@]}" +fi +install_args="--build-from-source" +if [[ ${#BREW_FROM_SRC_PACKAGES[@]} -gt 0 ]]; then + brew_install_packages "${BREW_FROM_SRC_PACKAGES[@]}" +fi +unset install_args -echo "Successfully installed packages: ${successful_packages[*]}" +log "Successfully installed packages: ${successful_packages[*]}" if [[ ${#failed_packages[@]} -gt 0 ]]; then - echo >&2 "Failed to install packages: ${failed_packages[*]}" - exit 1 + fatal "Failed to install packages: ${failed_packages[*]}" fi if [[ ! -e VERSION_INFO ]]; then @@ -153,7 +177,7 @@ if [[ ! -e VERSION_INFO ]]; then mv VERSION_INFO.tmp VERSION_INFO fi -echo "Updating symlinks ..." +log "Updating symlinks ..." find . -type l | while read f do target=$(readlink "$f") @@ -163,14 +187,14 @@ do # We want to convert relative links pointing outside of Homebrew/Linuxbrew to absolute links. # -f to allow relinking. -T to avoid linking inside directory if $f already exists as # directory. - ln -sfT "$real_target" "$f" + create_symlink "$real_target" "$f" fi else - echo >&2 "Link $f seems broken" + log "Link $f seems broken" fi done -echo "Preparing list of files to be patched during installation ..." +log "Preparing list of files to be patched during installation ..." find ./Cellar -type f | while read f do if grep -q "$BREW_HOME" "$f"; then @@ -185,9 +209,20 @@ do fi done | sort >LINKS_TO_PATCH +for repo_dir in "" Library/Taps/*/*; do + ( + cd "$repo_dir" + log "Creating GIT_SHA1 and GIT_URL files in directory $PWD" + git rev-parse HEAD >GIT_SHA1 + log "Git SHA1: $( cat GIT_SHA1 )" + git remote -v | egrep '^origin.*[(]fetch[)]$' | awk '{print $2}' >GIT_URL + log "Git URL: $( cat GIT_URL )" + ) +done + BREW_HOME_ESCAPED=$(get_escaped_sed_replacement_str "$BREW_HOME") -cp $COMMON_SH . +cp "$COMMON_SH" . sed "s/{{ orig_brew_home }}/$BREW_HOME_ESCAPED/g" "${0%/*}/post_install.template" >post_install.sh chmod +x post_install.sh @@ -197,8 +232,8 @@ archive_name=$distr_name.tar.gz distr_path=$(realpath "../$archive_name") echo "Preparing Homebrew/Linuxbrew distribution archive: $distr_path ..." distr_name_escaped=$(get_escaped_sed_replacement_str "$distr_name" "%") -tar zcf "$distr_path" . --transform s%^./%$distr_name_escaped/% --exclude ".git" +run_tar zcf "$distr_path" --exclude ".git" --transform s%^./%$distr_name_escaped/% . pushd .. -sha256sum $archive_name >$archive_name.sha256 +sha256sum "$archive_name" >$archive_name.sha256 popd -echo "Done" +log "Done" diff --git a/brew-clone-and-build-all.sh b/brew-clone-and-build-all.sh index 773c748..f70951a 100755 --- a/brew-clone-and-build-all.sh +++ b/brew-clone-and-build-all.sh @@ -17,13 +17,19 @@ set -euo pipefail . "${0%/*}/brew-common.sh" +readonly YB_BREW_BUILD_ROOT=$( cd "${BASH_SOURCE%/*}" && pwd ) + export HOMEBREW_CACHE=$PWD/brew_cache export HOMEBREW_LOGS=$PWD/brew_logs set_brew_timestamp time ( - for YB_USE_SSE4 in 0 1; do + for YB_USE_SSE4 in 1 0; do + if [[ $YB_USE_SSE4 == "0" && ${YB_BREW_BUILD_SSE4_ONLY:-0} == "1" ]]; then + log "Skipping building the non-SSE4 configuration: YB_BREW_BUILD_SSE4_ONLY is set" + continue + fi export YB_USE_SSE4 if [[ $YB_USE_SSE4 == "1" ]]; then export YB_BREW_SUFFIX="" @@ -32,7 +38,6 @@ time ( fi rm -f "latest_brew_clone_dir.txt" "$YB_BREW_BUILD_ROOT"/brew-clone.sh - set -x brew_home=$( cat "latest_brew_clone_dir.txt" ) brew_path_prefix=$( cat "latest_brew_path_prefix.txt" ) archive_path=$brew_path_prefix.tar.gz diff --git a/brew-clone.sh b/brew-clone.sh index c203b1e..770fcfc 100755 --- a/brew-clone.sh +++ b/brew-clone.sh @@ -21,16 +21,18 @@ set -euo pipefail . "${0%/*}/brew-common.sh" -brew_path_prefix=$(get_brew_path_prefix) +get_brew_path_prefix if [[ -d $brew_path_prefix ]]; then fatal "Directory $brew_path_prefix already exists, cannot clone the repo." fi -set -x -git clone https://github.com/Homebrew/brew "$brew_path_prefix" -brew_home=$(get_fixed_length_path "$brew_path_prefix") +git clone https://github.com/Homebrew/brew "$brew_path_prefix" --depth 1 +get_fixed_length_path "$brew_path_prefix" +brew_home=$fixed_length_path if [[ -d $brew_home ]]; then - if [[ ${YB_BREW_REUSE_PREBUILT:-} == "1" ]]; then + if [[ $brew_prefix_path == $brew_home ]]; then + log "Directory path $brew_home is already of correct length." + elif [[ ${YB_BREW_REUSE_PREBUILT:-} == "1" ]]; then log "Directory $brew_home already exists, will reuse it." rm -rf "$brew_path_prefix" else @@ -38,7 +40,11 @@ if [[ -d $brew_home ]]; then fi else mv "$brew_path_prefix" "$brew_home" + create_symlink "${brew_home##*/}" "$brew_path_prefix" fi +echo "$brew_home" >"$brew_home/ORIG_BREW_HOME" +( cd "$brew_home" && git rev-parse HEAD ) >"$brew_home/GIT_SHA1" + echo "$brew_home" >latest_brew_clone_dir.txt echo "$brew_path_prefix" >latest_brew_path_prefix.txt diff --git a/brew-common.sh b/brew-common.sh index b21930a..653be9c 100755 --- a/brew-common.sh +++ b/brew-common.sh @@ -20,8 +20,33 @@ if [[ $BASH_SOURCE == $0 ]]; then exit 1 fi +# ------------------------------------------------------------------------------------------------- +# Constants +# ------------------------------------------------------------------------------------------------- + declare -i -r ABS_PATH_LIMIT=85 +if [[ $OSTYPE == linux* ]]; then + readonly YB_BREW_TYPE_LOWERCASE=linuxbrew + readonly YB_BREW_TYPE_CAPITALIZED=Linuxbrew + readonly YB_OS_FAMILY=linux +elif [[ $OSTYPE == darwin* ]]; then + readonly YB_BREW_TYPE_LOWERCASE=homebrew + readonly YB_BREW_TYPE_CAPITALIZED=Homebrew + readonly YB_OS_FAMILY=macos + + function sha256sum() { + shasum -a 256 "$@" + } +else + echo >&2 "Unknown OS type: $OSTYPE" + exit 1 +fi + +# ------------------------------------------------------------------------------------------------- +# Functions +# ------------------------------------------------------------------------------------------------- + log() { echo >&2 "[$( date +%Y-%m-%dT%H:%M:%S )] $*" } @@ -31,43 +56,79 @@ fatal() { exit 1 } +heading() { + echo >&2 "--------------------------------------------------------------------------------------" + echo >&2 "$*" + echo >&2 "--------------------------------------------------------------------------------------" +} + +create_symlink() { + if [[ $OSTYPE == linux* ]]; then + # -s - symbolic link + # -f - remove existing destination files + # -T (--no-target-directory) - treat LINK_NAME as a normal file always + ln -sfT "$@" + else + ln -sf "$@" + fi +} + +run_tar() { + if [[ $OSTYPE == linux* ]]; then + tar "$@" + else + gtar "$@" + fi +} + set_brew_timestamp() { if [[ -z ${YB_BREW_TIMESTAMP:-} ]]; then export YB_BREW_TIMESTAMP=$(date +%Y%m%dT%H%M%S) fi } +# Returns the prefix for a new Homebrew/Linuxbrew installation path, based on the current directory, +# YB_BREW_TYPE ("homebrew" or "linuxbrew") and YB_BREW_TIMESTAMP (which would be set on demand). +# The return value is placed in the brew_path_prefix variable in the parent scope. get_brew_path_prefix() { set_brew_timestamp - local brew_dirname="$YB_BREW_DIR_PREFIX-$YB_BREW_TIMESTAMP" - local brew_path_prefix="$(realpath .)/$brew_dirname" + brew_path_prefix="$(realpath .)/$YB_BREW_TYPE_LOWERCASE-$YB_BREW_TIMESTAMP" if [[ -n ${YB_BREW_SUFFIX:-} ]]; then brew_path_prefix+="-$YB_BREW_SUFFIX" fi local len=${#brew_path_prefix} if [[ $len -gt $ABS_PATH_LIMIT ]]; then - echo "Homebrew/Linuxbrew absolute path should be no more than $ABS_PATH_LIMIT bytes, but " \ - "actual length is $len bytes: $brew_path_prefix" >&2 - exit 1 + fatal "Homebrew/Linuxbrew absolute path should be no more than $ABS_PATH_LIMIT bytes, but " \ + "actual length is $len bytes: $brew_path_prefix" fi - echo "$brew_path_prefix" } -readonly YB_BREW_BUILD_ROOT=$( cd "${BASH_SOURCE%/*}" && pwd ) - # Extends the given path so that it has a fixed length. # Parameters: # path - source path. # len - required output path length. Optional parameter, if absent uses $ABS_PATH_LIMIT. +# git_sha1 - use this Git SHA1 for the filler part of the path. +# +# Return value: the variable fixed_length_path in the parent scope. get_fixed_length_path() { - local path="$1" - if [[ ! -d $path ]]; then - fatal "Directory '$path' does not exist" + local path=$1 + local len=${2:-$ABS_PATH_LIMIT} + local sha1=${3:-} + + # Use the Git SHA1 of the Homebrew repository as a filler. + if [[ -z $sha1 ]]; then + if [[ ! -d $path/.git ]]; then + fatal "Directory '$path' is not a Git repository, cannot get SHA1" + fi + sha1=$( cd "$path" && git rev-parse HEAD ) fi - local len="${2:-$ABS_PATH_LIMIT}" - # Generate a path of a fixed length (up to a certain maximum length). - local sha1=$( cd "$path" && git rev-parse HEAD ) - echo "$path-$(echo "$sha1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" )" | cut -c-$len + if [[ ! $sha1 =~ ^[0-9a-f]{40}$ ]]; then + fatal "Invalid Git SHA1: '$sha1'" + fi + + fixed_length_path=\ +"$path-${sha1}xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + fixed_length_path=${fixed_length_path:0:$len} } # Escape special characters in source string, so it can be used with sed as simple string pattern. @@ -91,9 +152,3 @@ get_escaped_sed_replacement_str() { local delim=${2:-/} sed "s/[$delim&\]/\\\\&/g" <<<$1 } - -if [[ $OSTYPE == linux* ]]; then - YB_BREW_DIR_PREFIX=linuxbrew -else - YB_BREW_DIR_PREFIX=homebrew -fi diff --git a/brew-copy.sh b/brew-copy.sh index 709169b..4033fb3 100755 --- a/brew-copy.sh +++ b/brew-copy.sh @@ -32,27 +32,48 @@ if [[ $# -lt 1 ]]; then show_help_and_exit fi -SRC_BREW_HOME=$(realpath $1) +if [[ -z "$1" ]]; then + fatal "Empty path specified" +fi + +SRC_BREW_HOME=$(realpath "$1") if [[ ! -x $SRC_BREW_HOME/bin/brew ]]; then - echo >&2 " should point to a Homebrew/Linuxbrew directory." - show_help_and_exit + fatal " should point to a Homebrew/Linuxbrew directory." +fi + +git_sha1_path="$SRC_BREW_HOME/GIT_SHA1" +if [[ ! -f $git_sha1_path ]]; then + fatal "File '$git_sha1_path' not found" +fi +git_sha1=$( cat "$git_sha1_path" ) +get_brew_path_prefix +BREW_LINK=$brew_path_prefix +get_fixed_length_path "$BREW_LINK" "$ABS_PATH_LIMIT" "$git_sha1" +BREW_HOME=$fixed_length_path +if [[ -e $BREW_HOME ]]; then + fatal "Directory or file '$BREW_HOME' already exists" fi -BREW_LINK=$(get_brew_link) -BREW_HOME=$(get_fixed_length_path "$BREW_LINK") +log "Copying existing Homebrew/Linuxbrew installation from $SRC_BREW_HOME to $BREW_HOME" -echo "Copying to $BREW_HOME ..." -mkdir -p "$BREW_HOME" -# Recursively copy files tree, copy symlinks as symlinks, preserve hard links. -rsync -rlH "$SRC_BREW_HOME/" "$BREW_HOME/" +( + set -x + mkdir -p "$BREW_HOME" -echo "Patching files ..." + # Recursively copy files tree, copy symlinks as symlinks, preserve hard links. + time rsync -rlH "$SRC_BREW_HOME/" "$BREW_HOME/" +) + +log "Patching files ..." SRC_BREW_HOME_ESCAPED=$(get_escaped_sed_re "$SRC_BREW_HOME") BREW_HOME_ESCAPED=$(get_escaped_sed_replacement_str "$BREW_HOME") + find "$BREW_HOME" -type f | while read f do - sed -i --binary "s/$SRC_BREW_HOME_ESCAPED/$BREW_HOME_ESCAPED/g" "$f" + # Regarding LC_ALL=C: + # https://stackoverflow.com/questions/19242275/re-error-illegal-byte-sequence-on-mac-os-x + LC_ALL=C sed -i --binary "s/$SRC_BREW_HOME_ESCAPED/$BREW_HOME_ESCAPED/g" "$f" done echo "Updating symlinks ..." @@ -62,10 +83,10 @@ do if [[ $target == $SRC_BREW_HOME* ]]; then target="${target/$SRC_BREW_HOME/$BREW_HOME}" # -f to allow relinking. -T to avoid linking inside directory if $f already exists as directory. - ln -sfT "$target" "$f" + create_symlink "$target" "$f" fi done echo "Done" -ln -s "$BREW_HOME" "$BREW_LINK" +create_symlink "$BREW_HOME" "$BREW_LINK" echo "Created link: $BREW_LINK -> $BREW_HOME" diff --git a/build-and-release.sh b/build-and-release.sh index 358b578..0c03844 100755 --- a/build-and-release.sh +++ b/build-and-release.sh @@ -12,6 +12,10 @@ run_hub_cmd() { fi } +# ------------------------------------------------------------------------------------------------- +# Parsing command-line options +# ------------------------------------------------------------------------------------------------- + recreate_release=false while [[ $# -gt 0 ]]; do case $1 in @@ -32,18 +36,20 @@ while [[ $# -gt 0 ]]; do shift done +if [[ ${GITHUB_TOKEN:-} == *yugabyte.githubToken* ]]; then + log "GITHUB_TOKEN contains the string yugabyte.githubToken, considering it unset." + GITHUB_TOKEN="" +fi +export GITHUB_TOKEN + if [[ -z ${GITHUB_TOKEN:-} ]]; then log "GITHUB_TOKEN is not set, won't be able to upload release artifacts" elif [[ ${#GITHUB_TOKEN} != 40 ]]; then - log "GITHUB_TOKEN has unexpected length: ${#GITHUB_TOKEN}, 40 characters expected" + fatal "GITHUB_TOKEN has unexpected length: ${#GITHUB_TOKEN}, 40 characters expected" else log "GITHUB_TOKEN has the expected length of 40 characters" fi -if [[ ${GITHUB_TOKEN:-} == "(yugabyte.githubToken)" ]]; then - log "GITHUB_TOKEN has its default value (yugabyte.githubToken), probably not set." -fi - this_repo_top_dir=$( cd "$( dirname "$0" )" && git rev-parse --show-toplevel ) if [[ ! -d $this_repo_top_dir ]]; then fatal "Failed to determine the top directory of the Git repository containing this script" @@ -54,19 +60,23 @@ export PATH=/usr/local/bin:$PATH repo_dir=$PWD timestamp=$( date +%Y-%m-%dT%H_%M_%S ) -num_commits=$( git rev-list --count HEAD ) -num_commits=$( printf "%06d" $num_commits ) set_brew_timestamp -tag=$YB_BREW_TIMESTAMP +tag=$YB_BREW_TIMESTAMP-$YB_OS_FAMILY readonly brew_dir=/opt/yb-build/brew mkdir -p "$brew_dir" cd "$brew_dir" "$repo_dir/brew-clone-and-build-all.sh" -create_release_cmd=( release create "$tag" -m "Release $tag" ) has_files=false -archive_prefix="$brew_dir/$YB_BREW_DIR_PREFIX-$YB_BREW_TIMESTAMP" +archive_prefix="$brew_dir/$YB_BREW_TYPE_LOWERCASE-$YB_BREW_TIMESTAMP" log "Looking for .tar.gz files and SHA256 checksum files with prefix: '$archive_prefix'" +msg_file=/tmp/release_message_${timestamp}_${RANDOM}_$$.tmp +create_release_cmd=( release create "$tag" -F "$msg_file" ) +added_versions=false +( + echo "Release $tag" + echo +) >"$msg_file" for f in "$archive_prefix.tar.gz" \ "$archive_prefix.tar.gz.sha256" \ "$archive_prefix-"*".tar.gz" \ @@ -74,11 +84,38 @@ for f in "$archive_prefix.tar.gz" \ if [[ -f $f ]]; then log "File '$f' exists, will upload." create_release_cmd+=( -a "$f" ) + brew_home=${f%.tar.gz} + if ! "$added_versions" && [[ -x $brew_home/bin/brew ]]; then + ( + cd "$brew_home" + echo "This pre-built binary package of $YB_BREW_TYPE_CAPITALIZED was built from commits:" + echo + for d in "" Library/Taps/*/*; do + ( + cd "$d" + git_url=$( cat GIT_URL ) + git_url_rel=${git_url#https://github.com/} + git_sha1=$( cat GIT_SHA1 ) + git_sha1_short=${git_sha1:0:10} + echo "- [$git_url_rel/$git_sha1_short]($git_url/commits/$git_sha1)" + ) + done + + echo + echo "Included package versions:" + echo + $brew_home/bin/brew list --versions + ) >>"$msg_file" + added_versions=true + fi has_files=true else log "File '$f' does not exist." fi done +if ! "$added_versions"; then + fatal "Could not determine installed package versions" +fi if ! "$has_files"; then fatal "No archive files found with prefix: '$archive_prefix'" fi diff --git a/post_install.template b/post_install.template index 2358982..d968239 100644 --- a/post_install.template +++ b/post_install.template @@ -21,43 +21,52 @@ set -euo pipefail . "${0%/*}/brew-common.sh" -BREW_HOME="${0%/*}" -[[ -x $BREW_HOME/bin/brew ]] || \ - (echo "This script should be located inside Homebrew/Linuxbrew directory."; exit 1) +readonly script_dir=$( cd "$( dirname "$0" )" && pwd ) +if [[ ! -x $script_dir/bin/brew ]]; then + fatal "This script should be located inside Homebrew/Linuxbrew directory." +fi -# {{ orig_brew_home }} is being replaced with original Homebrew/Linuxbrew home path. -ORIG_BREW_HOME="{{ orig_brew_home }}" -ORIG_LEN=${#ORIG_BREW_HOME} +# This is inserted at Homebrew/Linuxbrew build time. +readonly orig_brew_home="{{ orig_brew_home }}" +declare -i -r ORIG_LEN=${#orig_brew_home} -BREW_HOME="$PWD" -LEN=${#BREW_HOME} +brew_home=$PWD +LEN=${#brew_home} if [[ $LEN -gt $ORIG_LEN ]]; then - echo "Homebrew/Linuxbrew absolute path should be no more than $ORIG_LEN bytes, but actual " \ - "length is $LEN bytes: $BREW_HOME" >&2 - exit 1 + fatal "Homebrew/Linuxbrew absolute path should be no more than $ORIG_LEN bytes, but actual " \ + "length is $LEN bytes: $brew_home" fi -BREW_LINK=$(get_fixed_length_path "$BREW_HOME" "$ORIG_LEN") -LINK_LEN=${#BREW_LINK} -if [[ $LINK_LEN != $ORIG_LEN ]]; then - echo "Homebrew/Linuxbrew should be linked to a directory having absolute path length of" \ - "$ORIG_LEN bytes, but actual length is $LINK_LEN bytes: $BREW_LINK" >&2 - exit 1 +get_fixed_length_path "$brew_home" "$ORIG_LEN" +readonly brew_final_path=$fixed_length_path +declare -i -r final_path_len=${#brew_final_path} +if [[ $final_path_len != $ORIG_LEN ]]; then + fatal "Homebrew/Linuxbrew should be linked to a directory having absolute path length of" \ + "$ORIG_LEN bytes, but actual length is $final_path_len bytes: $brew_final_path" fi -ln -sfT "$BREW_HOME" "$BREW_LINK" +if [[ $brew_home != $brew_final_path ]]; then + if [[ -e $brew_final_path ]]; then + fatal "Fixed-length path '$brew_final_path' already exists" + fi + # Make the real directory be the fixed-length path, and the old name would be a link to it. + cd / + mv "$brew_home" "$brew_final_path" + create_symlink "$brew_final_path" "$brew_home" + cd "$brew_final_path" +fi -ORIG_BREW_HOME_ESCAPED=$(get_escaped_sed_re "$ORIG_BREW_HOME") -BREW_LINK_ESCAPED=$(get_escaped_sed_replacement_str "$BREW_LINK") +orig_brew_home_escaped=$(get_escaped_sed_re "$orig_brew_home") +brew_final_path_escaped=$(get_escaped_sed_replacement_str "$brew_final_path") cat FILES_TO_PATCH | while read f do - sed -i --binary "s/$ORIG_BREW_HOME_ESCAPED/$BREW_LINK_ESCAPED/g" "$f" + sed -i --binary "s/$orig_brew_home_escaped/$brew_final_path_escaped/g" "$f" done cat LINKS_TO_PATCH | while read f do - target="$(readlink "$f")" - target="${target/$ORIG_BREW_HOME/$BREW_LINK}" - ln -sfT "$target" "$f" + target=$(readlink "$f") + target="${target/$orig_brew_home/$brew_final_path}" + create_symlink "$target" "$f" done diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..5e4b7e0 --- /dev/null +++ b/test.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +# Copyright (c) YugaByte, Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except +# in compliance with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed under the License +# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express +# or implied. See the License for the specific language governing permissions and limitations +# under the License. +# + +set -euo pipefail + +show_usage() { + cat <<-EOT +Usage: ${0##*/} [] +Options: + -h, --help + Show usage + --work-dir + Use the given work directory instead of a temporary directory. The directory will be kept at + the end. + --sse4-only + Only build the configuration supporting SSE4. +EOT +} + +script_dir=$( cd "${0%/*}" && pwd ) +. "$script_dir/brew-common.sh" + +cleanup() { + exit_code=$? + if "$delete_work_dir" && [[ -n ${work_dir:-} ]]; then + cd /tmp + log "Removing temporary directory: $work_dir" + rm -rf "$work_dir" + fi + if [[ $exit_code -ne 0 ]]; then + log "TEST FAILED, exit code: $exit_code" + fi + exit "$exit_code" +} + +# ------------------------------------------------------------------------------------------------- +# Parsing command-line arguments +# ------------------------------------------------------------------------------------------------- + +delete_work_dir=true +while [[ $# -gt 0 ]]; do + case $1 in + --work-dir) + work_dir=$2 + delete_work_dir=false + shift + ;; + -h|--help) + show_usage + exit + ;; + --sse4-only) + export YB_BREW_BUILD_SSE4_ONLY=1 + ;; + *) + echo "Invalid argument: $1" >&2 + exit 1 + esac + shift +done + +# ------------------------------------------------------------------------------------------------- +# Main script +# ------------------------------------------------------------------------------------------------- + +delete_work_dir=true +if [[ -z ${work_dir:-} ]]; then + if [[ $OSTYPE == linux* ]]; then + tmp_dir=/tmp + else + # If we try to use /tmp on macOS, Homebrew says: + # "Your HOMEBREW_PREFIX is in the Homebrew temporary directory" + # (https://github.com/Homebrew/brew/blob/master/Library/Homebrew/brew.sh). + # So we use ~/tmp. + tmp_dir=$HOME/tmp + mkdir -p "$tmp_dir" + fi + work_dir=$tmp_dir/ybbrewtest-$$-$(date +%Y-%m-%dT%H_%M_%S) + trap cleanup EXIT +fi +mkdir -p "$work_dir" +cd "$work_dir" + +export YB_BREW_BUILD_UNIT_TEST_MODE=1 +"$script_dir/brew-clone-and-build-all.sh" + +heading "Testing brew-copy.sh" +brew_home=$( + find . -mindepth 1 -maxdepth 1 -type d -name "$YB_BREW_TYPE_LOWERCASE-*" | sort | head -1 +) +if [[ -z $brew_home ]]; then + fatal "Could not find a subdirectory starting with '$YB_BREW_TYPE_LOWERCASE-' in $PWD" +fi +"$script_dir/brew-copy.sh" "$brew_home" + +log "TEST SUCCEEDED"