1- #! /bin/bash
1+ #! /bin/sh
22
33# Get Pangolin - Cross-platform installation script
4- # Usage:
5- # curl -fsSL https://raw.githubusercontent.com/fosrl/cli/refs/heads/main/get-cli.sh | bash
4+ # Usage: curl -fsSL https://raw.githubusercontent.com/fosrl/cli/refs/heads/main/get-cli.sh | sh
65
76set -e
87
@@ -18,20 +17,20 @@ GITHUB_API_URL="https://api.github.com/repos/${REPO}/releases/latest"
1817
1918# Output helpers
2019print_status () {
21- echo -e " ${GREEN} [INFO] ${NC} $1 "
20+ printf ' %b[INFO]%b %s\n ' " ${GREEN} " " ${NC} " " $1 "
2221}
2322
2423print_warning () {
25- echo -e " ${YELLOW} [WARN] ${NC} $1 "
24+ printf ' %b[WARN]%b %s\n ' " ${YELLOW} " " ${NC} " " $1 "
2625}
2726
2827print_error () {
29- echo -e " ${RED} [ERROR] ${NC} $1 "
28+ printf ' %b[ERROR]%b %s\n ' " ${RED} " " ${NC} " " $1 "
3029}
3130
3231# Fetch latest version from GitHub API
3332get_latest_version () {
34- local latest_info
33+ latest_info= " "
3534 if command -v curl > /dev/null 2>&1 ; then
3635 latest_info=$( curl -fsSL " $GITHUB_API_URL " 2> /dev/null)
3736 elif command -v wget > /dev/null 2>&1 ; then
@@ -46,20 +45,20 @@ get_latest_version() {
4645 exit 1
4746 fi
4847
49- local version
50- version=$( echo " $latest_info " | grep ' "tag_name"' | head -1 | sed ' s/.*"tag_name": *"\([^"]*\)".*/\1/' )
48+ version=$( printf ' %s' " $latest_info " | grep ' "tag_name"' | head -1 | sed ' s/.*"tag_name": *"\([^"]*\)".*/\1/' )
5149 if [ -z " $version " ]; then
5250 print_error " Could not parse version from GitHub API response"
5351 exit 1
5452 fi
5553
56- version=$( echo " $version " | sed ' s/^v//' )
57- echo " $version "
54+ version=$( printf ' %s ' " $version " | sed ' s/^v//' )
55+ printf ' %s ' " $version "
5856}
5957
6058# Detect OS and architecture
6159detect_platform () {
62- local os arch
60+ os=" "
61+ arch=" "
6362 case " $( uname -s) " in
6463 Linux* ) os=" linux" ;;
6564 Darwin* ) os=" darwin" ;;
@@ -89,39 +88,66 @@ detect_platform() {
8988 * ) print_error " Unsupported architecture: $( uname -m) " ; exit 1 ;;
9089 esac
9190
92- echo " ${os} _ ${ arch} "
91+ printf ' %s_%s ' " $os " " $ arch"
9392}
9493
9594# Determine installation directory
9695get_install_dir () {
97- if [ " $OS " = " windows" ]; then
98- echo " $HOME /bin"
99- else
100- if echo " $PATH " | grep -q " /usr/local/bin" && [ -w " /usr/local/bin" ]; then
96+ case " $PLATFORM " in
97+ * windows* )
98+ echo " $HOME /bin"
99+ ;;
100+ * )
101+ # Prefer /usr/local/bin for system-wide installation
101102 echo " /usr/local/bin"
103+ ;;
104+ esac
105+ }
106+
107+ # Check if we need sudo for installation
108+ needs_sudo () {
109+ install_dir=" $1 "
110+ if [ -w " $install_dir " ] 2> /dev/null; then
111+ return 1 # No sudo needed
112+ else
113+ return 0 # Sudo needed
114+ fi
115+ }
116+
117+ # Get the appropriate command prefix (sudo or empty)
118+ get_sudo_cmd () {
119+ install_dir=" $1 "
120+ if needs_sudo " $install_dir " ; then
121+ if command -v sudo > /dev/null 2>&1 ; then
122+ echo " sudo"
102123 else
103- echo " $HOME /.local/bin"
124+ print_error " Cannot write to ${install_dir} and sudo is not available."
125+ print_error " Please run this script as root or install sudo."
126+ exit 1
104127 fi
128+ else
129+ echo " "
105130 fi
106131}
107132
108133# Download and install Pangolin
109134install_pangolin () {
110- local platform=" $1 "
111- local install_dir=" $2 "
112- local asset_name=" pangolin-cli_${platform} "
113- local exe_suffix=" "
114- local final_name=" pangolin"
115-
116- if [[ " $platform " == * " windows" * ]]; then
117- asset_name=" ${asset_name} .exe"
118- exe_suffix=" .exe"
119- final_name=" pangolin.exe"
120- fi
135+ platform=" $1 "
136+ install_dir=" $2 "
137+ sudo_cmd=" $3 "
138+ asset_name=" pangolin-cli_${platform} "
139+ final_name=" pangolin"
140+
141+ case " $platform " in
142+ * windows* )
143+ asset_name=" ${asset_name} .exe"
144+ final_name=" pangolin.exe"
145+ ;;
146+ esac
121147
122- local download_url=" ${BASE_URL} /${asset_name} "
123- local temp_file=" /tmp/${final_name} "
124- local final_path=" ${install_dir} /${final_name} "
148+ download_url=" ${BASE_URL} /${asset_name} "
149+ temp_file=" /tmp/${final_name} "
150+ final_path=" ${install_dir} /${final_name} "
125151
126152 print_status " Downloading Pangolin from ${download_url} "
127153
@@ -134,12 +160,22 @@ install_pangolin() {
134160 exit 1
135161 fi
136162
137- mkdir -p " $install_dir "
138- mv " $temp_file " " $final_path "
139- chmod +x " $final_path "
163+ # Make executable before moving
164+ chmod +x " $temp_file "
165+
166+ # Create install directory if it doesn't exist and move binary
167+ if [ -n " $sudo_cmd " ]; then
168+ $sudo_cmd mkdir -p " $install_dir "
169+ print_status " Using sudo to install to ${install_dir} "
170+ $sudo_cmd mv " $temp_file " " $final_path "
171+ else
172+ mkdir -p " $install_dir "
173+ mv " $temp_file " " $final_path "
174+ fi
140175
141176 print_status " Pangolin installed to ${final_path} "
142177
178+ # Check if install directory is in PATH
143179 if ! echo " $PATH " | grep -q " $install_dir " ; then
144180 print_warning " Install directory ${install_dir} is not in your PATH."
145181 print_warning " Add it with:"
@@ -149,17 +185,18 @@ install_pangolin() {
149185
150186# Verify installation
151187verify_installation () {
152- local install_dir=" $1 "
153- local exe_suffix=" "
188+ install_dir=" $1 "
189+ exe_suffix=" "
154190
155- if [[ " $PLATFORM " == * " windows" * ]]; then
156- exe_suffix=" .exe"
157- fi
191+ case " $PLATFORM " in
192+ * windows* ) exe_suffix=" .exe" ;;
193+ esac
194+
195+ pangolin_path=" ${install_dir} /pangolin${exe_suffix} "
158196
159- local pangolin_path=" ${install_dir} /pangolin${exe_suffix} "
160197 if [ -x " $pangolin_path " ]; then
161198 print_status " Installation successful!"
162- print_status " pangolin version: $( " $pangolin_path " version 2> /dev/null || echo " unknown" ) "
199+ print_status " pangolin version: $( " $pangolin_path " version 2> /dev/null || printf ' unknown' ) "
163200 return 0
164201 else
165202 print_error " Installation failed. Binary not found or not executable."
@@ -183,7 +220,13 @@ main() {
183220 INSTALL_DIR=$( get_install_dir)
184221 print_status " Install directory: ${INSTALL_DIR} "
185222
186- install_pangolin " $PLATFORM " " $INSTALL_DIR "
223+ # Check if we need sudo
224+ SUDO_CMD=$( get_sudo_cmd " $INSTALL_DIR " )
225+ if [ -n " $SUDO_CMD " ]; then
226+ print_status " Root privileges required for installation to ${INSTALL_DIR} "
227+ fi
228+
229+ install_pangolin " $PLATFORM " " $INSTALL_DIR " " $SUDO_CMD "
187230
188231 if verify_installation " $INSTALL_DIR " ; then
189232 print_status " Pangolin is ready to use!"
0 commit comments