Skip to content

Commit

Permalink
Sync eng/common directory with azure-sdk-tools for PR 9493 (Azure#32092)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
azure-sdk and scbedd authored Dec 12, 2024
1 parent 79d409b commit 1d41b74
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 39 deletions.
52 changes: 37 additions & 15 deletions eng/common/scripts/Helpers/PSModule-Helpers.ps1
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -11,7 +10,8 @@ function Update-PSModulePathForCI()
if ($IsWindows) {
$hostedAgentModulePath = $env:SystemDrive + "\Modules"
$moduleSeperator = ";"
} else {
}
else {
$hostedAgentModulePath = "/usr/share"
$moduleSeperator = ":"
}
Expand Down Expand Up @@ -55,19 +55,30 @@ function Get-ModuleRepositories([string]$moduleName) {

$repoUrls = if ($packageFeedOverrides.Contains("${moduleName}")) {
@($packageFeedOverrides["${moduleName}"], $DefaultPSRepositoryUrl)
} else {
}
else {
@($DefaultPSRepositoryUrl)
}

return $repoUrls
}

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]
}
Expand All @@ -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) {
Expand All @@ -102,17 +112,26 @@ 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

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,
Expand All @@ -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
}
Expand All @@ -151,13 +172,14 @@ function Install-ModuleIfNotInstalled()
}

Write-Host "Using module '$($module.Name)' with version '$($module.Version)'."
} finally {
}
finally {
$mutex.ReleaseMutex()
}

return $module
}

if ($null -ne $env:SYSTEM_TEAMPROJECTID) {
Update-PSModulePathForCI
Update-PSModulePathForCI
}
37 changes: 13 additions & 24 deletions eng/common/scripts/Helpers/Package-Helpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -68,28 +67,18 @@ 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
)

if (!($Content)) {
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
}

<#
Expand All @@ -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) {
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 1d41b74

Please sign in to comment.