From a26a560d9306468a66af406a62836e8a83304eca Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Thu, 27 Aug 2026 12:19:07 +0800 Subject: [PATCH 1/3] refactor!: guard install flow against dot-sourcing Signed-off-by: Chawye Hsu --- install.ps1 | 30 ++++++++++++++---------------- test/install.Tests.ps1 | 6 ++++++ 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/install.ps1 b/install.ps1 index fa78c2a..ad17208 100644 --- a/install.ps1 +++ b/install.ps1 @@ -575,10 +575,10 @@ function Test-CommandAvailable { function Install-Scoop { Write-InstallInfo 'Initializing...' - # Validate install parameters - Test-ValidateParameter # Check prerequisites Test-Prerequisite + # Validate install parameters + Test-ValidateParameter # Enable TLS 1.2 Optimize-SecurityProtocol @@ -680,12 +680,12 @@ function Write-DebugInfo { Write-Verbose "SCOOP_CONFIG_HOME: $SCOOP_CONFIG_HOME" } +# Quit if anything goes wrong +$ErrorActionPreference = 'Stop' + # Prepare variables $IS_EXECUTED_FROM_IEX = ($null -eq $MyInvocation.MyCommand.Path) -# Abort when the language mode is restricted -Test-LanguageMode - # Scoop root directory $SCOOP_DIR = $ScoopDir, $env:SCOOP, "$env:USERPROFILE\scoop" | Where-Object { -not [String]::IsNullOrEmpty($_) } | Select-Object -First 1 # Scoop global apps directory @@ -709,14 +709,12 @@ $SCOOP_MAIN_BUCKET_REPO = 'https://github.com/ScoopInstaller/Main/archive/master $SCOOP_PACKAGE_GIT_REPO = 'https://github.com/ScoopInstaller/Scoop.git' $SCOOP_MAIN_BUCKET_GIT_REPO = 'https://github.com/ScoopInstaller/Main.git' -# Quit if anything goes wrong -$oldErrorActionPreference = $ErrorActionPreference -$ErrorActionPreference = 'Stop' - -# Logging debug info -Write-DebugInfo $PSBoundParameters -# Bootstrap function -Install-Scoop - -# Reset $ErrorActionPreference to original value -$ErrorActionPreference = $oldErrorActionPreference +# The install flow triggers only when the script is executed directly, but +# not when dot-sourced. Dot-sourcing the installer will not trigger the +# installation, and only the functions will be loaded, e.g., for testing. +# Downstreams can call `Install-Scoop` explicitly to start the installation. +if ($MyInvocation.InvocationName -ne '.') { + Test-LanguageMode + Write-DebugInfo $PSBoundParameters + Install-Scoop +} diff --git a/test/install.Tests.ps1 b/test/install.Tests.ps1 index 806aa0d..e77a567 100644 --- a/test/install.Tests.ps1 +++ b/test/install.Tests.ps1 @@ -1,4 +1,10 @@ BeforeAll { + $script:TestScoopDir = Join-Path $TestDrive 'scoop' + $script:TestGlobalDir = Join-Path $TestDrive 'scoop-global' + + $env:SCOOP = $script:TestScoopDir + $env:SCOOP_GLOBAL = $script:TestGlobalDir + # Load SUT $sut = (Split-Path -Leaf $PSCommandPath).Replace('.Tests.ps1', '.ps1') . ".\$sut" From 53829d1d2cb00721baf21e50fbb213c1bf7619d8 Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Thu, 27 Aug 2026 12:40:19 +0800 Subject: [PATCH 2/3] test: remove intermediate variables Signed-off-by: Chawye Hsu --- test/install.Tests.ps1 | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/install.Tests.ps1 b/test/install.Tests.ps1 index e77a567..1c93d39 100644 --- a/test/install.Tests.ps1 +++ b/test/install.Tests.ps1 @@ -1,9 +1,6 @@ BeforeAll { - $script:TestScoopDir = Join-Path $TestDrive 'scoop' - $script:TestGlobalDir = Join-Path $TestDrive 'scoop-global' - - $env:SCOOP = $script:TestScoopDir - $env:SCOOP_GLOBAL = $script:TestGlobalDir + $env:SCOOP = Join-Path $TestDrive 'scoop' + $env:SCOOP_GLOBAL = Join-Path $TestDrive 'scoop-global' # Load SUT $sut = (Split-Path -Leaf $PSCommandPath).Replace('.Tests.ps1', '.ps1') From a36b3c4694cb28d80ade9eca08cc02307d23aefa Mon Sep 17 00:00:00 2001 From: Chawye Hsu Date: Thu, 27 Aug 2026 12:46:29 +0800 Subject: [PATCH 3/3] fix: restore caller error preference Signed-off-by: Chawye Hsu --- install.ps1 | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/install.ps1 b/install.ps1 index ad17208..82d311d 100644 --- a/install.ps1 +++ b/install.ps1 @@ -680,9 +680,6 @@ function Write-DebugInfo { Write-Verbose "SCOOP_CONFIG_HOME: $SCOOP_CONFIG_HOME" } -# Quit if anything goes wrong -$ErrorActionPreference = 'Stop' - # Prepare variables $IS_EXECUTED_FROM_IEX = ($null -eq $MyInvocation.MyCommand.Path) @@ -714,7 +711,13 @@ $SCOOP_MAIN_BUCKET_GIT_REPO = 'https://github.com/ScoopInstaller/Main.git' # installation, and only the functions will be loaded, e.g., for testing. # Downstreams can call `Install-Scoop` explicitly to start the installation. if ($MyInvocation.InvocationName -ne '.') { - Test-LanguageMode - Write-DebugInfo $PSBoundParameters - Install-Scoop + $oldErrorActionPreference = $ErrorActionPreference + try { + $ErrorActionPreference = 'Stop' + Test-LanguageMode + Write-DebugInfo $PSBoundParameters + Install-Scoop + } finally { + $ErrorActionPreference = $oldErrorActionPreference + } }