From 3088c38f43dbd4817a45543e178fbf7a8c282b73 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 27 Jan 2018 19:02:20 -0800 Subject: [PATCH 01/19] record support add record keyword add row keyword --- PSGraph/PSGraph.psd1 | 6 +-- PSGraph/Public/Record.ps1 | 102 ++++++++++++++++++++++++++++++++++++++ PSGraph/Public/Row.ps1 | 84 +++++++++++++++++++++++++++++++ 3 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 PSGraph/Public/Record.ps1 create mode 100644 PSGraph/Public/Row.ps1 diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 8b3b0aa..6e043c2 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -1,4 +1,4 @@ -# +# # Module manifest for module 'PSGraphViz' # # Generated by: Kevin Marquette @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '1.2.6' + ModuleVersion = '2.0.0' # Supported PSEditions # CompatiblePSEditions = @() @@ -69,7 +69,7 @@ # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. - FunctionsToExport = @('Edge', 'Export-PSGraph', 'Graph', 'Inline', 'Install-GraphViz', 'Node', 'Rank', 'Set-NodeFormatScript', 'SubGraph') + FunctionsToExport = @('Edge','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','SubGraph') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 new file mode 100644 index 0000000..3dfcde7 --- /dev/null +++ b/PSGraph/Public/Record.ps1 @@ -0,0 +1,102 @@ + +function Record +{ + <# + .SYNOPSIS + Creates a record object + + .DESCRIPTION + Creates a record object that contains rows of data. + + .PARAMETER Name + The node name for this record + + .PARAMETER List + An array of strings to place in this record + + .PARAMETER ScriptBlock + A sub expression that contains Row commands + + .EXAMPLE + graph { + + Record Components1 @( + 'Name' + 'Environment' + 'Test [string]' + ) + + Record Components2 { + Row Name + Row 'Environment test' + 'Test' + } + + Edge Components1:Name -to Components2:Name + + + Echo one two three | Record Fish + Record Cow red,blue,green + + } | Export-PSGraph -ShowGraph + + .NOTES + Early release version of this command. + A lot of stuff is hard coded that should be exposed as attributes + + #> + [OutputType('System.String')] + [cmdletbinding(DefaultParameterSetName = 'Script')] + param( + [Parameter( + Mandatory, + Position = 0 + )] + [string] + $Name, + + [Parameter( + Mandatory, + Position = 1, + ValueFromPipeline, + ParameterSetName = 'Strings' + )] + [string[]] + $List, + + [Parameter( + Mandatory, + Position = 1, + ParameterSetName = 'Script' + )] + [ScriptBlock] + $ScriptBlock + ) + begin + { + $td = [System.Collections.ArrayList]::new() + } + process + { + if ( $null -ne $ScriptBlock ) + { + $List = $ScriptBlock.Invoke() + } + + $results = foreach ($node in $List) + { + Row -Label $node + } + + foreach ($node in $results) + { + [void]$td.Add($node) + } + } + end + { + $label = '{1}
{0}
' -f $Name, ($td -join '') + Node $Name @{label = $label; shape = 'none'; fontname = "Courier New"; style = "filled"; penwidth = 1; fillcolor = "white"} + } +} + diff --git a/PSGraph/Public/Row.ps1 b/PSGraph/Public/Row.ps1 new file mode 100644 index 0000000..00151c1 --- /dev/null +++ b/PSGraph/Public/Row.ps1 @@ -0,0 +1,84 @@ +function Row +{ + <# + .SYNOPSIS + Adds a row to a record + + .Description + Adds a row to a record inside a PSGraph Graph + + .PARAMETER Label + This is the displayed data for the row + + .PARAMETER ID + This is the target ID for this row to be used in edges. + Will default to the label if the label has not special characters + + .EXAMPLE + graph { + + Record Components1 @( + 'Name' + 'Environment' + 'Test [string]' + ) + + Record Components2 { + Row Name + Row 'Environment test' + 'Test' + } + + + Edge Components1:Name -to Components2:Name + + } | Export-PSGraph -ShowGraph + + .NOTES + Need to add attribute support + + DSL planned syntax + # Row Label + # Row Label -ID + # Row Label Attributes + # Row Label -ID Attributes + + #> + [OutputType('System.String')] + [cmdletbinding()] + param( + [Parameter( + Mandatory, + Position = 0, + ValueFromPipeline + )] + [string] + $Label, + + [string] + $ID + ) + process + { + if ( [string]::IsNullOrEmpty($ID) ) + { + if ($Label -notmatch '[<,>\s]') + { + $ID = $Label + } + else + { + $ID = New-Guid + } + } + + if ($Label -match '^.*?') + { + $Label + } + else + { + '{1}' -f $ID, $Label + } + } +} \ No newline at end of file From 932c83d2c7d351935fdf1c51001b2f6bad6a592c Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 27 Jan 2018 20:59:46 -0800 Subject: [PATCH 02/19] add record tests add row tests add fingerprint sorting --- PSGraph/PSGraph.psd1 | 2 +- Tests/Record.Tests.ps1 | 40 +++++ Tests/Row.Tests.ps1 | 27 +++ fingerprint | 367 +++++++++++++++++++++++------------------ module.build.ps1 | 2 + 5 files changed, 278 insertions(+), 160 deletions(-) create mode 100644 Tests/Record.Tests.ps1 create mode 100644 Tests/Row.Tests.ps1 diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 6e043c2..666f2b8 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -69,7 +69,7 @@ # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. - FunctionsToExport = @('Edge','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','SubGraph') + FunctionsToExport = @('Edge', 'Export-PSGraph', 'Graph', 'Inline', 'Install-GraphViz', 'Node', 'Rank', 'Record', 'Row', 'Set-NodeFormatScript', 'SubGraph') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Tests/Record.Tests.ps1 b/Tests/Record.Tests.ps1 new file mode 100644 index 0000000..71d6653 --- /dev/null +++ b/Tests/Record.Tests.ps1 @@ -0,0 +1,40 @@ +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf + +Describe "Function Record" { + + It 'does not throw' { + Record Test {} | Should -Not -BeNullOrEmpty + } + + It 'simple script example' { + $result = Record test { + 'first' + 'second' + } + $result | Should -match test + $result | Should -match 'PORT="first"' + $result | Should -match 'PORT="Second"' + } + + It 'script example with row' { + $result = Record test { + Row 'first' + 'second' + } + $result | Should -match test + $result | Should -match 'PORT="first"' + $result | Should -match 'PORT="Second"' + } + + It 'simple array example' { + $result = Record test @( + 'first' + 'second' + ) + $result | Should -match test + $result | Should -match 'PORT="first"' + $result | Should -match 'PORT="Second"' + } +} diff --git a/Tests/Row.Tests.ps1 b/Tests/Row.Tests.ps1 new file mode 100644 index 0000000..c8fce11 --- /dev/null +++ b/Tests/Row.Tests.ps1 @@ -0,0 +1,27 @@ +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf + +Describe "Function Row" { + + It 'does not throw' { + Row Test | Should -Not -BeNullOrEmpty + } + + It 'returns a HTML row unmodified' { + $text = 'stuff' + Row $text | Should -Be $text + } + + It 'uses simple label as port id' { + Row Test | Should -Match 'PORT="Test"' + } + + It 'does not use complex label as port id' { + Row 'Testtest' | Should -Not -Match 'PORT="Test' + } + + It 'should use specified ID as port' { + Row Label -ID Test | Should -Match 'PORT="Test"' + } +} diff --git a/fingerprint b/fingerprint index 9d7240c..3664346 100644 --- a/fingerprint +++ b/fingerprint @@ -1,258 +1,307 @@ -Edge:From -Edge:NodeName -Edge:Name -Edge:SourceName -Edge:LeftHandSide -Edge:lhs -Edge:To -Edge:Destination -Edge:TargetName -Edge:RightHandSide -Edge:rhs Edge:Attributes -Edge:Node -Edge:InputObject -Edge:FromScript -Edge:FromScriptBlock -Edge:SourceScript -Edge:ToScript -Edge:ToScriptBlock -Edge:TargetScript -Edge:LiteralAttribute -Edge:Default -Edge:Verbose -Edge:vb -Edge:Debug Edge:db -Edge:ErrorAction +Edge:Debug +Edge:Default +Edge:Destination Edge:ea -Edge:WarningAction -Edge:wa -Edge:InformationAction -Edge:infa +Edge:ErrorAction Edge:ErrorVariable Edge:ev -Edge:WarningVariable -Edge:wv +Edge:From +Edge:FromScript +Edge:FromScriptBlock +Edge:infa +Edge:InformationAction Edge:InformationVariable +Edge:InputObject Edge:iv +Edge:LeftHandSide +Edge:lhs +Edge:LiteralAttribute +Edge:Name +Edge:Node +Edge:NodeName +Edge:ob +Edge:OutBuffer Edge:OutVariable Edge:ov -Edge:OutBuffer -Edge:ob Edge:PipelineVariable Edge:pv -Export-PSGraph:Source -Export-PSGraph:InputObject -Export-PSGraph:Graph -Export-PSGraph:SourcePath -Export-PSGraph:DestinationPath -Export-PSGraph:OutputFormat -Export-PSGraph:LayoutEngine -Export-PSGraph:GraphVizPath -Export-PSGraph:ShowGraph -Export-PSGraph:Verbose -Export-PSGraph:vb -Export-PSGraph:Debug +Edge:rhs +Edge:RightHandSide +Edge:SourceName +Edge:SourceScript +Edge:TargetName +Edge:TargetScript +Edge:To +Edge:ToScript +Edge:ToScriptBlock +Edge:vb +Edge:Verbose +Edge:wa +Edge:WarningAction +Edge:WarningVariable +Edge:wv Export-PSGraph:db -Export-PSGraph:ErrorAction +Export-PSGraph:Debug +Export-PSGraph:DestinationPath Export-PSGraph:ea -Export-PSGraph:WarningAction -Export-PSGraph:wa -Export-PSGraph:InformationAction -Export-PSGraph:infa +Export-PSGraph:ErrorAction Export-PSGraph:ErrorVariable Export-PSGraph:ev -Export-PSGraph:WarningVariable -Export-PSGraph:wv +Export-PSGraph:Graph +Export-PSGraph:GraphVizPath +Export-PSGraph:infa +Export-PSGraph:InformationAction Export-PSGraph:InformationVariable +Export-PSGraph:InputObject Export-PSGraph:iv +Export-PSGraph:LayoutEngine +Export-PSGraph:ob +Export-PSGraph:OutBuffer +Export-PSGraph:OutputFormat Export-PSGraph:OutVariable Export-PSGraph:ov -Export-PSGraph:OutBuffer -Export-PSGraph:ob Export-PSGraph:PipelineVariable Export-PSGraph:pv -Graph:Name -Graph:ScriptBlock +Export-PSGraph:ShowGraph +Export-PSGraph:Source +Export-PSGraph:SourcePath +Export-PSGraph:vb +Export-PSGraph:Verbose +Export-PSGraph:wa +Export-PSGraph:WarningAction +Export-PSGraph:WarningVariable +Export-PSGraph:wv Graph:Attributes -Graph:Type -Graph:Verbose -Graph:vb -Graph:Debug Graph:db -Graph:ErrorAction +Graph:Debug Graph:ea -Graph:WarningAction -Graph:wa -Graph:InformationAction -Graph:infa +Graph:ErrorAction Graph:ErrorVariable Graph:ev -Graph:WarningVariable -Graph:wv +Graph:infa +Graph:InformationAction Graph:InformationVariable Graph:iv +Graph:Name +Graph:ob +Graph:OutBuffer Graph:OutVariable Graph:ov -Graph:OutBuffer -Graph:ob Graph:PipelineVariable Graph:pv -Inline:InlineCommand -Inline:Verbose -Inline:vb -Inline:Debug +Graph:ScriptBlock +Graph:Type +Graph:vb +Graph:Verbose +Graph:wa +Graph:WarningAction +Graph:WarningVariable +Graph:wv Inline:db -Inline:ErrorAction +Inline:Debug Inline:ea -Inline:WarningAction -Inline:wa -Inline:InformationAction -Inline:infa +Inline:ErrorAction Inline:ErrorVariable Inline:ev -Inline:WarningVariable -Inline:wv +Inline:infa +Inline:InformationAction Inline:InformationVariable +Inline:InlineCommand Inline:iv +Inline:ob +Inline:OutBuffer Inline:OutVariable Inline:ov -Inline:OutBuffer -Inline:ob Inline:PipelineVariable Inline:pv -Install-GraphViz:Verbose -Install-GraphViz:vb -Install-GraphViz:Debug +Inline:vb +Inline:Verbose +Inline:wa +Inline:WarningAction +Inline:WarningVariable +Inline:wv +Install-GraphViz:cf +Install-GraphViz:Confirm Install-GraphViz:db -Install-GraphViz:ErrorAction +Install-GraphViz:Debug Install-GraphViz:ea -Install-GraphViz:WarningAction -Install-GraphViz:wa -Install-GraphViz:InformationAction -Install-GraphViz:infa +Install-GraphViz:ErrorAction Install-GraphViz:ErrorVariable Install-GraphViz:ev -Install-GraphViz:WarningVariable -Install-GraphViz:wv +Install-GraphViz:infa +Install-GraphViz:InformationAction Install-GraphViz:InformationVariable Install-GraphViz:iv +Install-GraphViz:ob +Install-GraphViz:OutBuffer Install-GraphViz:OutVariable Install-GraphViz:ov -Install-GraphViz:OutBuffer -Install-GraphViz:ob Install-GraphViz:PipelineVariable Install-GraphViz:pv +Install-GraphViz:vb +Install-GraphViz:Verbose +Install-GraphViz:wa +Install-GraphViz:WarningAction +Install-GraphViz:WarningVariable Install-GraphViz:WhatIf Install-GraphViz:wi -Install-GraphViz:Confirm -Install-GraphViz:cf -Node:Name -Node:NodeScript -Node:Script +Install-GraphViz:wv Node:Attributes -Node:Ranked -Node:Rank -Node:Default -Node:Verbose -Node:vb -Node:Debug Node:db -Node:ErrorAction +Node:Debug +Node:Default Node:ea -Node:WarningAction -Node:wa -Node:InformationAction -Node:infa +Node:ErrorAction Node:ErrorVariable Node:ev -Node:WarningVariable -Node:wv +Node:infa +Node:InformationAction Node:InformationVariable Node:iv +Node:Name +Node:NodeScript +Node:ob +Node:OutBuffer Node:OutVariable Node:ov -Node:OutBuffer -Node:ob Node:PipelineVariable Node:pv -Rank:Nodes +Node:Rank +Node:Ranked +Node:Script +Node:vb +Node:Verbose +Node:wa +Node:WarningAction +Node:WarningVariable +Node:wv Rank:AdditionalNodes -Rank:NodeScript -Rank:Script -Rank:Verbose -Rank:vb -Rank:Debug Rank:db -Rank:ErrorAction +Rank:Debug Rank:ea -Rank:WarningAction -Rank:wa -Rank:InformationAction -Rank:infa +Rank:ErrorAction Rank:ErrorVariable Rank:ev -Rank:WarningVariable -Rank:wv +Rank:infa +Rank:InformationAction Rank:InformationVariable Rank:iv +Rank:Nodes +Rank:NodeScript +Rank:ob +Rank:OutBuffer Rank:OutVariable Rank:ov -Rank:OutBuffer -Rank:ob Rank:PipelineVariable Rank:pv -Set-NodeFormatScript:ScriptBlock -Set-NodeFormatScript:Verbose -Set-NodeFormatScript:vb -Set-NodeFormatScript:Debug +Rank:Script +Rank:vb +Rank:Verbose +Rank:wa +Rank:WarningAction +Rank:WarningVariable +Rank:wv +Record:db +Record:Debug +Record:ea +Record:ErrorAction +Record:ErrorVariable +Record:ev +Record:infa +Record:InformationAction +Record:InformationVariable +Record:iv +Record:List +Record:Name +Record:ob +Record:OutBuffer +Record:OutVariable +Record:ov +Record:PipelineVariable +Record:pv +Record:ScriptBlock +Record:vb +Record:Verbose +Record:wa +Record:WarningAction +Record:WarningVariable +Record:wv +Row:db +Row:Debug +Row:ea +Row:ErrorAction +Row:ErrorVariable +Row:ev +Row:ID +Row:infa +Row:InformationAction +Row:InformationVariable +Row:iv +Row:Label +Row:ob +Row:OutBuffer +Row:OutVariable +Row:ov +Row:PipelineVariable +Row:pv +Row:vb +Row:Verbose +Row:wa +Row:WarningAction +Row:WarningVariable +Row:wv +Set-NodeFormatScript:cf +Set-NodeFormatScript:Confirm Set-NodeFormatScript:db -Set-NodeFormatScript:ErrorAction +Set-NodeFormatScript:Debug Set-NodeFormatScript:ea -Set-NodeFormatScript:WarningAction -Set-NodeFormatScript:wa -Set-NodeFormatScript:InformationAction -Set-NodeFormatScript:infa +Set-NodeFormatScript:ErrorAction Set-NodeFormatScript:ErrorVariable Set-NodeFormatScript:ev -Set-NodeFormatScript:WarningVariable -Set-NodeFormatScript:wv +Set-NodeFormatScript:infa +Set-NodeFormatScript:InformationAction Set-NodeFormatScript:InformationVariable Set-NodeFormatScript:iv +Set-NodeFormatScript:ob +Set-NodeFormatScript:OutBuffer Set-NodeFormatScript:OutVariable Set-NodeFormatScript:ov -Set-NodeFormatScript:OutBuffer -Set-NodeFormatScript:ob Set-NodeFormatScript:PipelineVariable Set-NodeFormatScript:pv +Set-NodeFormatScript:ScriptBlock +Set-NodeFormatScript:vb +Set-NodeFormatScript:Verbose +Set-NodeFormatScript:wa +Set-NodeFormatScript:WarningAction +Set-NodeFormatScript:WarningVariable Set-NodeFormatScript:WhatIf Set-NodeFormatScript:wi -Set-NodeFormatScript:Confirm -Set-NodeFormatScript:cf -SubGraph:Name -SubGraph:ID -SubGraph:ScriptBlock +Set-NodeFormatScript:wv SubGraph:Attributes -SubGraph:Verbose -SubGraph:vb -SubGraph:Debug SubGraph:db -SubGraph:ErrorAction +SubGraph:Debug SubGraph:ea -SubGraph:WarningAction -SubGraph:wa -SubGraph:InformationAction -SubGraph:infa +SubGraph:ErrorAction SubGraph:ErrorVariable SubGraph:ev -SubGraph:WarningVariable -SubGraph:wv +SubGraph:ID +SubGraph:infa +SubGraph:InformationAction SubGraph:InformationVariable SubGraph:iv +SubGraph:Name +SubGraph:ob +SubGraph:OutBuffer SubGraph:OutVariable SubGraph:ov -SubGraph:OutBuffer -SubGraph:ob SubGraph:PipelineVariable SubGraph:pv +SubGraph:ScriptBlock +SubGraph:vb +SubGraph:Verbose +SubGraph:wa +SubGraph:WarningAction +SubGraph:WarningVariable +SubGraph:wv diff --git a/module.build.ps1 b/module.build.ps1 index 7534326..bf4cdcc 100644 --- a/module.build.ps1 +++ b/module.build.ps1 @@ -130,6 +130,8 @@ TaskX BuildPSD1 @{ } } + $fingerprint = $fingerprint | Sort-Object + if (Test-Path .\fingerprint) { $oldFingerprint = Get-Content .\fingerprint From 6298dd1334f634da9e2c170945767e95ff24585d Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 27 Jan 2018 21:11:57 -0800 Subject: [PATCH 03/19] add change notes --- PSGraph/PSGraph.psd1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 666f2b8..e2bcda0 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -108,10 +108,16 @@ # ReleaseNotes of this module ReleaseNotes = @' +vNext +* add Record command +* add Row command + +* throws error when there are graphviz parse errors 1.2.0 20171022 * #53 add support for edges to and from a subgraph * #55 subgraph name is now optional * 56 remove extra blank lines in graph output + 1.1.4 20171021 * #51 Updated build script From 901f2b1f3db6acdb15a427995d92e9150c0a8b40 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sun, 28 Jan 2018 00:04:30 -0800 Subject: [PATCH 04/19] add EntityObject command --- PSGraph/PSGraph.psd1 | 4 +- PSGraph/Public/EntityObject.ps1 | 76 +++++++++++++++++++++++++++++++++ fingerprint | 24 +++++++++++ 3 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 PSGraph/Public/EntityObject.ps1 diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index e2bcda0..342590d 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.0.0' + ModuleVersion = '2.1.0' # Supported PSEditions # CompatiblePSEditions = @() @@ -69,7 +69,7 @@ # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. - FunctionsToExport = @('Edge', 'Export-PSGraph', 'Graph', 'Inline', 'Install-GraphViz', 'Node', 'Rank', 'Record', 'Row', 'Set-NodeFormatScript', 'SubGraph') + FunctionsToExport = @('Edge','EntityObject','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','SubGraph') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/PSGraph/Public/EntityObject.ps1 b/PSGraph/Public/EntityObject.ps1 new file mode 100644 index 0000000..1084353 --- /dev/null +++ b/PSGraph/Public/EntityObject.ps1 @@ -0,0 +1,76 @@ + +Enum EntityType +{ + Name + Value + TypeName +} + +Function EntityObject +{ + <# + .SYNOPSIS + Convert an object into a PSGraph Record + + .DESCRIPTION + Convert an object into a PSGraph Record + + .PARAMETER InputObject + The object to convert into a record + + .PARAMETER Show + The different details to show in the record + + .EXAMPLE + + $p = [pscustomobject]@{ + first = 1 + second = 'two' + } + graph { + $p | EntityObject $p -Show TypeName + } | export-PSGraph -ShowGraph + + .NOTES + General notes + #> + [CmdletBinding()] + param ( + [parameter( + ValueFromPipeline, + position = 0 + )] + $InputObject, + + [EntityType] + $Show = [EntityType]::TypeName + ) + + end + { + $Name = $InputObject.GetType().Name + $Members = $InputObject.PSObject.Properties + + $rows = foreach ($property in $members) + { + $propertyName = $property.name + switch ($Show) + { + Name + { + Row "$propertyName" -ID $propertyName + } + TypeName + { + Row ('{0} [{1}]' -f $propertyName, $property.TypeNameOfValue) -ID $propertyName + } + Value + { + Row ('{0} : {1}' -f $propertyName, $inputobject.($propertyName)) -ID $propertyName + } + } + } + + Record -Name $Name -List $rows + } +} diff --git a/fingerprint b/fingerprint index 3664346..dcc9752 100644 --- a/fingerprint +++ b/fingerprint @@ -42,6 +42,30 @@ Edge:wa Edge:WarningAction Edge:WarningVariable Edge:wv +EntityObject:db +EntityObject:Debug +EntityObject:ea +EntityObject:ErrorAction +EntityObject:ErrorVariable +EntityObject:ev +EntityObject:infa +EntityObject:InformationAction +EntityObject:InformationVariable +EntityObject:InputObject +EntityObject:iv +EntityObject:ob +EntityObject:OutBuffer +EntityObject:OutVariable +EntityObject:ov +EntityObject:PipelineVariable +EntityObject:pv +EntityObject:Show +EntityObject:vb +EntityObject:Verbose +EntityObject:wa +EntityObject:WarningAction +EntityObject:WarningVariable +EntityObject:wv Export-PSGraph:db Export-PSGraph:Debug Export-PSGraph:DestinationPath From 9034a1d4ae5a8f160c97df738e5e370b00bb2d49 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sun, 28 Jan 2018 01:07:44 -0800 Subject: [PATCH 05/19] rework record change List parameter to Row in Record command add label parameter to Record command --- PSGraph/PSGraph.psd1 | 2 +- PSGraph/Public/Record.ps1 | 28 +++++++++++++++++++--------- fingerprint | 5 +++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 342590d..de338a0 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.0' + ModuleVersion = '2.1.1' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 index 3dfcde7..7ce97c6 100644 --- a/PSGraph/Public/Record.ps1 +++ b/PSGraph/Public/Record.ps1 @@ -11,7 +11,10 @@ function Record .PARAMETER Name The node name for this record - .PARAMETER List + .PARAMETER Label + The label to use for the headder of the record. + + .PARAMETER Row An array of strings to place in this record .PARAMETER ScriptBlock @@ -62,7 +65,7 @@ function Record ParameterSetName = 'Strings' )] [string[]] - $List, + $Row, [Parameter( Mandatory, @@ -70,33 +73,40 @@ function Record ParameterSetName = 'Script' )] [ScriptBlock] - $ScriptBlock + $ScriptBlock, + + [string] + $Label ) begin { - $td = [System.Collections.ArrayList]::new() + $tableDate = [System.Collections.ArrayList]::new() + if ($null -eq $Label) + { + $Label = $Name + } } process { if ( $null -ne $ScriptBlock ) { - $List = $ScriptBlock.Invoke() + $Row = $ScriptBlock.Invoke() } - $results = foreach ($node in $List) + $results = foreach ($node in $Row) { Row -Label $node } foreach ($node in $results) { - [void]$td.Add($node) + [void]$tableDate.Add($node) } } end { - $label = '{1}
{0}
' -f $Name, ($td -join '') - Node $Name @{label = $label; shape = 'none'; fontname = "Courier New"; style = "filled"; penwidth = 1; fillcolor = "white"} + $html = '{1}
{0}
' -f $Label, ($tableDate -join '') + Node $Name @{label = $html; shape = 'none'; fontname = "Courier New"; style = "filled"; penwidth = 1; fillcolor = "white"} } } diff --git a/fingerprint b/fingerprint index dcc9752..1960060 100644 --- a/fingerprint +++ b/fingerprint @@ -237,14 +237,15 @@ Record:infa Record:InformationAction Record:InformationVariable Record:iv -Record:List -Record:Name +Record:Label +Record:Node Record:ob Record:OutBuffer Record:OutVariable Record:ov Record:PipelineVariable Record:pv +Record:Row Record:ScriptBlock Record:vb Record:Verbose From 9e2842b914250ac764a67b39603e5137010019c7 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sun, 28 Jan 2018 15:00:49 -0800 Subject: [PATCH 06/19] fix null checking bug --- PSGraph/Public/Record.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 index 7ce97c6..cf9111b 100644 --- a/PSGraph/Public/Record.ps1 +++ b/PSGraph/Public/Record.ps1 @@ -81,7 +81,7 @@ function Record begin { $tableDate = [System.Collections.ArrayList]::new() - if ($null -eq $Label) + if ( [string]::IsNullOrEmpty($Label) ) { $Label = $Name } From 9a2711d2cb6bb20a560b0560d383116ca4790756 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Thu, 15 Feb 2018 22:57:10 -0800 Subject: [PATCH 07/19] Add Record and Row commands --- PSGraph/PSGraph.psd1 | 2 +- .../Private/ConvertTo-GraphVizAttribute.ps1 | 2 +- PSGraph/Private/Format-KeyName.ps1 | 27 +++++++++++++++++++ PSGraph/Public/Record.ps1 | 2 ++ PSGraph/Public/Row.ps1 | 15 ++++++----- Tests/Row.Tests.ps1 | 1 + fingerprint | 4 +++ 7 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 PSGraph/Private/Format-KeyName.ps1 diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index de338a0..50dfbd4 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.1' + ModuleVersion = '2.1.3' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/PSGraph/Private/ConvertTo-GraphVizAttribute.ps1 b/PSGraph/Private/ConvertTo-GraphVizAttribute.ps1 index 400d080..af2de73 100644 --- a/PSGraph/Private/ConvertTo-GraphVizAttribute.ps1 +++ b/PSGraph/Private/ConvertTo-GraphVizAttribute.ps1 @@ -84,7 +84,7 @@ function ConvertTo-GraphVizAttribute { $value = $key.value } - '{0}={1};' -f $key.name, ( Format-Value $value ) + '{0}={1};' -f ( Format-KeyName $key.name ), ( Format-Value $value ) } if ( $UseGraphStyle ) diff --git a/PSGraph/Private/Format-KeyName.ps1 b/PSGraph/Private/Format-KeyName.ps1 new file mode 100644 index 0000000..16b5f09 --- /dev/null +++ b/PSGraph/Private/Format-KeyName.ps1 @@ -0,0 +1,27 @@ +function Format-KeyName +{ + [OutputType('System.String')] + [cmdletbinding()] + param( + [Parameter(Position = 0)] + [string] + $InputObject + ) + begin + { + $translate = @{ + Damping = 'Damping' + K = 'K' + URL = 'URL' + } + } + process + { + $InputObject = $InputObject.ToLower() + if ( $translate.ContainsKey( $InputObject ) ) + { + return $translate[ $InputObject ] + } + return $InputObject + } +} \ No newline at end of file diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 index cf9111b..32ec6c9 100644 --- a/PSGraph/Public/Record.ps1 +++ b/PSGraph/Public/Record.ps1 @@ -55,6 +55,7 @@ function Record Mandatory, Position = 0 )] + [alias('ID', 'Node')] [string] $Name, @@ -64,6 +65,7 @@ function Record ValueFromPipeline, ParameterSetName = 'Strings' )] + [alias('Rows')] [string[]] $Row, diff --git a/PSGraph/Public/Row.ps1 b/PSGraph/Public/Row.ps1 index 00151c1..606b54f 100644 --- a/PSGraph/Public/Row.ps1 +++ b/PSGraph/Public/Row.ps1 @@ -10,8 +10,8 @@ function Row .PARAMETER Label This is the displayed data for the row - .PARAMETER ID - This is the target ID for this row to be used in edges. + .PARAMETER Name + This is the target name of this row to be used in edges. Will default to the label if the label has not special characters .EXAMPLE @@ -55,20 +55,21 @@ function Row [string] $Label, + [alias('ID')] [string] - $ID + $Name ) process { - if ( [string]::IsNullOrEmpty($ID) ) + if ( [string]::IsNullOrEmpty($Name) ) { if ($Label -notmatch '[<,>\s]') { - $ID = $Label + $Name = $Label } else { - $ID = New-Guid + $Name = New-Guid } } @@ -78,7 +79,7 @@ function Row } else { - '{1}' -f $ID, $Label + '{1}' -f $Name, $Label } } } \ No newline at end of file diff --git a/Tests/Row.Tests.ps1 b/Tests/Row.Tests.ps1 index c8fce11..66ac744 100644 --- a/Tests/Row.Tests.ps1 +++ b/Tests/Row.Tests.ps1 @@ -23,5 +23,6 @@ Describe "Function Row" { It 'should use specified ID as port' { Row Label -ID Test | Should -Match 'PORT="Test"' + Row Label -Name Test | Should -Match 'PORT="Test"' } } diff --git a/fingerprint b/fingerprint index 1960060..7b339a0 100644 --- a/fingerprint +++ b/fingerprint @@ -233,11 +233,13 @@ Record:ea Record:ErrorAction Record:ErrorVariable Record:ev +Record:ID Record:infa Record:InformationAction Record:InformationVariable Record:iv Record:Label +Record:Name Record:Node Record:ob Record:OutBuffer @@ -246,6 +248,7 @@ Record:ov Record:PipelineVariable Record:pv Record:Row +Record:Rows Record:ScriptBlock Record:vb Record:Verbose @@ -265,6 +268,7 @@ Row:InformationAction Row:InformationVariable Row:iv Row:Label +Row:Name Row:ob Row:OutBuffer Row:OutVariable From 8b315586970242f7f8187a31aca1118b6716e2f8 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Fri, 16 Feb 2018 00:14:11 -0800 Subject: [PATCH 08/19] refactor entity command bump version update release notes --- PSGraph/PSGraph.psd1 | 9 +-- PSGraph/Public/Entity.ps1 | 112 ++++++++++++++++++++++++++++++++ PSGraph/Public/EntityObject.ps1 | 76 ---------------------- fingerprint | 24 ------- 4 files changed, 117 insertions(+), 104 deletions(-) create mode 100644 PSGraph/Public/Entity.ps1 delete mode 100644 PSGraph/Public/EntityObject.ps1 diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 50dfbd4..eb2df8d 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.3' + ModuleVersion = '2.1.5' # Supported PSEditions # CompatiblePSEditions = @() @@ -69,7 +69,7 @@ # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. - FunctionsToExport = @('Edge','EntityObject','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','SubGraph') + FunctionsToExport = @('Edge','Entity','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','SubGraph') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() @@ -108,11 +108,12 @@ # ReleaseNotes of this module ReleaseNotes = @' -vNext +2.1.5 20180216 * add Record command * add Row command - +* add Entity command * throws error when there are graphviz parse errors + 1.2.0 20171022 * #53 add support for edges to and from a subgraph * #55 subgraph name is now optional diff --git a/PSGraph/Public/Entity.ps1 b/PSGraph/Public/Entity.ps1 new file mode 100644 index 0000000..66c4e13 --- /dev/null +++ b/PSGraph/Public/Entity.ps1 @@ -0,0 +1,112 @@ + +Enum EntityType +{ + Name + Value + TypeName +} + +Function Entity +{ + <# + .SYNOPSIS + Convert an object into a PSGraph Record + + .DESCRIPTION + Convert an object into a PSGraph Record + + .PARAMETER InputObject + The object to convert into a record + + .PARAMETER Name + The name of the node + + .PARAMETER Show + The different details to show in the record. + + Name : The property name + Value : The property name and value + TypeName : The property name and the value type + + .PARAMETER Property + The list of properties to display. Default is to list them all. + Supports wildcards. + + .EXAMPLE + + $sample = [pscustomobject]@{ + first = 1 + second = 'two' + } + graph { + $sample | Entity -Show TypeName + } | export-PSGraph -ShowGraph + + .NOTES + General notes + #> + [CmdletBinding()] + param ( + [parameter( + ValueFromPipeline, + position = 0 + )] + $InputObject, + + [string] + $Name, + + [string[]] + $Property, + + [EntityType] + $Show = [EntityType]::TypeName + ) + + end + { + if([string]::isnullorempty($Name) ) + { + $Name = $InputObject.GetType().Name + } + + if($InputObject -is [System.Collections.IDictionary]) + { + $members = $InputObject.keys + } + else + { + $Members = $InputObject.PSObject.Properties.Name + } + + $rows = foreach ($propertyName in $members) + { + if($null -ne $Property) + { + $matches = $property | Where-Object {$propertyName -like $_} + if($null -eq $matches) + { + continue + } + } + + switch ($Show) + { + Name + { + Row "$propertyName" -Name $propertyName + } + TypeName + { + Row ('{0} [{1}]' -f $propertyName, $property.TypeNameOfValue) -Name $propertyName + } + Value + { + Row ('{0} : {1}' -f $propertyName, $inputobject.($propertyName)) -Name $propertyName + } + } + } + + Record -Name $Name -Row $rows + } +} diff --git a/PSGraph/Public/EntityObject.ps1 b/PSGraph/Public/EntityObject.ps1 deleted file mode 100644 index 1084353..0000000 --- a/PSGraph/Public/EntityObject.ps1 +++ /dev/null @@ -1,76 +0,0 @@ - -Enum EntityType -{ - Name - Value - TypeName -} - -Function EntityObject -{ - <# - .SYNOPSIS - Convert an object into a PSGraph Record - - .DESCRIPTION - Convert an object into a PSGraph Record - - .PARAMETER InputObject - The object to convert into a record - - .PARAMETER Show - The different details to show in the record - - .EXAMPLE - - $p = [pscustomobject]@{ - first = 1 - second = 'two' - } - graph { - $p | EntityObject $p -Show TypeName - } | export-PSGraph -ShowGraph - - .NOTES - General notes - #> - [CmdletBinding()] - param ( - [parameter( - ValueFromPipeline, - position = 0 - )] - $InputObject, - - [EntityType] - $Show = [EntityType]::TypeName - ) - - end - { - $Name = $InputObject.GetType().Name - $Members = $InputObject.PSObject.Properties - - $rows = foreach ($property in $members) - { - $propertyName = $property.name - switch ($Show) - { - Name - { - Row "$propertyName" -ID $propertyName - } - TypeName - { - Row ('{0} [{1}]' -f $propertyName, $property.TypeNameOfValue) -ID $propertyName - } - Value - { - Row ('{0} : {1}' -f $propertyName, $inputobject.($propertyName)) -ID $propertyName - } - } - } - - Record -Name $Name -List $rows - } -} diff --git a/fingerprint b/fingerprint index 7b339a0..5a3d2b4 100644 --- a/fingerprint +++ b/fingerprint @@ -42,30 +42,6 @@ Edge:wa Edge:WarningAction Edge:WarningVariable Edge:wv -EntityObject:db -EntityObject:Debug -EntityObject:ea -EntityObject:ErrorAction -EntityObject:ErrorVariable -EntityObject:ev -EntityObject:infa -EntityObject:InformationAction -EntityObject:InformationVariable -EntityObject:InputObject -EntityObject:iv -EntityObject:ob -EntityObject:OutBuffer -EntityObject:OutVariable -EntityObject:ov -EntityObject:PipelineVariable -EntityObject:pv -EntityObject:Show -EntityObject:vb -EntityObject:Verbose -EntityObject:wa -EntityObject:WarningAction -EntityObject:WarningVariable -EntityObject:wv Export-PSGraph:db Export-PSGraph:Debug Export-PSGraph:DestinationPath From b06d450c99bbbf54f29e89112d67c0770e2e09f5 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 01:19:26 -0800 Subject: [PATCH 09/19] fix null value breaking parsing html encode values arrays should not be shown as values --- PSGraph/Public/Entity.ps1 | 23 ++++++++++++++++++++--- fingerprint | 26 ++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/PSGraph/Public/Entity.ps1 b/PSGraph/Public/Entity.ps1 index 66c4e13..655dfd8 100644 --- a/PSGraph/Public/Entity.ps1 +++ b/PSGraph/Public/Entity.ps1 @@ -89,7 +89,8 @@ Function Entity continue } } - + + $value = $inputobject.($propertyName) switch ($Show) { Name @@ -98,11 +99,27 @@ Function Entity } TypeName { - Row ('{0} [{1}]' -f $propertyName, $property.TypeNameOfValue) -Name $propertyName + if($null -ne $value) + { + $type = $value.GetType().Name + } + else + { + $type = 'null' + } + Row ('{0} [{1}]' -f $propertyName, $type) -Name $propertyName } Value { - Row ('{0} : {1}' -f $propertyName, $inputobject.($propertyName)) -Name $propertyName + if([string]::IsNullOrEmpty($value)) + { + $value = ' ' + } + elseif ($value.count -gt 1) + { + $value = '[object[]]' + } + Row ('{0} : {1}' -f $propertyName, ([System.Net.WebUtility]::HtmlEncode($value))) -Name $propertyName } } } diff --git a/fingerprint b/fingerprint index 5a3d2b4..b8ceb0d 100644 --- a/fingerprint +++ b/fingerprint @@ -42,6 +42,32 @@ Edge:wa Edge:WarningAction Edge:WarningVariable Edge:wv +Entity:db +Entity:Debug +Entity:ea +Entity:ErrorAction +Entity:ErrorVariable +Entity:ev +Entity:infa +Entity:InformationAction +Entity:InformationVariable +Entity:InputObject +Entity:iv +Entity:Name +Entity:ob +Entity:OutBuffer +Entity:OutVariable +Entity:ov +Entity:PipelineVariable +Entity:Property +Entity:pv +Entity:Show +Entity:vb +Entity:Verbose +Entity:wa +Entity:WarningAction +Entity:WarningVariable +Entity:wv Export-PSGraph:db Export-PSGraph:Debug Export-PSGraph:DestinationPath From bcc73874844e94b47d35211447879e18eac0d1cf Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 01:56:16 -0800 Subject: [PATCH 10/19] add inline script and pipeline support to record --- PSGraph/Public/Record.ps1 | 30 ++++++++++++++++++++------ Tests/Record.Tests.ps1 | 45 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 index 32ec6c9..73ac476 100644 --- a/PSGraph/Public/Record.ps1 +++ b/PSGraph/Public/Record.ps1 @@ -15,8 +15,11 @@ function Record The label to use for the headder of the record. .PARAMETER Row - An array of strings to place in this record + An array of strings/objects to place in this record + .PARAMETER RowScript + A script to run on each row + .PARAMETER ScriptBlock A sub expression that contains Row commands @@ -66,9 +69,9 @@ function Record ParameterSetName = 'Strings' )] [alias('Rows')] - [string[]] + [Object[]] $Row, - + [Parameter( Mandatory, Position = 1, @@ -77,12 +80,18 @@ function Record [ScriptBlock] $ScriptBlock, + [Parameter( + Position = 2 + )] + [ScriptBlock] + $RowScript, + [string] $Label ) begin { - $tableDate = [System.Collections.ArrayList]::new() + $tableData = [System.Collections.ArrayList]::new() if ( [string]::IsNullOrEmpty($Label) ) { $Label = $Name @@ -97,17 +106,24 @@ function Record $results = foreach ($node in $Row) { - Row -Label $node + if ($RowScript) + { + @($node).ForEach($RowScript) + } + else + { + Row -Label $node + } } foreach ($node in $results) { - [void]$tableDate.Add($node) + [void]$tableData.Add($node) } } end { - $html = '{1}
{0}
' -f $Label, ($tableDate -join '') + $html = '{1}
{0}
' -f $Label, ($tableData -join '') Node $Name @{label = $html; shape = 'none'; fontname = "Courier New"; style = "filled"; penwidth = 1; fillcolor = "white"} } } diff --git a/Tests/Record.Tests.ps1 b/Tests/Record.Tests.ps1 index 71d6653..140dcc4 100644 --- a/Tests/Record.Tests.ps1 +++ b/Tests/Record.Tests.ps1 @@ -37,4 +37,49 @@ Describe "Function Record" { $result | Should -match 'PORT="first"' $result | Should -match 'PORT="Second"' } + + It 'simple array example with row script' { + + $list = @( + 'first', + 'Second' + ) + + $result = Record test $list { + Row -Name $PSItem -Label "$PSItem" + } + $result | Should -match test + $result | Should -match 'PORT="first"' + $result | Should -match 'PORT="Second"' + $result | Should -match 'first' + $result | Should -match 'Second' + } + + It 'pipeline example' { + $list = @( + 'first', + 'Second' + ) + $result = $list | Record test + + $result | Should -match test + $result | Should -match 'PORT="first"' + $result | Should -match 'PORT="Second"' + } + + It 'pipeline example with row script' { + $list = @( + 'first', + 'Second' + ) + + $result = $list | Record test -RowScript { + Row -Name $PSItem -Label "$PSItem" + } + $result | Should -match test + $result | Should -match 'PORT="first"' + $result | Should -match 'PORT="Second"' + $result | Should -match 'first' + $result | Should -match 'Second' + } } From a0edbf06c439c863d621173303b7982c2bc68720 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 02:03:23 -0800 Subject: [PATCH 11/19] add tests --- PSGraph/PSGraph.psd1 | 2 +- Tests/Record.Tests.ps1 | 5 +---- fingerprint | 1 + 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index eb2df8d..c05b640 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.5' + ModuleVersion = '2.1.6' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/Tests/Record.Tests.ps1 b/Tests/Record.Tests.ps1 index 140dcc4..6f4b71c 100644 --- a/Tests/Record.Tests.ps1 +++ b/Tests/Record.Tests.ps1 @@ -1,8 +1,5 @@ -$projectRoot = Resolve-Path "$PSScriptRoot\.." -$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") -$moduleName = Split-Path $moduleRoot -Leaf -Describe "Function Record" { +Describe "Function Record" -Tag Build { It 'does not throw' { Record Test {} | Should -Not -BeNullOrEmpty diff --git a/fingerprint b/fingerprint index b8ceb0d..f336c52 100644 --- a/fingerprint +++ b/fingerprint @@ -251,6 +251,7 @@ Record:PipelineVariable Record:pv Record:Row Record:Rows +Record:RowScript Record:ScriptBlock Record:vb Record:Verbose From 88f5f0eb2db0cf7f502b50e58564ec92f2d0cd4f Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 03:25:37 -0800 Subject: [PATCH 12/19] make parameters optional correct test that used hashtable --- PSGraph/PSGraph.psd1 | 2 +- PSGraph/Public/Record.ps1 | 2 -- Tests/Record.Tests.ps1 | 4 ++++ Tests/Unit.Tests.ps1 | 5 ++++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index c05b640..87c26c5 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.6' + ModuleVersion = '2.1.10' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 index 73ac476..43f7592 100644 --- a/PSGraph/Public/Record.ps1 +++ b/PSGraph/Public/Record.ps1 @@ -63,7 +63,6 @@ function Record $Name, [Parameter( - Mandatory, Position = 1, ValueFromPipeline, ParameterSetName = 'Strings' @@ -73,7 +72,6 @@ function Record $Row, [Parameter( - Mandatory, Position = 1, ParameterSetName = 'Script' )] diff --git a/Tests/Record.Tests.ps1 b/Tests/Record.Tests.ps1 index 6f4b71c..ce7094a 100644 --- a/Tests/Record.Tests.ps1 +++ b/Tests/Record.Tests.ps1 @@ -5,6 +5,10 @@ Describe "Function Record" -Tag Build { Record Test {} | Should -Not -BeNullOrEmpty } + It 'name only' { + $result = Record -Name test + $result | Should -match test + } It 'simple script example' { $result = Record test { 'first' diff --git a/Tests/Unit.Tests.ps1 b/Tests/Unit.Tests.ps1 index 8971742..bcb2704 100644 --- a/Tests/Unit.Tests.ps1 +++ b/Tests/Unit.Tests.ps1 @@ -92,7 +92,10 @@ Describe "Basic function unit tests" -Tags Build { It "Creates a node with attributes" { Node TestNode @{shape = 'rectangle'} | Should Match '"TestNode" \[shape="rectangle";\]' - Node TestNode @{shape = 'rectangle'; label = "myTest"} | Should Match '"TestNode" \[shape="rectangle";label="myTest";\]' + $result = Node TestNode @{shape = 'rectangle'; label = "myTest"} + $result | Should Match '"TestNode" \[.*=".*";.*=".*";\]' + $result | Should Match 'shape="rectangle";' + $result | Should Match 'label="myTest";' } } From 472dc139177d0aa6e214d6decf848f33f53284a5 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 11:10:31 -0800 Subject: [PATCH 13/19] fix resolve-path error on pscore --- PSGraph/Public/Export-PSGraph.ps1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/PSGraph/Public/Export-PSGraph.ps1 b/PSGraph/Public/Export-PSGraph.ps1 index 9f8466c..fef33ec 100644 --- a/PSGraph/Public/Export-PSGraph.ps1 +++ b/PSGraph/Public/Export-PSGraph.ps1 @@ -119,7 +119,15 @@ function Export-PSGraph # Resolve-path spits out an error with empty string paths, even with SilentlyContinue if ( @( $Source | Where-Object { [String]::IsNullOrEmpty($_) } ).Count -eq 0 ) { - $fileList = Resolve-Path -Path $Source -ErrorAction SilentlyContinue + try + { + $fileList = Resolve-Path -Path $Source -ErrorAction Stop + } + catch + { + # I don't care that it isn't a file, I'll do something else with the data + $fileList = $null + } } if ( $null -ne $fileList -and $Source.Count -gt 0 ) From 63b32cd1823b33564c6eb6e713bbc2f3958bd9ed Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 11:36:31 -0800 Subject: [PATCH 14/19] add Show-PSGraph command --- PSGraph/PSGraph.psd1 | 4 +- PSGraph/Public/Show-PSGraph.ps1 | 79 +++++++++++++++++++++++++++++++++ Tests/Show-PSGraph.Tests.ps1 | 33 ++++++++++++++ fingerprint | 30 +++++++++++++ 4 files changed, 144 insertions(+), 2 deletions(-) create mode 100644 PSGraph/Public/Show-PSGraph.ps1 create mode 100644 Tests/Show-PSGraph.Tests.ps1 diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 87c26c5..b3a4766 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.10' + ModuleVersion = '2.1.12' # Supported PSEditions # CompatiblePSEditions = @() @@ -69,7 +69,7 @@ # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. - FunctionsToExport = @('Edge','Entity','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','SubGraph') + FunctionsToExport = @('Edge','Entity','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','Show-PSGraph','SubGraph') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/PSGraph/Public/Show-PSGraph.ps1 b/PSGraph/Public/Show-PSGraph.ps1 new file mode 100644 index 0000000..20b4bda --- /dev/null +++ b/PSGraph/Public/Show-PSGraph.ps1 @@ -0,0 +1,79 @@ +function Show-PSGraph +{ + <# + + .ForwardHelpTargetName Export-PSGraph + .ForwardHelpCategory Function + .Notes + To regenerate most of this proxy function + $MetaData = New-Object System.Management.Automation.CommandMetaData (Get-Command Export-PSGraph) + $proxy = [System.Management.Automation.ProxyCommand]::Create($MetaData) + + #> + [CmdletBinding()] + param( + [Parameter(ValueFromPipeline = $true)] + [Alias('InputObject', 'Graph', 'SourcePath')] + [string[]] + ${Source}, + + [Parameter(Position = 0)] + [string] + ${DestinationPath}, + + [ValidateSet('jpg', 'png', 'gif', 'imap', 'cmapx', 'jp2', 'json', 'pdf', 'plain', 'dot')] + [string] + ${OutputFormat}, + + [ValidateSet('Hierarchical', 'SpringModelSmall', 'SpringModelMedium', 'SpringModelLarge', 'Radial', 'Circular', 'dot', 'neato', 'fdp', 'sfdp', 'twopi', 'circo')] + [string] + ${LayoutEngine}, + + [string[]] + ${GraphVizPath} + ) + + begin + { + try + { + $outBuffer = $null + if ($PSBoundParameters.TryGetValue('OutBuffer', [ref]$outBuffer)) + { + $PSBoundParameters['OutBuffer'] = 1 + } + $wrappedCmd = $ExecutionContext.InvokeCommand.GetCommand('Export-PSGraph', [System.Management.Automation.CommandTypes]::Function) + $scriptCmd = {& $wrappedCmd @PSBoundParameters -ShowGraph } + $steppablePipeline = $scriptCmd.GetSteppablePipeline() + $steppablePipeline.Begin($PSCmdlet) + } + catch + { + $PSCmdlet.ThrowTerminatingError( $PSitem ) + } + } + + process + { + try + { + $steppablePipeline.Process($_) + } + catch + { + $PSCmdlet.ThrowTerminatingError( $PSitem ) + } + } + + end + { + try + { + $steppablePipeline.End() + } + catch + { + $PSCmdlet.ThrowTerminatingError( $PSitem ) + } + } +} \ No newline at end of file diff --git a/Tests/Show-PSGraph.Tests.ps1 b/Tests/Show-PSGraph.Tests.ps1 new file mode 100644 index 0000000..f1b23c7 --- /dev/null +++ b/Tests/Show-PSGraph.Tests.ps1 @@ -0,0 +1,33 @@ +$projectRoot = Resolve-Path "$PSScriptRoot\.." +$moduleRoot = Split-Path (Resolve-Path "$projectRoot\*\*.psd1") +$moduleName = Split-Path $moduleRoot -Leaf + +#Import-Module (Join-Path $moduleRoot "$moduleName.psm1") -force + +# This one is not tagged with Build because it requires GraphViz +Describe "$ModuleName Show-PSGraph" { + + $dot = graph g { + node 2 @{shape = 'house'} + edge 2, 4, 8, 16 + } + + Context "Basic features" { + + It "Converts file to image" { + $path = "$testdrive\g.dot" + Set-Content -Path $path -Value $dot + Show-PSGraph -SourcePath $path -OutputFormat png + + "$path.png" | Should Exist + } + + It "Converts file to image over pipe" { + $path = "$testdrive\g2.dot" + Set-Content -Path $path -Value $dot + $path | Show-PSGraph -OutputFormat png + + "$path.png" | Should Exist + } + } +} diff --git a/fingerprint b/fingerprint index f336c52..7d88f2c 100644 --- a/fingerprint +++ b/fingerprint @@ -311,6 +311,36 @@ Set-NodeFormatScript:WarningVariable Set-NodeFormatScript:WhatIf Set-NodeFormatScript:wi Set-NodeFormatScript:wv +Show-PSGraph:db +Show-PSGraph:Debug +Show-PSGraph:DestinationPath +Show-PSGraph:ea +Show-PSGraph:ErrorAction +Show-PSGraph:ErrorVariable +Show-PSGraph:ev +Show-PSGraph:Graph +Show-PSGraph:GraphVizPath +Show-PSGraph:infa +Show-PSGraph:InformationAction +Show-PSGraph:InformationVariable +Show-PSGraph:InputObject +Show-PSGraph:iv +Show-PSGraph:LayoutEngine +Show-PSGraph:ob +Show-PSGraph:OutBuffer +Show-PSGraph:OutputFormat +Show-PSGraph:OutVariable +Show-PSGraph:ov +Show-PSGraph:PipelineVariable +Show-PSGraph:pv +Show-PSGraph:Source +Show-PSGraph:SourcePath +Show-PSGraph:vb +Show-PSGraph:Verbose +Show-PSGraph:wa +Show-PSGraph:WarningAction +Show-PSGraph:WarningVariable +Show-PSGraph:wv SubGraph:Attributes SubGraph:db SubGraph:Debug From 3d2db99b95df30f791f957db5e8c587fef8c4adc Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 13:36:59 -0800 Subject: [PATCH 15/19] correct rowscript processing logic --- PSGraph/Public/Record.ps1 | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/PSGraph/Public/Record.ps1 b/PSGraph/Public/Record.ps1 index 43f7592..d43de16 100644 --- a/PSGraph/Public/Record.ps1 +++ b/PSGraph/Public/Record.ps1 @@ -102,19 +102,20 @@ function Record $Row = $ScriptBlock.Invoke() } - $results = foreach ($node in $Row) + if ( $null -ne $RowScript ) { - if ($RowScript) - { + $Row = foreach ( $node in $Row ) + { @($node).ForEach($RowScript) } - else - { - Row -Label $node - } } - foreach ($node in $results) + $results = foreach ( $node in $Row ) + { + Row -Label $node + } + + foreach ( $node in $results ) { [void]$tableData.Add($node) } From f83d16fdc825e0155fe4014c9edaffc16d95d0af Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 13:39:13 -0800 Subject: [PATCH 16/19] Add html encoding support on the row --- PSGraph/PSGraph.psd1 | 2 +- PSGraph/Public/Row.ps1 | 13 ++++++++++++- Tests/Row.Tests.ps1 | 6 ++++++ fingerprint | 1 + 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index b3a4766..cede917 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSGraph.psm1' # Version number of this module. - ModuleVersion = '2.1.12' + ModuleVersion = '2.1.16' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/PSGraph/Public/Row.ps1 b/PSGraph/Public/Row.ps1 index 606b54f..bd79cc3 100644 --- a/PSGraph/Public/Row.ps1 +++ b/PSGraph/Public/Row.ps1 @@ -13,6 +13,10 @@ function Row .PARAMETER Name This is the target name of this row to be used in edges. Will default to the label if the label has not special characters + + .PARAMETER HtmlDecode + This will decode unintentional HTML. Characters like <>& would break html parsing if they are + contained in the source data. .EXAMPLE graph { @@ -57,7 +61,10 @@ function Row [alias('ID')] [string] - $Name + $Name, + + [switch] + $HtmlEncode ) process { @@ -79,6 +86,10 @@ function Row } else { + if ($HtmlEncode) + { + $Label = ([System.Net.WebUtility]::HtmlEncode($Label)) + } '{1}' -f $Name, $Label } } diff --git a/Tests/Row.Tests.ps1 b/Tests/Row.Tests.ps1 index 66ac744..4b0f3c1 100644 --- a/Tests/Row.Tests.ps1 +++ b/Tests/Row.Tests.ps1 @@ -13,6 +13,12 @@ Describe "Function Row" { Row $text | Should -Be $text } + It 'can encode html' { + $text = 'stuff' + $encoded = ([System.Net.WebUtility]::HtmlEncode($text)) + Row $text -HtmlEncode | Should -Be $encoded + } + It 'uses simple label as port id' { Row Test | Should -Match 'PORT="Test"' } diff --git a/fingerprint b/fingerprint index 7d88f2c..4a114a8 100644 --- a/fingerprint +++ b/fingerprint @@ -265,6 +265,7 @@ Row:ea Row:ErrorAction Row:ErrorVariable Row:ev +Row:HtmlEncode Row:ID Row:infa Row:InformationAction From a342e5a300406356c32d1ccb1350dafd595face6 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 13:44:26 -0800 Subject: [PATCH 17/19] update release notes --- PSGraph/PSGraph.psd1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index cede917..43c6ef7 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -69,7 +69,7 @@ # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. - FunctionsToExport = @('Edge','Entity','Export-PSGraph','Graph','Inline','Install-GraphViz','Node','Rank','Record','Row','Set-NodeFormatScript','Show-PSGraph','SubGraph') + FunctionsToExport = @('Edge', 'Entity', 'Export-PSGraph', 'Graph', 'Inline', 'Install-GraphViz', 'Node', 'Rank', 'Record', 'Row', 'Set-NodeFormatScript', 'Show-PSGraph', 'SubGraph') # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() @@ -108,10 +108,11 @@ # ReleaseNotes of this module ReleaseNotes = @' -2.1.5 20180216 +2.1.16 20180217 * add Record command * add Row command * add Entity command +* add Show-PSGraph command * throws error when there are graphviz parse errors 1.2.0 20171022 From ace99dee5c7eadbaae5199ddb9db41db1ce39f38 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 13:55:57 -0800 Subject: [PATCH 18/19] add case correction to release notes --- PSGraph/PSGraph.psd1 | 1 + 1 file changed, 1 insertion(+) diff --git a/PSGraph/PSGraph.psd1 b/PSGraph/PSGraph.psd1 index 43c6ef7..798e797 100644 --- a/PSGraph/PSGraph.psd1 +++ b/PSGraph/PSGraph.psd1 @@ -113,6 +113,7 @@ * add Row command * add Entity command * add Show-PSGraph command +* add key name case correction * throws error when there are graphviz parse errors 1.2.0 20171022 From 17937255026af861ba27df34b2492550c9ec76f6 Mon Sep 17 00:00:00 2001 From: KevinMarquette Date: Sat, 17 Feb 2018 14:03:25 -0800 Subject: [PATCH 19/19] correct help for HtmlEncode attribute --- PSGraph/Public/Row.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/PSGraph/Public/Row.ps1 b/PSGraph/Public/Row.ps1 index bd79cc3..fac4d9f 100644 --- a/PSGraph/Public/Row.ps1 +++ b/PSGraph/Public/Row.ps1 @@ -14,8 +14,8 @@ function Row This is the target name of this row to be used in edges. Will default to the label if the label has not special characters - .PARAMETER HtmlDecode - This will decode unintentional HTML. Characters like <>& would break html parsing if they are + .PARAMETER HtmlEncode + This will encode unintentional HTML. Characters like <>& would break html parsing if they are contained in the source data. .EXAMPLE