-
Notifications
You must be signed in to change notification settings - Fork 7.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make -NoTypeInformation Default on Export-Csv and ConvertTo-Csv #5164
Make -NoTypeInformation Default on Export-Csv and ConvertTo-Csv #5164
Conversation
} | ||
} | ||
private bool _includeTypeInformation; | ||
private bool _includeTypeInformationIsSet; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In ProcessRecord() we use only if (NoTypeInformation == false)
.
So I believe we should use auto-implemented property for IncludeTypeInformation
and NoTypeInformation
and check IncludeTypeInformation.IsPresent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did testing with that.. and... it resulted in conflicts when using @splatting and supplying both. :( I ultimately went with this method because it was the most reliable way to detect if both were supplied.
edit: for clarity, when you supply $false
to a switch parameter, IsPresent
reports false. either by -Switch:$false
or $hash = @{Switch = $false}; command @hash
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for @splatting - maybe it is a bug in @splatting ?
I think we should remove NoTypeInformation
everywhere in code and leave only its declaration - the parameter is dummy and we should ignore it in code at all.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a bug in splatting. Its the nature of how switch params work. IsPresent
is does not mean was supplied
but more user supplied $true
Function Test-SwitchParam {
param(
[Switch]$Switch
)
"Switch: {0}" -f $Switch
"Switch.IsPresent: {0}" -f $Switch.IsPresent
" "
}
'Test-SwitchParam'
Test-SwitchParam
'Test-SwitchParam -Switch'
Test-SwitchParam -Switch
'Test-SwitchParam -Switch:$true'
Test-SwitchParam -Switch:$true
'Test-SwitchParam -Switch:$false'
Test-SwitchParam -Switch:$false
'$Params = @{Switch = $true}; Test-SwitchParam @Params'
$Params = @{Switch = $true}; Test-SwitchParam @Params
'$Params = @{Switch = $false}; Test-SwitchParam @Params'
$Params = @{Switch = $false}; Test-SwitchParam @Params
Test-SwitchParam
Switch: False
Switch.IsPresent: False
Test-SwitchParam -Switch
Switch: True
Switch.IsPresent: True
Test-SwitchParam -Switch:$true
Switch: True
Switch.IsPresent: True
Test-SwitchParam -Switch:$false
Switch: False
Switch.IsPresent: False
$Params = @{Switch = $true}; Test-SwitchParam @Params
Switch: True
Switch.IsPresent: True
$Params = @{Switch = $false}; Test-SwitchParam @Params
Switch: False
Switch.IsPresent: False
I think we should remove
NoTypeInformation
everywhere in code and leave only its declaration - the parameter is dummy and we should ignore it in code at all.
I'm torn on that. It's still an active parameter and setting it still has impact and will continue to do so. It's just hidden in favor of the new switch to make the new default behavior more clear. The internal logic would all need to be reworked. I didn't see value in switching all the logic to use IncludeTypeInformation
when all that needs to be done is the upfront logic of detecting if both were supplied and setting NoTypeInformation
based on the presence and setting of -IncludeTypeInformation
. The logic would still need to be there, so why disturb the rest of the code for it?
for clarity: -NoTypeInformation:$false
-NoTypeInformation:$true
are both still valid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see - somebody can use -NoTypeInformation:$false
.
However, I think we should make the code simpler and more readable. Currently -IncludeTypeInformation:$false
don't work. I vote for removing many private variables and using IsPresent
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently -IncludeTypeInformation:$false don't work
It does currently work, that's not new functionality. The decision by the committee was to maintain that functionality. This is how we preserve that functionality while adding a new parameter that is basically a reverse switch for the existing one. You can't move to IsPresent
without breaking current functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov I think I can make us both happy using this.MyInvocation.BoundParameters.ContainsKey()
. I'll work on it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After nice walking and good dinner I was ready to agree with you 😄
@@ -45,27 +45,44 @@ Describe "ConvertTo-Csv" -Tags "CI" { | |||
} | |||
|
|||
It "Should output an array of objects" { | |||
$result = $testObject | ConvertTo-Csv | |||
$result = $testObject | ConvertTo-Csv -IncludeTypeInformation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we shouldn't add -IncludeTypeInformation
in tests where we don't check ""#TYPE ".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I miss understood what this one was testing. I will fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
It "Includes type information when -IncludeTypeInformation is supplied" { | ||
$result = $testObject | ConvertTo-Csv -IncludeTypeInformation | ||
|
||
($result -split ([Environment]::NewLine))[0] | Should BeExactly "#TYPE System.Management.Automation.PSCustomObject" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need add reverse test to check that ""#TYPE " is absent if -IncludeTypeInformation
is absent.
Also that -NoTypeInformation
do nothing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure I'll add those and do the same for the Export-Csv
tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
@@ -100,6 +96,16 @@ public virtual void WriteCsvLine(string line) | |||
/// </summary> | |||
protected override void BeginProcessing() | |||
{ | |||
if (this.MyInvocation.BoundParameters.ContainsKey("IncludeTypeInformation") && this.MyInvocation.BoundParameters.ContainsKey("NoTypeInformation")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting, can we replace the string names with strong typed names?
What about different parameter sets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we replace the string names with strong typed names?
I'm not sure I understand what you are asking. IncludeTypeInformation.GetType().Name
instead of "IncludeTypeInformation"
?
What about different parameter sets?
parameter sets wont work without creating a bunch more. The parameter sets are currently being used for culture vs delimiter. It would get messy and harder to maintain than a logic check, IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the future, we need to revisit how to make defining and reading mutual exclusion of parameters easier. Using multiple parametersets today can be quite complex to get right. For now, having a runtime check is ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@SteveL-MSFT I created #5175 to track/discuss mutually exclusive parameters from a general position.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant something like nameof(param1)
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov thanks. fixed.
@@ -50,22 +50,47 @@ Describe "ConvertTo-Csv" -Tags "CI" { | |||
} | |||
|
|||
It "Should return the type of data in the first element of the output array" { | |||
$result = $testObject | ConvertTo-Csv | |||
$result = $testObject | ConvertTo-Csv -IncludeTypeInformation | |||
|
|||
$result[0] | Should Be "#TYPE System.Management.Automation.PSCustomObject" | |||
} | |||
|
|||
It "Should return the column info in the second element of the output array" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could remove the test - it is dup test in line 28.
Or it is better move the checks and next test to the test in line 28 - there we can check a type, a header and data.
It is minor comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov Which test do you want to remove? the one you comment is on (lin 58) is not a duplicate of any of the tests. Line 28 is a delimiter test which needs to remain as its a different logic gate (parameter set).
the test on line 52 is now redundant with the the test on line 84, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems we could try to refactor the tests but not in the PR.
So skip the minor comment.
@@ -96,7 +96,7 @@ public virtual void WriteCsvLine(string line) | |||
/// </summary> | |||
protected override void BeginProcessing() | |||
{ | |||
if (this.MyInvocation.BoundParameters.ContainsKey("IncludeTypeInformation") && this.MyInvocation.BoundParameters.ContainsKey("NoTypeInformation")) | |||
if (this.MyInvocation.BoundParameters.ContainsKey(nameof(IncludeTypeInformation)) && this.MyInvocation.BoundParameters.ContainsKey(nameof(NoTypeInformation))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use different parameter sets to exclude the code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iSazonov we already discussed that here
The parameter sets are currently being used for delimiter vs culture. That would require we add 2 more parameter sets. It would make the code harder to maintain. The parameter sets would be confusing to the user because we are hiding -NoTypeInformation
with DontShow=true
. @SteveL-MSFT agreed that the runtime check was fine for now until we could address the larger general problem of mutex parameters. which prompted issue #5175
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I skipped this.
closes #5131
-NoTypeInformation
as the default behavior forExport-Csv
andConvertTo-Csv
-NoTypeInformation
parameter switch-IncludeTypeInformation
switch toExport-Csv
andConvertTo-Csv
to enable legacy behavior-NoTypeInformation
and-IncludeTypeInformation
are suppliedBreaking change was approved by committee in #5131
The new behavior will need to be documented.