Sync eng/common directory with azure-sdk-tools for PR 9493 (#6283)

* add and use new function to PSModule-Helpers.ps1 -- `InstallAndImport-ModuleIfNotInstalled` which smartly short circuits the install and module import to be as efficient as possible. This largely has impact of improving Save-Package-Properties performance on windows machines.

---------

Co-authored-by: Scott Beddall <scbedd@microsoft.com>
This commit is contained in:
Azure SDK Bot 2024-12-11 17:40:36 -08:00 committed by GitHub
parent e317102647
commit 30902ff60f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 50 additions and 39 deletions

View File

@ -1,7 +1,6 @@
$global:CurrentUserModulePath = ""
function Update-PSModulePathForCI()
{
function Update-PSModulePathForCI() {
# Information on PSModulePath taken from docs
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_psmodulepath
@ -11,7 +10,8 @@ function Update-PSModulePathForCI()
if ($IsWindows) {
$hostedAgentModulePath = $env:SystemDrive + "\Modules"
$moduleSeperator = ";"
} else {
}
else {
$hostedAgentModulePath = "/usr/share"
$moduleSeperator = ":"
}
@ -55,7 +55,8 @@ function Get-ModuleRepositories([string]$moduleName) {
$repoUrls = if ($packageFeedOverrides.Contains("${moduleName}")) {
@($packageFeedOverrides["${moduleName}"], $DefaultPSRepositoryUrl)
} else {
}
else {
@($DefaultPSRepositoryUrl)
}
@ -63,11 +64,21 @@ function Get-ModuleRepositories([string]$moduleName) {
}
function moduleIsInstalled([string]$moduleName, [string]$version) {
$modules = (Get-Module -ListAvailable $moduleName)
if (-not (Test-Path variable:script:InstalledModules)) {
$script:InstalledModules = @{}
}
if ($script:InstalledModules.ContainsKey("${moduleName}")) {
$modules = $script:InstalledModules["${moduleName}"]
}
else {
$modules = (Get-Module -ListAvailable $moduleName)
$script:InstalledModules["${moduleName}"] = $modules
}
if ($version -as [Version]) {
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
if ($modules.Count -gt 0)
{
if ($modules.Count -gt 0) {
Write-Host "Using module $($modules[0].Name) with version $($modules[0].Version)."
return $modules[0]
}
@ -77,8 +88,7 @@ function moduleIsInstalled([string]$moduleName, [string]$version) {
function installModule([string]$moduleName, [string]$version, $repoUrl) {
$repo = (Get-PSRepository).Where({ $_.SourceLocation -eq $repoUrl })
if ($repo.Count -eq 0)
{
if ($repo.Count -eq 0) {
Register-PSRepository -Name $repoUrl -SourceLocation $repoUrl -InstallationPolicy Trusted | Out-Null
$repo = (Get-PSRepository).Where({ $_.SourceLocation -eq $repoUrl })
if ($repo.Count -eq 0) {
@ -102,6 +112,8 @@ function installModule([string]$moduleName, [string]$version, $repoUrl) {
throw "Failed to install module $moduleName with version $version"
}
$script:InstalledModules["${moduleName}"] = $modules
# Unregister repository as it can cause overlap issues with `dotnet tool install`
# commands using the same devops feed
Unregister-PSRepository -Name $repoUrl | Out-Null
@ -109,10 +121,17 @@ function installModule([string]$moduleName, [string]$version, $repoUrl) {
return $modules[0]
}
function InstallAndImport-ModuleIfNotInstalled([string]$module, [string]$version) {
if ($null -eq (moduleIsInstalled $module $version)) {
Install-ModuleIfNotInstalled -WhatIf:$false $module $version | Import-Module
} elseif (!(Get-Module -Name $module)) {
Import-Module $module
}
}
# Manual test at eng/common-tests/psmodule-helpers/Install-Module-Parallel.ps1
# If we want to use another default repository other then PSGallery we can update the default parameters
function Install-ModuleIfNotInstalled()
{
function Install-ModuleIfNotInstalled() {
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[string]$moduleName,
@ -137,12 +156,14 @@ function Install-ModuleIfNotInstalled()
foreach ($url in $repoUrls) {
try {
$module = installModule -moduleName $moduleName -version $version -repoUrl $url
} catch {
}
catch {
if ($url -ne $repoUrls[-1]) {
Write-Warning "Failed to install powershell module from '$url'. Retrying with fallback repository"
Write-Warning $_
continue
} else {
}
else {
Write-Warning "Failed to install powershell module from $url"
throw
}
@ -151,7 +172,8 @@ function Install-ModuleIfNotInstalled()
}
Write-Host "Using module '$($module.Name)' with version '$($module.Version)'."
} finally {
}
finally {
$mutex.ReleaseMutex()
}
@ -159,5 +181,5 @@ function Install-ModuleIfNotInstalled()
}
if ($null -ne $env:SYSTEM_TEAMPROJECTID) {
Update-PSModulePathForCI
Update-PSModulePathForCI
}

View File

@ -46,7 +46,6 @@ function GetDocsTocDisplayName($pkg) {
return $displayName
}
<#
.SYNOPSIS
This function is a safe wrapper around `yq` and `ConvertFrom-Yaml` to convert YAML content to a PowerShell HashTable object
@ -68,7 +67,7 @@ Get-Content -Raw path/to/file.yml | CompatibleConvertFrom-Yaml
#>
function CompatibleConvertFrom-Yaml {
param(
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
[string]$Content
)
@ -76,20 +75,10 @@ function CompatibleConvertFrom-Yaml {
throw "Content to parse is a required input."
}
# Initialize any variables or checks that need to be done once
$yqPresent = Get-Command 'yq' -ErrorAction SilentlyContinue
if (-not $yqPresent) {
. (Join-Path $PSScriptRoot PSModule-Helpers.ps1)
Install-ModuleIfNotInstalled -WhatIf:$false "powershell-yaml" "0.4.7" | Import-Module
}
. (Join-Path $PSScriptRoot PSModule-Helpers.ps1)
InstallAndImport-ModuleIfNotInstalled "powershell-yaml" "0.4.7"
# Process the content (for example, you could convert from YAML here)
if ($yqPresent) {
return ($content | yq -o=json | ConvertFrom-Json -AsHashTable)
}
else {
return ConvertFrom-Yaml $content
}
return ConvertFrom-Yaml $content
}
<#
@ -114,7 +103,7 @@ LoadFrom-Yaml -YmlFile path/to/file.yml
#>
function LoadFrom-Yaml {
param(
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true)]
[string]$YmlFile
)
if (Test-Path -Path $YmlFile) {
@ -159,19 +148,19 @@ GetValueSafelyFrom-Yaml -YamlContentAsHashtable $YmlFileContent -Keys @("extends
#>
function GetValueSafelyFrom-Yaml {
param(
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true)]
$YamlContentAsHashtable,
[Parameter(Mandatory=$true)]
[Parameter(Mandatory = $true)]
[string[]]$Keys
)
$current = $YamlContentAsHashtable
foreach ($key in $Keys) {
if ($current.ContainsKey($key) -or $current[$key]) {
$current = $current[$key]
}
else {
return $null
}
if ($current.ContainsKey($key) -or $current[$key]) {
$current = $current[$key]
}
else {
return $null
}
}
return [object]$current