bucket-update-scripts für neues repo
This commit is contained in:
1 parent
079e69963d
commit
795a056564
3 files changed
+224
-2
No files matched your search
@@ -1,7 +1,5 @@
|
|||||||
*.bak
|
*.bak
|
||||||
*.exe
|
*.exe
|
||||||
scripts/*
|
|
||||||
!scripts/update-manifests.py
|
|
||||||
.vscode/*
|
.vscode/*
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
*.py[cod]
|
||||||
File renamed without changes.
@@ -0,0 +1,224 @@
|
|||||||
|
#requires -Version 5.1
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Stellt bestehende Scoop-Installationen von elexis/streichtech auf medelexis um.
|
||||||
|
.DESCRIPTION
|
||||||
|
Ohne -Apply nur ein Probelauf. Keine Sicherungen, Neuinstallationen oder Git-Pushes.
|
||||||
|
Bearbeitet alle Versionsverzeichnisse der benutzerspezifischen Scoop-Installation.
|
||||||
|
Ein passender bestehender Bucket wird umbenannt. Danach werden elexis und streichtech entfernt.
|
||||||
|
Andere Buckets wie main und extras bleiben bestehen.
|
||||||
|
Alte Paketnamen mit Unterstrich werden auf passende Manifestnamen mit Bindestrich umgestellt.
|
||||||
|
.EXAMPLE
|
||||||
|
.\scripts\update-bucket.ps1
|
||||||
|
.EXAMPLE
|
||||||
|
.\scripts\update-bucket.ps1 -Apply
|
||||||
|
#>
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[switch] $Apply,
|
||||||
|
[string] $ScoopRoot = $(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE 'scoop' })
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$repository = 'https://gitea.medelexis.ch/public/scoop'
|
||||||
|
$targetName = 'medelexis'
|
||||||
|
$target = Join-Path $ScoopRoot "buckets\$targetName"
|
||||||
|
$apps = Join-Path $ScoopRoot 'apps'
|
||||||
|
if (-not (Test-Path -LiteralPath $apps -PathType Container)) {
|
||||||
|
throw "Kein Scoop-Apps-Verzeichnis gefunden: $apps"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-MedelexisRepository([string] $Path) {
|
||||||
|
if (-not (Test-Path -LiteralPath $Path -PathType Container)) { return $false }
|
||||||
|
$remote = & git -C $Path remote get-url origin 2>$null
|
||||||
|
if ($LASTEXITCODE -ne 0) { return $false }
|
||||||
|
try { $uri = [Uri] ([string] $remote).Trim() } catch { return $false }
|
||||||
|
return ($uri.Scheme -eq 'https' -and $uri.Host -eq 'gitea.medelexis.ch' -and
|
||||||
|
$uri.AbsolutePath.TrimEnd('/').Replace('.git', '') -eq '/public/scoop')
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-PackageRenames([string] $BucketPath) {
|
||||||
|
if (-not $BucketPath -or -not (Test-Path -LiteralPath $BucketPath)) { return }
|
||||||
|
foreach ($app in Get-ChildItem -LiteralPath $apps -Directory) {
|
||||||
|
if (-not $app.Name.Contains('_')) { continue }
|
||||||
|
$newName = $app.Name.Replace('_', '-')
|
||||||
|
$newManifest = Join-Path $BucketPath "bucket\$newName.json"
|
||||||
|
if (-not (Test-Path -LiteralPath $newManifest)) {
|
||||||
|
$newManifest = Join-Path $BucketPath "$newName.json"
|
||||||
|
}
|
||||||
|
if (-not (Test-Path -LiteralPath $newManifest)) { continue }
|
||||||
|
$current = Join-Path $app.FullName 'current'
|
||||||
|
$installFile = Join-Path $current 'install.json'
|
||||||
|
if (-not (Test-Path -LiteralPath $installFile)) { continue }
|
||||||
|
$install = [IO.File]::ReadAllText($installFile) | ConvertFrom-Json
|
||||||
|
if ($install.bucket -notin @('elexis', 'streichtech', 'medelexis')) { continue }
|
||||||
|
$destination = Join-Path $apps $newName
|
||||||
|
if (Test-Path -LiteralPath $destination) {
|
||||||
|
throw "'$($app.Name)' und '$newName' sind beide installiert. Keine automatische Zusammenführung."
|
||||||
|
}
|
||||||
|
$link = Get-Item -LiteralPath $current -Force
|
||||||
|
if ($link.LinkType -ne 'Junction') {
|
||||||
|
throw "Für '$($app.Name)' wird eine Scoop-current-Junction erwartet. Keine automatische Umbenennung."
|
||||||
|
}
|
||||||
|
$versionPath = [IO.Path]::GetFullPath([string] @($link.Target)[0])
|
||||||
|
if ((Split-Path $versionPath -Parent) -ne $app.FullName) {
|
||||||
|
throw "Die current-Verknüpfung von '$($app.Name)' zeigt ausserhalb des Paketordners."
|
||||||
|
}
|
||||||
|
$persistSource = Join-Path $ScoopRoot "persist\$($app.Name)"
|
||||||
|
$persistTarget = Join-Path $ScoopRoot "persist\$newName"
|
||||||
|
if ((Test-Path -LiteralPath $persistSource) -and (Test-Path -LiteralPath $persistTarget)) {
|
||||||
|
throw "Beide Persistenzordner für '$($app.Name)' und '$newName' existieren. Keine automatische Zusammenführung."
|
||||||
|
}
|
||||||
|
Write-Host "Paket umbenennen: $($app.Name) -> $newName"
|
||||||
|
[pscustomobject]@{
|
||||||
|
OldName = $app.Name; NewName = $newName; Source = $app.FullName
|
||||||
|
Destination = $destination; Version = (Split-Path $versionPath -Leaf)
|
||||||
|
PersistSource = $persistSource; PersistTarget = $persistTarget
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$renameSource = $null
|
||||||
|
if (Test-Path -LiteralPath $target) {
|
||||||
|
if (-not (Test-MedelexisRepository $target)) {
|
||||||
|
throw 'Der vorhandene Bucket medelexis zeigt auf ein anderes Repository. Keine Änderung.'
|
||||||
|
}
|
||||||
|
Write-Host 'Bucket medelexis ist bereits korrekt eingerichtet.'
|
||||||
|
} else {
|
||||||
|
foreach ($oldName in @('elexis', 'streichtech')) {
|
||||||
|
$candidate = Join-Path $ScoopRoot "buckets\$oldName"
|
||||||
|
if (Test-MedelexisRepository $candidate) {
|
||||||
|
$renameSource = $candidate
|
||||||
|
Write-Host "Bucket umbenennen: $oldName -> $targetName"
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (-not $renameSource) { Write-Host "Bucket hinzufügen: $targetName -> $repository" }
|
||||||
|
}
|
||||||
|
|
||||||
|
$changes = @(
|
||||||
|
foreach ($app in Get-ChildItem -LiteralPath $apps -Directory) {
|
||||||
|
foreach ($version in Get-ChildItem -LiteralPath $app.FullName -Directory) {
|
||||||
|
# current und andere Verknüpfungen nicht nochmals bearbeiten.
|
||||||
|
if ($version.Attributes -band [IO.FileAttributes]::ReparsePoint) { continue }
|
||||||
|
$file = Join-Path $version.FullName 'install.json'
|
||||||
|
if (-not (Test-Path -LiteralPath $file -PathType Leaf)) { continue }
|
||||||
|
$original = [IO.File]::ReadAllText($file)
|
||||||
|
$data = $original | ConvertFrom-Json
|
||||||
|
if ($data.bucket -notin @('elexis', 'streichtech')) { continue }
|
||||||
|
$pattern = '(?i)("bucket"\s*:\s*)"(?:elexis|streichtech)"'
|
||||||
|
$updated = [regex]::Replace($original, $pattern, '${1}"medelexis"')
|
||||||
|
if (($updated | ConvertFrom-Json).bucket -ne $targetName) {
|
||||||
|
throw "Bucket-Zuordnung konnte nicht angepasst werden: $file"
|
||||||
|
}
|
||||||
|
Write-Host "$($app.Name) / $($version.Name): $($data.bucket) -> $targetName"
|
||||||
|
[pscustomobject]@{ File = $file; Original = $original; Updated = $updated; App = $app.Name }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
$manifestRoot = $(if (Test-Path -LiteralPath $target) { $target } else { $renameSource })
|
||||||
|
$renames = @(Get-PackageRenames $manifestRoot)
|
||||||
|
|
||||||
|
if (-not $Apply) {
|
||||||
|
foreach ($oldName in @('elexis', 'streichtech')) {
|
||||||
|
if (Test-Path -LiteralPath (Join-Path $ScoopRoot "buckets\$oldName")) {
|
||||||
|
Write-Host "Alter Bucket wird nach der Umstellung entfernt oder umbenannt: $oldName"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Host "Probelauf: $($changes.Count) install.json-Dateien würden geändert."
|
||||||
|
Write-Host "Probelauf: $($renames.Count) Paketnamen würden umgestellt."
|
||||||
|
Write-Host 'Mit -Apply anwenden. Es werden keine Sicherungen erstellt.'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-Path -LiteralPath $target)) {
|
||||||
|
if ($renameSource) {
|
||||||
|
$bucketRoot = (Resolve-Path -LiteralPath (Join-Path $ScoopRoot 'buckets')).Path
|
||||||
|
$sourcePath = (Resolve-Path -LiteralPath $renameSource).Path
|
||||||
|
$targetPath = [IO.Path]::GetFullPath($target)
|
||||||
|
if ((Split-Path $sourcePath -Parent) -ne $bucketRoot -or
|
||||||
|
(Split-Path $targetPath -Parent) -ne $bucketRoot) {
|
||||||
|
throw 'Bucket-Pfade liegen ausserhalb des erwarteten Verzeichnisses. Keine Umbenennung.'
|
||||||
|
}
|
||||||
|
[IO.Directory]::Move($sourcePath, $targetPath)
|
||||||
|
} else {
|
||||||
|
# scoop verwendet dieselbe Root-Variable für benutzerdefinierte Installationen.
|
||||||
|
if ([IO.Path]::GetFullPath($ScoopRoot).TrimEnd('\') -ne
|
||||||
|
[IO.Path]::GetFullPath($(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE 'scoop' })).TrimEnd('\')) {
|
||||||
|
throw 'ScoopRoot weicht von der aktiven Scoop-Installation ab; Bucket bitte dort zuerst einrichten.'
|
||||||
|
}
|
||||||
|
& scoop bucket add $targetName $repository
|
||||||
|
if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $target)) {
|
||||||
|
throw 'Bucket konnte nicht hinzugefügt werden. Installationsmetadaten bleiben unverändert.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Falls der Ziel-Bucket erst hinzugefügt wurde, stehen seine Manifestnamen jetzt bereit.
|
||||||
|
if (-not $manifestRoot) { $renames = @(Get-PackageRenames $target) }
|
||||||
|
|
||||||
|
# Vor dem ersten Schreiben prüfen, ob während des Probelaufs Dateien geändert wurden.
|
||||||
|
foreach ($change in $changes) {
|
||||||
|
if ([IO.File]::ReadAllText($change.File) -cne $change.Original) {
|
||||||
|
throw 'Installationsmetadaten wurden zwischenzeitlich geändert. Skript bitte erneut starten.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($change in $changes) {
|
||||||
|
[IO.File]::WriteAllText($change.File, $change.Updated, [Text.UTF8Encoding]::new($false))
|
||||||
|
}
|
||||||
|
foreach ($rename in $renames) {
|
||||||
|
$activeRoot = $(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE 'scoop' })
|
||||||
|
if ([IO.Path]::GetFullPath($ScoopRoot).TrimEnd('\') -ne [IO.Path]::GetFullPath($activeRoot).TrimEnd('\')) {
|
||||||
|
throw 'Für Paketumbenennungen muss ScoopRoot der aktiven Scoop-Installation entsprechen.'
|
||||||
|
}
|
||||||
|
$appsRoot = (Resolve-Path -LiteralPath $apps).Path
|
||||||
|
if ((Split-Path $rename.Source -Parent) -ne $appsRoot -or
|
||||||
|
(Split-Path $rename.Destination -Parent) -ne $appsRoot) {
|
||||||
|
throw 'Paketpfade liegen ausserhalb des Apps-Verzeichnisses.'
|
||||||
|
}
|
||||||
|
if (Test-Path -LiteralPath $rename.PersistSource) {
|
||||||
|
$persistRoot = (Resolve-Path -LiteralPath (Join-Path $ScoopRoot 'persist')).Path
|
||||||
|
if ((Split-Path $rename.PersistSource -Parent) -ne $persistRoot -or
|
||||||
|
(Split-Path $rename.PersistTarget -Parent) -ne $persistRoot) {
|
||||||
|
throw 'Persistenzpfade liegen ausserhalb des Persist-Verzeichnisses.'
|
||||||
|
}
|
||||||
|
[IO.Directory]::Move($rename.PersistSource, $rename.PersistTarget)
|
||||||
|
}
|
||||||
|
$oldCurrent = Join-Path $rename.Source 'current'
|
||||||
|
& attrib -R /L $oldCurrent
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw 'current-Verknüpfung konnte nicht freigegeben werden.' }
|
||||||
|
# Nur die Junction entfernen, ohne rekursiv ihren Inhalt zu löschen.
|
||||||
|
[IO.Directory]::Delete($oldCurrent)
|
||||||
|
[IO.Directory]::Move($rename.Source, $rename.Destination)
|
||||||
|
$newCurrent = Join-Path $rename.Destination 'current'
|
||||||
|
$newVersion = Join-Path $rename.Destination $rename.Version
|
||||||
|
New-Item -ItemType Junction -Path $newCurrent -Target $newVersion | Out-Null
|
||||||
|
Write-Host "Startverknüpfungen für $($rename.NewName) erneuern ..."
|
||||||
|
& scoop reset "$($rename.NewName)@$($rename.Version)"
|
||||||
|
if ($LASTEXITCODE -ne 0) { throw "Scoop reset für '$($rename.NewName)' fehlgeschlagen." }
|
||||||
|
}
|
||||||
|
foreach ($oldName in @('elexis', 'streichtech')) {
|
||||||
|
$oldPath = Join-Path $ScoopRoot "buckets\$oldName"
|
||||||
|
if (-not (Test-Path -LiteralPath $oldPath)) { continue }
|
||||||
|
$activeRoot = $(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE 'scoop' })
|
||||||
|
if ([IO.Path]::GetFullPath($ScoopRoot).TrimEnd('\') -ne [IO.Path]::GetFullPath($activeRoot).TrimEnd('\')) {
|
||||||
|
throw 'Zum Entfernen alter Buckets muss ScoopRoot der aktiven Scoop-Installation entsprechen.'
|
||||||
|
}
|
||||||
|
Write-Host "Alten Bucket entfernen: $oldName"
|
||||||
|
& scoop bucket rm $oldName
|
||||||
|
if ($LASTEXITCODE -ne 0 -or (Test-Path -LiteralPath $oldPath)) {
|
||||||
|
throw "Alter Bucket '$oldName' konnte nicht entfernt werden. Die Umstellung kann erneut ausgeführt werden."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($name in @((Get-ChildItem -LiteralPath $apps -Directory).Name)) {
|
||||||
|
$installFile = Join-Path $apps "$name\current\install.json"
|
||||||
|
if (-not (Test-Path -LiteralPath $installFile)) { continue }
|
||||||
|
if (([IO.File]::ReadAllText($installFile) | ConvertFrom-Json).bucket -ne $targetName) { continue }
|
||||||
|
if (-not (Test-Path -LiteralPath (Join-Path $target "bucket\$name.json")) -and
|
||||||
|
-not (Test-Path -LiteralPath (Join-Path $target "$name.json"))) {
|
||||||
|
Write-Warning "Für '$name' fehlt weiterhin ein gleichnamiges Manifest."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Write-Host "Fertig: $($changes.Count) install.json-Dateien auf medelexis umgestellt."
|
||||||
|
Write-Host "Paketnamen umgestellt: $($renames.Count)."
|
||||||
|
Write-Host 'Von elexis/streichtech/medelexis bleibt nur medelexis bestehen. Prüfung: scoop status --local'
|
||||||
Reference in new issue
Block a user