Skip to content

Commit 72efe9e

Browse files
authored
!deploy v0.2.0 release (#14)
## 0.2.0 - 2019-09-02 * [Issue #2](#2) * Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands. * [Issue #12](#12) * Added `Start-PSProfileConfigurationHelper` to provide an easy way to get started with configuring your PSProfile. * [Issue #6](#6) * Added `PSReadline` key to `$PSProfile.Settings` (Settings management in development still.) * Miscellaneous * Added support for multiple Command Aliases to be removed at once with `Remove-PSProfileCommandAlias`. * Updated default `SCRTHQ` prompt that comes with the module. * Added support for NerdFonts and PowerLine switches on the prompts to switch char sets depending on the FontType. * Added `IncludeVault` switch parameter to `Export-PSProfileConfiguration` to prevent exporting the Secrets Vault by default when creating portable configurations. * Added `_cleanModules()` method to PSProfile class to remove any null or empty values hanging over and convert any string values to the full hashtable value instead. * Cleaned up logic and fixed bugs in the following functions: * `Add-PSProfileModuleToImport` * `Remove-PSProfileModuleToImport` * `Add-PSProfileModuleToInstall` * `Remove-PSProfileModuleToInstall` * `Add-PSProfilePlugin` * Updated CONTRIBUTING.md with snippet to include for PSProfile developers on their PowerShell profile. * Refactored `Get-PSProfilePrompt` to return `$null` if a name is specified but does not exist on the current PSProfile configuration. * Refactored `$PSProfile._loadConfiguration()` to start with the base value of `$Global:PSProfile` if present, otherwise import the existing configuration from file. This is necessary to retain the existing configuration if an action is taken that forces the PSProfile to reload, e.g. adding a new plugin to the configuration. * Updated `$PSProfile._loadPrompt()` method to set the value of `$function:prompt` directly instead of calling `Switch-PSProfilePrompt` to reduce overhead.
2 parents 418bcf3 + 2726490 commit 72efe9e

27 files changed

+1152
-229
lines changed

.gitconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[alias]
2+
addup = !git remote add upstream https://github.com/scrthq/PSProfile.git
3+
syncup = !git fetch upstream && git checkout master && git merge upstream/master

CHANGELOG.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
* [PSProfile - ChangeLog](#psprofile---changelog)
2+
* [0.2.0 - 2019-09-02](#020---2019-09-02)
23
* [0.1.9 - 2019-08-26](#019---2019-08-26)
34
* [0.1.8 - 2019-08-26](#018---2019-08-26)
45
* [0.1.7 - 2019-08-25](#017---2019-08-25)
@@ -14,6 +15,31 @@
1415

1516
# PSProfile - ChangeLog
1617

18+
## 0.2.0 - 2019-09-02
19+
20+
* [Issue #2](https://github.com/scrthq/PSProfile/issues/2)
21+
* Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands.
22+
* [Issue #12](https://github.com/scrthq/PSProfile/issues/12)
23+
* Added `Start-PSProfileConfigurationHelper` to provide an easy way to get started with configuring your PSProfile.
24+
* [Issue #6](https://github.com/scrthq/PSProfile/issues/6)
25+
* Added `PSReadline` key to `$PSProfile.Settings` (Settings management in development still.)
26+
* Miscellaneous
27+
* Added support for multiple Command Aliases to be removed at once with `Remove-PSProfileCommandAlias`.
28+
* Updated default `SCRTHQ` prompt that comes with the module.
29+
* Added support for NerdFonts and PowerLine switches on the prompts to switch char sets depending on the FontType.
30+
* Added `IncludeVault` switch parameter to `Export-PSProfileConfiguration` to prevent exporting the Secrets Vault by default when creating portable configurations.
31+
* Added `_cleanModules()` method to PSProfile class to remove any null or empty values hanging over and convert any string values to the full hashtable value instead.
32+
* Cleaned up logic and fixed bugs in the following functions:
33+
* `Add-PSProfileModuleToImport`
34+
* `Remove-PSProfileModuleToImport`
35+
* `Add-PSProfileModuleToInstall`
36+
* `Remove-PSProfileModuleToInstall`
37+
* `Add-PSProfilePlugin`
38+
* Updated CONTRIBUTING.md with snippet to include for PSProfile developers on their PowerShell profile.
39+
* Refactored `Get-PSProfilePrompt` to return `$null` if a name is specified but does not exist on the current PSProfile configuration.
40+
* Refactored `$PSProfile._loadConfiguration()` to start with the base value of `$Global:PSProfile` if present, otherwise import the existing configuration from file. This is necessary to retain the existing configuration if an action is taken that forces the PSProfile to reload, e.g. adding a new plugin to the configuration.
41+
* Updated `$PSProfile._loadPrompt()` method to set the value of `$function:prompt` directly instead of calling `Switch-PSProfilePrompt` to reduce overhead.
42+
1743
## 0.1.9 - 2019-08-26
1844

1945
* Renamed `Copy-DynamicParameters` to `Copy-Parameters` for correctness and cleaned up approach for building the ParameterDictionary.

CONTRIBUTING.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* [Contributing to PSProfile](#contributing-to-psprofile)
66
* [Git and Pull requests](#git-and-pull-requests)
7+
* [Recommendations](#recommendations)
78
* [Overview](#overview)
89
* [Step by Step (High-Level)](#step-by-step-high-level)
910
* [Contributing Guidelines](#contributing-guidelines)
@@ -20,6 +21,27 @@ Thank you for your interest in helping PSProfile grow! Below you'll find some gu
2021
* Contributions are submitted, reviewed, and accepted using Github pull requests. [Read this article](https://help.github.com/articles/using-pull-requests) for some details. We use the _Fork and Pull_ model, as described there. More info can be found here: [Forking Projects](https://guides.github.com/activities/forking/)
2122
* Please make sure to leave the `Allow edits from maintainers` box checked when submitting PR's so that any edits can be made by maintainers of the repo directly to the source branch and into the same PR. More info can be found here: [Allowing changes to a pull request branch created from a fork](https://help.github.com/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork/#enabling-repository-maintainer-permissions-on-existing-pull-requests)
2223

24+
## Recommendations
25+
26+
To provide the easiest PSProfile development experience while ensuring normal consoles remain intact, it is recommended to add the following to your PowerShell profile:
27+
28+
```powershell
29+
$module = if (Test-Path '.\BuildOutput\PSProfile') {
30+
try {
31+
Import-Module '.\BuildOutput\PSProfile' -ErrorAction Stop
32+
}
33+
catch {
34+
Write-Warning "Error(s) when importing PSProfile from the BuildOutput folder:`n$($Error[0])`nFalling back to installed version"
35+
Import-Module PSProfile
36+
}
37+
}
38+
else {
39+
Import-Module PSProfile
40+
}
41+
```
42+
43+
This will import the most recently built module from the BuildOutput folder if you start your session in the PSProfile repo root (i.e. if you open the project in your default editor). If any errors are hit during module import, fall back to importing the installed version instead to retain access to PowerTools.
44+
2345
## Overview
2446

2547
### Step by Step (High-Level)

PSProfile/Classes/PSProfile.Classes.ps1

Lines changed: 166 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -119,49 +119,7 @@ class PSProfile {
119119
$this.GitPathMap = @{ }
120120
$this.PSBuildPathMap = @{ }
121121
$this.SymbolicLinks = @{ }
122-
$this.Prompts = @{
123-
Default = '"PS $($executionContext.SessionState.Path.CurrentLocation)$(">" * ($nestedPromptLevel + 1)) ";
124-
# .Link
125-
# https://go.microsoft.com/fwlink/?LinkID=225750
126-
# .ExternalHelp System.Management.Automation.dll-help.xml'
127-
SCRTHQ = '$lastStatus = $?
128-
$lastColor = if ($lastStatus -eq $true) {
129-
"Green"
130-
}
131-
else {
132-
"Red"
133-
}
134-
Write-Host "[" -NoNewline
135-
Write-Host -ForegroundColor Cyan "#$($MyInvocation.HistoryId)" -NoNewline
136-
Write-Host "] " -NoNewline
137-
Write-Host "[" -NoNewLine
138-
$verColor = @{
139-
ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) {
140-
"Yellow"
141-
}
142-
elseif ($PSVersionTable.PSVersion.Major -eq 6) {
143-
"Magenta"
144-
}
145-
else {
146-
"Cyan"
147-
}
148-
}
149-
Write-Host @verColor ("PS {0}" -f (Get-PSVersion)) -NoNewline
150-
Write-Host "] " -NoNewline
151-
Write-Host "[" -NoNewline
152-
Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-LastCommandDuration)) -NoNewline
153-
Write-Host "] [" -NoNewline
154-
Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow
155-
Write-Host "]" -NoNewline
156-
if ($PWD.Path -notlike "\\*" -and $env:DisablePoshGit -ne $true -and (Test-IfGit)) {
157-
Write-VcsStatus
158-
$GitPromptSettings.EnableWindowTitle = "PS {0} @" -f (Get-PSVersion)
159-
}
160-
else {
161-
$Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion)
162-
}
163-
"`n>> "'
164-
}
122+
$this.Prompts = @{ }
165123
$this.Variables = @{
166124
Environment = @{
167125
Home = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile)
@@ -174,9 +132,26 @@ class PSProfile {
174132
}
175133
}
176134
$this.Settings = @{
177-
DefaultPrompt = $null
178-
PSVersionStringLength = 3
179-
ConfigurationPath = (Join-Path (Get-ConfigurationPath -CompanyName 'SCRT HQ' -Name PSProfile) 'Configuration.psd1')
135+
DefaultPrompt = $null
136+
PSVersionStringLength = 3
137+
ConfigurationPath = (Join-Path (Get-ConfigurationPath -CompanyName 'SCRT HQ' -Name PSProfile) 'Configuration.psd1')
138+
FontType = 'Default'
139+
PromptCharacters = @{
140+
GitRepo = @{
141+
NerdFonts = "$([char]0xf418)"
142+
PowerLine = "$([char]0xe0a0)"
143+
Default = "@"
144+
}
145+
AWS = @{
146+
NerdFonts = "$([char]0xf270)"
147+
PowerLine = "$([char]0xf0e7)"
148+
Default = "AWS: "
149+
}
150+
}
151+
PSReadline = @{
152+
Options = @{}
153+
KeyHandlers = @{}
154+
}
180155
}
181156
$this.RefreshFrequency = (New-TimeSpan -Hours 1).ToString()
182157
$this.LastRefresh = [datetime]::Now.AddHours(-2)
@@ -197,21 +172,79 @@ class PSProfile {
197172
"Debug"
198173
)
199174
$this._loadConfiguration()
200-
$plugPaths = @()
175+
$this.Prompts['SCRTHQ'] = '$lastStatus = $?
176+
$lastColor = if ($lastStatus -eq $true) {
177+
"Green"
178+
}
179+
else {
180+
"Red"
181+
}
182+
$isAdmin = $false
183+
$isDesktop = ($PSVersionTable.PSVersion.Major -eq 5)
184+
if ($isDesktop -or $IsWindows) {
185+
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
186+
$windowsPrincipal = New-Object "System.Security.Principal.WindowsPrincipal" $windowsIdentity
187+
$isAdmin = $windowsPrincipal.IsInRole("Administrators") -eq 1
188+
} else {
189+
$isAdmin = ((& id -u) -eq 0)
190+
}
191+
if ($isAdmin) {
192+
$idColor = "Magenta"
193+
}
194+
else {
195+
$idColor = "Cyan"
196+
}
197+
Write-Host "[" -NoNewline
198+
Write-Host -ForegroundColor $idColor "#$($MyInvocation.HistoryId)" -NoNewline
199+
Write-Host "] [" -NoNewline
200+
$verColor = @{
201+
ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) {
202+
"Yellow"
203+
}
204+
elseif ($PSVersionTable.PSVersion.Major -eq 6) {
205+
"Magenta"
206+
}
207+
else {
208+
"Cyan"
209+
}
210+
}
211+
Write-Host @verColor ("PS {0}" -f (Get-PSVersion)) -NoNewline
212+
Write-Host "] [" -NoNewline
213+
Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-LastCommandDuration)) -NoNewline
214+
Write-Host "] [" -NoNewline
215+
Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow
216+
if ((Get-Location -Stack).Count -gt 0) {
217+
Write-Host (("+" * ((Get-Location -Stack).Count))) -NoNewLine -ForegroundColor Cyan
218+
}
219+
Write-Host "]" -NoNewline
220+
if ($PWD.Path -notlike "\\*" -and $env:DisablePoshGit -ne $true) {
221+
Write-VcsStatus
222+
$GitPromptSettings.EnableWindowTitle = "PS {0} @" -f (Get-PSVersion)
223+
}
224+
else {
225+
$Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion)
226+
}
227+
if ($env:AWS_PROFILE) {
228+
Write-Host "`n[" -NoNewline
229+
$awsIcon = if ($global:PSProfile.Settings.ContainsKey("FontType")) {
230+
$global:PSProfile.Settings.PromptCharacters.AWS[$global:PSProfile.Settings.FontType]
231+
}
232+
else {
233+
"AWS:"
234+
}
235+
if ([String]::IsNullOrEmpty($awsIcon)) {
236+
$awsIcon = "AWS:"
237+
}
238+
Write-Host -ForegroundColor Yellow "$($awsIcon) $($env:AWS_PROFILE)" -NoNewline
239+
Write-Host "]" -NoNewline
240+
}
241+
"`n>> "'
242+
$plugPaths = @((Join-Path $PSScriptRoot "Plugins"))
201243
$curVer = (Import-Metadata (Join-Path $PSScriptRoot "PSProfile.psd1")).ModuleVersion
202-
$this.PluginPaths | Where-Object { $_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+" } | ForEach-Object {
244+
$this.PluginPaths | Where-Object {-not [string]::IsNullOrEmpty($_) -and ($_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+") } | ForEach-Object {
203245
$plugPaths += $_
204246
}
205-
@(
206-
$env:PSModulePath.Split([System.IO.Path]::PathSeparator)
207-
(Get-Module PSProfile* | Select-Object -ExpandProperty ModuleBase)
208-
(Join-Path $PSScriptRoot "Plugins")
209-
) | ForEach-Object {
210-
if ($_ -notin $this.PluginPaths) {
211-
$plugPaths += $_
212-
}
213-
}
214-
$this.PluginPaths = $plugPaths
247+
$this.PluginPaths = $plugPaths | Select-Object -Unique
215248
if (-not ($this.Plugins | Where-Object { $_.Name -eq 'PSProfile.PowerTools' })) {
216249
$plugs = @(@{Name = 'PSProfile.PowerTools' })
217250
$this.Plugins | ForEach-Object {
@@ -244,14 +277,17 @@ class PSProfile {
244277
"MAIN",
245278
"Debug"
246279
)
247-
Write-Host "Loading PSProfile alone took $([Math]::Round($this._internal.ProfileLoadDuration.TotalMilliseconds))ms$withRefresh"
280+
if ($env:ShowPSProfileLoadTime -ne $false) {
281+
Write-Host "Loading PSProfile alone took $([Math]::Round($this._internal.ProfileLoadDuration.TotalMilliseconds))ms$withRefresh"
282+
}
248283
}
249284
[void] Refresh() {
250285
$this._log(
251286
"Refreshing project map, checking for modules to install and creating symbolic links",
252287
"MAIN",
253288
"Verbose"
254289
)
290+
$this._cleanConfig()
255291
$this._findProjects()
256292
$this._installModules()
257293
$this._createSymbolicLinks()
@@ -280,6 +316,50 @@ class PSProfile {
280316
}
281317
return $content
282318
}
319+
hidden [void] _cleanConfig() {
320+
$this._log(
321+
"SECTION START",
322+
"CleanConfig",
323+
"Debug"
324+
)
325+
foreach ($section in @('ModulesToImport','ModulesToInstall')) {
326+
$this._log(
327+
"[$section] Cleaning section",
328+
"CleanConfig",
329+
"Verbose"
330+
)
331+
[hashtable[]]$final = @()
332+
$this.$section | Where-Object {$_ -is [hashtable] -and $_.Name} | ForEach-Object {
333+
$final += $_
334+
}
335+
$this.$section | Where-Object {$_ -is [string]} | ForEach-Object {
336+
$this._log(
337+
"[$section] Converting module string to hashtable: $_",
338+
"CleanConfig",
339+
"Verbose"
340+
)
341+
$final += @{Name = $_}
342+
}
343+
$this.$section = $final
344+
}
345+
foreach ($section in @('ScriptPaths','PluginPaths','ProjectPaths')) {
346+
$this._log(
347+
"[$section] Cleaning section",
348+
"CleanConfig",
349+
"Verbose"
350+
)
351+
[string[]]$final = @()
352+
$this.$section | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object {
353+
$final += $_
354+
}
355+
$this.$section = $final
356+
}
357+
$this._log(
358+
"SECTION END",
359+
"CleanConfig",
360+
"Debug"
361+
)
362+
}
283363
hidden [void] _loadPrompt() {
284364
$this._log(
285365
"SECTION START",
@@ -292,7 +372,7 @@ class PSProfile {
292372
"LoadPrompt",
293373
"Verbose"
294374
)
295-
Switch-PSProfilePrompt -Name $this.Settings.DefaultPrompt
375+
$function:prompt = $this.Prompts[$this.Settings.DefaultPrompt]
296376
}
297377
else {
298378
$this._log(
@@ -642,7 +722,7 @@ class PSProfile {
642722
'Debug'
643723
)
644724
if (-not [string]::IsNullOrEmpty((-join $this.ModulesToInstall))) {
645-
$null = $this.ModulesToInstall | Where-Object {-not [string]::IsNullOrEmpty($_)} | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock {
725+
$null = $this.ModulesToInstall | Where-Object { ($_ -is [hashtable] -and $_.Name) -or ($_ -is [string] -and -not [string]::IsNullOrEmpty($_.Trim())) } | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock {
646726
Param (
647727
[parameter()]
648728
[object]
@@ -699,7 +779,7 @@ class PSProfile {
699779
'Debug'
700780
)
701781
if (-not [string]::IsNullOrEmpty((-join $this.ModulesToImport))) {
702-
$this.ModulesToImport | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object {
782+
$this.ModulesToImport | Where-Object { ($_ -is [hashtable] -and $_.Name) -or ($_ -is [string] -and -not [string]::IsNullOrEmpty($_.Trim())) } | ForEach-Object {
703783
try {
704784
$params = if ($_ -is [string]) {
705785
@{Name = $_ }
@@ -716,12 +796,25 @@ class PSProfile {
716796
$params.Remove($_)
717797
}
718798
}
719-
Import-Module @params -Global -ErrorAction SilentlyContinue -Verbose:$false
720-
$this._log(
721-
"Module imported: $($params | ConvertTo-Json -Compress)",
722-
'ImportModules',
723-
'Verbose'
724-
)
799+
if ($params.Name -ne 'EditorServicesCommandSuite') {
800+
Import-Module @params -Global -ErrorAction SilentlyContinue -Verbose:$false
801+
$this._log(
802+
"Module imported: $($params | ConvertTo-Json -Compress)",
803+
'ImportModules',
804+
'Verbose'
805+
)
806+
}
807+
elseif ($params.Name -eq 'EditorServicesCommandSuite' -and $psEditor) {
808+
Import-Module EditorServicesCommandSuite -ErrorAction SilentlyContinue -Global -Force -Verbose:$false
809+
# Twice because: https://github.com/SeeminglyScience/EditorServicesCommandSuite/issues/40
810+
Import-Module EditorServicesCommandSuite -ErrorAction SilentlyContinue -Global -Force -Verbose:$false
811+
Import-EditorCommand -Module EditorServicesCommandSuite -Force -Verbose:$false
812+
$this._log(
813+
"Module imported: $($params | ConvertTo-Json -Compress)",
814+
'ImportModules',
815+
'Verbose'
816+
)
817+
}
725818
}
726819
else {
727820
$this._log(
@@ -776,7 +869,11 @@ class PSProfile {
776869
if ($plugin.ArgumentList) {
777870
$importParams['ArgumentList'] = $plugin.ArgumentList
778871
}
779-
foreach ($plugPath in $this.PluginPaths) {
872+
[string[]]$pathsToSearch = @($this.PluginPaths)
873+
$env:PSModulePath.Split([System.IO.Path]::PathSeparator) | ForEach-Object {
874+
$pathsToSearch += $_
875+
}
876+
foreach ($plugPath in $pathsToSearch) {
780877
$fullPath = [System.IO.Path]::Combine($plugPath,"$($plugin.Name).ps1")
781878
$this._log(
782879
"'$($plugin.Name)' Checking path: $fullPath",

0 commit comments

Comments
 (0)