browser4-cli 0.1.17 → 0.1.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -8
- package/bin/browser4-cli-darwin-arm64 +0 -0
- package/bin/browser4-cli-darwin-x64 +0 -0
- package/bin/browser4-cli-linux-arm64 +0 -0
- package/bin/browser4-cli-linux-musl-arm64 +0 -0
- package/bin/browser4-cli-linux-musl-x64 +0 -0
- package/bin/browser4-cli-linux-x64 +0 -0
- package/bin/browser4-cli-win32-x64.exe +0 -0
- package/package.json +1 -1
- package/scripts/README.md +0 -0
- package/scripts/install-browser4-cli.ps1 +157 -6
- package/scripts/install-browser4-cli.sh +138 -4
package/README.md
CHANGED
|
@@ -152,7 +152,10 @@ The tables below mirror the commands surfaced by the global `browser4-cli help`
|
|
|
152
152
|
| `uncheck <ref>` | Uncheck a checkbox or radio button |
|
|
153
153
|
| `drag <startRef> <endRef>` | Drag and drop between two elements |
|
|
154
154
|
| `snapshot` | Capture accessibility snapshot |
|
|
155
|
-
| `eval <expression> [ref]` | Evaluate JavaScript on the page or a target element |
|
|
155
|
+
| `eval <expression> [ref]` | Evaluate JavaScript on the page or a target element. Use `--file=<path>` to read the expression from a file. |
|
|
156
|
+
| `get <mode> <selector> [name]` | Extract data from a page element. Modes: `text`, `html`, `box`, `styles`, `property`, `attr`. `name` is required for `property` and `attr`. |
|
|
157
|
+
| `scroll <direction> <pixels>` | Scroll the page. Direction: `up`, `down`, `left`, or `right`. |
|
|
158
|
+
| `wait [target]` | Wait for a condition. Positional: selector or milliseconds. Options: `--text=<text>`, `--url=<glob>`, `--load=<state>` (networkidle/domcontentloaded), `--fn=<JS expr>`. |
|
|
156
159
|
| `dialog-accept [prompt]` | Accept a dialog |
|
|
157
160
|
| `dialog-dismiss` | Dismiss a dialog |
|
|
158
161
|
| `resize <w> <h>` | Resize the browser window |
|
|
@@ -193,12 +196,12 @@ The tables below mirror the commands surfaced by the global `browser4-cli help`
|
|
|
193
196
|
|
|
194
197
|
| Command | Description |
|
|
195
198
|
|---|---|
|
|
196
|
-
| `tab-list` | List all tabs |
|
|
199
|
+
| `tab-list` | List all tabs with their zero-based index |
|
|
197
200
|
| `tab-new [url]` | Create a new tab |
|
|
198
|
-
| `tab-close [index]` | Close a
|
|
199
|
-
| `tab-select <index>` | Select a
|
|
201
|
+
| `tab-close [index]` | Close a tab by its zero-based index |
|
|
202
|
+
| `tab-select <index>` | Select a tab by its zero-based index |
|
|
200
203
|
|
|
201
|
-
|
|
204
|
+
Run `tab-list` first to find each tab's zero-based index. Pass that index to `tab-select` or `tab-close`.
|
|
202
205
|
|
|
203
206
|
#### Browser storage
|
|
204
207
|
|
|
@@ -515,7 +518,7 @@ browser4-cli open --headed https://browser4.io
|
|
|
515
518
|
browser4-cli open --headless https://browser4.io
|
|
516
519
|
|
|
517
520
|
# Navigate to a page — auto-opens a session if none is active
|
|
518
|
-
browser4-cli goto https://
|
|
521
|
+
browser4-cli goto https://browser4.io
|
|
519
522
|
|
|
520
523
|
# Inspect the page — note the eN labels on interactive nodes
|
|
521
524
|
browser4-cli snapshot
|
|
@@ -545,10 +548,10 @@ browser4-cli open --server http://localhost:9090
|
|
|
545
548
|
# Advanced: execute multiple commands in one process (batch mode)
|
|
546
549
|
# Batch mode only supports DOM operations. You must run `open` separately first.
|
|
547
550
|
browser4-cli open
|
|
548
|
-
browser4-cli batch "goto https://
|
|
551
|
+
browser4-cli batch "goto https://browser4.io" "snapshot"
|
|
549
552
|
|
|
550
553
|
# Advanced: stop on the first batch failure
|
|
551
|
-
browser4-cli batch --bail "goto https://
|
|
554
|
+
browser4-cli batch --bail "goto https://browser4.io" "click e1" "screenshot"
|
|
552
555
|
|
|
553
556
|
# Advanced: batch mode for form filling (recommended use case)
|
|
554
557
|
browser4-cli batch "fill e1 'John Doe'" "fill e2 'john@example.com'" "click e3"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
File without changes
|
|
@@ -11,9 +11,11 @@
|
|
|
11
11
|
Windows: $env:LOCALAPPDATA\Programs\browser4-cli
|
|
12
12
|
(override with -InstallDir)
|
|
13
13
|
|
|
14
|
-
Download sources (
|
|
15
|
-
1. GitHub Releases
|
|
16
|
-
|
|
14
|
+
Download sources (auto-selected by locale; use -Source to override):
|
|
15
|
+
Outside China: 1. GitHub Releases -> 2. Aliyun OSS
|
|
16
|
+
China mainland: 1. Aliyun OSS -> 2. GitHub Releases
|
|
17
|
+
GitHub Releases — https://github.com/platonai/Browser4
|
|
18
|
+
Aliyun OSS — https://browser4.oss-cn-beijing.aliyuncs.com
|
|
17
19
|
|
|
18
20
|
.PARAMETER Version
|
|
19
21
|
Release version tag to download (e.g. "v4.11.0" or "v0.1.12-cli").
|
|
@@ -25,7 +27,7 @@
|
|
|
25
27
|
|
|
26
28
|
.PARAMETER Source
|
|
27
29
|
Force a specific download source: "github" or "oss".
|
|
28
|
-
Default:
|
|
30
|
+
Default (auto): locale-aware — OSS first in China mainland, GitHub first elsewhere.
|
|
29
31
|
|
|
30
32
|
.PARAMETER AddToPath
|
|
31
33
|
Add the install directory to the current user's PATH environment variable.
|
|
@@ -37,6 +39,15 @@
|
|
|
37
39
|
.PARAMETER DryRun
|
|
38
40
|
Print what would be done without actually doing it.
|
|
39
41
|
|
|
42
|
+
.PARAMETER SkipLocal
|
|
43
|
+
Skip checking for a locally-bundled binary alongside the script.
|
|
44
|
+
By default the script looks for the platform binary in its own directory
|
|
45
|
+
before downloading — use this to force a fresh download.
|
|
46
|
+
|
|
47
|
+
.PARAMETER Locate
|
|
48
|
+
Print detection results (OS, architecture, script location, China locale)
|
|
49
|
+
and exit without installing. Useful for diagnostics.
|
|
50
|
+
|
|
40
51
|
.EXAMPLE
|
|
41
52
|
# Quick install — default location, latest version, add to PATH
|
|
42
53
|
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1
|
|
@@ -48,6 +59,24 @@
|
|
|
48
59
|
.EXAMPLE
|
|
49
60
|
# Install from OSS only, custom directory
|
|
50
61
|
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -Source oss -InstallDir "C:\tools\browser4"
|
|
62
|
+
|
|
63
|
+
.EXAMPLE
|
|
64
|
+
# Run diagnostics — see what the script detects without installing
|
|
65
|
+
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -Locate
|
|
66
|
+
|
|
67
|
+
.EXAMPLE
|
|
68
|
+
# Use a locally-bundled binary (place binary next to the script)
|
|
69
|
+
# The script auto-detects binaries in its own directory
|
|
70
|
+
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1
|
|
71
|
+
|
|
72
|
+
.EXAMPLE
|
|
73
|
+
# Force download even when a local binary exists
|
|
74
|
+
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -SkipLocal
|
|
75
|
+
|
|
76
|
+
.EXAMPLE
|
|
77
|
+
# For China mainland: OSS is auto-preferred via locale detection,
|
|
78
|
+
# or force it explicitly
|
|
79
|
+
powershell -ExecutionPolicy Bypass -File install-browser4-cli.ps1 -Source oss
|
|
51
80
|
#>
|
|
52
81
|
|
|
53
82
|
[CmdletBinding()]
|
|
@@ -58,11 +87,65 @@ param(
|
|
|
58
87
|
[string]$Source = "",
|
|
59
88
|
[bool]$AddToPath = $true,
|
|
60
89
|
[switch]$Silent,
|
|
61
|
-
[switch]$DryRun
|
|
90
|
+
[switch]$DryRun,
|
|
91
|
+
[switch]$SkipLocal,
|
|
92
|
+
[switch]$Locate
|
|
62
93
|
)
|
|
63
94
|
|
|
64
95
|
$ErrorActionPreference = "Stop"
|
|
65
96
|
|
|
97
|
+
# ──────────────────────────────────────────────
|
|
98
|
+
# Script location — find ourselves on disk
|
|
99
|
+
# ──────────────────────────────────────────────
|
|
100
|
+
|
|
101
|
+
# $PSScriptRoot is the directory containing this script (PS 3+).
|
|
102
|
+
# Falls back to $MyInvocation for edge cases (dot-sourced, PS 2).
|
|
103
|
+
$ScriptDir = if ($PSScriptRoot) {
|
|
104
|
+
$PSScriptRoot
|
|
105
|
+
} elseif ($MyInvocation -and $MyInvocation.MyCommand.Path) {
|
|
106
|
+
Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
107
|
+
} else {
|
|
108
|
+
$null
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
<#
|
|
112
|
+
.SYNOPSIS
|
|
113
|
+
Search for a pre-downloaded binary near the script (bundled/sideload install).
|
|
114
|
+
Returns the full path if found, $null otherwise.
|
|
115
|
+
#>
|
|
116
|
+
function Find-LocalBinary {
|
|
117
|
+
param([string]$BinaryName)
|
|
118
|
+
|
|
119
|
+
if (-not $ScriptDir) { return $null }
|
|
120
|
+
|
|
121
|
+
$localPath = Join-Path $ScriptDir $BinaryName
|
|
122
|
+
if (Test-Path $localPath -PathType Leaf) {
|
|
123
|
+
$size = (Get-Item $localPath).Length
|
|
124
|
+
if ($size -gt 102400) { # > 100 KB minimum
|
|
125
|
+
return $localPath
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return $null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
<#
|
|
132
|
+
.SYNOPSIS
|
|
133
|
+
Check whether a local binary is usable by querying its version.
|
|
134
|
+
Returns $true if --version executes successfully, $false otherwise.
|
|
135
|
+
#>
|
|
136
|
+
function Test-LocalBinary {
|
|
137
|
+
param([string]$Path)
|
|
138
|
+
|
|
139
|
+
if (-not $Path -or -not (Test-Path $Path)) { return $false }
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
$null = & $Path --version 2>&1
|
|
143
|
+
return ($LASTEXITCODE -eq 0)
|
|
144
|
+
} catch {
|
|
145
|
+
return $false
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
66
149
|
# ──────────────────────────────────────────────
|
|
67
150
|
# OS detection (compatible with PS 5.1+)
|
|
68
151
|
# ──────────────────────────────────────────────
|
|
@@ -423,6 +506,49 @@ function Main {
|
|
|
423
506
|
# Detect platform
|
|
424
507
|
$platformKey = Get-PlatformKey
|
|
425
508
|
$binaryName = Get-BinaryName -PlatformKey $platformKey
|
|
509
|
+
|
|
510
|
+
# ── Locate mode: print diagnostics and exit ──
|
|
511
|
+
if ($Locate) {
|
|
512
|
+
Write-Summary "─── Locate / diagnostics ───" -Color Cyan
|
|
513
|
+
Write-Summary ""
|
|
514
|
+
Write-Step "Script dir: $ScriptDir"
|
|
515
|
+
Write-Step "Platform key: $platformKey"
|
|
516
|
+
Write-Step "Binary name: $binaryName"
|
|
517
|
+
Write-Step "Default install: $(Get-DefaultInstallDir)"
|
|
518
|
+
Write-Step "China locale: $script:ChinaDetected"
|
|
519
|
+
Write-Step "Source override: $(if ($Source) { $Source } else { 'auto' })"
|
|
520
|
+
Write-Step "OS: $(if ($script:OSWin) { 'Windows' } elseif ($script:OSMac) { 'macOS' } elseif ($script:OSLinux) { 'Linux' } else { 'Unknown' })"
|
|
521
|
+
|
|
522
|
+
# Check for local binary
|
|
523
|
+
$localPath = Find-LocalBinary -BinaryName $binaryName
|
|
524
|
+
if ($localPath) {
|
|
525
|
+
$localOk = Test-LocalBinary -Path $localPath
|
|
526
|
+
Write-Step "Local binary: $localPath $(if ($localOk) { '(valid)' } else { '(present but --version failed)' })"
|
|
527
|
+
} else {
|
|
528
|
+
Write-Step "Local binary: not found alongside script"
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
# Check for already-installed binary
|
|
532
|
+
$defaultDir = Get-DefaultInstallDir
|
|
533
|
+
$existingPath = Join-Path $defaultDir $binaryName
|
|
534
|
+
if (Test-Path $existingPath) {
|
|
535
|
+
Write-Step "Already installed: $existingPath"
|
|
536
|
+
} else {
|
|
537
|
+
Write-Step "Already installed: not found at $defaultDir"
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
# Show download URLs that would be tried
|
|
541
|
+
$urls = Get-DownloadUrls -BinaryName $binaryName -VersionTag $Version
|
|
542
|
+
Write-Summary ""
|
|
543
|
+
Write-Step "Download order:"
|
|
544
|
+
foreach ($entry in $urls) {
|
|
545
|
+
Write-Step " $($entry.Label): $($entry.Url)"
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
Write-Summary ""
|
|
549
|
+
return
|
|
550
|
+
}
|
|
551
|
+
|
|
426
552
|
Write-Step "Platform: $platformKey"
|
|
427
553
|
Write-Step "Binary: $binaryName"
|
|
428
554
|
|
|
@@ -440,9 +566,33 @@ function Main {
|
|
|
440
566
|
|
|
441
567
|
$binaryPath = Join-Path $installDir $binaryName
|
|
442
568
|
|
|
569
|
+
# ── Local binary discovery (bundled/sideload) ──
|
|
570
|
+
$useLocalBinary = $false
|
|
571
|
+
if (-not $SkipLocal) {
|
|
572
|
+
$localBinaryPath = Find-LocalBinary -BinaryName $binaryName
|
|
573
|
+
if ($localBinaryPath) {
|
|
574
|
+
Write-Step "Found local binary alongside script: $(Split-Path $localBinaryPath -Leaf)"
|
|
575
|
+
if (Test-LocalBinary -Path $localBinaryPath) {
|
|
576
|
+
Write-Check "Local binary verified (--version OK)"
|
|
577
|
+
$useLocalBinary = $true
|
|
578
|
+
} else {
|
|
579
|
+
Write-WarnMsg "Local binary found but --version check failed — will download instead"
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
} elseif ($SkipLocal) {
|
|
583
|
+
Write-Step "Skipping local binary check (-SkipLocal)"
|
|
584
|
+
}
|
|
585
|
+
|
|
443
586
|
# If binary already exists and no version override, skip download
|
|
444
|
-
if ((Test-Path $binaryPath) -and (-not $Version)) {
|
|
587
|
+
if ((Test-Path $binaryPath) -and (-not $Version) -and (-not $useLocalBinary)) {
|
|
445
588
|
Write-Check "Binary already installed: $binaryPath"
|
|
589
|
+
} elseif ($useLocalBinary) {
|
|
590
|
+
# Copy local binary to install dir
|
|
591
|
+
if (-not $DryRun) {
|
|
592
|
+
if (Test-Path $binaryPath) { Remove-Item $binaryPath -Force }
|
|
593
|
+
Copy-Item $localBinaryPath $binaryPath -Force
|
|
594
|
+
}
|
|
595
|
+
Write-Check "Installed (local): $binaryPath"
|
|
446
596
|
} else {
|
|
447
597
|
# Build download URLs
|
|
448
598
|
$urls = Get-DownloadUrls -BinaryName $binaryName -VersionTag $Version
|
|
@@ -472,6 +622,7 @@ Please check:
|
|
|
472
622
|
- Network connectivity
|
|
473
623
|
- The version/tag exists: $Version
|
|
474
624
|
- For GitHub rate limits, set GITHUB_TOKEN environment variable
|
|
625
|
+
- If you have a local copy, place it alongside this script and re-run
|
|
475
626
|
"@
|
|
476
627
|
}
|
|
477
628
|
|
|
@@ -16,7 +16,10 @@
|
|
|
16
16
|
# --version, -v TAG Release tag (e.g. "v4.11.0"). Default: latest.
|
|
17
17
|
# --install-dir, -d DIR Install directory (default: ~/.local/bin).
|
|
18
18
|
# --source SRC Force download source: "github" or "oss".
|
|
19
|
+
# Default (auto): locale-aware — OSS first for China mainland.
|
|
19
20
|
# --no-path Skip adding install dir to PATH.
|
|
21
|
+
# --skip-local Skip checking for a locally-bundled binary.
|
|
22
|
+
# --locate Print detection results and exit (no install).
|
|
20
23
|
# --silent, -s Suppress non-error output.
|
|
21
24
|
# --dry-run Print what would be done without doing it.
|
|
22
25
|
# --help, -h Show this message.
|
|
@@ -36,7 +39,10 @@ SOURCE=""
|
|
|
36
39
|
ADD_TO_PATH=true
|
|
37
40
|
SILENT=false
|
|
38
41
|
DRY_RUN=false
|
|
42
|
+
SKIP_LOCAL=false
|
|
43
|
+
LOCATE_MODE=false
|
|
39
44
|
CHINA_DETECTED=false
|
|
45
|
+
SCRIPT_DIR=""
|
|
40
46
|
|
|
41
47
|
# ──────────────────────────────────────────────
|
|
42
48
|
# Helpers
|
|
@@ -62,6 +68,49 @@ header() {
|
|
|
62
68
|
fi
|
|
63
69
|
}
|
|
64
70
|
|
|
71
|
+
# ──────────────────────────────────────────────
|
|
72
|
+
# Script location — find ourselves on disk
|
|
73
|
+
# ──────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
detect_script_dir() {
|
|
76
|
+
# BASH_SOURCE works even when sourced; prefer it over $0.
|
|
77
|
+
if [[ -n "${BASH_SOURCE[0]:-}" ]] && [[ "${BASH_SOURCE[0]}" != "bash" ]] && [[ "${BASH_SOURCE[0]}" != *stdin* ]]; then
|
|
78
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
79
|
+
elif [[ -n "${0:-}" ]] && [[ "$0" != "bash" ]] && [[ "$0" != "-bash" ]] && [[ -f "$0" ]]; then
|
|
80
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
81
|
+
fi
|
|
82
|
+
# If piped via curl | bash, SCRIPT_DIR stays empty — no local binaries available.
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# Search for a pre-downloaded binary near the script (bundled/sideload install).
|
|
86
|
+
# Echoes the full path on success; returns non-zero when not found.
|
|
87
|
+
find_local_binary() {
|
|
88
|
+
local binary_name="$1"
|
|
89
|
+
if [[ -z "$SCRIPT_DIR" ]]; then
|
|
90
|
+
return 1
|
|
91
|
+
fi
|
|
92
|
+
local local_path="${SCRIPT_DIR}/${binary_name}"
|
|
93
|
+
if [[ -f "$local_path" ]]; then
|
|
94
|
+
local size
|
|
95
|
+
size=$(stat -c%s "$local_path" 2>/dev/null || stat -f%z "$local_path" 2>/dev/null || echo 0)
|
|
96
|
+
if [[ "$size" -gt 102400 ]]; then # > 100 KB minimum
|
|
97
|
+
echo "$local_path"
|
|
98
|
+
return 0
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
return 1
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
# Check whether a local binary is usable by querying its version.
|
|
105
|
+
# Returns 0 if --version executes successfully, non-zero otherwise.
|
|
106
|
+
test_local_binary() {
|
|
107
|
+
local path="$1"
|
|
108
|
+
if [[ -z "$path" ]] || [[ ! -f "$path" ]]; then
|
|
109
|
+
return 1
|
|
110
|
+
fi
|
|
111
|
+
"$path" --version >/dev/null 2>&1
|
|
112
|
+
}
|
|
113
|
+
|
|
65
114
|
usage() {
|
|
66
115
|
cat <<EOF
|
|
67
116
|
Usage: $(basename "$0") [OPTIONS]
|
|
@@ -71,8 +120,11 @@ Download and install the browser4-cli native binary.
|
|
|
71
120
|
Options:
|
|
72
121
|
--version, -v TAG Release tag (e.g. "v4.11.0"). Default: latest.
|
|
73
122
|
--install-dir, -d DIR Install directory (default: ~/.local/bin).
|
|
74
|
-
--source SRC Force source: "github" or "oss"
|
|
123
|
+
--source SRC Force source: "github" or "oss".
|
|
124
|
+
Default (auto): OSS first for China mainland, GitHub first elsewhere.
|
|
75
125
|
--no-path Skip adding install dir to shell rc file.
|
|
126
|
+
--skip-local Skip checking for a locally-bundled binary alongside this script.
|
|
127
|
+
--locate Print detection results and exit without installing.
|
|
76
128
|
--silent, -s Suppress non-error output.
|
|
77
129
|
--dry-run Print what would be done without doing it.
|
|
78
130
|
--help, -h Show this message.
|
|
@@ -82,6 +134,9 @@ Examples:
|
|
|
82
134
|
$(basename "$0") --version v4.11.0 # Install specific version
|
|
83
135
|
$(basename "$0") --source oss --silent # Silent install from Aliyun OSS
|
|
84
136
|
$(basename "$0") --install-dir /usr/local/bin # System-wide install (needs sudo)
|
|
137
|
+
$(basename "$0") --locate # Run diagnostics (no install)
|
|
138
|
+
$(basename "$0") --skip-local # Force download, ignore bundled binary
|
|
139
|
+
$(basename "$0") --source oss # Force Aliyun OSS (China mainland)
|
|
85
140
|
EOF
|
|
86
141
|
}
|
|
87
142
|
|
|
@@ -104,6 +159,8 @@ while [[ $# -gt 0 ]]; do
|
|
|
104
159
|
fi
|
|
105
160
|
SOURCE="$1"; shift ;;
|
|
106
161
|
--no-path) ADD_TO_PATH=false; shift ;;
|
|
162
|
+
--skip-local) SKIP_LOCAL=true; shift ;;
|
|
163
|
+
--locate) LOCATE_MODE=true; shift ;;
|
|
107
164
|
--silent|-s) SILENT=true; shift ;;
|
|
108
165
|
--dry-run) DRY_RUN=true; shift ;;
|
|
109
166
|
--help|-h) usage; exit 0 ;;
|
|
@@ -465,6 +522,9 @@ main() {
|
|
|
465
522
|
check_commands
|
|
466
523
|
header
|
|
467
524
|
|
|
525
|
+
# Locate ourselves on disk (only works when run as a file, not piped)
|
|
526
|
+
detect_script_dir
|
|
527
|
+
|
|
468
528
|
# Auto-detect China mainland locale when no explicit source is given
|
|
469
529
|
if [[ -z "$SOURCE" ]]; then
|
|
470
530
|
if detect_china_locale; then
|
|
@@ -478,6 +538,54 @@ main() {
|
|
|
478
538
|
platform_key=$(get_platform_key)
|
|
479
539
|
binary_name=$(get_binary_name "$platform_key")
|
|
480
540
|
|
|
541
|
+
# ── Locate mode: print diagnostics and exit ──
|
|
542
|
+
if [[ "$LOCATE_MODE" == true ]]; then
|
|
543
|
+
echo -e "${color_cyan}─── Locate / diagnostics ───${color_reset}"
|
|
544
|
+
echo ""
|
|
545
|
+
step "Script dir: ${SCRIPT_DIR:-'(not available — piped via curl?)'}"
|
|
546
|
+
step "Platform key: $platform_key"
|
|
547
|
+
step "Binary name: $binary_name"
|
|
548
|
+
step "Default install: $(get_default_install_dir)"
|
|
549
|
+
step "China locale: $CHINA_DETECTED"
|
|
550
|
+
step "Source override: ${SOURCE:-auto}"
|
|
551
|
+
step "OS: $(uname -s)"
|
|
552
|
+
|
|
553
|
+
# Check for local binary
|
|
554
|
+
local locate_local
|
|
555
|
+
if locate_local=$(find_local_binary "$binary_name" 2>/dev/null); then
|
|
556
|
+
local local_status="(present but --version failed)"
|
|
557
|
+
if test_local_binary "$locate_local"; then
|
|
558
|
+
local_status="(valid)"
|
|
559
|
+
fi
|
|
560
|
+
step "Local binary: ${locate_local} ${local_status}"
|
|
561
|
+
else
|
|
562
|
+
step "Local binary: not found alongside script"
|
|
563
|
+
fi
|
|
564
|
+
|
|
565
|
+
# Check for already-installed binary
|
|
566
|
+
local default_dir existing_path
|
|
567
|
+
default_dir=$(get_default_install_dir)
|
|
568
|
+
existing_path="${default_dir}/${binary_name}"
|
|
569
|
+
if [[ -f "$existing_path" ]]; then
|
|
570
|
+
step "Already installed: $existing_path"
|
|
571
|
+
else
|
|
572
|
+
step "Already installed: not found at $default_dir"
|
|
573
|
+
fi
|
|
574
|
+
|
|
575
|
+
# Show download URLs that would be tried
|
|
576
|
+
local locate_urls
|
|
577
|
+
IFS=$'\n' read -r -d '' -a locate_urls < <(get_download_urls "$binary_name" "$VERSION" && printf '\0')
|
|
578
|
+
echo ""
|
|
579
|
+
step "Download order:"
|
|
580
|
+
for entry in "${locate_urls[@]}"; do
|
|
581
|
+
local l="${entry%%|*}" u="${entry#*|}"
|
|
582
|
+
step " ${l}: ${u}"
|
|
583
|
+
done
|
|
584
|
+
|
|
585
|
+
echo ""
|
|
586
|
+
return
|
|
587
|
+
fi
|
|
588
|
+
|
|
481
589
|
step "Platform: $platform_key"
|
|
482
590
|
step "Binary: $binary_name"
|
|
483
591
|
|
|
@@ -498,9 +606,34 @@ main() {
|
|
|
498
606
|
|
|
499
607
|
local binary_path="${INSTALL_DIR}/${binary_name}"
|
|
500
608
|
|
|
501
|
-
#
|
|
502
|
-
|
|
609
|
+
# ── Local binary discovery (bundled/sideload) ──
|
|
610
|
+
local use_local_binary=false
|
|
611
|
+
local local_binary_path=""
|
|
612
|
+
if [[ "$SKIP_LOCAL" != true ]]; then
|
|
613
|
+
if local_binary_path=$(find_local_binary "$binary_name" 2>/dev/null) && [[ -n "$local_binary_path" ]]; then
|
|
614
|
+
step "Found local binary alongside script: $(basename "$local_binary_path")"
|
|
615
|
+
if test_local_binary "$local_binary_path"; then
|
|
616
|
+
ok "Local binary verified (--version OK)"
|
|
617
|
+
use_local_binary=true
|
|
618
|
+
else
|
|
619
|
+
warn "Local binary found but --version check failed — will download instead"
|
|
620
|
+
fi
|
|
621
|
+
fi
|
|
622
|
+
else
|
|
623
|
+
step "Skipping local binary check (--skip-local)"
|
|
624
|
+
fi
|
|
625
|
+
|
|
626
|
+
# Install binary: local copy > already installed > download
|
|
627
|
+
if [[ -f "$binary_path" ]] && [[ -z "$VERSION" ]] && [[ "$use_local_binary" != true ]]; then
|
|
503
628
|
ok "Binary already installed: $binary_path"
|
|
629
|
+
elif [[ "$use_local_binary" == true ]]; then
|
|
630
|
+
# Copy local binary to install dir
|
|
631
|
+
if [[ "$DRY_RUN" != true ]]; then
|
|
632
|
+
rm -f "$binary_path"
|
|
633
|
+
cp "$local_binary_path" "$binary_path"
|
|
634
|
+
chmod +x "$binary_path"
|
|
635
|
+
fi
|
|
636
|
+
ok "Installed (local): $binary_path"
|
|
504
637
|
else
|
|
505
638
|
local urls
|
|
506
639
|
IFS=$'\n' read -r -d '' -a urls < <(get_download_urls "$binary_name" "$VERSION" && printf '\0')
|
|
@@ -537,7 +670,8 @@ main() {
|
|
|
537
670
|
tried_msg+=$'\n'"Please check:"$'\n'
|
|
538
671
|
tried_msg+=" - Network connectivity"$'\n'
|
|
539
672
|
tried_msg+=" - The version/tag exists: ${VERSION:-latest}"$'\n'
|
|
540
|
-
tried_msg+=" - For GitHub rate limits, set GITHUB_TOKEN environment variable"
|
|
673
|
+
tried_msg+=" - For GitHub rate limits, set GITHUB_TOKEN environment variable"$'\n'
|
|
674
|
+
tried_msg+=" - If you have a local copy, place it alongside this script and re-run"
|
|
541
675
|
die "$tried_msg"
|
|
542
676
|
fi
|
|
543
677
|
|