Skip to content

Commit 2de0ec1

Browse files
committed
feat: Add file lock to prevent concurrent executions
1 parent 03d831d commit 2de0ec1

File tree

3 files changed

+56
-34
lines changed

3 files changed

+56
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
*.log
22
.DS_Store
33
._.DS_Store
4+
.lock
45
scoop.sublime-workspace
56
test/installer/tmp/*
67
test/tmp/*

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- **install:** Add separator at the end of notes, highlight suggestions ([#6418](https://github.com/ScoopInstaller/Scoop/issues/6418))
88
- **download|scoop-download:** Add GitHub issue prompt when the default downloader fails ([#6539](https://github.com/ScoopInstaller/Scoop/issues/6539))
99
- **download|scoop-config:** Allow disabling automatic fallback to the default downloader when Aria2c download fails ([#6538](https://github.com/ScoopInstaller/Scoop/issues/6538))
10+
- **core:** Add file lock to prevent concurrent executions ([#6557](https://github.com/ScoopInstaller/Scoop/issues/6557))
1011

1112
### Bug Fixes
1213

bin/scoop.ps1

Lines changed: 54 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,48 +6,68 @@ Set-StrictMode -Off
66
. "$PSScriptRoot\..\lib\commands.ps1"
77
. "$PSScriptRoot\..\lib\help.ps1"
88

9-
$subCommand = $Args[0]
9+
$lock_file_path = "$PSScriptRoot\..\.lock"
10+
$lock_show_waiting_message = $true
1011

11-
# for aliases where there's a local function, re-alias so the function takes precedence
12-
$aliases = Get-Alias | Where-Object { $_.Options -notmatch 'ReadOnly|AllScope' } | ForEach-Object { $_.Name }
13-
Get-ChildItem Function: | Where-Object -Property Name -In -Value $aliases | ForEach-Object {
14-
Set-Alias -Name $_.Name -Value Local:$($_.Name) -Scope Script
12+
while (-not $lock_stream.CanWrite) {
13+
try {
14+
$lock_stream = [System.IO.File]::Open($lock_file_path, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write)
15+
} catch [System.IO.IOException] {
16+
if ($lock_show_waiting_message) {
17+
'Waiting for exclusive access...'
18+
$lock_show_waiting_message = $false
19+
}
20+
Start-Sleep -Seconds 1
21+
}
1522
}
1623

17-
switch ($subCommand) {
18-
({ $subCommand -in @($null, '-h', '--help', '/?') }) {
19-
exec 'help'
24+
try {
25+
$subCommand = $Args[0]
26+
27+
# for aliases where there's a local function, re-alias so the function takes precedence
28+
$aliases = Get-Alias | Where-Object { $_.Options -notmatch 'ReadOnly|AllScope' } | ForEach-Object { $_.Name }
29+
Get-ChildItem Function: | Where-Object -Property Name -In -Value $aliases | ForEach-Object {
30+
Set-Alias -Name $_.Name -Value Local:$($_.Name) -Scope Script
2031
}
21-
({ $subCommand -in @('-v', '--version') }) {
22-
Write-Host 'Current Scoop version:'
23-
if ((Test-GitAvailable) -and (Test-Path "$PSScriptRoot\..\.git") -and ((get_config SCOOP_BRANCH 'master') -ne 'master')) {
24-
Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
25-
} else {
26-
$version = Select-String -Pattern '^## \[(v[\d.]+)\].*?([\d-]+)$' -Path "$PSScriptRoot\..\CHANGELOG.md"
27-
Write-Host $version.Matches.Groups[1].Value -ForegroundColor Cyan -NoNewline
28-
Write-Host " - Released at $($version.Matches.Groups[2].Value)"
32+
33+
switch ($subCommand) {
34+
({ $subCommand -in @($null, '-h', '--help', '/?') }) {
35+
exec 'help'
2936
}
30-
Write-Host ''
37+
({ $subCommand -in @('-v', '--version') }) {
38+
Write-Host 'Current Scoop version:'
39+
if ((Test-GitAvailable) -and (Test-Path "$PSScriptRoot\..\.git") -and ((get_config SCOOP_BRANCH 'master') -ne 'master')) {
40+
Invoke-Git -Path "$PSScriptRoot\.." -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
41+
} else {
42+
$version = Select-String -Pattern '^## \[(v[\d.]+)\].*?([\d-]+)$' -Path "$PSScriptRoot\..\CHANGELOG.md"
43+
Write-Host $version.Matches.Groups[1].Value -ForegroundColor Cyan -NoNewline
44+
Write-Host " - Released at $($version.Matches.Groups[2].Value)"
45+
}
46+
Write-Host ''
3147

32-
Get-LocalBucket | ForEach-Object {
33-
$bucketLoc = Find-BucketDirectory $_ -Root
34-
if ((Test-GitAvailable) -and (Test-Path "$bucketLoc\.git")) {
35-
Write-Host "'$_' bucket:"
36-
Invoke-Git -Path $bucketLoc -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
37-
Write-Host ''
48+
Get-LocalBucket | ForEach-Object {
49+
$bucketLoc = Find-BucketDirectory $_ -Root
50+
if ((Test-GitAvailable) -and (Test-Path "$bucketLoc\.git")) {
51+
Write-Host "'$_' bucket:"
52+
Invoke-Git -Path $bucketLoc -ArgumentList @('--no-pager', 'log', 'HEAD', '-1', '--oneline')
53+
Write-Host ''
54+
}
3855
}
3956
}
40-
}
41-
({ $subCommand -in (commands) }) {
42-
[string[]]$arguments = $Args | Select-Object -Skip 1
43-
if ($null -ne $arguments -and $arguments[0] -in @('-h', '--help', '/?')) {
44-
exec 'help' @($subCommand)
45-
} else {
46-
exec $subCommand $arguments
57+
({ $subCommand -in (commands) }) {
58+
[string[]]$arguments = $Args | Select-Object -Skip 1
59+
if ($null -ne $arguments -and $arguments[0] -in @('-h', '--help', '/?')) {
60+
exec 'help' @($subCommand)
61+
} else {
62+
exec $subCommand $arguments
63+
}
64+
}
65+
default {
66+
warn "scoop: '$subCommand' isn't a scoop command. See 'scoop help'."
67+
exit 1
4768
}
4869
}
49-
default {
50-
warn "scoop: '$subCommand' isn't a scoop command. See 'scoop help'."
51-
exit 1
52-
}
70+
} finally {
71+
$lock_stream.Close()
72+
$lock_stream.Dispose()
5373
}

0 commit comments

Comments
 (0)