Skip to content

Instantly share code, notes, and snippets.

@ClassicDarkChocolate
Last active September 10, 2023 20:51
Show Gist options
  • Save ClassicDarkChocolate/4f10ad43e5de4fb103fa2ac5a1727005 to your computer and use it in GitHub Desktop.
Save ClassicDarkChocolate/4f10ad43e5de4fb103fa2ac5a1727005 to your computer and use it in GitHub Desktop.
Commands: Get-ScoopPackageVersions, Invoke-ScoopPackageCommand, Install-ScoopPackage
function Get-ScoopRoot {
$scoopdir = & {
$env:SCOOP, (scoop config 'rootPath'), "$env:USERPROFILE\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1
} 6>$null
$scoopdir
}
function Get-ScoopPackageVersions {
param (
[Parameter(Position = 1, Mandatory = $true)]
$Name,
[switch]
$IncludeDescription
)
$info = $(scoop info $Name) 6>$null
if (-not $?) {
Write-Error "Could not find manifest for '$Name'." -ErrorAction Stop
}
$scoopdir = Get-ScoopRoot
$bucket = $info.Bucket
Push-Location -Path "$scoopdir\buckets\$bucket\bucket"
$rawLogs = $(git grep '\"version\": \?\"' $(git rev-list --all -- "$Name.json") -- "$Name.json")
$logs = $rawLogs | ForEach-Object {
($_ -match '^(?<hash>[\w\d]+):.+?\"version\": ?\"(?<version>.+?)\"') | Out-Null
$obj = [PSCustomObject]@{
CommitHash = $Matches.hash
Version = $Matches.version
Description = ""
}
if ($IncludeDescription.IsPresent) {
$obj.Description = $(git log --format=%B -n 1 $Matches.hash)[0]
}
$obj
}
Pop-Location
$logs
}
function Invoke-ScoopPackageCommand {
param (
[ValidateSet(
"cat",
"depends",
"home",
"info",
"install",
"virustotal"
)]
[Parameter(Position = 1, Mandatory = $true)]
$Command,
[Parameter(Position = 2, Mandatory = $true)]
$PackageName,
$CommandArgs,
$CommitHash,
$Version
)
$info = $(scoop info $PackageName) 6>$null
if (-not $?) {
Write-Error "Could not find manifest for '$PackageName'." -ErrorAction Stop
}
$scoopdir = Get-ScoopRoot
$bucket = $info.Bucket
Push-Location -Path "$scoopdir\buckets\$bucket\bucket"
if ($null -ne $CommitHash) {
git restore --source=$CommitHash "$PackageName.json"
if ($?) {
scoop $Command $CommandArgs $PackageName
}
}
elseif ($null -ne $Version) {
$commits = Get-ScoopPackageVersions -Name $PackageName
$filteredCommits = $commits | Where-Object Version -EQ $Version
if ($null -ne $filteredCommits) {
git restore --source=$($filteredCommits[0].CommitHash) "$PackageName.json"
if ($?) {
scoop $Command $CommandArgs $PackageName
}
}
else {
Write-Error "Could not find manifest for $PackageName@$Version"
}
}
else {
scoop $Command $CommandArgs $PackageName
}
git restore "$PackageName.json"
Pop-Location
}
function Install-ScoopPackage {
param (
[Parameter(Position = 1, Mandatory = $true)]
$Name,
$CommandArgs,
$CommitHash,
$Version
)
Invoke-ScoopPackageCommand -Command install -CommandArgs $CommandArgs -PackageName $Name -Version $Version -CommitHash $CommitHash
}
@jkniiv
Copy link

jkniiv commented May 26, 2022

Bravo! These powershell functions are a great addition for somebody who knows his way around git repos which Scoop buckets indeed are. At the moment you could argue that Scoop has a naive (or a bit too straightforward) way of using git for app manifest versioning. One could easily imagine a system where past versions of app manifests would be always available alongside the current one and not just checkpointed by git in a HEAD version. However, as long as Scoop's manifest framework remains they way it is now, the approach taken by this script is golden -- within the scalability limits git greps etc. of course.

Btw. I made the following aliases for myself:

Set-Alias -Name scoopx -Value Invoke-ScoopPackageCommand
Set-Alias -Name scoopx-install -Value Install-ScoopPackage
Set-Alias -Name scoopx-versions Get-ScoopPackageVersions

You probably didn't want to be so opinionated, so just an idea. :)

@ClassicDarkChocolate
Copy link
Author

@jkniiv Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment