mad-bot's picture
Publish verified DinoVision case-study artifacts (part 2)
da5fb15 verified
Raw
History Blame Contribute Delete
3.63 kB
param(
[Parameter(Mandatory = $true)]
[string]$OutputDir
)
$ErrorActionPreference = "Stop"
function Relative-Path([string]$Base, [string]$Path) {
$basePath = [System.IO.Path]::GetFullPath($Base).TrimEnd([char[]]@('\', '/'))
$fullPath = [System.IO.Path]::GetFullPath($Path)
$prefix = $basePath + [System.IO.Path]::DirectorySeparatorChar
if (-not $fullPath.StartsWith($prefix, [System.StringComparison]::OrdinalIgnoreCase)) {
throw "$fullPath is not inside $basePath"
}
$fullPath.Substring($prefix.Length)
}
$adbCandidates = @()
if ($env:LOCALAPPDATA) {
$adbCandidates += Join-Path $env:LOCALAPPDATA "Android\Sdk\platform-tools\adb.exe"
}
if ($env:ANDROID_HOME) {
$adbCandidates += Join-Path $env:ANDROID_HOME "platform-tools\adb.exe"
}
$adbCandidates = @($adbCandidates | Where-Object { Test-Path -LiteralPath $_ })
if ($adbCandidates.Count -eq 0) {
throw "adb.exe was not found under LOCALAPPDATA or ANDROID_HOME"
}
$adb = $adbCandidates[0]
$devices = @(& $adb devices | Select-Object -Skip 1 | Where-Object { $_ -match "\tdevice$" })
if ($devices.Count -ne 1) {
throw "Expected exactly one authorized device; found $($devices.Count). Check 'adb devices'."
}
$destination = [System.IO.Path]::GetFullPath($OutputDir)
if (Test-Path -LiteralPath $destination) {
if (@(Get-ChildItem -LiteralPath $destination -Force).Count -ne 0) {
throw "Refusing to merge a recovery pull into non-empty directory: $destination"
}
} else {
New-Item -ItemType Directory -Path $destination | Out-Null
}
$runtimeDir = Join-Path $destination "runtime"
$captureDir = Join-Path $destination "captures"
New-Item -ItemType Directory -Path $runtimeDir | Out-Null
New-Item -ItemType Directory -Path $captureDir | Out-Null
$runtimeRemote = "/data/local/tmp/dinovision"
$capturesRemote = "/sdcard/Android/data/rust.dinovision_xr/files/captures"
# adb pull is read-only on the headset. Pull the whole runtime directory first
# so unknown historical files are preserved rather than guessed at by name.
$runtimePresent = $false
& $adb shell "test -d $runtimeRemote"
if ($LASTEXITCODE -eq 0) {
$runtimePresent = $true
& $adb pull "$runtimeRemote/." $runtimeDir
if ($LASTEXITCODE -ne 0) {
throw "Failed to pull $runtimeRemote"
}
}
$capturesPresent = $false
& $adb shell "test -d $capturesRemote"
if ($LASTEXITCODE -eq 0) {
$capturesPresent = $true
& $adb pull "$capturesRemote/." $captureDir
if ($LASTEXITCODE -ne 0) {
throw "Failed to pull $capturesRemote"
}
}
$metadata = [ordered]@{
schema_version = 1
pulled_utc = [DateTime]::UtcNow.ToString("o")
device = (& $adb get-serialno).Trim()
product = (& $adb shell getprop ro.product.name).Trim()
model = (& $adb shell getprop ro.product.model).Trim()
build_fingerprint = (& $adb shell getprop ro.build.fingerprint).Trim()
runtime_directory_present = $runtimePresent
capture_directory_present = $capturesPresent
files = @(
Get-ChildItem -LiteralPath $destination -File -Recurse | ForEach-Object {
[ordered]@{
path = (Relative-Path $destination $_.FullName).Replace("\", "/")
bytes = $_.Length
sha256 = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
}
}
)
}
$manifestPath = Join-Path $destination "recovery_manifest.json"
$metadata | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $manifestPath -Encoding utf8
Write-Host "Recovered $($metadata.files.Count) files to $destination"
Write-Host "Manifest: $manifestPath"