Files
ebook-skill/tools/build.ps1
T
cheney 221b1f8add feat: 引入 so-novel submodule 并提供非交互下载工具
- vendor/so-novel: 上游 v1.12.0 (规则驱动的书源抓取/下载引擎)
- tools/src: ToolMain 封装 search/download/toc/sources,stdout 只输出 JSON
- tools/build.ps1: 自动定位/下载 JDK21,按平台显式激活 javet 原生库 profile
- bin/novel.ps1|.cmd: 命令行入口(人读输出或 -Json)
- SKILL.md/README.md: 使用说明与下载原理分析
2026-11-04 15:12:10 +08:00

115 lines
5.5 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Builds the so-novel engine jar (from the submodule) and the tool wrapper classes.
# Run once after clone / submodule update: pwsh tools\build.ps1
param(
[switch]$Force, # rebuild so-novel even if runtime\app.jar exists
[switch]$RefreshRules # re-copy bundle\rules over runtime\rules
)
$ErrorActionPreference = 'Stop'
. (Join-Path $PSScriptRoot 'lib.ps1')
$p = Get-ToolPaths
Write-Host "[build] project root : $($p.Root)"
# ---------------------------------------------------------------- 1. JDK 21
$jdk = Find-Jdk21 -AllowDownload
if (-not $jdk) { throw 'No JDK 21 available and download failed. Set EBOOK_NOVEL_JAVA_HOME.' }
Write-Host "[build] JDK 21 : $jdk"
$javac = Join-Path $jdk 'bin\javac.exe'
if (-not (Test-Path $javac)) { throw "javac not found in $jdk (a JRE is not enough)" }
# ---------------------------------------------------------------- 2. so-novel app.jar
New-Item -ItemType Directory -Force $p.Runtime | Out-Null
if ($Force -or -not (Test-Path $p.AppJar)) {
if (-not (Test-Path (Join-Path $p.Vendor 'pom.xml'))) {
throw 'vendor/so-novel is empty. Run: git submodule update --init --recursive'
}
$mvn = Get-Command mvn -ErrorAction SilentlyContinue
if (-not $mvn) { throw 'Maven (mvn) is required to build so-novel. Install Maven or use a prebuilt app.jar.' }
Write-Host '[build] mvn package so-novel ...' -ForegroundColor Cyan
# so-novel 用 <os><arch>x86_64</arch> 激活 javet 原生库 profile,而 Windows JDK 报的是 amd64,
# 自动激活会失效(导致 JS 规则的书源全部 "Javet library ... not found"),这里显式指定。
$platformProfile = switch -Regex ("$([System.Runtime.InteropServices.RuntimeInformation]::OSDescription)|$([System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture)") {
'Windows.*X64' { 'windows-x64' }
'Linux.*X64' { 'linux-x64' }
'Linux.*Arm64' { 'linux-arm64' }
'OSX|Darwin.*X64' { 'macos-x64' }
'OSX|Darwin.*Arm64' { 'macos-arm64' }
default { $null }
}
if ($platformProfile) {
Write-Host "[build] javet profile: $platformProfile" -ForegroundColor Cyan
} else {
Write-Warning 'Unknown platform, javet native library may be missing (JS-based rules will fail).'
}
$previousJavaHome = $env:JAVA_HOME
$previousPath = $env:PATH
try {
$env:JAVA_HOME = $jdk
$env:PATH = (Join-Path $jdk 'bin') + ';' + $previousPath
Push-Location $p.Vendor
try {
$mvnArgs = @('-B', '-DskipTests', '-Dlaunch4j.skip=true')
if ($platformProfile) { $mvnArgs += @('-P', $platformProfile) }
$mvnArgs += @('clean', 'package')
& $mvn.Source @mvnArgs
if ($LASTEXITCODE -ne 0) { throw "mvn package failed with exit code $LASTEXITCODE" }
} finally {
Pop-Location
}
} finally {
$env:JAVA_HOME = $previousJavaHome
$env:PATH = $previousPath
}
$built = Join-Path $p.Vendor 'target\app-jar-with-dependencies.jar'
if (-not (Test-Path $built)) { $built = Join-Path $p.Vendor 'target\app.jar' }
if (-not (Test-Path $built)) { throw 'so-novel build produced no jar in target/' }
Copy-Item $built $p.AppJar -Force
Write-Host "[build] app.jar : $($p.AppJar) ($([math]::Round((Get-Item $p.AppJar).Length / 1MB, 1)) MB)"
} else {
Write-Host "[build] app.jar : up to date ($([math]::Round((Get-Item $p.AppJar).Length / 1MB, 1)) MB)"
}
# ---------------------------------------------------------------- 3. rule bundles
New-Item -ItemType Directory -Force $p.Rules | Out-Null
$sourceRules = Join-Path $p.Vendor 'bundle\rules'
foreach ($file in (Get-ChildItem $sourceRules -Filter '*.json*' -File)) {
$target = Join-Path $p.Rules $file.Name
if ($RefreshRules -or -not (Test-Path $target)) {
Copy-Item $file.FullName $target -Force
}
}
Write-Host "[build] rules : $((Get-ChildItem $p.Rules -File).Count) files in $($p.Rules)"
# ---------------------------------------------------------------- 4. tool classes
if (Test-Path $p.Classes) { Remove-Item $p.Classes -Recurse -Force }
New-Item -ItemType Directory -Force $p.Classes | Out-Null
$sources = @(Get-ChildItem (Join-Path $p.Tools 'src') -Filter '*.java' -Recurse | ForEach-Object { $_.FullName })
Write-Host '[build] javac : tool wrapper ...' -ForegroundColor Cyan
& $javac '-encoding' 'UTF-8' '--release' '21' '-cp' $p.AppJar '-d' $p.Classes @sources
if ($LASTEXITCODE -ne 0) { throw "javac failed with exit code $LASTEXITCODE" }
# Optional single-file tool jar (a plain classes dir works too; JBR has no jar.exe).
$jarTool = Find-JarTool
if ($jarTool) {
& $jarTool '--create' '--file' $p.ToolJar '-C' $p.Classes '.'
if ($LASTEXITCODE -ne 0) { Write-Warning 'jar packaging failed; the classes directory will be used instead.' }
}
# ---------------------------------------------------------------- 5. runtime config
New-Item -ItemType Directory -Force $p.Books | Out-Null
if ($Force -or -not (Test-Path $p.Config)) {
$template = Get-Content (Join-Path $p.Tools 'config.ini.template') -Raw
$ini = $template.Replace('@BOOKS@', ($p.Books -replace '\\', '/'))
$ini = $ini.Replace('@RULES@', ((Join-Path $p.Rules 'main.json') -replace '\\', '/'))
[System.IO.File]::WriteAllText($p.Config, $ini, (New-Object System.Text.UTF8Encoding($false)))
Write-Host "[build] config.ini : $($p.Config)"
} else {
Write-Host "[build] config.ini : kept existing ($($p.Config))"
}
Write-Host ''
Write-Host 'Build finished. Try: pwsh bin\novel.ps1 sources' -ForegroundColor Green