browser4-cli 0.1.13 → 0.1.15
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 +31 -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/install-browser4-cli.ps1 +115 -12
- package/scripts/install-browser4-cli.sh +50 -0
- package/scripts/npm-publish-check.js +12 -0
- package/scripts/sync-version.js +55 -18
package/README.md
CHANGED
|
@@ -61,19 +61,42 @@ the full option reference, supported platforms, and examples.
|
|
|
61
61
|
|
|
62
62
|
### From Source
|
|
63
63
|
|
|
64
|
+
**Build prerequisites:** Rust (stable, edition 2021), Node.js 24+, pnpm 10+, git.
|
|
65
|
+
|
|
64
66
|
```bash
|
|
65
|
-
git clone https://github.com/platonai/
|
|
66
|
-
cd cli/browser4-cli
|
|
67
|
+
git clone https://github.com/platonai/Browser4.git
|
|
68
|
+
cd Browser4/cli/browser4-cli
|
|
67
69
|
pnpm install
|
|
68
|
-
pnpm build:native #
|
|
70
|
+
pnpm build:native # Compiles the Rust binary (requires https://rustup.rs)
|
|
69
71
|
pnpm link --global # Makes browser4-cli available globally
|
|
70
72
|
```
|
|
71
73
|
|
|
74
|
+
Cross-compilation from Linux (for release builds) additionally requires:
|
|
75
|
+
`cargo-zigbuild`, Zig 0.13.0, `gcc-aarch64-linux-gnu`, and `mingw-w64`.
|
|
76
|
+
See `cli/docker/Dockerfile.build` for a Dockerized build environment.
|
|
77
|
+
|
|
72
78
|
### Requirements
|
|
73
79
|
|
|
74
|
-
- **Chrome**
|
|
75
|
-
- **Java 17+**
|
|
76
|
-
- **Rust**
|
|
80
|
+
- **Chrome** — Latest Chrome installed on your system. The CLI can auto-install Chrome on most platforms when missing.
|
|
81
|
+
- **Java 17+** — Required to run the Browser4 backend (`Browser4.jar`). Eclipse Temurin recommended. JDK 21+ enables best jlink compression when the CLI auto-builds a runtime bundle from source.
|
|
82
|
+
- **Rust** — Only needed when building the CLI from source (see From Source above). The `stable` toolchain (edition 2021) is sufficient.
|
|
83
|
+
|
|
84
|
+
#### Additional requirements for auto-building a runtime bundle from source
|
|
85
|
+
|
|
86
|
+
When the CLI detects a Browser4 repository checkout, it attempts to build a
|
|
87
|
+
self-contained runtime bundle (bundled JRE + dependency JARs) from source
|
|
88
|
+
instead of downloading a pre-built release. This requires:
|
|
89
|
+
|
|
90
|
+
| Tool | Version | Linux | macOS | Windows |
|
|
91
|
+
|------|---------|-------|-------|---------|
|
|
92
|
+
| **Maven** | 3.9+ | via `mvnw` wrapper | via `mvnw` wrapper | via `mvnw.cmd` wrapper |
|
|
93
|
+
| **JDK tools** (`jdeps`, `jlink`) | bundled with JDK 16+ | included in JDK | included in JDK | included in JDK |
|
|
94
|
+
| **PowerShell 7** (`pwsh`) | 7.0+ | **required** | **required** | built-in (`powershell.exe`) |
|
|
95
|
+
| **tar** | any | **required** | **required** | built-in |
|
|
96
|
+
|
|
97
|
+
Set `BROWSER4_CLI_FORCE_REMOTE_BUNDLE=1` to skip the local build and always
|
|
98
|
+
download a pre-built bundle — useful in CI / corporate environments where
|
|
99
|
+
Maven or jlink are unavailable.
|
|
77
100
|
|
|
78
101
|
## Usage
|
|
79
102
|
|
|
@@ -366,7 +389,7 @@ browser4-cli swarm submit https://example.com/direct \
|
|
|
366
389
|
--seed-file=./swarm-seeds.txt \
|
|
367
390
|
--deadline=2026-03-30T00:00:00Z \
|
|
368
391
|
--expires=1d \
|
|
369
|
-
--refresh --
|
|
392
|
+
--refresh --store-content
|
|
370
393
|
|
|
371
394
|
# poll and fetch the result
|
|
372
395
|
browser4-cli swarm status scrape-task-4
|
|
@@ -391,7 +414,7 @@ browser4-cli swarm query "https://www.amazon.com/dp/B08PP5MSVB" --sql "
|
|
|
391
414
|
browser4-cli swarm query "https://www.amazon.com/dp/B08PP5MSVB" --sql @query.sql
|
|
392
415
|
|
|
393
416
|
# With seed file and load options:
|
|
394
|
-
browser4-cli swarm query --sql @query.sql --seed-file=./urls.txt --refresh
|
|
417
|
+
browser4-cli swarm query --sql @query.sql --seed-file=./urls.txt --refresh
|
|
395
418
|
```
|
|
396
419
|
|
|
397
420
|
### Notes
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -67,9 +67,17 @@ $ErrorActionPreference = "Stop"
|
|
|
67
67
|
# OS detection (compatible with PS 5.1+)
|
|
68
68
|
# ──────────────────────────────────────────────
|
|
69
69
|
|
|
70
|
-
$
|
|
71
|
-
|
|
72
|
-
$
|
|
70
|
+
# Avoid assigning to $IsLinux / $IsWindows / $IsMacOS directly —
|
|
71
|
+
# they are read-only automatic variables in PowerShell 7+.
|
|
72
|
+
if ($PSVersionTable.PSVersion.Major -ge 6) {
|
|
73
|
+
$script:OSWin = $IsWindows
|
|
74
|
+
$script:OSLinux = $IsLinux
|
|
75
|
+
$script:OSMac = $IsMacOS
|
|
76
|
+
} else {
|
|
77
|
+
$script:OSWin = [System.Environment]::OSVersion.Platform -eq "Win32NT"
|
|
78
|
+
$script:OSMac = $false
|
|
79
|
+
$script:OSLinux = $false
|
|
80
|
+
}
|
|
73
81
|
|
|
74
82
|
# ──────────────────────────────────────────────
|
|
75
83
|
# Helpers
|
|
@@ -102,13 +110,13 @@ function Write-WarnMsg {
|
|
|
102
110
|
function Get-PlatformKey {
|
|
103
111
|
$arch = if ([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture -eq [System.Runtime.InteropServices.Architecture]::Arm64) { "arm64" } else { "x64" }
|
|
104
112
|
|
|
105
|
-
if ($script:
|
|
113
|
+
if ($script:OSWin) {
|
|
106
114
|
return "win32-$arch"
|
|
107
115
|
}
|
|
108
|
-
elseif ($script:
|
|
116
|
+
elseif ($script:OSMac) {
|
|
109
117
|
return "darwin-$arch"
|
|
110
118
|
}
|
|
111
|
-
elseif ($script:
|
|
119
|
+
elseif ($script:OSLinux) {
|
|
112
120
|
# Detect musl
|
|
113
121
|
$isMusl = $false
|
|
114
122
|
try {
|
|
@@ -133,10 +141,10 @@ function Get-BinaryName {
|
|
|
133
141
|
}
|
|
134
142
|
|
|
135
143
|
function Get-DefaultInstallDir {
|
|
136
|
-
if ($script:
|
|
144
|
+
if ($script:OSWin) {
|
|
137
145
|
return Join-Path $env:LOCALAPPDATA "Programs\browser4-cli"
|
|
138
146
|
}
|
|
139
|
-
elseif ($script:
|
|
147
|
+
elseif ($script:OSLinux -or $script:OSMac) {
|
|
140
148
|
# Prefer ~/.local/bin for user installs
|
|
141
149
|
if (Test-Path "$env:HOME/.local/bin") {
|
|
142
150
|
return "$env:HOME/.local/bin"
|
|
@@ -216,6 +224,97 @@ function Invoke-Download {
|
|
|
216
224
|
}
|
|
217
225
|
}
|
|
218
226
|
|
|
227
|
+
# ──────────────────────────────────────────────
|
|
228
|
+
# Symlinks
|
|
229
|
+
# ──────────────────────────────────────────────
|
|
230
|
+
|
|
231
|
+
function New-PlatformLink {
|
|
232
|
+
param([string]$LinkPath, [string]$TargetName, [string]$DisplayName)
|
|
233
|
+
|
|
234
|
+
# Try symbolic link first (works on Unix; on Windows needs Admin or Developer Mode)
|
|
235
|
+
try {
|
|
236
|
+
New-Item -ItemType SymbolicLink -Path $LinkPath -Target $TargetName -Force -ErrorAction Stop | Out-Null
|
|
237
|
+
Write-Check "Created symlink: $DisplayName -> $TargetName"
|
|
238
|
+
return $true
|
|
239
|
+
} catch {
|
|
240
|
+
# Symbolic link failed — try hard link on Windows
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
# Try hard link (Windows, same volume)
|
|
244
|
+
if ($script:OSWin) {
|
|
245
|
+
try {
|
|
246
|
+
$targetPath = Join-Path (Split-Path $LinkPath -Parent) $TargetName
|
|
247
|
+
New-Item -ItemType HardLink -Path $LinkPath -Target $targetPath -Force -ErrorAction Stop | Out-Null
|
|
248
|
+
Write-Check "Created hard link: $DisplayName -> $TargetName"
|
|
249
|
+
return $true
|
|
250
|
+
} catch {
|
|
251
|
+
# Hard link also failed — create a .cmd wrapper as last resort
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
# Last resort: .cmd wrapper that forwards all arguments
|
|
255
|
+
try {
|
|
256
|
+
$wrapperContent = '@"%~dp0' + $TargetName + '" %*'
|
|
257
|
+
Set-Content -Path ($LinkPath -replace '\.exe$', '.cmd') -Value $wrapperContent -Force -ErrorAction Stop
|
|
258
|
+
Write-Check "Created wrapper: " + (Split-Path ($LinkPath -replace '\.exe$', '.cmd') -Leaf) + " -> $TargetName"
|
|
259
|
+
return $true
|
|
260
|
+
} catch {
|
|
261
|
+
Write-WarnMsg "Could not create link for $DisplayName (may need admin privileges)"
|
|
262
|
+
return $false
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
Write-WarnMsg "Could not create link for $DisplayName"
|
|
267
|
+
return $false
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function New-Symlinks {
|
|
271
|
+
param([string]$BinaryName, [string]$InstallDir, [string]$PlatformKey)
|
|
272
|
+
|
|
273
|
+
$ext = if ($PlatformKey.StartsWith("win32")) { ".exe" } else { "" }
|
|
274
|
+
|
|
275
|
+
# 1) Always: browser4-cli -> browser4-cli-<platform>
|
|
276
|
+
$linkName = "browser4-cli$ext"
|
|
277
|
+
$linkPath = Join-Path $InstallDir $linkName
|
|
278
|
+
|
|
279
|
+
if ($DryRun) {
|
|
280
|
+
Write-Step "[DRY-RUN] Would create link: $linkName -> $BinaryName"
|
|
281
|
+
} else {
|
|
282
|
+
New-PlatformLink -LinkPath $linkPath -TargetName $BinaryName -DisplayName $linkName
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
# 2) Only if no conflict: b4 -> browser4-cli-<platform>
|
|
286
|
+
$shortName = "b4$ext"
|
|
287
|
+
$shortPath = Join-Path $InstallDir $shortName
|
|
288
|
+
|
|
289
|
+
# Check if b4 is already on PATH (conflict with another tool)
|
|
290
|
+
$existingCmd = Get-Command b4 -ErrorAction SilentlyContinue
|
|
291
|
+
if ($existingCmd) {
|
|
292
|
+
Write-WarnMsg "Skipping short link '$shortName': 'b4' already found on PATH ($($existingCmd.Source))"
|
|
293
|
+
return
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
# Check if b4 already exists in the install directory
|
|
297
|
+
if (Test-Path $shortPath) {
|
|
298
|
+
Write-WarnMsg "Skipping short link '$shortName': already exists in $InstallDir"
|
|
299
|
+
return
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# Also check b4.cmd if on Windows (wrapper fallback)
|
|
303
|
+
if ($script:OSWin) {
|
|
304
|
+
$shortCmdPath = Join-Path $InstallDir "b4.cmd"
|
|
305
|
+
if (Test-Path $shortCmdPath) {
|
|
306
|
+
Write-WarnMsg "Skipping short link '$shortName': 'b4.cmd' already exists in $InstallDir"
|
|
307
|
+
return
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if ($DryRun) {
|
|
312
|
+
Write-Step "[DRY-RUN] Would create link: $shortName -> $BinaryName"
|
|
313
|
+
} else {
|
|
314
|
+
New-PlatformLink -LinkPath $shortPath -TargetName $BinaryName -DisplayName $shortName
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
219
318
|
# ──────────────────────────────────────────────
|
|
220
319
|
# PATH management
|
|
221
320
|
# ──────────────────────────────────────────────
|
|
@@ -324,17 +423,21 @@ Please check:
|
|
|
324
423
|
}
|
|
325
424
|
|
|
326
425
|
# On Unix, ensure executable bit
|
|
327
|
-
if (-not $script:
|
|
426
|
+
if (-not $script:OSWin) {
|
|
328
427
|
if (-not $DryRun) {
|
|
329
428
|
try { chmod +x $binaryPath 2>$null } catch { }
|
|
330
429
|
}
|
|
331
430
|
}
|
|
332
431
|
|
|
432
|
+
# Create symlinks (browser4-cli -> platform binary, b4 if no conflict)
|
|
433
|
+
Write-Summary ""
|
|
434
|
+
New-Symlinks -BinaryName $binaryName -InstallDir $installDir -PlatformKey $platformKey
|
|
435
|
+
|
|
333
436
|
# Add to PATH
|
|
334
|
-
if ($AddToPath -and $script:
|
|
437
|
+
if ($AddToPath -and $script:OSWin) {
|
|
335
438
|
Write-Summary ""
|
|
336
439
|
Add-DirectoryToUserPath -Dir $installDir
|
|
337
|
-
} elseif ($AddToPath -and -not $script:
|
|
440
|
+
} elseif ($AddToPath -and -not $script:OSWin) {
|
|
338
441
|
Write-Summary ""
|
|
339
442
|
$shellRc = if (Test-Path "$env:HOME/.zshrc") { "$env:HOME/.zshrc" } elseif (Test-Path "$env:HOME/.bashrc") { "$env:HOME/.bashrc" } elseif (Test-Path "$env:HOME/.bash_profile") { "$env:HOME/.bash_profile" } else { "$env:HOME/.profile" }
|
|
340
443
|
$pathLine = "export PATH=""$installDir`:`$PATH"""
|
|
@@ -370,7 +473,7 @@ Please check:
|
|
|
370
473
|
Write-Summary ""
|
|
371
474
|
Write-Summary "Run 'browser4-cli --help' to get started." -Color Cyan
|
|
372
475
|
|
|
373
|
-
if ($script:
|
|
476
|
+
if ($script:OSWin) {
|
|
374
477
|
Write-Summary "If the command isn't found, restart your terminal or run:"
|
|
375
478
|
Write-Summary " `$env:Path = [System.Environment]::GetEnvironmentVariable('Path','User') + ';' + [System.Environment]::GetEnvironmentVariable('Path','Machine')"
|
|
376
479
|
}
|
|
@@ -307,6 +307,52 @@ add_to_shell_rc() {
|
|
|
307
307
|
say " Reload with: source $rc_file"
|
|
308
308
|
}
|
|
309
309
|
|
|
310
|
+
# ──────────────────────────────────────────────
|
|
311
|
+
# Symlinks
|
|
312
|
+
# ──────────────────────────────────────────────
|
|
313
|
+
|
|
314
|
+
create_symlinks() {
|
|
315
|
+
local binary_name="$1"
|
|
316
|
+
local install_dir="$2"
|
|
317
|
+
|
|
318
|
+
local ext=""
|
|
319
|
+
if [[ "$binary_name" == *.exe ]]; then
|
|
320
|
+
ext=".exe"
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
# 1) Always: browser4-cli -> browser4-cli-<platform>
|
|
324
|
+
local link_name="browser4-cli${ext}"
|
|
325
|
+
local link_path="${install_dir}/${link_name}"
|
|
326
|
+
|
|
327
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
328
|
+
step "[DRY-RUN] Would create symlink: ${link_name} -> ${binary_name}"
|
|
329
|
+
else
|
|
330
|
+
ln -sf "$binary_name" "$link_path"
|
|
331
|
+
ok "Created symlink: ${link_name} -> ${binary_name}"
|
|
332
|
+
fi
|
|
333
|
+
|
|
334
|
+
# 2) Only if no conflict: b4 -> browser4-cli-<platform>
|
|
335
|
+
local short_name="b4${ext}"
|
|
336
|
+
local short_path="${install_dir}/${short_name}"
|
|
337
|
+
|
|
338
|
+
if command -v b4 >/dev/null 2>&1; then
|
|
339
|
+
warn "Skipping short link '${short_name}': 'b4' already found on PATH"
|
|
340
|
+
return
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
if [[ -e "$short_path" ]] || [[ -L "$short_path" ]]; then
|
|
344
|
+
warn "Skipping short link '${short_name}': already exists in ${install_dir}"
|
|
345
|
+
return
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
349
|
+
step "[DRY-RUN] Would create symlink: ${short_name} -> ${binary_name}"
|
|
350
|
+
else
|
|
351
|
+
ln -sf "$binary_name" "$short_path"
|
|
352
|
+
ok "Created symlink: ${short_name} -> ${binary_name}"
|
|
353
|
+
fi
|
|
354
|
+
}
|
|
355
|
+
|
|
310
356
|
# ──────────────────────────────────────────────
|
|
311
357
|
# Main
|
|
312
358
|
# ──────────────────────────────────────────────
|
|
@@ -399,6 +445,10 @@ main() {
|
|
|
399
445
|
chmod +x "$binary_path" 2>/dev/null || true
|
|
400
446
|
fi
|
|
401
447
|
|
|
448
|
+
# Create symlinks (browser4-cli -> platform binary, b4 if no conflict)
|
|
449
|
+
say ""
|
|
450
|
+
create_symlinks "$binary_name" "$INSTALL_DIR"
|
|
451
|
+
|
|
402
452
|
# Add to PATH
|
|
403
453
|
if [[ "$ADD_TO_PATH" == true ]]; then
|
|
404
454
|
say ""
|
|
@@ -9,6 +9,9 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
9
9
|
export const cliRootDir = join(__dirname, '..');
|
|
10
10
|
const packageJsonPath = join(cliRootDir, 'package.json');
|
|
11
11
|
|
|
12
|
+
/** The only valid npm package name for the CLI. */
|
|
13
|
+
const EXPECTED_PACKAGE_NAME = 'browser4-cli';
|
|
14
|
+
|
|
12
15
|
/**
|
|
13
16
|
* Reads browser4-cli package metadata.
|
|
14
17
|
*
|
|
@@ -16,6 +19,15 @@ const packageJsonPath = join(cliRootDir, 'package.json');
|
|
|
16
19
|
*/
|
|
17
20
|
export function readPackageMetadata() {
|
|
18
21
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
22
|
+
|
|
23
|
+
if (packageJson.name !== EXPECTED_PACKAGE_NAME) {
|
|
24
|
+
console.error(
|
|
25
|
+
`ERROR: cli/package.json name is "${packageJson.name}", expected "${EXPECTED_PACKAGE_NAME}". ` +
|
|
26
|
+
`Refusing to proceed with an unexpected package name.`
|
|
27
|
+
);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
|
|
19
31
|
return {
|
|
20
32
|
name: packageJson.name,
|
|
21
33
|
version: packageJson.version,
|
package/scripts/sync-version.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Syncs the CLI version from cli/
|
|
4
|
+
* Syncs the CLI version from cli/VERSION-CLI to all dependent files.
|
|
5
5
|
*
|
|
6
|
-
* cli/
|
|
6
|
+
* cli/VERSION-CLI is the single source of truth for the CLI version. This
|
|
7
7
|
* allows the backend Maven project and the CLI to be published separately with
|
|
8
8
|
* different versions. This script:
|
|
9
|
-
* - Reads the version from cli/
|
|
10
|
-
* - Strips
|
|
9
|
+
* - Reads the version from cli/VERSION-CLI
|
|
10
|
+
* - Strips any "-SNAPSHOT" suffix (if present)
|
|
11
11
|
* - Fetches the latest published version from npm and compares it
|
|
12
12
|
* against the local version, warning when the bump is neither a
|
|
13
13
|
* patch nor a minor increment.
|
|
14
|
-
* - Writes the
|
|
14
|
+
* - Writes the version to cli/package.json
|
|
15
|
+
* - Writes the version to cli/browser4-cli/Cargo.toml
|
|
15
16
|
* - Updates Cargo.lock to match
|
|
16
17
|
*
|
|
17
18
|
* Usage:
|
|
@@ -126,19 +127,26 @@ function checkVersionBump(published, local) {
|
|
|
126
127
|
|
|
127
128
|
const checkOnly = process.argv.includes("--check");
|
|
128
129
|
|
|
129
|
-
//
|
|
130
|
-
const
|
|
131
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
132
|
-
const pkgName = packageJson.name;
|
|
133
|
-
const pkgVersion = packageJson.version;
|
|
130
|
+
// The npm package name (hard-coded — stable across versions)
|
|
131
|
+
const pkgName = "browser4-cli";
|
|
134
132
|
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
// 1. Read the CLI version from cli/VERSION-CLI (the single source of truth)
|
|
134
|
+
const versionCliPath = join(cliDir, "VERSION-CLI");
|
|
135
|
+
let versionRaw;
|
|
136
|
+
try {
|
|
137
|
+
versionRaw = readFileSync(versionCliPath, "utf-8").trim();
|
|
138
|
+
} catch {
|
|
139
|
+
console.error(`ERROR: Cannot read ${versionCliPath}`);
|
|
137
140
|
process.exit(1);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
|
|
141
|
-
|
|
143
|
+
if (!versionRaw) {
|
|
144
|
+
console.error("ERROR: cli/VERSION-CLI is empty.");
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const version = stripSnapshot(versionRaw);
|
|
149
|
+
if (checkOnly) console.log(`cli/VERSION-CLI: ${version}`);
|
|
142
150
|
|
|
143
151
|
// 2. Compare against the latest published version on npm
|
|
144
152
|
const publishedVersion = getLatestPublishedVersion(pkgName);
|
|
@@ -154,7 +162,34 @@ if (publishedVersion) {
|
|
|
154
162
|
console.log(`Latest published: (not found — package may not be published yet)`);
|
|
155
163
|
}
|
|
156
164
|
|
|
157
|
-
//
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// 3. Sync cli/package.json
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
const packageJsonPath = join(cliDir, "package.json");
|
|
169
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
170
|
+
|
|
171
|
+
if (!packageJson.version) {
|
|
172
|
+
console.error("ERROR: cli/package.json does not contain a version field.");
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (packageJson.version !== version) {
|
|
177
|
+
if (checkOnly) {
|
|
178
|
+
console.error(`MISMATCH: ${packageJsonPath} version is "${packageJson.version}", expected "${version}"`);
|
|
179
|
+
process.exitCode = 1;
|
|
180
|
+
} else {
|
|
181
|
+
const oldVersion = packageJson.version;
|
|
182
|
+
packageJson.version = version;
|
|
183
|
+
writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n");
|
|
184
|
+
console.log(` Updated ${packageJsonPath}: ${oldVersion} -> ${version}`);
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
if (!checkOnly) console.log(` ${packageJsonPath} already up to date`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// 4. Sync cli/browser4-cli/Cargo.toml
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
158
193
|
const cargoTomlPath = join(cargoDir, "Cargo.toml");
|
|
159
194
|
let cargoToml = readFileSync(cargoTomlPath, "utf-8");
|
|
160
195
|
const cargoVersionRegex = /^version\s*=\s*"[^"]*"/m;
|
|
@@ -179,7 +214,9 @@ if (cargoVersion !== version) {
|
|
|
179
214
|
if (!checkOnly) console.log(` ${cargoTomlPath} already up to date`);
|
|
180
215
|
}
|
|
181
216
|
|
|
182
|
-
//
|
|
217
|
+
// ---------------------------------------------------------------------------
|
|
218
|
+
// 5. Update Cargo.lock (only in sync mode)
|
|
219
|
+
// ---------------------------------------------------------------------------
|
|
183
220
|
if (!checkOnly && cargoVersion !== version) {
|
|
184
221
|
let lockUpdated = false;
|
|
185
222
|
try {
|
|
@@ -228,12 +265,12 @@ if (!checkOnly && cargoVersion !== version) {
|
|
|
228
265
|
}
|
|
229
266
|
}
|
|
230
267
|
|
|
231
|
-
//
|
|
268
|
+
// 6. Report
|
|
232
269
|
if (checkOnly) {
|
|
233
270
|
if (process.exitCode === 1) {
|
|
234
271
|
console.error("\nVersion mismatch detected! Run 'node cli/scripts/sync-version.js' to fix.");
|
|
235
272
|
} else {
|
|
236
|
-
console.log(`\nAll versions in sync: ${version}`);
|
|
273
|
+
console.log(`\nAll versions in sync with cli/VERSION-CLI: ${version}`);
|
|
237
274
|
}
|
|
238
275
|
} else {
|
|
239
276
|
console.log(`\nVersion sync complete: ${pkgName}@${version}`);
|