# collect-debs.ps1 — сбор offline-пакетов через устройство (Windows-хост, без WSL). # # Шаг 1 (подключите ГОЛОЕ target-устройство): # powershell -ExecutionPolicy Bypass -File collect-debs.ps1 -Step target # -> снимет список уже установленных пакетов в target-installed.txt # # Шаг 2 (подключите РЕФЕРЕНС-устройство с интернетом): # powershell -ExecutionPolicy Bypass -File collect-debs.ps1 -Step fetch # -> скачает недостающие .deb на референсе и заберёт их в .\debs # # Подключайте устройства по одному. -Adb можно указать путь к adb.exe. param( [Parameter(Mandatory = $true)][ValidateSet('target', 'fetch')][string]$Step, [string]$Adb ) # native-команды adb пишут в stderr (adb root, прогресс push); Stop делает это фатальным $ErrorActionPreference = 'Continue' $Here = Split-Path -Parent $MyInvocation.MyCommand.Path # adb по умолчанию берём из .\bin\adb.exe рядом со скриптом, иначе из PATH if (-not $Adb) { $cand = Join-Path $Here 'bin\adb.exe' $Adb = if (Test-Path $cand) { $cand } else { 'adb' } } function Log($m) { Write-Host "[collect] $m" -ForegroundColor Green } function Warn($m) { Write-Host "[warn] $m" -ForegroundColor Yellow } function Die($m) { Write-Host "[error] $m" -ForegroundColor Red; exit 1 } function Write-Lf($path, [string[]]$lines) { $text = ($lines -join "`n") + "`n" [System.IO.File]::WriteAllText($path, $text, (New-Object System.Text.UTF8Encoding($false))) } function AdbOut($arglist) { (& $Adb @arglist | Out-String) } if (-not (Get-Command $Adb -ErrorAction SilentlyContinue)) { Die "не найден '$Adb'. Добавьте platform-tools в PATH или укажите -Adb C:\path\adb.exe" } function Assert-OneDevice { & $Adb start-server 2>$null | Out-Null $n = @(& $Adb devices | Select-Object -Skip 1 | Where-Object { $_ -match '\sdevice$' }).Count if ($n -ne 1) { Die "ожидаю ровно одно adb-устройство в состоянии 'device' (сейчас: $n)" } } # --------------------------------------------------------------------------- if ($Step -eq 'target') { Assert-OneDevice Log "снимаю список установленных пакетов с голого устройства..." $raw = AdbOut @('shell', 'dpkg-query -W | cut -f1') $pkgs = $raw -replace "`r", '' -split "`n" | Where-Object { $_ -ne '' } | Sort-Object -Unique if ($pkgs.Count -eq 0) { Die "не получил список пакетов (это точно Debian-rootfs?)" } $out = Join-Path $Here 'target-installed.txt' Write-Lf $out $pkgs Log "сохранено $($pkgs.Count) пакетов -> $out" Log "теперь подключите референс-устройство и запустите: -Step fetch" exit 0 } # --------------------------------------------------------------------------- # Step 'fetch' Assert-OneDevice $pkgsList = Join-Path $Here 'packages.list' $helper = Join-Path $Here 'collect-on-device.sh' $tgt = Join-Path $Here 'target-installed.txt' foreach ($f in @($pkgsList, $helper)) { if (-not (Test-Path $f)) { Die "нет файла: $f" } } & $Adb root 2>$null | Out-Null & $Adb wait-for-device $uid = (AdbOut @('shell', 'id -u')).Trim() $sudo = if ($uid -eq '0') { '' } else { Warn "adb не root — иду через sudo"; 'sudo' } Log "заливаю списки и хелпер на референс-устройство..." & $Adb shell 'rm -rf /tmp/btcollect && mkdir -p /tmp/btcollect' | Out-Null & $Adb push $pkgsList /tmp/btcollect/packages.list | Out-Null & $Adb push $helper /tmp/btcollect/collect-on-device.sh | Out-Null if (Test-Path $tgt) { & $Adb push $tgt /tmp/btcollect/target-installed.txt | Out-Null } else { Warn "нет target-installed.txt — сначала лучше прогнать -Step target на голом устройстве" } # на случай CRLF после Windows & $Adb shell "sed -i 's/\r$//' /tmp/btcollect/* 2>/dev/null; true" | Out-Null Log "качаю зависимости на референсе (нужен интернет на нём)..." $cmd = ("$sudo bash /tmp/btcollect/collect-on-device.sh").Trim() $output = & $Adb shell $cmd 2>&1 | Out-String Write-Host $output if ($output -notmatch 'COLLECT-OK') { Die "сбор пакетов не дошёл до COLLECT-OK" } Log "забираю .deb на хост..." $debs = Join-Path $Here 'debs' if (Test-Path $debs) { Remove-Item -Recurse -Force $debs } & $Adb pull /tmp/btdebs $Here | Out-Null Rename-Item (Join-Path $Here 'btdebs') $debs $n = (Get-ChildItem $debs -Filter *.deb).Count Log "готово: $n .deb в $debs"