Skip to content

Commit 0de6547

Browse files
azure-sdkscbedd
andauthored
Sync eng/common directory with azure-sdk-tools for PR 9493 (#23844)
* 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 <[email protected]>
1 parent 6f7ee6b commit 0de6547

File tree

2 files changed

+50
-39
lines changed

2 files changed

+50
-39
lines changed

eng/common/scripts/Helpers/PSModule-Helpers.ps1

+37-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
$global:CurrentUserModulePath = ""
22

3-
function Update-PSModulePathForCI()
4-
{
3+
function Update-PSModulePathForCI() {
54
# Information on PSModulePath taken from docs
65
# https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_psmodulepath
76

@@ -11,7 +10,8 @@ function Update-PSModulePathForCI()
1110
if ($IsWindows) {
1211
$hostedAgentModulePath = $env:SystemDrive + "\Modules"
1312
$moduleSeperator = ";"
14-
} else {
13+
}
14+
else {
1515
$hostedAgentModulePath = "/usr/share"
1616
$moduleSeperator = ":"
1717
}
@@ -55,19 +55,30 @@ function Get-ModuleRepositories([string]$moduleName) {
5555

5656
$repoUrls = if ($packageFeedOverrides.Contains("${moduleName}")) {
5757
@($packageFeedOverrides["${moduleName}"], $DefaultPSRepositoryUrl)
58-
} else {
58+
}
59+
else {
5960
@($DefaultPSRepositoryUrl)
6061
}
6162

6263
return $repoUrls
6364
}
6465

6566
function moduleIsInstalled([string]$moduleName, [string]$version) {
66-
$modules = (Get-Module -ListAvailable $moduleName)
67+
if (-not (Test-Path variable:script:InstalledModules)) {
68+
$script:InstalledModules = @{}
69+
}
70+
71+
if ($script:InstalledModules.ContainsKey("${moduleName}")) {
72+
$modules = $script:InstalledModules["${moduleName}"]
73+
}
74+
else {
75+
$modules = (Get-Module -ListAvailable $moduleName)
76+
$script:InstalledModules["${moduleName}"] = $modules
77+
}
78+
6779
if ($version -as [Version]) {
6880
$modules = $modules.Where({ [Version]$_.Version -ge [Version]$version })
69-
if ($modules.Count -gt 0)
70-
{
81+
if ($modules.Count -gt 0) {
7182
Write-Host "Using module $($modules[0].Name) with version $($modules[0].Version)."
7283
return $modules[0]
7384
}
@@ -77,8 +88,7 @@ function moduleIsInstalled([string]$moduleName, [string]$version) {
7788

7889
function installModule([string]$moduleName, [string]$version, $repoUrl) {
7990
$repo = (Get-PSRepository).Where({ $_.SourceLocation -eq $repoUrl })
80-
if ($repo.Count -eq 0)
81-
{
91+
if ($repo.Count -eq 0) {
8292
Register-PSRepository -Name $repoUrl -SourceLocation $repoUrl -InstallationPolicy Trusted | Out-Null
8393
$repo = (Get-PSRepository).Where({ $_.SourceLocation -eq $repoUrl })
8494
if ($repo.Count -eq 0) {
@@ -102,17 +112,26 @@ function installModule([string]$moduleName, [string]$version, $repoUrl) {
102112
throw "Failed to install module $moduleName with version $version"
103113
}
104114

115+
$script:InstalledModules["${moduleName}"] = $modules
116+
105117
# Unregister repository as it can cause overlap issues with `dotnet tool install`
106118
# commands using the same devops feed
107119
Unregister-PSRepository -Name $repoUrl | Out-Null
108120

109121
return $modules[0]
110122
}
111123

124+
function InstallAndImport-ModuleIfNotInstalled([string]$module, [string]$version) {
125+
if ($null -eq (moduleIsInstalled $module $version)) {
126+
Install-ModuleIfNotInstalled -WhatIf:$false $module $version | Import-Module
127+
} elseif (!(Get-Module -Name $module)) {
128+
Import-Module $module
129+
}
130+
}
131+
112132
# Manual test at eng/common-tests/psmodule-helpers/Install-Module-Parallel.ps1
113133
# If we want to use another default repository other then PSGallery we can update the default parameters
114-
function Install-ModuleIfNotInstalled()
115-
{
134+
function Install-ModuleIfNotInstalled() {
116135
[CmdletBinding(SupportsShouldProcess = $true)]
117136
param(
118137
[string]$moduleName,
@@ -137,12 +156,14 @@ function Install-ModuleIfNotInstalled()
137156
foreach ($url in $repoUrls) {
138157
try {
139158
$module = installModule -moduleName $moduleName -version $version -repoUrl $url
140-
} catch {
159+
}
160+
catch {
141161
if ($url -ne $repoUrls[-1]) {
142162
Write-Warning "Failed to install powershell module from '$url'. Retrying with fallback repository"
143163
Write-Warning $_
144164
continue
145-
} else {
165+
}
166+
else {
146167
Write-Warning "Failed to install powershell module from $url"
147168
throw
148169
}
@@ -151,13 +172,14 @@ function Install-ModuleIfNotInstalled()
151172
}
152173

153174
Write-Host "Using module '$($module.Name)' with version '$($module.Version)'."
154-
} finally {
175+
}
176+
finally {
155177
$mutex.ReleaseMutex()
156178
}
157179

158180
return $module
159181
}
160182

161183
if ($null -ne $env:SYSTEM_TEAMPROJECTID) {
162-
Update-PSModulePathForCI
184+
Update-PSModulePathForCI
163185
}

eng/common/scripts/Helpers/Package-Helpers.ps1

+13-24
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ function GetDocsTocDisplayName($pkg) {
4646
return $displayName
4747
}
4848

49-
5049
<#
5150
.SYNOPSIS
5251
This function is a safe wrapper around `yq` and `ConvertFrom-Yaml` to convert YAML content to a PowerShell HashTable object
@@ -68,28 +67,18 @@ Get-Content -Raw path/to/file.yml | CompatibleConvertFrom-Yaml
6867
#>
6968
function CompatibleConvertFrom-Yaml {
7069
param(
71-
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
70+
[Parameter(Mandatory = $true, ValueFromPipeline = $true)]
7271
[string]$Content
7372
)
7473

7574
if (!($Content)) {
7675
throw "Content to parse is a required input."
7776
}
7877

79-
# Initialize any variables or checks that need to be done once
80-
$yqPresent = Get-Command 'yq' -ErrorAction SilentlyContinue
81-
if (-not $yqPresent) {
82-
. (Join-Path $PSScriptRoot PSModule-Helpers.ps1)
83-
Install-ModuleIfNotInstalled -WhatIf:$false "powershell-yaml" "0.4.7" | Import-Module
84-
}
78+
. (Join-Path $PSScriptRoot PSModule-Helpers.ps1)
79+
InstallAndImport-ModuleIfNotInstalled "powershell-yaml" "0.4.7"
8580

86-
# Process the content (for example, you could convert from YAML here)
87-
if ($yqPresent) {
88-
return ($content | yq -o=json | ConvertFrom-Json -AsHashTable)
89-
}
90-
else {
91-
return ConvertFrom-Yaml $content
92-
}
81+
return ConvertFrom-Yaml $content
9382
}
9483

9584
<#
@@ -114,7 +103,7 @@ LoadFrom-Yaml -YmlFile path/to/file.yml
114103
#>
115104
function LoadFrom-Yaml {
116105
param(
117-
[Parameter(Mandatory=$true)]
106+
[Parameter(Mandatory = $true)]
118107
[string]$YmlFile
119108
)
120109
if (Test-Path -Path $YmlFile) {
@@ -159,19 +148,19 @@ GetValueSafelyFrom-Yaml -YamlContentAsHashtable $YmlFileContent -Keys @("extends
159148
#>
160149
function GetValueSafelyFrom-Yaml {
161150
param(
162-
[Parameter(Mandatory=$true)]
151+
[Parameter(Mandatory = $true)]
163152
$YamlContentAsHashtable,
164-
[Parameter(Mandatory=$true)]
153+
[Parameter(Mandatory = $true)]
165154
[string[]]$Keys
166155
)
167156
$current = $YamlContentAsHashtable
168157
foreach ($key in $Keys) {
169-
if ($current.ContainsKey($key) -or $current[$key]) {
170-
$current = $current[$key]
171-
}
172-
else {
173-
return $null
174-
}
158+
if ($current.ContainsKey($key) -or $current[$key]) {
159+
$current = $current[$key]
160+
}
161+
else {
162+
return $null
163+
}
175164
}
176165

177166
return [object]$current

0 commit comments

Comments
 (0)