Add a public API for getting locations of PSModulePath elements (#19422)

This commit is contained in:
James Truher [MSFT]
2023-05-22 17:02:31 -07:00
committed by GitHub
parent e5728b63bf
commit d9697f07ba
3 changed files with 81 additions and 0 deletions
@@ -1172,6 +1172,42 @@ namespace System.Management.Automation
return result.ToString();
}
/// <summary>
/// The available module path scopes.
/// </summary>
public enum PSModulePathScope
{
/// <summary>The users module path.</summary>
User,
/// <summary>The Builtin module path. This is where PowerShell is installed (PSHOME).</summary>
Builtin,
/// <summary>The machine module path. This is the shared location for all users of the system.</summary>
Machine
}
/// <summary>
/// Retrieve the current PSModulePath for the specified scope.
/// </summary>
/// <param name="scope">The scope of module path to retrieve. This can be User, Builtin, or Machine.</param>
/// <returns>The string representing the requested module path type.</returns>
public static string GetPSModulePath(PSModulePathScope scope)
{
if (scope == PSModulePathScope.User)
{
return GetPersonalModulePath();
}
else if (scope == PSModulePathScope.Builtin)
{
return GetPSHomeModulePath();
}
else
{
return GetSharedModulePath();
}
}
/// <summary>
/// Checks the various PSModulePath environment string and returns PSModulePath string as appropriate.
/// </summary>
@@ -202,3 +202,48 @@ Describe "SxS Module Path Basic Tests" -tags "CI" {
$out.Split([System.IO.Path]::PathSeparator, [System.StringSplitOptions]::RemoveEmptyEntries) | Should -Not -BeLike $validation
}
}
Describe "ModuleIntrinsics.GetPSModulePath API tests" -tag @('CI', 'RequireAdminOnWindows', 'RequireSudoOnUnix') {
BeforeAll {
# create a local repostory and install a module
$localSourceName = [Guid]::NewGuid().ToString("n")
$localSourceLocation = Join-Path $PSScriptRoot assets
Register-PSRepository -Name $localSourceName -SourceLocation $localSourceLocation -InstallationPolicy Trusted -ErrorAction SilentlyContinue
Install-Module -Force -Scope AllUsers -Name PowerShell.TestPackage -Repository $localSourceName -ErrorAction SilentlyContinue
Install-Module -Force -Scope CurrentUser -Name PowerShell.TestPackage -Repository $localSourceName -ErrorAction SilentlyContinue
$testCases = @(
@{ Name = "User" ; Expected = $IsWindows ?
(Resolve-Path ([Environment]::GetFolderPath("Personal") + "\PowerShell\Modules")).Path :
(Resolve-Path ([System.Management.Automation.Platform]::SelectProductNameForDirectory("USER_MODULES"))).Path
}
@{ Name = "Machine" ; Expected = $IsWindows ?
[Environment]::GetFolderPath("ProgramFiles") + "\PowerShell\Modules" :
(Resolve-Path ([System.Management.Automation.Platform]::SelectProductNameForDirectory("SHARED_MODULES"))).Path
}
@{ Name = "Builtin" ; Expected = (Resolve-Path (Join-Path $PSHOME Modules)).Path }
)
# resolve the paths to ensure they are in the correct format
$currentModulePathElements = $env:PSModulePath -split [System.IO.Path]::PathSeparator | Foreach-Object { (Resolve-Path $_).Path }
}
AfterAll {
Unregister-PSRepository -Name $localSourceName -ErrorAction SilentlyContinue
}
It "The value '<Name>' should return the proper value" -testcase $testCases {
param ( $Name, $Expected )
$result = [System.Management.Automation.ModuleIntrinsics]::GetPSModulePath($name)
$result | Should -not -BeNullOrEmpty
# spot check pshome, the user and shared paths may not be present
if ( $name -eq "PSHOME") {
$result | Should -Be $Expected
}
}
It "The current module path should contain the expected paths for '<Name>'" -testcase $testCases {
param ( $Name, $Expected )
$mPath = (Resolve-Path ([System.Management.Automation.ModuleIntrinsics]::GetPSModulePath($name))).Path
$currentModulePathElements | Should -Contain $mPath
}
}