setup.sh (5078B)
1 #!/bin/bash 2 3 # Copyright (c) Microsoft Corporation. 4 # Licensed under the MIT License. 5 6 # Synopsis: Sets up dependencies required to build and work with the SFS Client. 7 # 8 # Description: This script will install all of the dependencies required to build and work with the SFS Client. 9 # Use this on non-Windows platforms in a bash session. It must be sourced. 10 # 11 # Example: 12 # $ source ./scripts/setup.sh 13 # 14 15 COLOR_RED="\033[1;31m" 16 COLOR_CYAN="\033[1;36m" 17 NO_COLOR="\033[0m" 18 19 header() { echo -e "${COLOR_CYAN}$*${NO_COLOR}"; } 20 error() { echo -e "${COLOR_RED}$*${NO_COLOR}" >&2; } 21 22 if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then 23 error "Script is being run directly, it should be sourced instead." 24 exit 1 25 fi 26 27 script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" > /dev/null 2>&1 && pwd)" 28 git_root=$(git -C "$script_dir" rev-parse --show-toplevel) 29 30 sudo apt-get -qq update 31 32 install_with_apt() { 33 program_to_install=$1 34 35 if ! sudo apt-get -qq install "$program_to_install"; then 36 error "Failed to install $program_to_install" 37 return 1 38 fi 39 return 0 40 } 41 42 install_python() { 43 header "Installing latest Python if it's not installed" 44 45 if ! install_with_apt "python3"; then 46 return 47 fi 48 if ! install_with_apt "python3-pip"; then 49 return 50 fi 51 return 0 52 } 53 54 install_pip_dependencies() { 55 header "\nInstalling dependencies using pip" 56 57 # Upgrade pip and install requirements. Filter out output for dependencies that are already installed 58 python3 -m pip install --upgrade pip | grep -v -e "already satisfied" -e "Defaulting to user installation" 59 ret="${PIPESTATUS[0]}" 60 if [ "$ret" -ne 0 ]; then 61 return "$ret" 62 fi 63 64 pip_reqs="$script_dir/pip.requirements.txt" 65 66 pip install -r "$pip_reqs" | grep -v -e "already satisfied" -e "Defaulting to user installation" 67 ret="${PIPESTATUS[0]}" 68 if [ "$ret" -ne 0 ]; then 69 return "$ret" 70 fi 71 72 return 0 73 } 74 75 install_cmake() { 76 header "\nInstalling cmake if it's not installed" 77 78 if ! install_with_apt "cmake"; then 79 return 80 fi 81 return 0 82 } 83 84 install_vcpkg() { 85 header "\nSetting up vcpkg" 86 87 vcpkg_dir="$git_root/vcpkg" 88 if [ -d "$vcpkg_dir" ]; then 89 echo "Checking if vcpkg repo has new commits" 90 git -C "$vcpkg_dir" pull --show-forced-updates | grep -v 'Already up to date' 91 else 92 echo "Cloning vcpkg repo" 93 git clone https://github.com/microsoft/vcpkg "$vcpkg_dir" 94 # Needed for the bootstrap and for other vcpkg packages 95 if ! sudo apt-get -qq install curl zip unzip tar pkg-config; then 96 return 97 fi 98 "$vcpkg_dir/bootstrap-vcpkg.sh" 99 fi 100 return 0 101 } 102 103 # Dependency for compiling CorrelationVector C++ library 104 install_uuid() { 105 header "\nInstalling uuid-dev if it's not installed" 106 107 if ! install_with_apt "pkg-config"; then 108 return 109 fi 110 if ! install_with_apt "uuid-dev"; then 111 return 112 fi 113 return 0 114 } 115 116 set_git_hooks() { 117 header "\nSetting Git hooks" 118 119 hook_dest_dir="$git_root/.git/hooks" 120 declare -A git_hooks=( ["pre-commit-wrapper.sh"]="pre-commit") 121 for src in "${!git_hooks[@]}"; do 122 hook_src="$git_root/$src" 123 hook_dest="$hook_dest_dir/${git_hooks[$src]}" 124 125 # If the destination doesn't exist or is different than the one in the source, we'll copy it over. 126 if [ ! -f "$hook_dest" ] || ! cmp -s "$hook_src" "$hook_dest"; then 127 cp -f "$hook_src" "$hook_dest" 128 echo "Setup git ${git_hooks[$src]} hook with $hook_src" 129 fi 130 done 131 } 132 133 set_aliases() { 134 header "\nSetting aliases" 135 136 python_scripts_dir=$(python3 -c 'import os,sysconfig;print(sysconfig.get_path("scripts",f"{os.name}_user"))') 137 138 declare -A aliases=( ["build"]="$git_root/scripts/build.sh" 139 ["clang-format"]="$python_scripts_dir/clang-format" 140 ["cmake-format"]="$python_scripts_dir/cmake-format" 141 ["test"]="$git_root/scripts/test.sh" 142 ["vcpkg"]="$git_root/vcpkg/vcpkg") 143 144 for alias in "${!aliases[@]}"; do 145 target="${aliases[$alias]}" 146 147 # If the alias doesn't exist or is set to something different than the one we want to target, we'll add it. 148 149 # If alias doesn't exist, the alias command returns a non-zero result 150 alias_does_not_exist=false 151 alias_exists_not_the_same=false 152 if ! alias "$alias" > /dev/null 2>&1; then 153 alias_does_not_exist=true 154 else 155 output=$(alias "$alias") 156 expected_output="alias $alias='$target'" 157 if [ "$output" != "$expected_output" ]; then 158 alias_exists_not_the_same=true 159 fi 160 fi 161 162 if $alias_does_not_exist || $alias_exists_not_the_same; then 163 eval "alias $alias=$target" 164 echo "Setup alias $alias" 165 fi 166 done 167 } 168 169 if ! install_python; then 170 return 171 fi 172 173 if ! install_pip_dependencies; then 174 return 175 fi 176 177 if ! install_cmake; then 178 return 179 fi 180 181 if ! install_vcpkg; then 182 return 183 fi 184 185 if ! install_uuid; then 186 return 187 fi 188 189 set_git_hooks 190 set_aliases