Skip to content

Commit 5fc37ec

Browse files
author
Friedrich Weinmann
committed
Fixing splatting detection error
1 parent 7fec660 commit 5fc37ec

File tree

2 files changed

+65
-72
lines changed

2 files changed

+65
-72
lines changed

PSModuleDevelopment/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## ???
4+
5+
- Fix: Export-PSMDString - Failed with splatting detection
6+
37
## 2.2.8.104 (July 26th, 2020)
48

59
- Fix: Various bugs in the new functions

PSModuleDevelopment/functions/refactor/Export-PSMDString.ps1

Lines changed: 61 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
[string]
2626
$ModuleRoot
2727
)
28-
28+
2929
process
3030
{
3131
#region Find Language Files : $languageFiles
@@ -40,23 +40,24 @@
4040
}
4141
}
4242
#endregion Find Language Files : $languageFiles
43-
43+
4444
#region Find Keys : $foundKeys
4545
$foundKeys = foreach ($file in (Get-ChildItem -Path $ModuleRoot -Recurse | Where-Object Extension -match '^\.ps1$|^\.psm1$'))
4646
{
4747
$ast = (Read-PSMDScript -Path $file.FullName).Ast
48+
#region Command Parameters
4849
$commandAsts = $ast.FindAll({
4950
if ($args[0] -isnot [System.Management.Automation.Language.CommandAst]) { return $false }
5051
if ($args[0].CommandElements[0].Value -notmatch '^Invoke-PSFProtectedCommand$|^Write-PSFMessage$|^Stop-PSFFunction$') { return $false }
5152
if (-not ($args[0].CommandElements.ParameterName -match '^String$|^ActionString$')) { return $false }
5253
$true
5354
}, $true)
54-
55+
5556
foreach ($commandAst in $commandAsts)
5657
{
5758
$stringParam = $commandAst.CommandElements | Where-Object ParameterName -match '^String$|^ActionString$'
5859
$stringParamValue = $commandAst.CommandElements[($commandAst.CommandElements.IndexOf($stringParam) + 1)].Value
59-
60+
6061
$stringValueParam = $commandAst.CommandElements | Where-Object ParameterName -match '^StringValues$|^ActionStringValues$'
6162
if ($stringValueParam)
6263
{
@@ -72,77 +73,64 @@
7273
StringValues = $stringValueParamValue
7374
}
7475
}
75-
76-
# Additional checks for splatted commands
77-
# find all splatted commands
78-
$splattedVariables = $ast.FindAll( {
79-
if ($args[0] -isnot [System.Management.Automation.Language.VariableExpressionAst ]) { return $false }
80-
if (-not ($args[0].Splatted -eq $true)) { return $false }
81-
$true
82-
}, $true)
83-
84-
foreach ($splattedVariable in $splattedVariables)
85-
{
86-
#get the variable name
87-
$splatParamName = $splattedVariable.VariablePath.UserPath
88-
if ($splatParamName)
89-
{
90-
# match the $param = @{
91-
$splatParamNameRegex = "^\s?\`$$($splatParamName)\s?=\s?\@\{"
92-
# get all variable assignments where the
93-
# left side matches our param
94-
# operator is =
95-
# matches our assignment regex
96-
$splatAssignmentAsts = $ast.FindAll( {
97-
if ($args[0] -isnot [System.Management.Automation.Language.AssignmentStatementAst ]) { return $false }
98-
if (-not ($args[0].Left -match $splatParamName)) { return $false }
99-
if (-not ($args[0].Operator -eq 'Equals')) { return $false }
100-
if (-not ($args[0].Extent -match $splatParamNameRegex)) { return $false }
101-
$true
102-
}, $true)
103-
foreach ($splatAssignmentAst in $splatAssignmentAsts)
104-
{
105-
# get the hashtable
106-
$splatHashTable = $splatAssignmentAst.Right.Expression
107-
# see if its an empty assignment or null
108-
if ($splatHashTable -and $splatHashTable.KeyValuePairs.Count -gt 0)
109-
{
110-
# find any String or ActionString
111-
$splatParam = $splatAssignmentAst.Right.Expression.KeyValuePairs | Where-Object Item1 -match '^String$|^ActionString$'
112-
if ($splatParam)
113-
{
114-
# The kvp.item.extent.text returns nested quotes where as the commandast.extent.text doesn't so strip them off
115-
$splatParamValue = $splatParam.Item2.Extent.Text.Trim('"').Trim("'")
116-
# find any StringValue or ActionStringValue
117-
$splatValueParam = $splatAssignmentAst.Right.Expression.KeyValuePairs | Where-Object Item1 -match '^StringValues$|^ActionStringValues$'
118-
}
119-
if ($splatValueParam)
120-
{
121-
# The kvp.item.extent.text returns nested quotes whereas the commandast.extent.text doesn't so strip them off
122-
$splatValueParamValue = $splatValueParam.Item2.Extent.Text.Trim('"').Trim("'")
123-
}
124-
else { $splatValueParamValue = '' }
125-
126-
[PSCustomObject]@{
127-
PSTypeName = 'PSModuleDevelopment.String.ParsedItem'
128-
File = $file.FullName
129-
Line = $splatHashTable.Extent.StartLineNumber
130-
CommandName = $splattedVariable.Parent.CommandElements[0].Value
131-
String = $splatParamValue
132-
StringValues = $splatValueParamValue
133-
}
134-
}
135-
}
136-
}
137-
}
138-
76+
#endregion Command Parameters
77+
78+
#region Splatted Variables
79+
$splattedVariables = $ast.FindAll({
80+
if ($args[0] -isnot [System.Management.Automation.Language.VariableExpressionAst]) { return $false }
81+
if (-not ($args[0].Splatted -eq $true)) { return $false }
82+
try { if ($args[0].Parent.CommandElements[0].Value -notmatch '^Invoke-PSFProtectedCommand$|^Write-PSFMessage$|^Stop-PSFFunction$') { return $false } }
83+
catch { return $false }
84+
$true
85+
}, $true)
86+
87+
foreach ($splattedVariable in $splattedVariables)
88+
{
89+
$splatParamName = $splattedVariable.VariablePath.UserPath
90+
91+
$splatAssignmentAsts = $ast.FindAll({
92+
if ($args[0] -isnot [System.Management.Automation.Language.AssignmentStatementAst]) { return $false }
93+
if ($args[0].Left.VariablePath.userPath -ne $splatParamName) { return $false }
94+
if ($args[0].Operator -ne 'Equals') { return $false }
95+
if ($args[0].Right.Expression -isnot [System.Management.Automation.Language.HashtableAst]) { return $false }
96+
$keys = $args[0].Right.Expression.KeyValuePairs.Item1.Value
97+
if (($keys -notcontains 'String') -and ($keys -notcontains 'ActionString')) { return $false }
98+
99+
$true
100+
}, $true)
101+
102+
foreach ($splatAssignmentAst in $splatAssignmentAsts)
103+
{
104+
$splatHashTable = $splatAssignmentAst.Right.Expression
105+
106+
$splatParam = $splathashTable.KeyValuePairs | Where-Object Item1 -in 'String', 'ActionString'
107+
$splatValueParam = $splathashTable.KeyValuePairs | Where-Object Item1 -in 'StringValues', 'ActionStringValues'
108+
if ($splatValueParam)
109+
{
110+
$splatValueParamValue = $splatValueParam.Item2.Extent.Text
111+
}
112+
else { $splatValueParamValue = '' }
113+
114+
[PSCustomObject]@{
115+
PSTypeName = 'PSModuleDevelopment.String.ParsedItem'
116+
File = $file.FullName
117+
Line = $splatHashTable.Extent.StartLineNumber
118+
CommandName = $splattedVariable.Parent.CommandElements[0].Value
119+
String = $splatParam.Item2.Extent.Text.Trim("'").Trim('"')
120+
StringValues = $splatValueParamValue
121+
}
122+
}
123+
}
124+
#endregion Splatted Variables
125+
126+
#region Attributes
139127
$validateAsts = $ast.FindAll({
140128
if ($args[0] -isnot [System.Management.Automation.Language.AttributeAst]) { return $false }
141129
if ($args[0].TypeName -notmatch '^PsfValidateScript$|^PsfValidatePattern$') { return $false }
142130
if (-not ($args[0].NamedArguments.ArgumentName -eq 'ErrorString')) { return $false }
143131
$true
144132
}, $true)
145-
133+
146134
foreach ($validateAst in $validateAsts)
147135
{
148136
[PSCustomObject]@{
@@ -154,9 +142,10 @@
154142
StringValues = '<user input>, <validation item>'
155143
}
156144
}
145+
#endregion Attributes
157146
}
158147
#endregion Find Keys : $foundKeys
159-
148+
160149
#region Report Findings
161150
$totalResults = foreach ($languageFile in $languageFiles.Keys)
162151
{
@@ -169,7 +158,7 @@
169158
$results[$foundKey.String].Entries += $foundKey
170159
continue
171160
}
172-
161+
173162
$results[$foundKey.String] = [PSCustomObject] @{
174163
PSTypeName = 'PSmoduleDevelopment.String.LanguageFinding'
175164
Language = $languageFile
@@ -183,7 +172,7 @@
183172
}
184173
$results.Values
185174
#endregion Phase 1: Matching parsed strings to language file
186-
175+
187176
#region Phase 2: Finding unneeded strings
188177
foreach ($key in $languageFiles[$languageFile].Keys)
189178
{

0 commit comments

Comments
 (0)