完成网络音乐、工具页面与安装器体验升级
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
param(
|
||||
[string]$Destination,
|
||||
[string]$NodeVersion = '22.18.0',
|
||||
[switch]$Force
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
function Get-Sha256Hex([string]$Path) {
|
||||
$stream = [IO.File]::OpenRead($Path)
|
||||
$algorithm = [Security.Cryptography.SHA256]::Create()
|
||||
try {
|
||||
return ([BitConverter]::ToString($algorithm.ComputeHash($stream))).Replace('-', '')
|
||||
} finally {
|
||||
$algorithm.Dispose()
|
||||
$stream.Dispose()
|
||||
}
|
||||
}
|
||||
|
||||
$RepoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$SourceRoot = Join-Path $RepoRoot 'third_party\MoeKoeMusic'
|
||||
$ApiSource = Join-Path $SourceRoot 'api'
|
||||
if ([string]::IsNullOrWhiteSpace($Destination)) {
|
||||
$Destination = Join-Path $RepoRoot 'build\music-api'
|
||||
}
|
||||
$Destination = [IO.Path]::GetFullPath($Destination)
|
||||
$BuildRoot = [IO.Path]::GetFullPath((Join-Path $RepoRoot 'build'))
|
||||
if (-not $Destination.StartsWith($BuildRoot + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) {
|
||||
throw "Music API destination must be inside $BuildRoot"
|
||||
}
|
||||
|
||||
$requiredSource = @(
|
||||
(Join-Path $SourceRoot 'UPSTREAM_COMMIT'),
|
||||
(Join-Path $SourceRoot 'API_SUBMODULE_COMMIT'),
|
||||
(Join-Path $SourceRoot 'MOEKOE_LICENSE'),
|
||||
(Join-Path $SourceRoot 'MOEKOE_README.md'),
|
||||
(Join-Path $ApiSource 'package.json'),
|
||||
(Join-Path $ApiSource 'pnpm-lock.yaml'),
|
||||
(Join-Path $ApiSource 'LICENSE'),
|
||||
(Join-Path $ApiSource 'README.md'),
|
||||
(Join-Path $ApiSource 'ymhut-sidecar.js')
|
||||
)
|
||||
foreach ($path in $requiredSource) {
|
||||
if (-not (Test-Path -LiteralPath $path -PathType Leaf)) { throw "Required music API source is missing: $path" }
|
||||
}
|
||||
|
||||
$fingerprintLines = Get-ChildItem -LiteralPath $SourceRoot -Recurse -File |
|
||||
Where-Object { $_.FullName -notlike '*\node_modules\*' } |
|
||||
Sort-Object FullName |
|
||||
ForEach-Object {
|
||||
$relative = $_.FullName.Substring($SourceRoot.TrimEnd('\').Length + 1).Replace('\', '/')
|
||||
"$relative|$(Get-Sha256Hex $_.FullName)"
|
||||
}
|
||||
$fingerprintBytes = [Text.Encoding]::UTF8.GetBytes(($fingerprintLines -join "`n"))
|
||||
$sha256 = [Security.Cryptography.SHA256]::Create()
|
||||
try {
|
||||
$fingerprint = ([BitConverter]::ToString($sha256.ComputeHash($fingerprintBytes))).Replace('-', '')
|
||||
} finally {
|
||||
$sha256.Dispose()
|
||||
}
|
||||
$markerPath = Join-Path $Destination 'payload.json'
|
||||
if (-not $Force -and (Test-Path -LiteralPath $markerPath)) {
|
||||
try {
|
||||
$marker = Get-Content -LiteralPath $markerPath -Raw | ConvertFrom-Json
|
||||
if ($marker.nodeVersion -eq $NodeVersion -and $marker.sourceFingerprint -eq $fingerprint -and
|
||||
(Test-Path -LiteralPath (Join-Path $Destination 'node.exe')) -and
|
||||
(Test-Path -LiteralPath (Join-Path $Destination 'api\node_modules\express\package.json') -PathType Leaf) -and
|
||||
(Test-Path -LiteralPath (Join-Path $Destination 'api\pnpm-lock.yaml')) -and
|
||||
(Test-Path -LiteralPath (Join-Path $Destination 'api\LICENSE'))) {
|
||||
return
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
}
|
||||
|
||||
$CacheRoot = Join-Path $RepoRoot '.cache\node-runtime'
|
||||
New-Item -ItemType Directory -Force -Path $CacheRoot | Out-Null
|
||||
$archiveName = "node-v$NodeVersion-win-x64.zip"
|
||||
$archivePath = Join-Path $CacheRoot $archiveName
|
||||
$checksumsPath = Join-Path $CacheRoot "SHASUMS256-$NodeVersion.txt"
|
||||
$distRoot = "https://nodejs.org/dist/v$NodeVersion"
|
||||
if (-not (Test-Path -LiteralPath $archivePath)) {
|
||||
Invoke-WebRequest -UseBasicParsing "$distRoot/$archiveName" -OutFile $archivePath
|
||||
}
|
||||
if (-not (Test-Path -LiteralPath $checksumsPath)) {
|
||||
Invoke-WebRequest -UseBasicParsing "$distRoot/SHASUMS256.txt" -OutFile $checksumsPath
|
||||
}
|
||||
$checksumLine = Get-Content -LiteralPath $checksumsPath | Where-Object { $_ -match "\s$([regex]::Escape($archiveName))$" } | Select-Object -First 1
|
||||
if (-not $checksumLine) { throw "Node checksum was not found for $archiveName" }
|
||||
$expectedHash = ($checksumLine -split '\s+')[0].ToUpperInvariant()
|
||||
$actualHash = (Get-Sha256Hex $archivePath).ToUpperInvariant()
|
||||
if ($actualHash -ne $expectedHash) { throw "Node runtime checksum mismatch for $archiveName" }
|
||||
|
||||
$staging = Join-Path $BuildRoot ("music-api.staging." + $PID)
|
||||
if (Test-Path -LiteralPath $staging) { Remove-Item -LiteralPath $staging -Recurse -Force }
|
||||
New-Item -ItemType Directory -Force -Path $staging | Out-Null
|
||||
$extractRoot = Join-Path $staging '_node'
|
||||
Expand-Archive -LiteralPath $archivePath -DestinationPath $extractRoot -Force
|
||||
$nodeRoot = Join-Path $extractRoot "node-v$NodeVersion-win-x64"
|
||||
Copy-Item -LiteralPath (Join-Path $nodeRoot 'node.exe') -Destination (Join-Path $staging 'node.exe')
|
||||
Copy-Item -LiteralPath (Join-Path $nodeRoot 'LICENSE') -Destination (Join-Path $staging 'NODE_LICENSE')
|
||||
Copy-Item -LiteralPath (Join-Path $nodeRoot 'README.md') -Destination (Join-Path $staging 'NODE_README.md')
|
||||
Remove-Item -LiteralPath $extractRoot -Recurse -Force
|
||||
|
||||
$apiDestination = Join-Path $staging 'api'
|
||||
robocopy $ApiSource $apiDestination /E /XD node_modules .git /NFL /NDL /NJH /NJS /NP | Out-Null
|
||||
if ($LASTEXITCODE -ge 8) { throw "Failed to copy music API source (robocopy exit $LASTEXITCODE)." }
|
||||
Copy-Item -LiteralPath (Join-Path $SourceRoot 'MOEKOE_LICENSE') -Destination (Join-Path $staging 'MOEKOE_LICENSE')
|
||||
Copy-Item -LiteralPath (Join-Path $SourceRoot 'MOEKOE_README.md') -Destination (Join-Path $staging 'MOEKOE_README.md')
|
||||
Copy-Item -LiteralPath (Join-Path $SourceRoot 'UPSTREAM_COMMIT') -Destination (Join-Path $staging 'UPSTREAM_COMMIT')
|
||||
Copy-Item -LiteralPath (Join-Path $SourceRoot 'API_SUBMODULE_COMMIT') -Destination (Join-Path $staging 'API_SUBMODULE_COMMIT')
|
||||
Copy-Item -LiteralPath (Join-Path $SourceRoot 'YMhut_PATCHES.md') -Destination (Join-Path $staging 'YMhut_PATCHES.md')
|
||||
|
||||
Push-Location $apiDestination
|
||||
try {
|
||||
& corepack pnpm install --prod --frozen-lockfile --ignore-scripts --package-import-method=copy --config.node-linker=hoisted --store-dir (Join-Path $RepoRoot '.cache\pnpm-store-music')
|
||||
if ($LASTEXITCODE -ne 0) { throw "pnpm failed to install the locked music API dependencies." }
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
[ordered]@{
|
||||
protocolVersion = 1
|
||||
moekoeCommit = '4581660209c9cdd07669e8bd5bcbe136b7d91e02'
|
||||
apiCommit = '06560e3e053bda1ab830750db6f645bab703f824'
|
||||
nodeVersion = $NodeVersion
|
||||
sourceFingerprint = $fingerprint
|
||||
} | ConvertTo-Json | Set-Content -LiteralPath (Join-Path $staging 'payload.json') -Encoding utf8
|
||||
|
||||
if (Test-Path -LiteralPath $Destination) { Remove-Item -LiteralPath $Destination -Recurse -Force }
|
||||
Move-Item -LiteralPath $staging -Destination $Destination
|
||||
Reference in New Issue
Block a user