Skip to content

Commit

Permalink
## 0.1.6 - 2019-08-24
Browse files Browse the repository at this point in the history
* Added `Copy-DynamicParameters` to clone DynamicParams from another file or function.
* Updated `Start-BuildScript` in `PSProfile.PowerTools` with better argument completers to enable listing available Tasks and other parameters directly from the build script you are executing.
* Added `Dockerfile` to enable testing in an Ubuntu container.
  • Loading branch information
scrthq committed Aug 25, 2019
1 parent a725e0b commit 3fb8811
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 71 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
* [PSProfile - ChangeLog](#psprofile---changelog)
* [0.1.6 - 2019-08-24](#016---2019-08-24)
* [0.1.5 - 2019-08-22](#015---2019-08-22)
* [0.1.4 - 2019-08-22](#014---2019-08-22)
* [0.1.3 - 2019-08-20](#013---2019-08-20)
Expand All @@ -10,6 +11,12 @@

# PSProfile - ChangeLog

## 0.1.6 - 2019-08-24

* Added `Copy-DynamicParameters` to clone DynamicParams from another file or function.
* Updated `Start-BuildScript` in `PSProfile.PowerTools` with better argument completers to enable listing available Tasks and other parameters directly from the build script you are executing.
* Added `Dockerfile` to enable testing in an Ubuntu container.

## 0.1.5 - 2019-08-22

* Added `Export-PSProfileConfiguration` to export your configuration to a portable file.
Expand Down
10 changes: 10 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM mcr.microsoft.com/powershell:ubuntu-16.04 as base
RUN apt-get update && apt-get install -y git

FROM base as src
LABEL maintainer="nferrell"
LABEL description="PSProfile container for Ubuntu 16.04"
LABEL vendor="scrthq"
COPY [".", "/tmp/PSProfile/"]
WORKDIR /tmp/PSProfile
CMD ["pwsh","-c","./build.ps1","-Task Build,Test"]
2 changes: 1 addition & 1 deletion PSProfile/PSProfile.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'PSProfile.psm1'

# Version number of this module.
ModuleVersion = '0.1.5'
ModuleVersion = '0.1.6'

# Supported PSEditions
CompatiblePSEditions = @('Desktop','Core')
Expand Down
151 changes: 81 additions & 70 deletions PSProfile/Plugins/PSProfile.PowerTools.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,9 @@ function Open-Code {
}
}

if ($null -ne (Get-Command Get-PSProfileArguments*)) {
Register-ArgumentCompleter -CommandName 'Open-Code' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}
Register-ArgumentCompleter -CommandName 'Open-Code' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}

Register-ArgumentCompleter -CommandName 'Open-Code' -ParameterName 'Language' -ScriptBlock {
Expand Down Expand Up @@ -391,11 +389,10 @@ function Open-Item {
}
}

if ($null -ne (Get-Command Get-PSProfileArguments*)) {
Register-ArgumentCompleter -CommandName 'Open-Item' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}

Register-ArgumentCompleter -CommandName 'Open-Item' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}

New-Alias -Name open -Value 'Open-Item' -Scope Global -Option AllScope -Force
Expand Down Expand Up @@ -488,11 +485,9 @@ function Pop-Path {

New-Alias -Name pop -Value Pop-Path -Option AllScope -Scope Global -Force

if ($null -ne (Get-Command Get-PSProfileArguments*)) {
Register-ArgumentCompleter -CommandName 'Push-Path' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}
Register-ArgumentCompleter -CommandName 'Push-Path' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}

function Get-Gist {
Expand Down Expand Up @@ -718,59 +713,44 @@ function Start-BuildScript {
#>
[CmdletBinding(PositionalBinding = $false)]
Param (
[Parameter(Position = 0)]
[Alias('p')]
[String]
$Project,
[Parameter(Position = 1)]
[Alias('t')]
[String]
$Task,
[Parameter(Position = 2)]
[Alias('e')]
[String]
$Engine,
[parameter()]
[Alias('ne')]
[Alias('ne','noe')]
[Switch]
$NoExit,
[parameter()]
[Alias('nr')]
[Alias('nr','nor')]
[Switch]
$NoRestore
)
DynamicParam {
$RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $false
$ParamAttrib.Position = 0
$AttribColl.Add($ParamAttrib)
$set = @()
$set += $global:PSProfile.PSBuildPathMap.Keys
$set += '.'
$AttribColl.Add((New-Object System.Management.Automation.ValidateSetAttribute($set)))
$AttribColl.Add((New-Object System.Management.Automation.AliasAttribute('p')))
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter('Project', [string], $AttribColl)
$RuntimeParamDic.Add('Project', $RuntimeParam)

$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $false
$ParamAttrib.Position = 1
$AttribColl.Add($ParamAttrib)
$bldFile = Join-Path $PWD.Path "build.ps1"
$set = if (Test-Path $bldFile) {
((([System.Management.Automation.Language.Parser]::ParseFile($bldFile, [ref]$null, [ref]$null)).ParamBlock.Parameters | Where-Object { $_.Name.VariablePath.UserPath -eq 'Task' }).Attributes | Where-Object { $_.TypeName.Name -eq 'ValidateSet' }).PositionalArguments.Value
$bldFolder = if ([String]::IsNullOrEmpty($PSBoundParameters['Project']) -or $PSBoundParameters['Project'] -eq '.') {
$PWD.Path
}
elseif ($Global:PSProfile.PSBuildPathMap.ContainsKey($PSBoundParameters['Project'])) {
Get-LongPath -Path $PSBoundParameters['Project']
}
else {
@('Clean','Build','Import','Test','Deploy')
(Resolve-Path $PSBoundParameters['Project']).Path
}
$AttribColl.Add((New-Object System.Management.Automation.ValidateSetAttribute($set)))
$AttribColl.Add((New-Object System.Management.Automation.AliasAttribute('t')))
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter('Task', [string[]], $AttribColl)
$RuntimeParamDic.Add('Task', $RuntimeParam)

$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
$ParamAttrib = New-Object System.Management.Automation.ParameterAttribute
$ParamAttrib.Mandatory = $false
$ParamAttrib.Position = 2
$AttribColl.Add($ParamAttrib)
$set = @('powershell','pwsh','pwsh-preview')
$AttribColl.Add((New-Object System.Management.Automation.ValidateSetAttribute($set)))
$AttribColl.Add((New-Object System.Management.Automation.AliasAttribute('e')))
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter('Engine', [string], $AttribColl)
$RuntimeParamDic.Add('Engine', $RuntimeParam)

return $RuntimeParamDic
$bldFile = if ($bldFolder -like '*.ps1') {
$bldFolder
}
else {
Join-Path $bldFolder "build.ps1"
}
Copy-DynamicParameters -File $bldFile -ExcludeParameter Project,Task,Engine,NoExit,NoRestore
}
Process {
if (-not $PSBoundParameters.ContainsKey('Project')) {
Expand Down Expand Up @@ -807,8 +787,13 @@ function Start-BuildScript {
$command += "```$false;"
}
$command += "Set-Location '$parent'; . .\build.ps1"
if ($PSBoundParameters.ContainsKey('Task')) {
$command += " -Task '$($PSBoundParameters['Task'] -join "','")'"
$PSBoundParameters.Keys | Where-Object {$_ -notin @('Project','Engine','NoExit','NoRestore','Debug','ErrorAction','ErrorVariable','InformationAction','InformationVariable','OutBuffer','OutVariable','PipelineVariable','WarningAction','WarningVariable','Verbose','Confirm','WhatIf')} | ForEach-Object {
if ($PSBoundParameters[$_].ToString() -in @('True','False')) {
$command += " -$($_):```$$($PSBoundParameters[$_].ToString())"
}
else {
$command += " -$($_) '$($PSBoundParameters[$_] -join "','")'"
}
}
$command += '"'
Write-Verbose "Invoking expression: $command"
Expand All @@ -821,10 +806,38 @@ function Start-BuildScript {
}
}

if ($null -ne (Get-Command Get-PSProfileArguments*)) {
Register-ArgumentCompleter -CommandName 'Start-BuildScript' -ParameterName 'Project' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "PSBuildPathMap.$wordToComplete" -FinalKeyOnly
Register-ArgumentCompleter -CommandName Start-BuildScript -ParameterName Project -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "PSBuildPathMap.$wordToComplete" -FinalKeyOnly
}

Register-ArgumentCompleter -CommandName Start-BuildScript -ParameterName Task -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
$bldFolder = if ([String]::IsNullOrEmpty($fakeBoundParameter.Project) -or $fakeBoundParameter.Project -eq '.') {
$PWD.Path
}
elseif ($Global:PSProfile.PSBuildPathMap.ContainsKey($fakeBoundParameter.Project)) {
Get-LongPath -Path $fakeBoundParameter.Project
}
else {
(Resolve-Path $fakeBoundParameter.Project).Path
}
$bldFile = if ($bldFolder -like '*.ps1') {
$bldFolder
}
else {
Join-Path $bldFolder "build.ps1"
}
$set = if (Test-Path $bldFile) {
((([System.Management.Automation.Language.Parser]::ParseFile(
$bldFile, [ref]$null, [ref]$null
)).ParamBlock.Parameters | Where-Object { $_.Name.VariablePath.UserPath -eq 'Task' }).Attributes | Where-Object { $_.TypeName.Name -eq 'ValidateSet' }).PositionalArguments.Value
}
else {
@('Clean','Build','Import','Test','Deploy')
}
$set | Where-Object {$_ -like "$wordToComplete*"} | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}

Expand Down Expand Up @@ -935,11 +948,11 @@ function Get-LongPath {
$global:PSProfile.GitPathMap[$PSBoundParameters['Path']]
}
else {
$PSBoundParameters['Path']
(Resolve-Path $PSBoundParameters['Path']).Path
}
}
else {
$PSBoundParameters['Path']
(Resolve-Path $PSBoundParameters['Path']).Path
}
}
Cookbook {
Expand All @@ -955,11 +968,9 @@ function Get-LongPath {
}
}

if ($null -ne (Get-Command Get-PSProfileArguments*)) {
Register-ArgumentCompleter -CommandName 'Get-LongPath' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}
Register-ArgumentCompleter -CommandName 'Get-LongPath' -ParameterName 'Path' -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
Get-PSProfileArguments -WordToComplete "GitPathMap.$wordToComplete" -FinalKeyOnly
}

New-Alias -Name path -Value 'Get-LongPath' -Scope Global -Option AllScope -Force
Expand Down
134 changes: 134 additions & 0 deletions PSProfile/Public/Helpers/Copy-DynamicParameters.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
function Copy-DynamicParameters {
<#
.SYNOPSIS
Copies parameters from a file or function and returns a RuntimeDefinedParameterDictionary with the parameters replicated. Used in DynamicParam blocks.
.DESCRIPTION
Copies parameters from a file or function and returns a RuntimeDefinedParameterDictionary with the parameters replicated. Used in DynamicParam blocks.
.PARAMETER File
The file to replicate parameters from.
.PARAMETER Function
The function to replicate parameters from.
.PARAMETER ExcludeParameter
The parameter or list of parameters to exclude from replicating into the returned Dictionary.
.EXAMPLE
function Start-Build {
[CmdletBinding()]
Param ()
DynamicParam {
Copy-DynamicParameters -File ".\build.ps1"
}
Process {
#Function logic
}
}
Replicates the parameters from the build.ps1 script into the Start-Build function.
#>
[OutputType('System.Management.Automation.RuntimeDefinedParameterDictionary')]
[CmdletBinding(DefaultParameterSetName = "File")]
Param (
[Parameter(Mandatory,Position = 0,ParameterSetName = "File")]
[String]
$File,
[Parameter(Mandatory,ParameterSetName = "Function")]
[String]
$Function,
[Parameter()]
[String[]]
$ExcludeParameter = @()
)
Begin {
$RuntimeParamDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
$ast = switch ($PSCmdlet.ParameterSetName) {
File {
[System.Management.Automation.Language.Parser]::ParseFile($PSBoundParameters['File'],[ref]$null,[ref]$null)
}
Function {
[System.Management.Automation.Language.Parser]::ParseInput((Get-Command $PSBoundParameters['Function']).Definition,[ref]$null,[ref]$null)
}
}
}
Process {
foreach ($parameter in $ast.ParamBlock.Parameters | Where-Object {$_.Name.VariablePath.UserPath -notin $ExcludeParameter}) {
$AttribColl = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
foreach ($paramAtt in $parameter.Attributes) {
switch ($paramAtt.TypeName.FullName) {
Parameter {
$attribute = New-Object System.Management.Automation.ParameterAttribute
foreach ($boolParam in @('Mandatory','DontShow','ValueFromPipeline','ValueFromPipelineByPropertyName','ValueFromRemainingArguments')) {
$attribute.$boolParam = ($null -ne ($paramAtt.NamedArguments | Where-Object {$_.ArgumentName -eq $boolParam -and $_.Argument.Value -eq $true}))
}
foreach ($otherParam in @('Position','HelpMessage','HelpMessageBaseName','HelpMessageResourceId','ParameterSetName')) {
if ($item = $paramAtt.NamedArguments | Where-Object {$_.ArgumentName -eq $otherParam}) {
$attribute.$otherParam = $item.Argument.Value
}
}
$AttribColl.Add($attribute)
}
Alias {
$AttribColl.Add((New-Object System.Management.Automation.AliasAttribute($paramAtt.PositionalArguments.SafeGetValue())))
}
ValidateScript {
$AttribColl.Add((New-Object System.Management.Automation.ValidateScriptAttribute($paramAtt.PositionalArguments.ScriptBlock.GetScriptBlock())))
}
ValidateRange {
$AttribColl.Add((New-Object System.Management.Automation.ValidateRangeAttribute($paramAtt.PositionalArguments.SafeGetValue())))
}
ValidateCount {
$AttribColl.Add((New-Object System.Management.Automation.ValidateCountAttribute($paramAtt.PositionalArguments.SafeGetValue())))
}
ValidatePattern {
$AttribColl.Add((New-Object System.Management.Automation.ValidatePatternAttribute($paramAtt.PositionalArguments.SafeGetValue())))
}
ValidateSet {
$AttribColl.Add((New-Object System.Management.Automation.ValidateSetAttribute($paramAtt.PositionalArguments.SafeGetValue())))
}
ValidateLength {
$AttribColl.Add((New-Object System.Management.Automation.ValidateLengthAttribute($paramAtt.PositionalArguments.SafeGetValue())))
}
}
}
$RuntimeParam = New-Object System.Management.Automation.RuntimeDefinedParameter(
$parameter.Name.VariablePath.UserPath,
$parameter.StaticType,
$AttribColl
)
$RuntimeParamDic.Add($parameter.Name.VariablePath.UserPath,$RuntimeParam)
}
}
End {
return $RuntimeParamDic
}
}

Register-ArgumentCompleter -CommandName Copy-DynamicParameters -ParameterName ExcludeParameter -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
$set = if (-not [String]::IsNullOrEmpty($fakeBoundParameter.File)) {
([System.Management.Automation.Language.Parser]::ParseFile(
$fakeBoundParameter.File, [ref]$null, [ref]$null
)).ParamBlock.Parameters.Name.VariablePath.UserPath
}
elseif (-not [String]::IsNullOrEmpty($fakeBoundParameter.Function)) {
([System.Management.Automation.Language.Parser]::ParseInput(
(Get-Command $fakeBoundParameter.Function).Definition, [ref]$null, [ref]$null
)).ParamBlock.Parameters.Name.VariablePath.UserPath
}
else {
@()
}
$set | Where-Object {$_ -like "$wordToComplete*"} | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}

Register-ArgumentCompleter -CommandName Copy-DynamicParameters -ParameterName Function -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)
(Get-Command "$wordToComplete*").Name | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
Loading

0 comments on commit 3fb8811

Please sign in to comment.