1+ #! /bin/bash
2+
3+ # JuliaHub CLI (jh) installer script
4+ # This script downloads and installs the latest release of jh from GitHub
5+
6+ set -e
7+
8+ # Configuration
9+ REPO_OWNER=" JuliaComputing"
10+ REPO_NAME=" gojuliahub"
11+ BINARY_NAME=" jh"
12+ INSTALL_DIR=" ${INSTALL_DIR:- $HOME / .local/ bin} "
13+
14+ # Colors for output
15+ RED=' \033[0;31m'
16+ GREEN=' \033[0;32m'
17+ YELLOW=' \033[1;33m'
18+ BLUE=' \033[0;34m'
19+ NC=' \033[0m' # No Color
20+
21+ # Logging functions
22+ info () {
23+ echo -e " ${BLUE} INFO${NC} : $1 "
24+ }
25+
26+ success () {
27+ echo -e " ${GREEN} SUCCESS${NC} : $1 "
28+ }
29+
30+ warning () {
31+ echo -e " ${YELLOW} WARNING${NC} : $1 "
32+ }
33+
34+ error () {
35+ echo -e " ${RED} ERROR${NC} : $1 " >&2
36+ exit 1
37+ }
38+
39+ # Detect OS and architecture
40+ detect_platform () {
41+ local os arch
42+
43+ # Detect OS
44+ case " $( uname -s) " in
45+ Linux* ) os=" linux" ;;
46+ Darwin* ) os=" darwin" ;;
47+ CYGWIN* |MINGW* |MSYS* ) os=" windows" ;;
48+ * ) error " Unsupported operating system: $( uname -s) " ;;
49+ esac
50+
51+ # Detect architecture
52+ case " $( uname -m) " in
53+ x86_64|amd64) arch=" amd64" ;;
54+ aarch64|arm64) arch=" arm64" ;;
55+ * ) error " Unsupported architecture: $( uname -m) " ;;
56+ esac
57+
58+ echo " ${os} -${arch} "
59+ }
60+
61+ # Check if command exists
62+ command_exists () {
63+ command -v " $1 " > /dev/null 2>&1
64+ }
65+
66+ # Get latest release version from GitHub API
67+ get_latest_version () {
68+ local api_url=" https://api.github.com/repos/${REPO_OWNER} /${REPO_NAME} /releases/latest"
69+
70+ if command_exists curl; then
71+ curl -s " $api_url " | grep ' "tag_name":' | sed -E ' s/.*"tag_name": "([^"]+)".*/\1/'
72+ elif command_exists wget; then
73+ wget -qO- " $api_url " | grep ' "tag_name":' | sed -E ' s/.*"tag_name": "([^"]+)".*/\1/'
74+ else
75+ error " curl or wget is required to download the release"
76+ fi
77+ }
78+
79+ # Download and install binary
80+ install_binary () {
81+ local platform=" $1 "
82+ local version=" $2 "
83+ local os_part=" ${platform% -* } "
84+ local arch_part=" ${platform#* -} "
85+
86+ # Construct download URL
87+ local binary_name=" ${BINARY_NAME} -${os_part} -${arch_part} "
88+ if [ " $os_part " = " windows" ]; then
89+ binary_name=" ${binary_name} .exe"
90+ fi
91+
92+ local download_url=" https://github.com/${REPO_OWNER} /${REPO_NAME} /releases/download/${version} /${binary_name} "
93+
94+ info " Downloading ${BINARY_NAME} ${version} for ${platform} ..."
95+ info " Download URL: $download_url "
96+
97+ # Create install directory if it doesn't exist
98+ mkdir -p " $INSTALL_DIR "
99+
100+ # Download binary
101+ local temp_file=" ${INSTALL_DIR} /${binary_name} .tmp"
102+ local final_file=" ${INSTALL_DIR} /${BINARY_NAME} "
103+
104+ if [ " $os_part " = " windows" ]; then
105+ final_file=" ${final_file} .exe"
106+ fi
107+
108+ if command_exists curl; then
109+ curl -L -o " $temp_file " " $download_url "
110+ elif command_exists wget; then
111+ wget -O " $temp_file " " $download_url "
112+ else
113+ error " curl or wget is required to download the release"
114+ fi
115+
116+ # Verify download was successful
117+ if [ ! -f " $temp_file " ] || [ ! -s " $temp_file " ]; then
118+ rm -f " $temp_file "
119+ error " Failed to download binary from $download_url "
120+ fi
121+
122+ # Move to final location and make executable
123+ mv " $temp_file " " $final_file "
124+ chmod +x " $final_file "
125+
126+ success " Installed ${BINARY_NAME} to $final_file "
127+
128+ # Check if install directory is in PATH
129+ case " :$PATH :" in
130+ * " :$INSTALL_DIR :" * ) ;;
131+ * ) warning " $INSTALL_DIR is not in your PATH. Add it to your shell profile:"
132+ echo " echo 'export PATH=\" $INSTALL_DIR :\$ PATH\" ' >> ~/.bashrc"
133+ echo " echo 'export PATH=\" $INSTALL_DIR :\$ PATH\" ' >> ~/.zshrc"
134+ ;;
135+ esac
136+ }
137+
138+ # Verify installation
139+ verify_installation () {
140+ local binary_path=" ${INSTALL_DIR} /${BINARY_NAME} "
141+ if [ " $( uname -s) " = " CYGWIN" ] || [ " $( uname -s) " = " MINGW" ] || [ " $( uname -s) " = " MSYS" ]; then
142+ binary_path=" ${binary_path} .exe"
143+ fi
144+
145+ if [ -x " $binary_path " ]; then
146+ local version_output
147+ if version_output=$( " $binary_path " --version 2> /dev/null) ; then
148+ success " Installation verified: $version_output "
149+ info " Run '$BINARY_NAME --help' to get started"
150+ else
151+ warning " Binary installed but version check failed"
152+ fi
153+ else
154+ error " Installation failed: binary not found or not executable"
155+ fi
156+ }
157+
158+ # Main installation function
159+ main () {
160+ echo " JuliaHub CLI (${BINARY_NAME} ) Installer"
161+ echo " ======================================"
162+
163+ # Detect platform
164+ local platform
165+ platform=$( detect_platform)
166+ info " Detected platform: $platform "
167+
168+ # Get latest version
169+ info " Fetching latest release information..."
170+ local version
171+ version=$( get_latest_version)
172+
173+ if [ -z " $version " ]; then
174+ error " Failed to get latest version information"
175+ fi
176+
177+ info " Latest version: $version "
178+
179+ # Check if binary already exists
180+ local existing_binary=" ${INSTALL_DIR} /${BINARY_NAME} "
181+ if [ " $( uname -s | tr ' [:upper:]' ' [:lower:]' ) " = " windows" ]; then
182+ existing_binary=" ${existing_binary} .exe"
183+ fi
184+
185+ if [ -f " $existing_binary " ]; then
186+ if current_version=$( " $existing_binary " --version 2> /dev/null) ; then
187+ info " Current installation: $current_version "
188+ if echo " $current_version " | grep -q " $version " ; then
189+ info " Latest version is already installed"
190+ exit 0
191+ fi
192+ fi
193+ warning " Existing installation found. It will be replaced."
194+ fi
195+
196+ # Install binary
197+ install_binary " $platform " " $version "
198+
199+ # Verify installation
200+ verify_installation
201+
202+ echo " "
203+ success " Installation complete!"
204+ info " You can now use '${BINARY_NAME} ' to interact with JuliaHub"
205+ info " Start with: ${BINARY_NAME} auth login"
206+ }
207+
208+ # Parse command line arguments
209+ while [[ $# -gt 0 ]]; do
210+ case $1 in
211+ --install-dir)
212+ INSTALL_DIR=" $2 "
213+ shift 2
214+ ;;
215+ --help|-h)
216+ echo " JuliaHub CLI Installer"
217+ echo " "
218+ echo " Usage: $0 [options]"
219+ echo " "
220+ echo " Options:"
221+ echo " --install-dir DIR Install directory (default: \$ HOME/.local/bin)"
222+ echo " --help, -h Show this help message"
223+ echo " "
224+ echo " Environment variables:"
225+ echo " INSTALL_DIR Same as --install-dir"
226+ exit 0
227+ ;;
228+ * )
229+ error " Unknown option: $1 . Use --help for usage information."
230+ ;;
231+ esac
232+ done
233+
234+ # Run main installation
235+ main
0 commit comments