github.com/jdhenke/godel@v0.0.0-20161213181855-abeb3861bf0d/godelw (about)

     1  #!/bin/bash
     2  
     3  set -euo pipefail
     4  
     5  # Version and checksums for godel. Values are populated by the godel "dist" task.
     6  VERSION=0.11.1
     7  DARWIN_CHECKSUM=c6a2e803afbdad1a2ee918e34f886a92534a7d191a87bb8eac33164cd23cdbbf
     8  LINUX_CHECKSUM=4874e222083c69adfe8a715063033061f1299a9fd52f94cee045bcefa3885c8a
     9  
    10  # Downloads file at URL to destination path using wget or curl. Prints an error and exits if wget or curl is not present.
    11  function download {
    12      local url=$1
    13      local dst=$2
    14  
    15      # determine whether wget, curl or both are present
    16      set +e
    17      command -v wget >/dev/null 2>&1
    18      local wget_exists=$?
    19      command -v curl >/dev/null 2>&1
    20      local curl_exists=$?
    21      set -e
    22  
    23      # if one of wget or curl is not present, exit with error
    24      if [ "$wget_exists" -ne 0 -a "$curl_exists" -ne 0 ]; then
    25          echo "wget or curl must be present to download distribution. Install one of these programs and try again or install the distribution manually."
    26          exit 1
    27      fi
    28  
    29      if [ "$wget_exists" -eq 0 ]; then
    30          # attempt download using wget
    31          echo "Downloading $url to $dst..."
    32          local progress_opt=""
    33          if wget --help | grep -q '\--show-progress'; then
    34              progress_opt="-q --show-progress"
    35          fi
    36          set +e
    37          wget -O "$dst" $progress_opt "$url"
    38          rv=$?
    39          set -e
    40          if [ "$rv" -eq 0 ]; then
    41              # success
    42              return
    43          fi
    44  
    45          echo "Download failed using command: wget -O $dst $progress_opt $url"
    46  
    47          # curl does not exist, so nothing more to try: exit
    48          if [ "$curl_exists" -ne 0 ]; then
    49              echo "Download failed using wget and curl was not found. Verify that the distribution URL is correct and try again or install the distribution manually."
    50              exit 1
    51          fi
    52          # curl exists, notify that download will be attempted using curl
    53          echo "Attempting download using curl..."
    54      fi
    55  
    56      # attempt download using curl
    57      echo "Downloading $url to $dst..."
    58      set +e
    59      curl -f -L -o "$dst" "$url"
    60      rv=$?
    61      set -e
    62      if [ "$rv" -ne 0 ]; then
    63          echo "Download failed using command: curl -f -L -o $dst $url"
    64          if [ "$wget_exists" -eq 0 ]; then
    65              echo "Download failed using wget and curl. Verify that the distribution URL is correct and try again or install the distribution manually."
    66          else
    67              echo "Download failed using curl and wget was not found. Verify that the distribution URL is correct and try again or install the distribution manually."
    68          fi
    69          exit 1
    70      fi
    71  }
    72  
    73  # verifies that the provided checksum matches the computed SHA-256 checksum of the specified file. If not, echoes an
    74  # error and exits.
    75  function verify_checksum {
    76      local file=$1
    77      local expected_checksum=$2
    78      local computed_checksum=$(compute_sha256 $file)
    79      if [ "$expected_checksum" != "$computed_checksum" ]; then
    80          echo "SHA-256 checksum for $file did not match expected value."
    81          echo "Expected: $expected_checksum"
    82          echo "Actual:   $computed_checksum"
    83          exit 1
    84      fi
    85  }
    86  
    87  # computes the SHA-256 hash of the provided file. Uses openssl, shasum or sha1sum program.
    88  function compute_sha256 {
    89      local file=$1
    90      if command -v openssl >/dev/null 2>&1; then
    91          # print SHA-256 hash using openssl
    92          openssl dgst -sha256 "$file" | sed -E 's/SHA256\(.*\)= //'
    93      elif command -v shasum >/dev/null 2>&1; then
    94          # Darwin systems ship with "shasum" utility
    95          shasum -a 256 "$file" | sed -E 's/[[:space:]]+.+//'
    96      elif command -v sha256sum >/dev/null 2>&1; then
    97          # Most Linux systems ship with sha256sum utility
    98          sha256sum "$file" | sed -E 's/[[:space:]]+.+//'
    99      else
   100          echo "Could not find program to calculate SHA-256 checksum for file"
   101          exit 1
   102      fi
   103  }
   104  
   105  # Verifies that the tgz file at the provided path contains the paths/files that would be expected in a valid gödel
   106  # distribution with the provided version.
   107  function verify_dist_tgz_valid {
   108      local tgz_path=$1
   109      local version=$2
   110  
   111      local expected_paths=("godel-$version/" "godel-$version/bin/darwin-amd64/godel" "godel-$version/bin/linux-amd64/godel" "godel-$version/wrapper/godelw" "godel-$version/wrapper/godel/config/")
   112      local files=($(tar -tf "$tgz_path"))
   113  
   114      # this is a double-for loop, but fine since $expected_paths is small and bash doesn't have good primitives for set/map/list manipulation
   115      for curr_line in "${files[@]}"; do
   116          # if all expected paths have been found, terminate
   117          if [[ ${#expected_paths[*]} == 0 ]]; then
   118              break
   119          fi
   120  
   121          # check for expected path and splice out if match is found
   122          idx=0
   123          for curr_expected in "${expected_paths[@]}"; do
   124              if [ "$curr_expected" = "$curr_line" ]; then
   125                  expected_paths=(${expected_paths[@]:0:idx} ${expected_paths[@]:$(($idx + 1))})
   126                  break
   127              fi
   128              idx=$idx+1
   129          done
   130      done
   131  
   132      # if any expected paths still remain, raise error and exit
   133      if [[ ${#expected_paths[*]} > 0 ]]; then
   134          echo "Required paths were not present in $tgz_path: ${expected_paths[@]}"
   135          exit 1
   136      fi
   137  }
   138  
   139  # Verifies that the gödel binary in the distribution reports the expected version when called with the "version"
   140  # argument. Assumes that a valid gödel distribution directory for the given version exists in the provided directory.
   141  function verify_godel_version {
   142      local base_dir=$1
   143      local version=$2
   144      local os=$3
   145  
   146      local expected_output="godel version $version"
   147      local version_output=$($base_dir/godel-$version/bin/$os-amd64/godel --verify-path=false version)
   148  
   149      if [ "$expected_output" != "$version_output" ]; then
   150          echo "Version reported by godel executable did not match expected version: expected \"$expected_output\", was \"$version_output\""
   151          exit 1
   152      fi
   153  }
   154  
   155  # directory of godelw script
   156  SCRIPT_HOME=$(cd "$(dirname "$0")" && pwd)
   157  
   158  # use $GODEL_HOME or default value
   159  GODEL_BASE_DIR=${GODEL_HOME:-$HOME/.godel}
   160  
   161  # determine OS
   162  OS=""
   163  EXPECTED_CHECKSUM=""
   164  case "$(uname)" in
   165    Darwin*)
   166      OS=darwin
   167      EXPECTED_CHECKSUM=$DARWIN_CHECKSUM
   168      ;;
   169    Linux*)
   170      OS=linux
   171      EXPECTED_CHECKSUM=$LINUX_CHECKSUM
   172      ;;
   173    *)
   174      echo "Unsupported operating system: $(uname)"
   175      exit 1
   176      ;;
   177  esac
   178  
   179  # path to godel binary
   180  CMD=$GODEL_BASE_DIR/dists/godel-$VERSION/bin/$OS-amd64/godel
   181  
   182  # godel binary is not present -- download distribution
   183  if [ ! -f "$CMD" ]; then
   184      # get download URL
   185      PROPERTIES_FILE=$SCRIPT_HOME/godel/config/godel.properties
   186      if [ ! -f "$PROPERTIES_FILE" ]; then
   187          echo "Properties file must exist at $PROPERTIES_FILE"
   188          exit 1
   189      fi
   190      DOWNLOAD_URL=$(cat "$PROPERTIES_FILE" | sed -E -n "s/^distributionURL=//p")
   191      if [ -z "$DOWNLOAD_URL" ]; then
   192          echo "Value for property \"distributionURL\" was empty in $PROPERTIES_FILE"
   193          exit 1
   194      fi
   195      DOWNLOAD_CHECKSUM=$(cat "$PROPERTIES_FILE" | sed -E -n "s/^distributionSHA256=//p")
   196  
   197      # create downloads directory if it does not already exist
   198      mkdir -p "$GODEL_BASE_DIR/downloads"
   199  
   200      # download tgz and verify its contents
   201      DOWNLOAD_DST=$GODEL_BASE_DIR/downloads/godel-$VERSION.tgz
   202      download "$DOWNLOAD_URL" "$DOWNLOAD_DST"
   203      if [ -n "$DOWNLOAD_CHECKSUM" ]; then
   204          verify_checksum "$DOWNLOAD_DST" "$DOWNLOAD_CHECKSUM"
   205      fi
   206      verify_dist_tgz_valid "$DOWNLOAD_DST" "$VERSION"
   207  
   208      # create temporary directory for unarchiving, unarchive downloaded file and verify directory
   209      TMP_DIST_DIR=$(mktemp -d "$GODEL_BASE_DIR/tmp_XXXXXX" 2>/dev/null || mktemp -d -t "$GODEL_BASE_DIR/tmp_XXXXXX")
   210      trap 'rm -rf "$TMP_DIST_DIR"' EXIT
   211      tar zxvf "$DOWNLOAD_DST" -C "$TMP_DIST_DIR" >/dev/null 2>&1
   212      verify_godel_version "$TMP_DIST_DIR" "$VERSION" "$OS"
   213  
   214      # if destination directory for distribution already exists, remove it
   215      if [ -d "$GODEL_BASE_DIR/dists/godel-$VERSION" ]; then
   216            rm -rf "$GODEL_BASE_DIR/dists/godel-$VERSION"
   217      fi
   218  
   219      # ensure that parent directory of destination exists
   220      mkdir -p "$GODEL_BASE_DIR/dists"
   221  
   222      # move expanded distribution directory to destination location. The location of the unarchived directory is known to
   223      # be in the same directory tree as the destination, so "mv" should always work.
   224      mv "$TMP_DIST_DIR/godel-$VERSION" "$GODEL_BASE_DIR/dists/godel-$VERSION"
   225  fi
   226  
   227  verify_checksum "$CMD" "$EXPECTED_CHECKSUM"
   228  
   229  # execute command
   230  $CMD --wrapper "$SCRIPT_HOME/$(basename "$0")" "$@"