Seriki commited on
Commit
cfbfe0b
·
verified ·
1 Parent(s): 97a649e

Create install.sh

Browse files
Files changed (1) hide show
  1. install.sh +570 -0
install.sh ADDED
@@ -0,0 +1,570 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+ # Hugging Face CLI Installer for Linux/MacOS
3
+ # Usage: curl -LsSf https://hf.co/cli/install.sh | bash -s
4
+ # Usage: curl -LsSf https://hf.co/cli/install.sh | bash -s --with-transformers
5
+ # Usage: curl -LsSf https://hf.co/cli/install.sh | bash -s -- [OPTIONS]
6
+
7
+
8
+ if [ -z "$BASH_VERSION" ]; then
9
+ if command -v bash >/dev/null 2>&1; then
10
+ if [ -f "$0" ] && [ "$0" != "sh" ] && [ "$0" != "bash" ]; then
11
+ exec bash "$0" "$@"
12
+ else
13
+ tmp_dir=$(mktemp -d 2>/dev/null || mktemp -d -t hf-cli-install)
14
+ tmp_script="$tmp_dir/install.sh"
15
+ cat >"$tmp_script"
16
+ chmod +x "$tmp_script"
17
+ bash "$tmp_script" "$@"
18
+ exit_code=$?
19
+ rm -rf "$tmp_dir"
20
+ exit $exit_code
21
+ fi
22
+ else
23
+ echo "[ERROR] bash is required to run this installer." >&2
24
+ echo "[ERROR] Please run: curl -LsSf https://hf.co/cli/install.sh | bash" >&2
25
+ exit 1
26
+ fi
27
+ fi
28
+
29
+ set -e
30
+
31
+ # Colors for output
32
+ RED='\033[0;31m'
33
+ GREEN='\033[0;32m'
34
+ YELLOW='\033[1;33m'
35
+ BLUE='\033[0;34m'
36
+ NC='\033[0m' # No Color
37
+
38
+ # Logging level: 0=quiet, 1=info (default), 2=verbose
39
+ LOG_LEVEL=1
40
+
41
+ # Configuration
42
+ FORCE_REINSTALL="false"
43
+ BIN_DIR="${HF_CLI_BIN_DIR:-$HOME/.local/bin}"
44
+ UPDATED_RC_FILE=""
45
+ SKIP_PATH_UPDATE="false"
46
+ UPDATED_FISH_PATH="false"
47
+ WITH_TRANSFORMERS="false"
48
+ EXCLUDE_SKILL="false"
49
+
50
+ # Logging functions
51
+ log_debug() {
52
+ if [ "$LOG_LEVEL" -lt 2 ]; then
53
+ return 0
54
+ fi
55
+ printf '%b\n' "${BLUE}[DEBUG]${NC} $1"
56
+ }
57
+
58
+ log_info() {
59
+ if [ "$LOG_LEVEL" -lt 1 ]; then
60
+ return 0
61
+ fi
62
+ printf '%b\n' "${BLUE}[INFO]${NC} $1"
63
+ }
64
+
65
+ log_success() {
66
+ printf '%b\n' "${GREEN}[SUCCESS]${NC} $1"
67
+ }
68
+
69
+ log_warning() {
70
+ printf '%b\n' "${YELLOW}[WARNING]${NC} $1"
71
+ }
72
+
73
+ log_error() {
74
+ printf '%b\n' "${RED}[ERROR]${NC} $1" >&2
75
+ }
76
+
77
+ run_command() {
78
+ local description="$1"
79
+ shift
80
+ set +e
81
+ "$@"
82
+ local status=$?
83
+ set -e
84
+ if [ $status -ne 0 ]; then
85
+ log_error "$description"
86
+ log_error "Command: $*"
87
+ log_error "Re-run with --verbose for detailed output."
88
+ exit $status
89
+ fi
90
+ }
91
+
92
+ usage() {
93
+ cat <<'EOF'
94
+ Usage: curl -LsSf https://hf.co/cli/install.sh | bash -s -- [OPTIONS]
95
+
96
+ Options:
97
+ --force Recreate the Hugging Face CLI virtual environment if it exists
98
+ --no-modify-path Skip adding the hf wrapper directory to PATH
99
+ --with-transformers Also install the transformers CLI
100
+ --exclude-skill Skip installing the `hf-cli` skill for AI agents
101
+ -v, --verbose Enable verbose output (includes full pip logs)
102
+ --help, -h Show this message and exit
103
+
104
+ Environment variables:
105
+ HF_HOME Installation base directory; installer uses $HF_HOME/cli when set
106
+ HF_CLI_BIN_DIR Directory for the hf wrapper (default: ~/.local/bin)
107
+ EOF
108
+ }
109
+
110
+ # Normalize user paths to absolute paths
111
+ expand_path() {
112
+ local input="$1"
113
+ if [ -z "$input" ]; then
114
+ return 0
115
+ fi
116
+
117
+ case "$input" in
118
+ ~)
119
+ printf '%s\n' "$HOME"
120
+ ;;
121
+ ~/*)
122
+ printf '%s/%s\n' "$HOME" "${input#~/}"
123
+ ;;
124
+ /*)
125
+ printf '%s\n' "$input"
126
+ ;;
127
+ *)
128
+ printf '%s/%s\n' "$PWD" "$input"
129
+ ;;
130
+ esac
131
+ }
132
+
133
+ while [ $# -gt 0 ]; do
134
+ case "$1" in
135
+ --force)
136
+ FORCE_REINSTALL="true"
137
+ ;;
138
+ --no-modify-path)
139
+ SKIP_PATH_UPDATE="true"
140
+ ;;
141
+ --with-transformers)
142
+ WITH_TRANSFORMERS="true"
143
+ ;;
144
+ --exclude-skill)
145
+ EXCLUDE_SKILL="true"
146
+ ;;
147
+ -v|--verbose)
148
+ LOG_LEVEL=2
149
+ HF_CLI_VERBOSE_PIP=1
150
+ ;;
151
+ --help|-h)
152
+ usage
153
+ exit 0
154
+ ;;
155
+ *)
156
+ log_error "Unknown option: $1"
157
+ usage
158
+ exit 1
159
+ ;;
160
+ esac
161
+ shift
162
+ done
163
+
164
+ # Persist fully resolved paths for downstream use and wrapper creation
165
+ BIN_DIR=$(expand_path "$BIN_DIR")
166
+
167
+ if [ -n "$HF_HOME" ]; then
168
+ HF_CLI_DIR="$HF_HOME/cli"
169
+ else
170
+ HF_CLI_DIR="$HOME/.hf-cli"
171
+ fi
172
+
173
+ HF_CLI_DIR=$(expand_path "$HF_CLI_DIR")
174
+ VENV_DIR="$HF_CLI_DIR/venv"
175
+
176
+ # Check if command exists
177
+ command_exists() {
178
+ command -v "$1" >/dev/null 2>&1
179
+ }
180
+
181
+ # Detect OS
182
+ detect_os() {
183
+ if [[ "$OSTYPE" == "linux-gnu"* ]]; then
184
+ echo "linux"
185
+ elif [[ "$OSTYPE" == "darwin"* ]]; then
186
+ echo "macos"
187
+ else
188
+ echo "unknown"
189
+ fi
190
+ }
191
+
192
+ # Install Python if not available
193
+ python_version_supported() {
194
+ "$1" <<'PY' >/dev/null 2>&1
195
+ import sys
196
+ sys.exit(0 if sys.version_info >= (3, 10) else 1)
197
+ PY
198
+ }
199
+
200
+ ensure_python() {
201
+ local candidates=(python3 python)
202
+ local chosen=""
203
+ local version_output=""
204
+
205
+ for candidate in "${candidates[@]}"; do
206
+ if command_exists "$candidate"; then
207
+ version_output="$($candidate --version 2>&1)"
208
+ if python_version_supported "$candidate"; then
209
+ PYTHON_CMD="$candidate"
210
+ chosen="$candidate"
211
+ break
212
+ else
213
+ log_warning "$candidate detected ($version_output) but Python 3.10+ is required."
214
+ fi
215
+ fi
216
+ done
217
+
218
+ if [ -z "$chosen" ]; then
219
+ log_error "Python 3.10+ is required but was not found."
220
+ case "$(detect_os)" in
221
+ macos)
222
+ log_info "On macOS: brew install python (or download Python 3.10+ from python.org)"
223
+ ;;
224
+ linux)
225
+ if command_exists apt-get || command_exists apt; then
226
+ log_info "On Debian/Ubuntu: sudo apt update && sudo apt install python3 python3-pip"
227
+ elif command_exists dnf; then
228
+ log_info "On Fedora/RHEL: sudo dnf install python3 python3-pip"
229
+ elif command_exists yum; then
230
+ log_info "On CentOS/RHEL: sudo yum install python3 python3-pip"
231
+ else
232
+ log_info "Install Python 3.10+ with your distro's package manager."
233
+ fi
234
+ ;;
235
+ *)
236
+ log_info "Install Python 3.10+ from https://www.python.org/downloads/"
237
+ ;;
238
+ esac
239
+ exit 1
240
+ fi
241
+
242
+ log_info "Using Python: $($PYTHON_CMD --version)"
243
+ }
244
+
245
+ # Create directories
246
+ create_directories() {
247
+ log_info "Creating directories..."
248
+ run_command "Failed to create install directory $HF_CLI_DIR" mkdir -p "$HF_CLI_DIR"
249
+ run_command "Failed to create bin directory $BIN_DIR" mkdir -p "$BIN_DIR"
250
+ }
251
+
252
+ # Create virtual environment
253
+ create_venv() {
254
+ log_info "Creating virtual environment..."
255
+ if [ -d "$VENV_DIR" ]; then
256
+ if [ "$FORCE_REINSTALL" = "true" ]; then
257
+ log_warning "Virtual environment already exists; removing it since --force was passed"
258
+ rm -rf "$VENV_DIR"
259
+ else
260
+ log_info "Virtual environment already exists; reusing (pass --force to recreate)"
261
+ return
262
+ fi
263
+ fi
264
+
265
+ # Fail early with guidance when python lacks the venv module
266
+ if ! "$PYTHON_CMD" -m venv --help >/dev/null 2>&1; then
267
+ log_error "Python's venv module is unavailable. Install python3-venv / ensurepip and retry."
268
+ case "$(detect_os)" in
269
+ linux)
270
+ log_info "Try: sudo apt install python3-venv # Debian/Ubuntu"
271
+ log_info " sudo dnf install python3-venv # Fedora"
272
+ ;;
273
+ macos)
274
+ log_info "Try reinstalling Python via Homebrew: brew install python"
275
+ ;;
276
+ esac
277
+ exit 1
278
+ fi
279
+
280
+ run_command "Failed to create virtual environment at $VENV_DIR" "$PYTHON_CMD" -m venv "$VENV_DIR"
281
+
282
+ # Mark this installation as installer-managed
283
+ touch "$VENV_DIR/.hf_installer_marker"
284
+
285
+ # Use the venv python for pip management
286
+ log_info "Upgrading pip..."
287
+ run_command "Failed to upgrade pip" "$VENV_DIR/bin/python" -m pip install --upgrade pip
288
+ }
289
+
290
+ # Install a Python package in the venv
291
+ install_package() {
292
+ local package_spec="$1"
293
+
294
+ local extra_pip_args="${HF_CLI_PIP_ARGS:-${HF_PIP_ARGS:-}}"
295
+ local verbose="${HF_CLI_VERBOSE_PIP:-}"
296
+
297
+ if [ -n "$extra_pip_args" ]; then
298
+ log_info "Passing extra arguments: $extra_pip_args"
299
+ fi
300
+
301
+ if [ "$verbose" != "1" ]; then
302
+ log_info "Installation output suppressed; set HF_CLI_VERBOSE_PIP=1 for full logs"
303
+ fi
304
+
305
+ # Check if uv is available and use it for faster installation
306
+ if command_exists uv; then
307
+ log_info "Using uv for faster installation"
308
+ local -a uv_flags
309
+ if [ "$verbose" != "1" ]; then
310
+ uv_flags=(--quiet)
311
+ else
312
+ uv_flags=()
313
+ fi
314
+
315
+ # shellcheck disable=SC2086
316
+ run_command "Failed to install $package_spec" uv pip install --python "$VENV_DIR/bin/python" --upgrade ${uv_flags[*]} "$package_spec" $extra_pip_args
317
+ else
318
+ local -a pip_flags
319
+ if [ "$verbose" != "1" ]; then
320
+ pip_flags=(--quiet --progress-bar off --disable-pip-version-check)
321
+ else
322
+ pip_flags=()
323
+ fi
324
+
325
+ # shellcheck disable=SC2086
326
+ run_command "Failed to install $package_spec" "$VENV_DIR/bin/python" -m pip install --upgrade "$package_spec" ${pip_flags[*]} $extra_pip_args
327
+ fi
328
+ }
329
+
330
+ # Install huggingface_hub with CLI extras
331
+ install_hf_hub() {
332
+ log_info "Installing/upgrading Hugging Face CLI (latest)..."
333
+
334
+ install_package "huggingface_hub"
335
+ }
336
+
337
+ # Check if transformers is installed in the venv (using importlib.metadata for speed)
338
+ transformers_installed() {
339
+ "$VENV_DIR/bin/python" -c "import importlib.metadata; importlib.metadata.version('transformers')" >/dev/null 2>&1
340
+ }
341
+
342
+ # Install transformers CLI
343
+ install_transformers() {
344
+ # Install if --with-transformers was passed OR if transformers is already in the venv
345
+ if [ "$WITH_TRANSFORMERS" != "true" ] && ! transformers_installed; then
346
+ return
347
+ fi
348
+
349
+ log_info "Installing/upgrading transformers CLI (latest)..."
350
+ install_package "transformers"
351
+ }
352
+
353
+ # Expose the hf CLI by linking or copying the console script from the virtualenv
354
+ expose_cli_command() {
355
+ log_info "Linking hf CLI into $BIN_DIR..."
356
+
357
+ local source_cli="$VENV_DIR/bin/hf"
358
+ if [ ! -x "$source_cli" ]; then
359
+ log_error "hf command not found in the virtual environment at $source_cli"
360
+ log_error "Verify that The Hugging Face CLI is installed correctly."
361
+ exit 1
362
+ fi
363
+
364
+ local link_method=""
365
+ if ln -sf "$source_cli" "$BIN_DIR/hf" 2>/dev/null; then
366
+ link_method="symlink"
367
+ else
368
+ if cp "$source_cli" "$BIN_DIR/hf" 2>/dev/null; then
369
+ link_method="copy"
370
+ else
371
+ log_error "Failed to place hf command in $BIN_DIR (tried symlink and copy)."
372
+ exit 1
373
+ fi
374
+ fi
375
+
376
+ chmod +x "$BIN_DIR/hf"
377
+
378
+ if [ "$link_method" = "symlink" ]; then
379
+ log_info "hf available at $BIN_DIR/hf (symlink to venv)"
380
+ else
381
+ log_info "hf available at $BIN_DIR/hf"
382
+ fi
383
+ log_info "Run without touching PATH: env PATH=\"$BIN_DIR:\$PATH\" hf --help"
384
+ }
385
+
386
+ # Install the `hf-cli` skill globally (opt-out with --exclude-skill)
387
+ install_skill() {
388
+ if [ "$EXCLUDE_SKILL" = "true" ]; then
389
+ log_info "Skipping the hf-cli skill (--exclude-skill)"
390
+ return
391
+ fi
392
+
393
+ log_info "Installing the hf-cli skill for AI agents..."
394
+ if ! "$BIN_DIR/hf" skills add hf-cli --global --claude --force; then
395
+ log_warning "Failed to install the hf-cli skill. Install it later with: hf skills add -g --claude"
396
+ return
397
+ fi
398
+ log_info "The hf-cli skill was installed automatically so AI agents know how to use the hf CLI."
399
+ log_info "Pass --exclude-skill to skip it."
400
+ }
401
+
402
+ # Update PATH if needed
403
+ update_path() {
404
+ local shell_rc=""
405
+ local -a shell_rc_candidates=()
406
+
407
+ # Broaden shell detection and guidance for PATH propagation
408
+ case "$SHELL" in
409
+ */bash)
410
+ shell_rc_candidates=()
411
+ shell_rc_candidates+=("$HOME/.bashrc")
412
+ shell_rc_candidates+=("$HOME/.bash_profile")
413
+ shell_rc_candidates+=("$HOME/.profile")
414
+ ;;
415
+ */zsh)
416
+ shell_rc_candidates=()
417
+ shell_rc_candidates+=("$HOME/.zshrc")
418
+ shell_rc_candidates+=("$HOME/.zprofile")
419
+ ;;
420
+ */fish)
421
+ shell_rc_candidates=()
422
+ if command -v fish >/dev/null 2>&1; then
423
+ if fish -c "contains \"$BIN_DIR\" \$fish_user_paths" >/dev/null 2>&1; then
424
+ log_info "$BIN_DIR already present in fish_user_paths"
425
+ UPDATED_FISH_PATH="true"
426
+ return
427
+ elif fish -c "set -Ux fish_user_paths \"$BIN_DIR\" \$fish_user_paths" >/dev/null 2>&1; then
428
+ UPDATED_FISH_PATH="true"
429
+ log_success "Added $BIN_DIR to fish_user_paths"
430
+ log_info "Apply it now with: set -Ux fish_user_paths $BIN_DIR \$fish_user_paths"
431
+ return
432
+ else
433
+ log_warning "Could not update fish_user_paths automatically."
434
+ fi
435
+ fi
436
+ ;;
437
+ *)
438
+ shell_rc_candidates=()
439
+ shell_rc_candidates+=("$HOME/.profile")
440
+ ;;
441
+ esac
442
+
443
+ if [[ ":$PATH:" != *":$BIN_DIR:"* ]]; then
444
+ if [ "$SKIP_PATH_UPDATE" = "true" ]; then
445
+ log_info "Skipping PATH update (--no-modify-path)."
446
+ return
447
+ fi
448
+
449
+ log_info "$BIN_DIR is not in your PATH"
450
+
451
+ if [ "${#shell_rc_candidates[@]}" -gt 0 ]; then
452
+ for candidate in "${shell_rc_candidates[@]}"; do
453
+ if [ -f "$candidate" ]; then
454
+ shell_rc="$candidate"
455
+ break
456
+ fi
457
+ done
458
+
459
+ if [ -z "$shell_rc" ]; then
460
+ shell_rc="${shell_rc_candidates[0]}"
461
+ log_info "Creating shell config file at $shell_rc to update PATH"
462
+ touch "$shell_rc"
463
+ fi
464
+
465
+ if ! grep -Fq "$BIN_DIR" "$shell_rc"; then
466
+ {
467
+ echo ""
468
+ echo "# Added by Hugging Face CLI installer"
469
+ echo "export PATH=\"$BIN_DIR:\$PATH\""
470
+ } >> "$shell_rc"
471
+ UPDATED_RC_FILE="$shell_rc"
472
+ log_success "Added $BIN_DIR to PATH via $shell_rc"
473
+ if [ "$LOG_LEVEL" -ge 1 ]; then
474
+ log_info "Apply it now with: source $shell_rc"
475
+ fi
476
+ fi
477
+ else
478
+ log_warning "Could not automatically update PATH for your shell."
479
+ if [[ "$SHELL" == *"/fish" ]]; then
480
+ if [ "$UPDATED_FISH_PATH" != "true" ]; then
481
+ log_warning "Run: set -Ux fish_user_paths $BIN_DIR \$fish_user_paths"
482
+ fi
483
+ else
484
+ log_warning "Add this line to your shell config: export PATH=\"$BIN_DIR:\$PATH\""
485
+ fi
486
+ fi
487
+ fi
488
+ }
489
+
490
+ # Verify installation
491
+ verify_installation() {
492
+ log_info "Verifying installation..."
493
+
494
+ if [ -x "$BIN_DIR/hf" ]; then
495
+ # Test the CLI
496
+ if "$BIN_DIR/hf" version >/dev/null 2>&1; then
497
+ log_success "Hugging Face CLI installed successfully!"
498
+ log_info "CLI location: $BIN_DIR/hf"
499
+ log_info "Installation directory: $HF_CLI_DIR"
500
+ else
501
+ log_error "Installation verification failed. The hf command is not working properly."
502
+ exit 1
503
+ fi
504
+ else
505
+ log_error "Installation failed. Wrapper script not found."
506
+ exit 1
507
+ fi
508
+ }
509
+
510
+ # Uninstall function
511
+ show_uninstall_info() {
512
+ log_info ""
513
+ log_info "To uninstall the Hugging Face CLI, run:"
514
+ log_info " rm -rf $HF_CLI_DIR"
515
+ log_info " rm -f $BIN_DIR/hf"
516
+ log_info ""
517
+ if [ -n "$UPDATED_RC_FILE" ]; then
518
+ log_info " (shell) Undo PATH entry: sed -i.bak '/Added by Hugging Face CLI installer/d' $UPDATED_RC_FILE && rm -f ${UPDATED_RC_FILE}.bak"
519
+ elif [ "$UPDATED_FISH_PATH" = "true" ]; then
520
+ log_info " (fish) Undo PATH entry: fish -c 'set -Ux fish_user_paths (string match -v \"$BIN_DIR\" \$fish_user_paths)'"
521
+ elif [ "$SKIP_PATH_UPDATE" = "true" ]; then
522
+ log_info " (PATH unchanged because --no-modify-path was used)"
523
+ else
524
+ log_info " Remove any PATH edits you made manually."
525
+ fi
526
+ }
527
+
528
+ # Main installation process
529
+ main() {
530
+ log_info "Installing Hugging Face CLI..."
531
+ log_info "OS: $(detect_os)"
532
+ log_info "Force reinstall: $FORCE_REINSTALL"
533
+ log_info "Install dir: $HF_CLI_DIR"
534
+ log_info "Bin dir: $BIN_DIR"
535
+ log_info "Skip PATH update: $SKIP_PATH_UPDATE"
536
+ log_info "Exclude skill: $EXCLUDE_SKILL"
537
+
538
+ ensure_python
539
+ create_directories
540
+ create_venv
541
+ install_hf_hub
542
+ install_transformers
543
+ expose_cli_command
544
+ install_skill
545
+ update_path
546
+ verify_installation
547
+
548
+ if [[ ":$PATH:" == *":$BIN_DIR:"* ]]; then
549
+ log_info "Current version: $(hf version 2>/dev/null || echo 'Run source ~/.bashrc or restart your shell first')"
550
+ else
551
+ log_info "Current version: $($BIN_DIR/hf version)"
552
+ fi
553
+
554
+ show_uninstall_info
555
+
556
+ log_success "hf CLI ready!"
557
+ log_info "Binary: $BIN_DIR/hf"
558
+ log_info "Virtualenv: $HF_CLI_DIR"
559
+ log_info "Try it now: env PATH=\"$BIN_DIR:\$PATH\" hf --help"
560
+ log_info "Examples:"
561
+ log_info " hf auth login"
562
+ log_info " hf download deepseek-ai/DeepSeek-R1"
563
+ log_info " hf jobs run python:3.12 python -c 'print(\"Hello from HF CLI!\")'"
564
+ log_info ""
565
+ }
566
+
567
+ # Handle Ctrl+C
568
+ trap 'log_error "Installation interrupted"; exit 130' INT
569
+
570
+ main "$@"