/ install.sh
install.sh
1 #!/usr/bin/env bash 2 set -e 3 4 # Install Codex on Linux, macOS, and Windows (msys2) 5 6 # Variables 7 VERSION=${VERSION:-latest} 8 CIRDL=${CIRDL:-false} 9 INSTALL_DIR=${INSTALL_DIR:-/usr/local/bin} 10 CODEX_ARCHIVE_PREFIX="codex" 11 CIRDL_ARCHIVE_PREFIX="cirdl" 12 CODEX_BINARY_PREFIX="codex" 13 CIRDL_BINARY_PREFIX="cirdl" 14 WINDOWS_LIBS=${WINDOWS_LIBS:-false} 15 WINDOWS_LIBS_LIST="libstdc++-6.dll libgomp-1.dll libgcc_s_seh-1.dll libwinpthread-1.dll" 16 BASE_URL=${BASE_URL:-https://github.com/codex-storage/nim-codex} 17 API_BASE_URL="https://api.github.com/repos/codex-storage/nim-codex" 18 BRANCH="${BRANCH:-master}" 19 TEMP_DIR="${TEMP_DIR:-.}" 20 PROGRESS_MARK="\033[0;36m\u2022\033[0m" 21 PASS_MARK="\033[0;32m\u2714\033[0m" 22 FAIL_MARK="\033[0;31m\u2718\033[0m" 23 SCRIPT_URL="${SCRIPT_URL:-https://get.codex.storage/install.sh}" 24 25 # Debug 26 if [[ "${DEBUG:-false}" == "true" ]]; then 27 echo -e "\n \e[33mVariables:\e[0m" 28 echo " VERSION: ${VERSION}" 29 echo " CIRDL: ${CIRDL}" 30 echo " INSTALL_DIR: ${INSTALL_DIR}" 31 echo " BRANCH: ${BRANCH}" 32 echo " TEMP_DIR: ${TEMP_DIR}" 33 echo " BASE_URL: ${BASE_URL}" 34 echo " SCRIPT_URL: ${SCRIPT_URL}" 35 fi 36 37 # Help 38 if [[ $1 == *"help"* ]] ; then 39 COMMAND="curl -s ${SCRIPT_URL}" 40 echo -e " 41 \e[33mInstall Codex\e[0m\n 42 \e[33mUsage:\e[0m 43 ${COMMAND} | bash 44 ${COMMAND} | VERSION=0.1.7 bash 45 ${COMMAND} | VERSION=0.1.7 CIRDL=true bash 46 ${COMMAND} | bash -s help 47 48 \e[33mVariables:\e[0m 49 - VERSION=0.1.7 - codex and cird version to install 50 - CIRDL=true - install cirdl 51 - INSTALL_DIR=/usr/local/bin - directory to install binaries 52 - WINDOWS_LIBS=true - download and install archive with libs for windows 53 - BASE_URL=https://builds.codex.storage - custom base URL for binaries downloading 54 - BRANCH=fix/custom-branch - custom branch builds 55 " 56 exit 0 57 fi 58 59 # Show 60 show_start() { 61 echo -e "\n \e[33m${1}\e[0m\n" 62 } 63 64 show_progress() { 65 echo -e " ${PROGRESS_MARK} ${1}" 66 } 67 68 show_pass() { 69 echo -e "\r\e[${TRIM:-1}A\e[0K ${PASS_MARK} ${1}" 70 unset TRIM 71 } 72 73 show_fail() { 74 echo -e "\r\e[1A\e[0K ${FAIL_MARK} ${1}" 75 [[ -n "${2}" ]] && echo -e "\e[31m \n Error: ${2}\e[0m\n" 76 exit 1 77 } 78 79 show_end() { 80 echo -e "\n\e[32m ${1}\e[0m\n" 81 } 82 83 # Start 84 show_start "Installing Codex..." 85 86 # Version 87 message="Compute version" 88 show_progress "${message}" 89 if [[ "${BASE_URL}" == *"https://github.com/"* ]]; then 90 if [[ "${VERSION}" == "latest" ]]; then 91 VERSION=$(curl -s "${API_BASE_URL}/releases/latest" | grep tag_name | cut -d '"' -f 4) 92 else 93 VERSION="v${VERSION}" 94 fi 95 else 96 if [[ "${BRANCH}" == "releases" ]]; then 97 if [[ "${VERSION}" == "latest" ]]; then 98 VERSION=$(curl -s "${BASE_URL}/${BRANCH}/latest") 99 else 100 VERSION="v${VERSION}" 101 fi 102 else 103 VERSION="${BRANCH/\//-}" 104 fi 105 fi 106 [[ $? -eq 0 ]] && show_pass "${message}" || show_fail "${message}" 107 108 # Archives and binaries 109 message="Compute archives and binaries names" 110 show_progress "${message}" 111 [[ "${CIRDL}" == "true" ]] && ARCHIVES=("${CODEX_ARCHIVE_PREFIX}" "${CIRDL_ARCHIVE_PREFIX}") || ARCHIVES=("${CODEX_ARCHIVE_PREFIX}") 112 [[ "${CIRDL}" == "true" ]] && BINARIES=("${CODEX_BINARY_PREFIX}" "${CIRDL_BINARY_PREFIX}") || BINARIES=("${CODEX_BINARY_PREFIX}") 113 show_pass "${message}" 114 115 # Get the current OS 116 message="Checking the current OS" 117 show_progress "${message}" 118 case "$(uname -s)" in 119 Linux*) OS="linux" ;; 120 Darwin*) OS="darwin" ;; 121 CYGWIN*|MINGW*|MSYS*) OS="windows" ;; 122 *) show_fail "${message}" "Unsupported OS $(uname -s)" ;; 123 esac 124 [[ $? -eq 0 ]] && show_pass "${message}" || show_fail "${message}" 125 126 # Get the current architecture 127 message="Checking the current architecture" 128 show_progress "${message}" 129 case "$(uname -m)" in 130 x86_64|amd64) ARCHITECTURE="amd64" ;; 131 arm64|aarch64) ARCHITECTURE="arm64" ;; 132 *) show_fail "${message}" "Unsupported architecture: $(uname -m)" ;; 133 esac 134 [[ $? -eq 0 ]] && show_pass "${message}" || show_fail "${message}" 135 136 # Not supported 137 if [[ "${OS}" == "windows" && "${ARCHITECTURE}" == "arm64" ]]; then 138 show_fail "${message}" "Windows ${ARCHITECTURE} is not supported at the moment" 139 fi 140 141 # Prerequisites 142 message="Checking prerequisites" 143 show_progress "${message}" 144 if [[ ("${OS}" != "windows") ]]; then 145 $(command -v tar &> /dev/null) || show_fail "${message}" "Please install tar to continue installation" 146 fi 147 show_pass "${message}" 148 149 # Archive and binaries names 150 if [[ "$OS" == "windows" ]]; then 151 [[ "${WINDOWS_LIBS}" == "true" ]] && ARCHIVE_SUFFIX="${VERSION}-${OS}-${ARCHITECTURE}-libs.zip" || ARCHIVE_SUFFIX="${VERSION}-${OS}-${ARCHITECTURE}.zip" 152 BINARY_SUFFIX="${VERSION}-${OS}-${ARCHITECTURE}" 153 else 154 ARCHIVE_SUFFIX="${VERSION}-${OS}-${ARCHITECTURE}.tar.gz" 155 BINARY_SUFFIX="${VERSION}-${OS}-${ARCHITECTURE}" 156 fi 157 158 # Download 159 for ARCHIVE in "${ARCHIVES[@]}"; do 160 ARCHIVE_NAME="${ARCHIVE}-${ARCHIVE_SUFFIX}" 161 162 for FILE in "${ARCHIVE_NAME}" "${ARCHIVE_NAME}.sha256"; do 163 if [[ "${BASE_URL}" == *"https://github.com/"* ]]; then 164 DOWNLOAD_URL="${BASE_URL}/releases/download/${VERSION}/${FILE}" 165 else 166 if [[ "${BRANCH}" == "releases" ]]; then 167 DOWNLOAD_URL="${BASE_URL}/${BRANCH}/${VERSION}/${FILE}" 168 elif [[ "${BRANCH}" == "master" ]]; then 169 DOWNLOAD_URL="${BASE_URL}/${BRANCH}/${FILE}" 170 else 171 DOWNLOAD_URL="${BASE_URL}/branches/${VERSION}/${FILE}" 172 fi 173 fi 174 175 message="Downloading ${FILE}" 176 show_progress "${message}" 177 http_code=$(curl --write-out "%{http_code}" --connect-timeout 5 --retry 5 -sL "${DOWNLOAD_URL}" -o "${TEMP_DIR}/${FILE}") 178 [[ "${http_code}" -eq 200 ]] && show_pass "${message}" || show_fail "${message}" "Failed to download ${DOWNLOAD_URL}" 179 done 180 done 181 182 # Checksum 183 for ARCHIVE in "${ARCHIVES[@]}"; do 184 ARCHIVE_NAME="${ARCHIVE}-${ARCHIVE_SUFFIX}" 185 message="Verifying checksum for ${ARCHIVE_NAME}" 186 show_progress "${message}" 187 188 EXPECTED_SHA256=$(cat "${TEMP_DIR}/${ARCHIVE_NAME}.sha256" | cut -d' ' -f1) 189 if [[ "${OS}" == "darwin" ]]; then 190 ACTUAL_SHA256=$(shasum -a 256 "${TEMP_DIR}/${ARCHIVE_NAME}" | cut -d ' ' -f 1) 191 else 192 ACTUAL_SHA256=$(sha256sum "${TEMP_DIR}/${ARCHIVE_NAME}" | cut -d ' ' -f 1) 193 fi 194 195 if [[ "$ACTUAL_SHA256" == "$EXPECTED_SHA256" ]]; then 196 show_pass "${message}" 197 else 198 show_fail "${message}" "Checksum verification failed for ${ARCHIVE_NAME}. Expected: $EXPECTED_SHA256, Got: $ACTUAL_SHA256" 199 fi 200 done 201 202 # Extract 203 for ARCHIVE in "${ARCHIVES[@]}"; do 204 ARCHIVE_NAME="${ARCHIVE}-${ARCHIVE_SUFFIX}" 205 206 message="Extracting ${ARCHIVE_NAME}" 207 show_progress "${message}" 208 209 if [[ "${OS}" == "windows" ]]; then 210 if unzip -v &> /dev/null; then 211 unzip -q -o "${TEMP_DIR}/${ARCHIVE_NAME}" -d "${TEMP_DIR}" 212 [[ $? -ne 0 ]] && show_fail "${message}" 213 else 214 C:/Windows/system32/tar.exe -xzf "${TEMP_DIR}/${ARCHIVE_NAME}" -C "${TEMP_DIR}" 215 [[ $? -ne 0 ]] && show_fail "${message}" 216 fi 217 else 218 tar -xzf "${TEMP_DIR}/${ARCHIVE_NAME}" -C "${TEMP_DIR}" 219 [[ $? -ne 0 ]] && show_fail "${message}" 220 fi 221 show_pass "${message}" 222 done 223 224 # Install 225 for BINARY in "${BINARIES[@]}"; do 226 BINARY_NAME="${BINARY}-${BINARY_SUFFIX}" 227 INSTALL_PATH="${INSTALL_DIR}/${BINARY}" 228 229 # Install 230 message="Installing ${BINARY_NAME} to ${INSTALL_PATH}" 231 show_progress "${message}" 232 [[ -d "${INSTALL_PATH}" ]] && show_fail "${message}" "Installation path ${INSTALL_PATH} is a directory" 233 if ! (mkdir -p "${INSTALL_DIR}" && install -m 755 "${TEMP_DIR}/${BINARY_NAME}" "${INSTALL_PATH}") 2> /dev/null; then 234 $(sudo -n true 2>/dev/null) || TRIM=2 235 sudo mkdir -p "${INSTALL_DIR}" && sudo install -m 755 "${TEMP_DIR}/${BINARY_NAME}" "${INSTALL_PATH}" 236 [[ $? -ne 0 ]] && show_fail "${message}" 237 fi 238 show_pass "${message}" 239 done 240 241 # Windows libs 242 if [[ "${OS}" == "windows" && "${WINDOWS_LIBS}" == "true" ]]; then 243 message="Copy libs to ${MINGW_PREFIX}/bin" 244 show_progress "${message}" 245 for LIB in ${WINDOWS_LIBS_LIST}; do 246 mv "${TEMP_DIR}/${LIB}" "${MINGW_PREFIX}/bin" 247 done 248 [[ $? -eq 0 ]] && show_pass "${message}" || show_fail "${message}" 249 fi 250 251 # Cleanup 252 message="Cleanup" 253 show_progress "${message}" 254 for BINARY in "${BINARIES[@]}"; do 255 ARCHIVE_NAME="${BINARY}-${BINARY_SUFFIX}" 256 rm -f "${TEMP_DIR}/${ARCHIVE_NAME}"* 257 [[ $? -ne 0 ]] && show_fail "${message}" 258 done 259 show_pass "${message}" 260 261 # End 262 show_end "Setup completed successfully!" 263 264 # Dependencies 265 dependencies=() 266 for BINARY in "${BINARIES[@]}"; do 267 LOCATION="${INSTALL_DIR}/${BINARY}" 268 case "${OS}" in 269 linux) dependencies+=($(ldd "${LOCATION}" | awk '/not found/ {print $1}')) ;; 270 darwin) dependencies+=($(otool -L "${LOCATION}" | awk '/not found/ {print $1}')) ;; 271 esac 272 done 273 274 if [[ ${#dependencies[@]} -ne 0 ]]; then 275 echo -e " Please inatall the following dpependencies: 276 ${dependencies[@]}\n" 277 fi 278 279 # Path 280 if [[ "${INSTALL_DIR}" != "." && "${PATH}" != *"${INSTALL_DIR}"* ]]; then 281 echo -e " Note: Please add install directory '"${INSTALL_DIR}"' to your PATH\n" 282 fi