Skip to content

Commit 32de4c5

Browse files
authored
refactor(bucket): Move 'Find-Manifest' and 'list_buckets' to 'buckets' (#4814)
1 parent ced36b2 commit 32de4c5

7 files changed

Lines changed: 155 additions & 108 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
### Code Refactoring
1818

19+
- **bucket:** Move 'Find-Manifest' and 'list_buckets' to 'buckets' ([#4814](https://github.com/ScoopInstaller/Scoop/issues/4814))
1920
- **relpath:** Use `$PSScriptRoot` instead of `relpath` ([#4793](https://github.com/ScoopInstaller/Scoop/issues/4793))
2021
- **reset_aliases:** Move core function of `reset_aliases` to `scoop` ([#4794](https://github.com/ScoopInstaller/Scoop/issues/4794))
2122

lib/buckets.ps1

Lines changed: 103 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ function Find-BucketDirectory {
1818
)
1919

2020
# Handle info passing empty string as bucket ($install.bucket)
21-
if(($null -eq $Name) -or ($Name -eq '')) { $Name = 'main' }
21+
if (($null -eq $Name) -or ($Name -eq '')) {
22+
$Name = 'main'
23+
}
2224
$bucket = "$bucketsdir\$Name"
2325

2426
if ((Test-Path "$bucket\bucket") -and !$Root) {
@@ -37,7 +39,7 @@ function bucketdir($name) {
3739
function known_bucket_repos {
3840
$json = "$PSScriptRoot\..\buckets.json"
3941

40-
return Get-Content $json -raw | convertfrom-json -ea stop
42+
return Get-Content $json -Raw | ConvertFrom-Json -ErrorAction stop
4143
}
4244

4345
function known_bucket_repo($name) {
@@ -46,11 +48,11 @@ function known_bucket_repo($name) {
4648
}
4749

4850
function known_buckets {
49-
known_bucket_repos | ForEach-Object { $_.psobject.properties | Select-Object -expand 'name' }
51+
known_bucket_repos | ForEach-Object { $_.PSObject.Properties | Select-Object -Expand 'name' }
5052
}
5153

5254
function apps_in_bucket($dir) {
53-
return Get-ChildItem $dir | Where-Object { $_.Name.endswith('.json') } | ForEach-Object { $_.Name -replace '.json$', '' }
55+
return Get-ChildItem $dir | Where-Object { $_.Name.EndsWith('.json') } | ForEach-Object { $_.Name -replace '.json$', '' }
5456
}
5557

5658
function Get-LocalBucket {
@@ -68,65 +70,134 @@ function buckets {
6870
return Get-LocalBucket
6971
}
7072

71-
function find_manifest($app, $bucket) {
72-
if ($bucket) {
73-
$manifest = manifest $app $bucket
74-
if ($manifest) { return $manifest, $bucket }
75-
return $null
73+
function Find-Manifest($app, $bucket) {
74+
$manifest, $url = $null, $null
75+
76+
# check if app is a URL or UNC path
77+
if ($app -match '^(ht|f)tps?://|\\\\') {
78+
$url = $app
79+
$app = appname_from_url $url
80+
$manifest = url_manifest $url
81+
} else {
82+
if ($bucket) {
83+
$manifest = manifest $app $bucket
84+
} else {
85+
foreach ($bucket in Get-LocalBucket) {
86+
$manifest = manifest $app $bucket
87+
if ($manifest) { break }
88+
}
89+
}
90+
91+
if (!$manifest) {
92+
# couldn't find app in buckets: check if it's a local path
93+
$path = $app
94+
if (!$path.endswith('.json')) { $path += '.json' }
95+
if (Test-Path $path) {
96+
$url = "$(Resolve-Path $path)"
97+
$app = appname_from_url $url
98+
$manifest, $bucket = url_manifest $url
99+
}
100+
}
76101
}
77102

78-
foreach($bucket in Get-LocalBucket) {
79-
$manifest = manifest $app $bucket
80-
if($manifest) { return $manifest, $bucket }
103+
return $app, $manifest, $bucket, $url
104+
}
105+
106+
function Convert-RepositoryUri {
107+
[CmdletBinding()]
108+
param (
109+
[Parameter(Mandatory, Position = 0, ValueFromPipeline = $true)]
110+
[String] $Uri
111+
)
112+
113+
process {
114+
# https://git-scm.com/docs/git-clone#_git_urls
115+
# https://regex101.com/r/xGmwRr/1
116+
if ($Uri -match '(?:@|/{1,3})(?:www\.|.*@)?(?<provider>[^/]+?)(?::\d+)?[:/](?<user>.+)/(?<repo>.+?)(?:\.git)?/?$') {
117+
$Matches.provider, $Matches.user, $Matches.repo -join '/'
118+
} else {
119+
error "$Uri is not a valid Git URL!"
120+
error "Please see https://git-scm.com/docs/git-clone#_git_urls for valid ones."
121+
return $null
122+
}
81123
}
82124
}
83125

84-
function add_bucket($name, $repo) {
85-
if (!$name) { "<name> missing"; $usage_add; exit 1 }
86-
if (!$repo) {
87-
$repo = known_bucket_repo $name
88-
if (!$repo) { "Unknown bucket '$name'. Try specifying <repo>."; $usage_add; exit 1 }
126+
function list_buckets {
127+
$buckets = @()
128+
Get-LocalBucket | ForEach-Object {
129+
$bucket = [Ordered]@{ Name = $_ }
130+
$path = Find-BucketDirectory $_ -Root
131+
if ((Test-Path (Join-Path $path '.git')) -and (Get-Command git -ErrorAction SilentlyContinue)) {
132+
$bucket.Source = git -C $path config remote.origin.url
133+
$bucket.Updated = git -C $path log --format='%aD' -n 1 | Get-Date
134+
} else {
135+
$bucket.Source = friendly_path $path
136+
$bucket.Updated = (Get-Item "$path\bucket").LastWriteTime
137+
}
138+
$bucket.Manifests = Get-ChildItem "$path\bucket" -Force -Recurse -ErrorAction SilentlyContinue |
139+
Measure-Object | Select-Object -ExpandProperty Count
140+
$buckets += [PSCustomObject]$bucket
89141
}
142+
$buckets
143+
}
90144

145+
function add_bucket($name, $repo) {
91146
if (!(Test-CommandAvailable git)) {
92-
abort "Git is required for buckets. Run 'scoop install git' and try again."
147+
error "Git is required for buckets. Run 'scoop install git' and try again."
148+
return 1
93149
}
94150

95151
$dir = Find-BucketDirectory $name -Root
96-
if (test-path $dir) {
152+
if (Test-Path $dir) {
97153
warn "The '$name' bucket already exists. Use 'scoop bucket rm $name' to remove it."
98-
exit 0
154+
return 2
155+
}
156+
157+
$uni_repo = Convert-RepositoryUri -Uri $repo
158+
if ($null -eq $uni_repo) {
159+
return 1
160+
}
161+
foreach ($bucket in Get-LocalBucket) {
162+
$remote = git -C "$bucketsdir\$bucket" config --get remote.origin.url
163+
if ((Convert-RepositoryUri -Uri $remote) -eq $uni_repo) {
164+
warn "Bucket $bucket already exists for $repo"
165+
return 2
166+
}
99167
}
100168

101-
write-host 'Checking repo... ' -nonewline
169+
Write-Host 'Checking repo... ' -NoNewline
102170
$out = git_cmd ls-remote $repo 2>&1
103-
if ($lastexitcode -ne 0) {
104-
abort "'$repo' doesn't look like a valid git repository`n`nError given:`n$out"
171+
if ($LASTEXITCODE -ne 0) {
172+
error "'$repo' doesn't look like a valid git repository`n`nError given:`n$out"
173+
return 1
105174
}
106-
write-host 'ok'
175+
Write-Host 'OK'
107176

108-
ensure $bucketsdir > $null
177+
ensure $bucketsdir | Out-Null
109178
$dir = ensure $dir
110179
git_cmd clone "$repo" "`"$dir`"" -q
111180
success "The $name bucket was added successfully."
181+
return 0
112182
}
113183

114184
function rm_bucket($name) {
115-
if (!$name) { "<name> missing"; $usage_rm; exit 1 }
116185
$dir = Find-BucketDirectory $name -Root
117-
if (!(test-path $dir)) {
118-
abort "'$name' bucket not found."
186+
if (!(Test-Path $dir)) {
187+
error "'$name' bucket not found."
188+
return 1
119189
}
120190

121-
Remove-Item $dir -r -force -ea stop
191+
Remove-Item $dir -Recurse -Force -ErrorAction Stop
192+
return 0
122193
}
123194

124195
function new_issue_msg($app, $bucket, $title, $body) {
125196
$app, $manifest, $bucket, $url = Find-Manifest $app $bucket
126197
$url = known_bucket_repo $bucket
127198
$bucket_path = "$bucketsdir\$bucket"
128199

129-
if (Test-path $bucket_path) {
200+
if (Test-Path $bucket_path) {
130201
$remote = Invoke-Expression "git -C '$bucket_path' config --get remote.origin.url"
131202
# Support ssh and http syntax
132203
# git@PROVIDER:USER/REPO.git
@@ -135,15 +206,15 @@ function new_issue_msg($app, $bucket, $title, $body) {
135206
$url = "https://$($Matches.Provider)/$($Matches.User)/$($Matches.Repo)"
136207
}
137208

138-
if(!$url) { return 'Please contact the bucket maintainer!' }
209+
if (!$url) { return 'Please contact the bucket maintainer!' }
139210

140211
# Print only github repositories
141212
if ($url -like '*github*') {
142213
$title = [System.Web.HttpUtility]::UrlEncode("$app@$($manifest.version): $title")
143214
$body = [System.Web.HttpUtility]::UrlEncode($body)
144215
$url = $url -replace '\.git$', ''
145216
$url = "$url/issues/new?title=$title"
146-
if($body) {
217+
if ($body) {
147218
$url += "&body=$body"
148219
}
149220
}

lib/install.ps1

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -83,38 +83,6 @@ function install_app($app, $architecture, $global, $suggested, $use_cache = $tru
8383
show_notes $manifest $dir $original_dir $persist_dir
8484
}
8585

86-
function locate($app, $bucket) {
87-
Show-DeprecatedWarning $MyInvocation 'Find-Manifest'
88-
return Find-Manifest $app $bucket
89-
}
90-
91-
function Find-Manifest($app, $bucket) {
92-
$manifest, $url = $null, $null
93-
94-
# check if app is a URL or UNC path
95-
if($app -match '^(ht|f)tps?://|\\\\') {
96-
$url = $app
97-
$app = appname_from_url $url
98-
$manifest = url_manifest $url
99-
} else {
100-
# check buckets
101-
$manifest, $bucket = find_manifest $app $bucket
102-
103-
if(!$manifest) {
104-
# couldn't find app in buckets: check if it's a local path
105-
$path = $app
106-
if(!$path.endswith('.json')) { $path += '.json' }
107-
if(test-path $path) {
108-
$url = "$(resolve-path $path)"
109-
$app = appname_from_url $url
110-
$manifest, $bucket = url_manifest $url
111-
}
112-
}
113-
}
114-
115-
return $app, $manifest, $bucket, $url
116-
}
117-
11886
function dl_with_cache($app, $version, $url, $to, $cookies = $null, $use_cache = $true) {
11987
$cached = fullpath (cache_path $app $version $url)
12088

libexec/scoop-bucket.ps1

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -23,42 +23,47 @@ param($cmd, $name, $repo)
2323
. "$PSScriptRoot\..\lib\buckets.ps1"
2424
. "$PSScriptRoot\..\lib\help.ps1"
2525

26-
$usage_add = "usage: scoop bucket add <name> [<repo>]"
27-
$usage_rm = "usage: scoop bucket rm <name>"
26+
$usage_add = 'usage: scoop bucket add <name> [<repo>]'
27+
$usage_rm = 'usage: scoop bucket rm <name>'
2828

29-
function list_buckets {
30-
$buckets = @()
31-
32-
foreach ($bucket in Get-LocalBucket) {
33-
$source = Find-BucketDirectory $bucket -Root
34-
$manifests = (
35-
Get-ChildItem "$source\bucket" -Force -Recurse -ErrorAction SilentlyContinue |
36-
Measure-Object | Select-Object -ExpandProperty Count
37-
)
38-
$updated = 'N/A'
39-
if ((Test-Path (Join-Path $source '.git')) -and (Get-Command git -ErrorAction SilentlyContinue)) {
40-
$updated = git -C $source log --format='%aD' -n 1 | Get-Date
41-
$source = git -C $source config remote.origin.url
42-
} else {
43-
$updated = (Get-Item "$source\bucket").LastWriteTime
44-
$source = friendly_path $source
29+
switch ($cmd) {
30+
'add' {
31+
if (!$name) {
32+
'<name> missing'
33+
$usage_add
34+
exit 1
4535
}
46-
$buckets += New-Object PSObject -Property @{
47-
Name = $bucket
48-
Source = $source
49-
Updated = $updated
50-
Manifests = $manifests
36+
if (!$repo) {
37+
$repo = known_bucket_repo $name
38+
if (!$repo) {
39+
"Unknown bucket '$name'. Try specifying <repo>."
40+
$usage_add
41+
exit 1
42+
}
5143
}
44+
$status = add_bucket $name $repo
45+
exit $status
46+
}
47+
'rm' {
48+
if (!$name) {
49+
'<name> missing'
50+
$usage_rm
51+
exit 1
52+
}
53+
$status = rm_bucket $name
54+
exit $status
55+
}
56+
'list' {
57+
list_buckets
58+
exit 0
59+
}
60+
'known' {
61+
known_buckets
62+
exit 0
63+
}
64+
default {
65+
"scoop bucket: cmd '$cmd' not supported"
66+
my_usage
67+
exit 1
5268
}
53-
return $buckets | Select-Object Name, Source, Updated, Manifests
54-
}
55-
56-
switch ($cmd) {
57-
'add' { add_bucket $name $repo }
58-
'rm' { rm_bucket $name }
59-
'list' { list_buckets }
60-
'known' { known_buckets }
61-
default { "scoop bucket: cmd '$cmd' not supported"; my_usage; exit 1 }
6269
}
63-
64-
exit 0

libexec/scoop-home.ps1

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,20 @@ param($app)
77
. "$PSScriptRoot\..\lib\manifest.ps1"
88
. "$PSScriptRoot\..\lib\buckets.ps1"
99

10-
if($app) {
11-
$manifest, $bucket = find_manifest $app
12-
if($manifest) {
13-
if([string]::isnullorempty($manifest.homepage)) {
10+
if ($app) {
11+
$null, $manifest, $bucket, $null = Find-Manifest $app
12+
if ($manifest) {
13+
if ($manifest.homepage) {
14+
Start-Process $manifest.homepage
15+
} else {
1416
abort "Could not find homepage in manifest for '$app'."
1517
}
16-
Start-Process $manifest.homepage
17-
}
18-
else {
18+
} else {
1919
abort "Could not find manifest for '$app'."
2020
}
21-
} else { my_usage }
21+
} else {
22+
my_usage
23+
exit 1
24+
}
2225

2326
exit 0

libexec/scoop-virustotal.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ Function Submit-ToVirusTotal ($url, $app, $do_scan, $retrying=$False) {
207207
$apps | ForEach-Object {
208208
$app = $_
209209
# write-host $app
210-
$manifest, $bucket = find_manifest $app
210+
$null, $manifest, $bucket, $null = Find-Manifest $app
211211
if(!$manifest) {
212212
$exit_code = $exit_code -bor $_ERR_NO_INFO
213213
warn "$app`: manifest not found"

test/Import-Bucket-Tests.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,3 @@ Describe 'manifest validates against the schema' -Tag 'Manifests' {
125125
}
126126
}
127127
}
128-

0 commit comments

Comments
 (0)