diff --git a/src/System.Management.Automation/engine/CommandDiscovery.cs b/src/System.Management.Automation/engine/CommandDiscovery.cs index 2dc02351489..3333a3f81f8 100644 --- a/src/System.Management.Automation/engine/CommandDiscovery.cs +++ b/src/System.Management.Automation/engine/CommandDiscovery.cs @@ -888,7 +888,7 @@ internal static void AutoloadModulesWithJobSourceAdapters(System.Management.Auto It attempts to load modules from a fixed ModulesWithJobSourceAdapters list that currently has only `PSScheduledJob` module that is not PS-Core compatible. Because this function does not check the result of a (currently failing) `PSScheduledJob` module autoload, it provides no value. After discussion it was decided to comment out this code as it may be useful if ModulesWithJobSourceAdapters list changes in the future. - + if (!context.IsModuleWithJobSourceAdapterLoaded) { PSModuleAutoLoadingPreference moduleAutoLoadingPreference = GetCommandDiscoveryPreference(context, SpecialVariables.PSModuleAutoLoadingPreferenceVarPath, "PSModuleAutoLoadingPreference"); @@ -1328,6 +1328,15 @@ internal LookupPathCollection GetLookupDirectoryPaths() foreach (string directory in tokenizedPath) { string tempDir = directory.TrimStart(); + if (tempDir.EqualsOrdinalIgnoreCase("~")) + { + tempDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); + } + else if (tempDir.StartsWith("~" + Path.DirectorySeparatorChar)) + { + tempDir = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + Path.DirectorySeparatorChar + tempDir.Substring(2); + } + _cachedPath.Add(tempDir); result.Add(tempDir); } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Environment-Variables.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Environment-Variables.Tests.ps1 index 0d79efbe85b..3760489ebef 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Environment-Variables.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Environment-Variables.Tests.ps1 @@ -3,44 +3,76 @@ Describe "Environment-Variables" -Tags "CI" { It "Should have environment variables" { - Get-Item ENV: | Should -Not -BeNullOrEmpty + Get-Item ENV: | Should -Not -BeNullOrEmpty } It "Should have a nonempty PATH" { - $ENV:PATH | Should -Not -BeNullOrEmpty + $ENV:PATH | Should -Not -BeNullOrEmpty } It "Should contain /bin in the PATH" { - if ($IsWindows) - { - $ENV:PATH | Should -Match "C:" - } - else - { - $ENV:PATH | Should -Match "/bin" - } + if ($IsWindows) { + $ENV:PATH | Should -Match "C:" + } else { + $ENV:PATH | Should -Match "/bin" + } } It "Should have the correct HOME" { - if ($IsWindows) - { - # \Windows\System32 is found as $env:HOMEPATH for temporary profiles - $expected = "\Users", "\Windows" - Split-Path $ENV:HOMEPATH -Parent | Should -BeIn $expected - } - else - { - $expected = /bin/bash -c "cd ~ && pwd" - $ENV:HOME | Should -Be $expected - } + if ($IsWindows) { + # \Windows\System32 is found as $env:HOMEPATH for temporary profiles + $expected = "\Users", "\Windows" + Split-Path $ENV:HOMEPATH -Parent | Should -BeIn $expected + } else { + $expected = /bin/bash -c "cd ~ && pwd" + $ENV:HOME | Should -Be $expected + } } It "Should be able to set the environment variables" { - $expected = "this is a test environment variable" - { $ENV:TESTENVIRONMENTVARIABLE = $expected } | Should -Not -Throw + $expected = "this is a test environment variable" + { $ENV:TESTENVIRONMENTVARIABLE = $expected } | Should -Not -Throw - $ENV:TESTENVIRONMENTVARIABLE | Should -Not -BeNullOrEmpty - $ENV:TESTENVIRONMENTVARIABLE | Should -Be $expected + $ENV:TESTENVIRONMENTVARIABLE | Should -Not -BeNullOrEmpty + $ENV:TESTENVIRONMENTVARIABLE | Should -Be $expected } + + Context "~ in PATH" { + AfterEach { + $env:PATH = $oldPath + } + + BeforeAll { + $oldPath = $env:PATH + $pwsh = (Get-Command pwsh | Select-Object -First 1).Source + if ($IsWindows) { + $pwsh2 = "pwsh2.exe" + } else { + $pwsh2 = "pwsh2" + } + + Copy-Item -Path $pwsh -Destination "~/$pwsh2" + $testPath = Join-Path -Path "~" -ChildPath (New-Guid) + New-Item -Path $testPath -ItemType Directory > $null + Copy-Item -Path $pwsh -Destination "$testPath/$pwsh2" + } + + AfterAll { + Remove-Item -Path "~/pwsh2" -Force + Remove-Item -Path $testPath -Recurse -Force + } + + It "Should be able to resolve ~ in PATH" { + $env:PATH = "~" + [System.IO.Path]::PathSeparator + $env:PATH + $out = Get-Command pwsh2 + $out.Source | Should -BeExactly (Join-Path -Path ([System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile)) -ChildPath $pwsh2) + } + + It "Should be able to resolve ~/folder in PATH" { + $env:PATH = $testPath + [System.IO.Path]::PathSeparator + $env:PATH + $out = Get-Command pwsh2 + $out.Source | Should -BeExactly (Join-Path -Path (Resolve-Path $testPath) -ChildPath $pwsh2) + } + } }