Skip to content

Commit

Permalink
feat(scoop-import): Import a Scoop installation from JSON (ScoopInsta…
Browse files Browse the repository at this point in the history
…ller#5014)

* feat(scoop-export): Export Scoop installation in JSON

* optimize

* yesss done

* complete

* Update CHANGELOG.md

* Add suggestions from code review

* fix CI
  • Loading branch information
rashil2000 authored and slaughtering committed Jul 7, 2022
1 parent c736f09 commit d04581f
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 51 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- **chore:** Add missing -a/--all param to all commands ([#5004](https://github.com/ScoopInstaller/Scoop/issues/5004))
- **scoop-status:** Check bucket status, improve output ([#5011](https://github.com/ScoopInstaller/Scoop/issues/5011))
- **scoop-info:** Show app installed/download size ([#4886](https://github.com/ScoopInstaller/Scoop/issues/4886))
- **scoop-import:** Import a Scoop installation from JSON ([#5014](https://github.com/ScoopInstaller/Scoop/issues/5014))

### Bug Fixes

Expand Down
8 changes: 6 additions & 2 deletions lib/manifest.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ function parse_json($path) {
try {
Get-Content $path -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop
} catch {
warn "Error parsing manifest at $path."
warn "Error parsing JSON at $path."
}
}

Expand All @@ -24,7 +24,11 @@ function url_manifest($url) {
throw
}
if(!$str) { return $null }
$str | convertfrom-json
try {
$str | ConvertFrom-Json -ErrorAction Stop
} catch {
warn "Error parsing JSON at $url."
}
}

function Get-Manifest($app) {
Expand Down
64 changes: 15 additions & 49 deletions libexec/scoop-export.ps1
Original file line number Diff line number Diff line change
@@ -1,57 +1,23 @@
# Usage: scoop export > filename
# Summary: Exports (an importable) list of installed apps
# Help: Lists all installed apps.
# Usage: scoop export > scoopfile.json
# Summary: Exports installed apps, buckets (and optionally configs) in JSON format
# Options:
# -c, --config Export the Scoop configuration file too

. "$PSScriptRoot\..\lib\versions.ps1" # 'Select-CurrentVersion'
. "$PSScriptRoot\..\lib\manifest.ps1" # 'default_architecture' 'Select-CurrentVersion' (indirectly)
. "$PSScriptRoot\..\lib\json.ps1" # 'ConvertToPrettyJson'

$def_arch = default_architecture
$export = @{}

$local = installed_apps $false | ForEach-Object { @{ name = $_; global = $false } }
$global = installed_apps $true | ForEach-Object { @{ name = $_; global = $true } }

$apps = @($local) + @($global)
$count = 0

# json
# echo "{["

if($apps) {
$apps | Sort-Object { $_.name } | Where-Object { !$query -or ($_.name -match $query) } | ForEach-Object {
$app = $_.name
$global = $_.global
$ver = Select-CurrentVersion -AppName $app -Global:$global
$global_display = $null; if($global) { $global_display = ' *global*'}

$install_info = install_info $app $ver $global
$bucket = ''
if ($install_info.bucket) {
$bucket = ' [' + $install_info.bucket + ']'
} elseif ($install_info.url) {
$bucket = ' [' + $install_info.url + ']'
}
if ($install_info.architecture -and $def_arch -ne $install_info.architecture) {
$arch = ' {' + $install_info.architecture + '}'
} else {
$arch = ''
}

# json
# $val = "{ 'name': '$app', 'version': '$ver', 'global': $($global.toString().tolower()) }"
# if($count -gt 0) {
# " ," + $val
# } else {
# " " + $val
# }

# "$app (v:$ver) global:$($global.toString().tolower())"
"$app (v:$ver)$global_display$bucket$arch"

$count++
if ($args[0] -eq '-c' -or $args[0] -eq '--config') {
$export.config = $scoopConfig
# Remove machine-specific properties
foreach ($prop in 'lastUpdate', 'rootPath', 'globalPath', 'cachePath', 'alias') {
$export.config.PSObject.Properties.Remove($prop)
}
}

# json
# echo "]}"
$export.buckets = list_buckets
$export.apps = @(& "$PSScriptRoot\scoop-list.ps1" 6>$null)

$export | ConvertToPrettyJSON

exit 0
62 changes: 62 additions & 0 deletions libexec/scoop-import.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Usage: scoop import <path/url to scoopfile.json>
# Summary: Imports apps, buckets and configs from a Scoopfile in JSON format

param(
[Parameter(Mandatory)]
[String]
$scoopfile
)

. "$PSScriptRoot\..\lib\manifest.ps1"

$import = $null
$bucket_names = @()
$def_arch = default_architecture

if (Test-Path $scoopfile) {
$import = parse_json $scoopfile
} elseif ($scoopfile -match '^(ht|f)tps?://|\\\\') {
$import = url_manifest $scoopfile
}

if (!$import) { abort 'Input file not a valid JSON.' }

$import.config.PSObject.Properties | ForEach-Object {
set_config $_.Name $_.Value | Out-Null
Write-Host "'$($_.Name)' has been set to '$($_.Value)'"
}

$import.buckets | ForEach-Object {
add_bucket $_.Name $_.Source | Out-Null
$bucket_names += $_.Name
}

$import.apps | ForEach-Object {
$info = $_.Info -Split ', '
$global = if ('Global install' -in $info) {
' --global'
} else {
''
}
$arch = if ('64bit' -in $info -and '32bit' -eq $def_arch) {
' --arch 64bit'
} elseif ('32bit' -in $info -and '64bit' -eq $def_arch) {
' --arch 32bit'
} else {
''
}

$app = if ($_.Source -in $bucket_names) {
"$($_.Source)/$($_.Name)"
} elseif ($_.Source -eq '<auto-generated>') {
"$($_.Name)@$($_.Version)"
} else {
$_.Source
}

& "$PSScriptRoot\scoop-install.ps1" $app$global$arch

if ('Held package' -in $info) {
& "$PSScriptRoot\scoop-hold.ps1" $($_.Name)$global
}
}

0 comments on commit d04581f

Please sign in to comment.