Skip to content

Commit

Permalink
!deploy v0.2.0 release (#14)
Browse files Browse the repository at this point in the history
## 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.
  • Loading branch information
scrthq authored Sep 3, 2019
2 parents 418bcf3 + 2726490 commit 72efe9e
Show file tree
Hide file tree
Showing 27 changed files with 1,152 additions and 229 deletions.
3 changes: 3 additions & 0 deletions .gitconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[alias]
addup = !git remote add upstream https://github.com/scrthq/PSProfile.git
syncup = !git fetch upstream && git checkout master && git merge upstream/master
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
* [PSProfile - ChangeLog](#psprofile---changelog)
* [0.2.0 - 2019-09-02](#020---2019-09-02)
* [0.1.9 - 2019-08-26](#019---2019-08-26)
* [0.1.8 - 2019-08-26](#018---2019-08-26)
* [0.1.7 - 2019-08-25](#017---2019-08-25)
Expand All @@ -14,6 +15,31 @@

# PSProfile - ChangeLog

## 0.2.0 - 2019-09-02

* [Issue #2](https://github.com/scrthq/PSProfile/issues/2)
* Added special module import process when the `ModuleToImport` is `EditorServicesCommandSuite` so it also automatically registers the available editor commands.
* [Issue #12](https://github.com/scrthq/PSProfile/issues/12)
* Added `Start-PSProfileConfigurationHelper` to provide an easy way to get started with configuring your PSProfile.
* [Issue #6](https://github.com/scrthq/PSProfile/issues/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.

## 0.1.9 - 2019-08-26

* Renamed `Copy-DynamicParameters` to `Copy-Parameters` for correctness and cleaned up approach for building the ParameterDictionary.
Expand Down
22 changes: 22 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* [Contributing to PSProfile](#contributing-to-psprofile)
* [Git and Pull requests](#git-and-pull-requests)
* [Recommendations](#recommendations)
* [Overview](#overview)
* [Step by Step (High-Level)](#step-by-step-high-level)
* [Contributing Guidelines](#contributing-guidelines)
Expand All @@ -20,6 +21,27 @@ Thank you for your interest in helping PSProfile grow! Below you'll find some gu
* 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/)
* 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)

## Recommendations

To provide the easiest PSProfile development experience while ensuring normal consoles remain intact, it is recommended to add the following to your PowerShell profile:

```powershell
$module = if (Test-Path '.\BuildOutput\PSProfile') {
try {
Import-Module '.\BuildOutput\PSProfile' -ErrorAction Stop
}
catch {
Write-Warning "Error(s) when importing PSProfile from the BuildOutput folder:`n$($Error[0])`nFalling back to installed version"
Import-Module PSProfile
}
}
else {
Import-Module PSProfile
}
```

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.

## Overview

### Step by Step (High-Level)
Expand Down
235 changes: 166 additions & 69 deletions PSProfile/Classes/PSProfile.Classes.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -119,49 +119,7 @@ class PSProfile {
$this.GitPathMap = @{ }
$this.PSBuildPathMap = @{ }
$this.SymbolicLinks = @{ }
$this.Prompts = @{
Default = '"PS $($executionContext.SessionState.Path.CurrentLocation)$(">" * ($nestedPromptLevel + 1)) ";
# .Link
# https://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml'
SCRTHQ = '$lastStatus = $?
$lastColor = if ($lastStatus -eq $true) {
"Green"
}
else {
"Red"
}
Write-Host "[" -NoNewline
Write-Host -ForegroundColor Cyan "#$($MyInvocation.HistoryId)" -NoNewline
Write-Host "] " -NoNewline
Write-Host "[" -NoNewLine
$verColor = @{
ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) {
"Yellow"
}
elseif ($PSVersionTable.PSVersion.Major -eq 6) {
"Magenta"
}
else {
"Cyan"
}
}
Write-Host @verColor ("PS {0}" -f (Get-PSVersion)) -NoNewline
Write-Host "] " -NoNewline
Write-Host "[" -NoNewline
Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-LastCommandDuration)) -NoNewline
Write-Host "] [" -NoNewline
Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow
Write-Host "]" -NoNewline
if ($PWD.Path -notlike "\\*" -and $env:DisablePoshGit -ne $true -and (Test-IfGit)) {
Write-VcsStatus
$GitPromptSettings.EnableWindowTitle = "PS {0} @" -f (Get-PSVersion)
}
else {
$Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion)
}
"`n>> "'
}
$this.Prompts = @{ }
$this.Variables = @{
Environment = @{
Home = [System.Environment]::GetFolderPath([System.Environment+SpecialFolder]::UserProfile)
Expand All @@ -174,9 +132,26 @@ class PSProfile {
}
}
$this.Settings = @{
DefaultPrompt = $null
PSVersionStringLength = 3
ConfigurationPath = (Join-Path (Get-ConfigurationPath -CompanyName 'SCRT HQ' -Name PSProfile) 'Configuration.psd1')
DefaultPrompt = $null
PSVersionStringLength = 3
ConfigurationPath = (Join-Path (Get-ConfigurationPath -CompanyName 'SCRT HQ' -Name PSProfile) 'Configuration.psd1')
FontType = 'Default'
PromptCharacters = @{
GitRepo = @{
NerdFonts = "$([char]0xf418)"
PowerLine = "$([char]0xe0a0)"
Default = "@"
}
AWS = @{
NerdFonts = "$([char]0xf270)"
PowerLine = "$([char]0xf0e7)"
Default = "AWS: "
}
}
PSReadline = @{
Options = @{}
KeyHandlers = @{}
}
}
$this.RefreshFrequency = (New-TimeSpan -Hours 1).ToString()
$this.LastRefresh = [datetime]::Now.AddHours(-2)
Expand All @@ -197,21 +172,79 @@ class PSProfile {
"Debug"
)
$this._loadConfiguration()
$plugPaths = @()
$this.Prompts['SCRTHQ'] = '$lastStatus = $?
$lastColor = if ($lastStatus -eq $true) {
"Green"
}
else {
"Red"
}
$isAdmin = $false
$isDesktop = ($PSVersionTable.PSVersion.Major -eq 5)
if ($isDesktop -or $IsWindows) {
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$windowsPrincipal = New-Object "System.Security.Principal.WindowsPrincipal" $windowsIdentity
$isAdmin = $windowsPrincipal.IsInRole("Administrators") -eq 1
} else {
$isAdmin = ((& id -u) -eq 0)
}
if ($isAdmin) {
$idColor = "Magenta"
}
else {
$idColor = "Cyan"
}
Write-Host "[" -NoNewline
Write-Host -ForegroundColor $idColor "#$($MyInvocation.HistoryId)" -NoNewline
Write-Host "] [" -NoNewline
$verColor = @{
ForegroundColor = if ($PSVersionTable.PSVersion.Major -eq 7) {
"Yellow"
}
elseif ($PSVersionTable.PSVersion.Major -eq 6) {
"Magenta"
}
else {
"Cyan"
}
}
Write-Host @verColor ("PS {0}" -f (Get-PSVersion)) -NoNewline
Write-Host "] [" -NoNewline
Write-Host -ForegroundColor $lastColor ("{0}" -f (Get-LastCommandDuration)) -NoNewline
Write-Host "] [" -NoNewline
Write-Host ("{0}" -f $(Get-PathAlias)) -NoNewline -ForegroundColor DarkYellow
if ((Get-Location -Stack).Count -gt 0) {
Write-Host (("+" * ((Get-Location -Stack).Count))) -NoNewLine -ForegroundColor Cyan
}
Write-Host "]" -NoNewline
if ($PWD.Path -notlike "\\*" -and $env:DisablePoshGit -ne $true) {
Write-VcsStatus
$GitPromptSettings.EnableWindowTitle = "PS {0} @" -f (Get-PSVersion)
}
else {
$Host.UI.RawUI.WindowTitle = "PS {0}" -f (Get-PSVersion)
}
if ($env:AWS_PROFILE) {
Write-Host "`n[" -NoNewline
$awsIcon = if ($global:PSProfile.Settings.ContainsKey("FontType")) {
$global:PSProfile.Settings.PromptCharacters.AWS[$global:PSProfile.Settings.FontType]
}
else {
"AWS:"
}
if ([String]::IsNullOrEmpty($awsIcon)) {
$awsIcon = "AWS:"
}
Write-Host -ForegroundColor Yellow "$($awsIcon) $($env:AWS_PROFILE)" -NoNewline
Write-Host "]" -NoNewline
}
"`n>> "'
$plugPaths = @((Join-Path $PSScriptRoot "Plugins"))
$curVer = (Import-Metadata (Join-Path $PSScriptRoot "PSProfile.psd1")).ModuleVersion
$this.PluginPaths | Where-Object { $_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+" } | ForEach-Object {
$this.PluginPaths | Where-Object {-not [string]::IsNullOrEmpty($_) -and ($_ -match "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]$curVer" -or $_ -notmatch "[\/\\](Modules|BuildOutput)[\/\\]PSProfile[\/\\]\d+\.\d+\.\d+") } | ForEach-Object {
$plugPaths += $_
}
@(
$env:PSModulePath.Split([System.IO.Path]::PathSeparator)
(Get-Module PSProfile* | Select-Object -ExpandProperty ModuleBase)
(Join-Path $PSScriptRoot "Plugins")
) | ForEach-Object {
if ($_ -notin $this.PluginPaths) {
$plugPaths += $_
}
}
$this.PluginPaths = $plugPaths
$this.PluginPaths = $plugPaths | Select-Object -Unique
if (-not ($this.Plugins | Where-Object { $_.Name -eq 'PSProfile.PowerTools' })) {
$plugs = @(@{Name = 'PSProfile.PowerTools' })
$this.Plugins | ForEach-Object {
Expand Down Expand Up @@ -244,14 +277,17 @@ class PSProfile {
"MAIN",
"Debug"
)
Write-Host "Loading PSProfile alone took $([Math]::Round($this._internal.ProfileLoadDuration.TotalMilliseconds))ms$withRefresh"
if ($env:ShowPSProfileLoadTime -ne $false) {
Write-Host "Loading PSProfile alone took $([Math]::Round($this._internal.ProfileLoadDuration.TotalMilliseconds))ms$withRefresh"
}
}
[void] Refresh() {
$this._log(
"Refreshing project map, checking for modules to install and creating symbolic links",
"MAIN",
"Verbose"
)
$this._cleanConfig()
$this._findProjects()
$this._installModules()
$this._createSymbolicLinks()
Expand Down Expand Up @@ -280,6 +316,50 @@ class PSProfile {
}
return $content
}
hidden [void] _cleanConfig() {
$this._log(
"SECTION START",
"CleanConfig",
"Debug"
)
foreach ($section in @('ModulesToImport','ModulesToInstall')) {
$this._log(
"[$section] Cleaning section",
"CleanConfig",
"Verbose"
)
[hashtable[]]$final = @()
$this.$section | Where-Object {$_ -is [hashtable] -and $_.Name} | ForEach-Object {
$final += $_
}
$this.$section | Where-Object {$_ -is [string]} | ForEach-Object {
$this._log(
"[$section] Converting module string to hashtable: $_",
"CleanConfig",
"Verbose"
)
$final += @{Name = $_}
}
$this.$section = $final
}
foreach ($section in @('ScriptPaths','PluginPaths','ProjectPaths')) {
$this._log(
"[$section] Cleaning section",
"CleanConfig",
"Verbose"
)
[string[]]$final = @()
$this.$section | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object {
$final += $_
}
$this.$section = $final
}
$this._log(
"SECTION END",
"CleanConfig",
"Debug"
)
}
hidden [void] _loadPrompt() {
$this._log(
"SECTION START",
Expand All @@ -292,7 +372,7 @@ class PSProfile {
"LoadPrompt",
"Verbose"
)
Switch-PSProfilePrompt -Name $this.Settings.DefaultPrompt
$function:prompt = $this.Prompts[$this.Settings.DefaultPrompt]
}
else {
$this._log(
Expand Down Expand Up @@ -642,7 +722,7 @@ class PSProfile {
'Debug'
)
if (-not [string]::IsNullOrEmpty((-join $this.ModulesToInstall))) {
$null = $this.ModulesToInstall | Where-Object {-not [string]::IsNullOrEmpty($_)} | Start-RSJob -Name { "_PSProfile_InstallModule_$($_)" } -VariablesToImport this -ScriptBlock {
$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 {
Param (
[parameter()]
[object]
Expand Down Expand Up @@ -699,7 +779,7 @@ class PSProfile {
'Debug'
)
if (-not [string]::IsNullOrEmpty((-join $this.ModulesToImport))) {
$this.ModulesToImport | Where-Object {-not [string]::IsNullOrEmpty($_)} | ForEach-Object {
$this.ModulesToImport | Where-Object { ($_ -is [hashtable] -and $_.Name) -or ($_ -is [string] -and -not [string]::IsNullOrEmpty($_.Trim())) } | ForEach-Object {
try {
$params = if ($_ -is [string]) {
@{Name = $_ }
Expand All @@ -716,12 +796,25 @@ class PSProfile {
$params.Remove($_)
}
}
Import-Module @params -Global -ErrorAction SilentlyContinue -Verbose:$false
$this._log(
"Module imported: $($params | ConvertTo-Json -Compress)",
'ImportModules',
'Verbose'
)
if ($params.Name -ne 'EditorServicesCommandSuite') {
Import-Module @params -Global -ErrorAction SilentlyContinue -Verbose:$false
$this._log(
"Module imported: $($params | ConvertTo-Json -Compress)",
'ImportModules',
'Verbose'
)
}
elseif ($params.Name -eq 'EditorServicesCommandSuite' -and $psEditor) {
Import-Module EditorServicesCommandSuite -ErrorAction SilentlyContinue -Global -Force -Verbose:$false
# Twice because: https://github.com/SeeminglyScience/EditorServicesCommandSuite/issues/40
Import-Module EditorServicesCommandSuite -ErrorAction SilentlyContinue -Global -Force -Verbose:$false
Import-EditorCommand -Module EditorServicesCommandSuite -Force -Verbose:$false
$this._log(
"Module imported: $($params | ConvertTo-Json -Compress)",
'ImportModules',
'Verbose'
)
}
}
else {
$this._log(
Expand Down Expand Up @@ -776,7 +869,11 @@ class PSProfile {
if ($plugin.ArgumentList) {
$importParams['ArgumentList'] = $plugin.ArgumentList
}
foreach ($plugPath in $this.PluginPaths) {
[string[]]$pathsToSearch = @($this.PluginPaths)
$env:PSModulePath.Split([System.IO.Path]::PathSeparator) | ForEach-Object {
$pathsToSearch += $_
}
foreach ($plugPath in $pathsToSearch) {
$fullPath = [System.IO.Path]::Combine($plugPath,"$($plugin.Name).ps1")
$this._log(
"'$($plugin.Name)' Checking path: $fullPath",
Expand Down
Loading

0 comments on commit 72efe9e

Please sign in to comment.