diff --git a/PSProfile/Classes/PSProfile.Classes.ps1 b/PSProfile/Classes/PSProfile.Classes.ps1 index 641e4a5..ee76865 100644 --- a/PSProfile/Classes/PSProfile.Classes.ps1 +++ b/PSProfile/Classes/PSProfile.Classes.ps1 @@ -72,6 +72,7 @@ class PSProfile { [hashtable] $Prompts [hashtable] $InitScripts [string[]] $ScriptPaths + [string[]] $ConfigurationPaths [hashtable] $SymbolicLinks [hashtable] $Variables [hashtable] $Vault @@ -85,11 +86,7 @@ class PSProfile { $this.SymbolicLinks = @{ } $this.Prompts = @{ } $this.Variables = @{ - Environment = @{ - Home = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) - UserName = [System.Environment]::UserName - ComputerName = [System.Environment]::MachineName - } + Environment = @{} Global = @{ PathAliasDirectorySeparator = "$([System.IO.Path]::DirectorySeparatorChar)" AltPathAliasDirectorySeparator = "$([char]0xe0b1)" @@ -124,6 +121,7 @@ class PSProfile { $this.PluginPaths = @() $this.InitScripts = @{ } $this.ScriptPaths = @() + $this.ConfigurationPaths = @() $this.PathAliases = @{ '~' = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) } @@ -237,6 +235,11 @@ if ($env:AWS_PROFILE) { $this._setVariables() $this._setCommandAliases() $this._loadPrompt() + + $this.Variables['Environment']['Home'] = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile) + $this.Variables['Environment']['UserName'] = [System.Environment]::UserName + $this.Variables['Environment']['ComputerName'] = [System.Environment]::MachineName + $this._internal['ProfileLoadEnd'] = [datetime]::Now $this._internal['ProfileLoadDuration'] = $this._internal.ProfileLoadEnd - $this._internal.ProfileLoadStart $this._log( @@ -460,6 +463,13 @@ if ($env:AWS_PROFILE) { "Verbose" ) $this | Update-Object $conf + if ($this.ConfigurationPaths.Count) { + $this.ConfigurationPaths | ForEach-Object { + if (Test-Path $_) { + $this._loadAdditionalConfiguration($_) + } + } + } $this._log( "SECTION END", "Configuration", diff --git a/PSProfile/Public/Configuration/Add-PSProfileConfigurationPath.ps1 b/PSProfile/Public/Configuration/Add-PSProfileConfigurationPath.ps1 new file mode 100644 index 0000000..f77786b --- /dev/null +++ b/PSProfile/Public/Configuration/Add-PSProfileConfigurationPath.ps1 @@ -0,0 +1,55 @@ +function Add-PSProfileConfigurationPath { + <# + .SYNOPSIS + Adds a ConfigurationPath to your PSProfile to import during PSProfile load. + + .DESCRIPTION + Adds a ConfigurationPath to your PSProfile to import during PSProfile load. Useful for synced configurations. + + .PARAMETER Path + The path of the script to add to your $PSProfile.ConfigurationPaths. + + .PARAMETER Save + If $true, saves the updated PSProfile after updating. + + .EXAMPLE + Add-PSProfileConfigurationPath -Path ~\SyncConfiguration.psd1 -Save + + Adds the configuration 'SyncConfiguration.ps1' to $PSProfile.ConfigurationPaths and saves the configuration after updating. + + .EXAMPLE + Get-ChildItem .\PSProfileConfigurations -Recurse -File | Add-PSProfileConfigurationPath -Verbose + + Adds all psd1 files under the PSProfileConfigurations folder to $PSProfile.ConfigurationPaths but does not save to allow inspection. Call Save-PSProfile after to save the results if satisfied. + #> + [CmdletBinding()] + Param ( + [Parameter(Mandatory,Position = 0,ValueFromPipeline,ValueFromPipelineByPropertyName)] + [Alias('FullName')] + [String[]] + $Path, + [Parameter()] + [Switch] + $Save + ) + Process { + foreach ($p in $Path) { + if ($p -match '\.psd1$') { + $fP = (Resolve-Path $p).Path + if ($Global:PSProfile.ConfigurationPaths -notcontains $fP) { + Write-Verbose "Adding ConfigurationPath to PSProfile: $fP" + $Global:PSProfile.ConfigurationPaths += $fP + } + else { + Write-Verbose "ConfigurationPath already in PSProfile: $fP" + } + } + else { + Write-Verbose "Skipping non-psd1 file: $fP" + } + } + if ($Save) { + Save-PSProfile + } + } +} diff --git a/PSProfile/Public/Configuration/Get-PSProfileConfigurationPath.ps1 b/PSProfile/Public/Configuration/Get-PSProfileConfigurationPath.ps1 new file mode 100644 index 0000000..b532037 --- /dev/null +++ b/PSProfile/Public/Configuration/Get-PSProfileConfigurationPath.ps1 @@ -0,0 +1,45 @@ +function Get-PSProfileConfigurationPath { + <# + .SYNOPSIS + Gets a configuration path from $PSProfile.ConfigurationPaths. + + .DESCRIPTION + Gets a configuration path from $PSProfile.ConfigurationPaths. + + .PARAMETER Path + The configuration path to get from $PSProfile.ConfigurationPaths. + + .EXAMPLE + Get-PSProfileConfigurationPath -Path E:\Git\MyPSProfileConfig.psd1 + + Gets the path 'E:\Git\MyPSProfileConfig.psd1' from $PSProfile.ConfigurationPaths + + .EXAMPLE + Get-PSProfileConfigurationPath + + Gets the list of configuration paths from $PSProfile.ConfigurationPaths + #> + [CmdletBinding()] + Param ( + [Parameter(Position = 0,ValueFromPipeline)] + [String[]] + $Path + ) + Process { + if ($PSBoundParameters.ContainsKey('Path')) { + Write-Verbose "Getting configuration path '$Path' from `$PSProfile.ConfigurationPaths" + $Global:PSProfile.ConfigurationPaths | Where-Object {$_ -match "($(($Path | ForEach-Object {[regex]::Escape($_)}) -join '|'))"} + } + else { + Write-Verbose "Getting all configuration paths from `$PSProfile.ConfigurationPaths" + $Global:PSProfile.ConfigurationPaths + } + } +} + +Register-ArgumentCompleter -CommandName Get-PSProfileConfigurationPath -ParameterName Path -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) + $Global:PSProfile.ConfigurationPaths | Where-Object {$_ -like "$wordToComplete*"} | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} diff --git a/PSProfile/Public/Configuration/Remove-PSProfileConfigurationPath.ps1 b/PSProfile/Public/Configuration/Remove-PSProfileConfigurationPath.ps1 new file mode 100644 index 0000000..4155854 --- /dev/null +++ b/PSProfile/Public/Configuration/Remove-PSProfileConfigurationPath.ps1 @@ -0,0 +1,45 @@ +function Remove-PSProfileConfigurationPath { + <# + .SYNOPSIS + Removes a configuration path from $PSProfile.ConfigurationPaths. + + .DESCRIPTION + Removes a configuration path from $PSProfile.ConfigurationPaths. + + .PARAMETER Path + The path to remove from $PSProfile.ConfigurationPaths. + + .PARAMETER Save + If $true, saves the updated PSProfile after updating. + + .EXAMPLE + Remove-PSProfileConfigurationPath -Name ~\PSProfile\MyConfig.psd1 -Save + + Removes the path '~\PSProfile\MyConfig.psd1' from $PSProfile.ConfigurationPaths then saves the updated configuration. + #> + [CmdletBinding(SupportsShouldProcess,ConfirmImpact = "High")] + Param ( + [Parameter(Mandatory,Position = 0,ValueFromPipeline)] + [String] + $Path, + [Parameter()] + [Switch] + $Save + ) + Process { + if ($PSCmdlet.ShouldProcess("Removing '$Path' from `$PSProfile.ConfigurationPaths")) { + Write-Verbose "Removing '$Path' from `$PSProfile.ConfigurationPaths" + $Global:PSProfile.ConfigurationPaths = $Global:PSProfile.ConfigurationPaths | Where-Object {$_ -notin @($Path,(Resolve-Path $Path).Path)} + if ($Save) { + Save-PSProfile + } + } + } +} + +Register-ArgumentCompleter -CommandName Remove-PSProfileConfigurationPath -ParameterName Path -ScriptBlock { + param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) + $Global:PSProfile.ConfigurationPaths | Where-Object {$_ -like "$wordToComplete*"} | ForEach-Object { + [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) + } +} diff --git a/PSProfile/Public/Plugin Paths/Get-PSProfilePluginPath.ps1 b/PSProfile/Public/Plugin Paths/Get-PSProfilePluginPath.ps1 index 4cfecb5..01d0eea 100644 --- a/PSProfile/Public/Plugin Paths/Get-PSProfilePluginPath.ps1 +++ b/PSProfile/Public/Plugin Paths/Get-PSProfilePluginPath.ps1 @@ -28,7 +28,7 @@ function Get-PSProfilePluginPath { Process { if ($PSBoundParameters.ContainsKey('Path')) { Write-Verbose "Getting plugin path '$Path' from `$PSProfile.PluginPaths" - $Global:PSProfile.PluginPaths | Where-Object {$_ -in $Path} + $Global:PSProfile.PluginPaths | Where-Object {$_ -match "($(($Path | ForEach-Object {[regex]::Escape($_)}) -join '|'))"} } else { Write-Verbose "Getting all plugin paths from `$PSProfile.PluginPaths" diff --git a/PSProfile/Public/Project Paths/Get-PSProfileProjectPath.ps1 b/PSProfile/Public/Project Paths/Get-PSProfileProjectPath.ps1 index 9d49b17..4b3f9f5 100644 --- a/PSProfile/Public/Project Paths/Get-PSProfileProjectPath.ps1 +++ b/PSProfile/Public/Project Paths/Get-PSProfileProjectPath.ps1 @@ -28,7 +28,7 @@ function Get-PSProfileProjectPath { Process { if ($PSBoundParameters.ContainsKey('Path')) { Write-Verbose "Getting project path '$Path' from `$PSProfile.ProjectPaths" - $Global:PSProfile.ProjectPaths | Where-Object {$_ -in $Path} + $Global:PSProfile.ProjectPaths | Where-Object {$_ -match "($(($Path | ForEach-Object {[regex]::Escape($_)}) -join '|'))"} } else { Write-Verbose "Getting all project paths from `$PSProfile.ProjectPaths" diff --git a/PSProfile/Public/Script Paths/Add-PSProfileScriptPath.ps1 b/PSProfile/Public/Script Paths/Add-PSProfileScriptPath.ps1 index 9beda06..8c552c4 100644 --- a/PSProfile/Public/Script Paths/Add-PSProfileScriptPath.ps1 +++ b/PSProfile/Public/Script Paths/Add-PSProfileScriptPath.ps1 @@ -12,9 +12,6 @@ function Add-PSProfileScriptPath { .PARAMETER Invoke If $true, invokes the script path after adding to $PSProfile.ScriptPaths to make it immediately available in the current session. - .PARAMETER Invoke - If $true, invokes the script at the path specified to load it into the current session. - .PARAMETER Save If $true, saves the updated PSProfile after updating. diff --git a/PSProfile/Public/Script Paths/Get-PSProfileScriptPath.ps1 b/PSProfile/Public/Script Paths/Get-PSProfileScriptPath.ps1 index 5822ca6..929ae9c 100644 --- a/PSProfile/Public/Script Paths/Get-PSProfileScriptPath.ps1 +++ b/PSProfile/Public/Script Paths/Get-PSProfileScriptPath.ps1 @@ -28,7 +28,7 @@ function Get-PSProfileScriptPath { Process { if ($PSBoundParameters.ContainsKey('Path')) { Write-Verbose "Getting script path '$Path' from `$PSProfile.ScriptPaths" - $Global:PSProfile.ScriptPaths | Where-Object {$_ -in $Path} + $Global:PSProfile.ScriptPaths | Where-Object {$_ -match "($(($Path | ForEach-Object {[regex]::Escape($_)}) -join '|'))"} } else { Write-Verbose "Getting all script paths from `$PSProfile.ScriptPaths" diff --git a/build.ps1 b/build.ps1 index 9c3bb2b..adedb41 100644 --- a/build.ps1 +++ b/build.ps1 @@ -36,16 +36,19 @@ $helperUri = @( 'scrthq' # User 'a99cc06e75eb31769d01b2adddc6d200' # Gist ID 'raw' - 'ca1b0def9321dc5a71b9092d34e91180720eda2d' # Commit SHA + '10d6ab6de6aa3f35c94acb7707970fe0ee755aa6' # Commit SHA 'AzurePipelineHelpers.ps1' # Filename ) -join '/' $fileUri = $helperUri -replace "[$([RegEx]::Escape("$(([System.IO.Path]::GetInvalidFileNameChars() + [System.IO.Path]::GetInvalidPathChars()) -join '')"))]","_" -$localGistPath = [System.IO.Path]::Combine($PSScriptRoot,'ci',$fileUri) +$ciPath = [System.IO.Path]::Combine($PSScriptRoot,'ci') +$localGistPath = [System.IO.Path]::Combine($ciPath,$fileUri) if (Test-Path $localGistPath) { Write-Host -ForegroundColor Cyan "##[section] Importing Azure Pipelines Helper from Cached Gist: $localGistPath" $helperContent = Get-Content $localGistPath -Raw } else { + Write-Host -ForegroundColor Cyan "##[section] Cleaning out stale Gist scripts from the CI Path" + Get-ChildItem $ciPath -Filter 'https___gist.githubusercontent.com_scrthq*.ps1' | Remove-Item -Force Write-Host -ForegroundColor Cyan "##[section] Importing Azure Pipelines Helper from Gist: $helperUri" $helperContent = Invoke-RestMethod -Uri $helperUri $helperContent | Set-Content $localGistPath -Force diff --git a/invoke.build.ps1 b/invoke.build.ps1 index 6ccdd75..2e40264 100644 --- a/invoke.build.ps1 +++ b/invoke.build.ps1 @@ -96,9 +96,9 @@ task Build Clean,{ $psm1Header | Add-Content -Path $psm1 -Encoding UTF8 foreach ($scope in @('Classes','Private','Public')) { - Write-BuildLog "Copying contents from files in source folder to PSM1: $($scope)" $gciPath = Join-Path $SourceModuleDirectory $scope if (Test-Path $gciPath) { + Write-BuildLog "Copying contents from files in source folder to PSM1: $($scope)" Get-ChildItem -Path $gciPath -Filter "*.ps1" -Recurse -File | ForEach-Object { Write-BuildLog "Working on: $($_.FullName.Replace("$gciPath\",''))" "$(Get-Content $_.FullName -Raw)`n" | Add-Content -Path $psm1 -Encoding UTF8 @@ -180,6 +180,7 @@ task Test Init,{ $parameters = @{ Name = 'Pester' MinimumVersion = '4.8.1' + MaximumVersion = '4.99.99' } Write-BuildLog "[$($parameters.Name)] Resolving" try { @@ -224,14 +225,14 @@ $psGalleryConditions = { -not [String]::IsNullOrEmpty($NextModuleVersion) -and $env:BHBuildSystem -eq 'VSTS' -and $env:BHCommitMessage -match '!deploy' -and - $env:BHBranchName -eq "master" + $env:BHBranchName -in @('master','main') } $gitHubConditions = { -not [String]::IsNullOrEmpty($env:GitHubPAT) -and -not [String]::IsNullOrEmpty($NextModuleVersion) -and $env:BHBuildSystem -eq 'VSTS' -and $env:BHCommitMessage -match '!deploy' -and - $env:BHBranchName -eq "master" + $env:BHBranchName -in @('master','main') } $tweetConditions = { -not [String]::IsNullOrEmpty($env:TwitterAccessSecret) -and @@ -241,7 +242,7 @@ $tweetConditions = { -not [String]::IsNullOrEmpty($NextModuleVersion) -and $env:BHBuildSystem -eq 'VSTS' -and $env:BHCommitMessage -match '!deploy' -and - $env:BHBranchName -eq "master" + $env:BHBranchName -in @('master','main') } task PublishToPSGallery -If $psGalleryConditions {