Skip to content

Fix Select-Object to approve UX and fix return a property named *#2421

Merged
daxian-dbw merged 7 commits intoPowerShell:masterfrom
iSazonov:selectobject
Nov 1, 2016
Merged

Fix Select-Object to approve UX and fix return a property named *#2421
daxian-dbw merged 7 commits intoPowerShell:masterfrom
iSazonov:selectobject

Conversation

@iSazonov
Copy link
Copy Markdown
Collaborator

@iSazonov iSazonov commented Oct 4, 2016

  1. Now ExcludeProperty imply Property = '*' to approve UX Select-Object -ExcludeProperty dependency on -Property is unintuitive.  #2351
  2. Don't return property named '*' Select-Object return a property named * #2420

Close #2351
Close #2420

@msftclas
Copy link
Copy Markdown

msftclas commented Oct 4, 2016

Hi @iSazonov, I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by Microsoft and real humans are currently evaluating your PR.

TTYL, MSBOT;

1. Now ExcludeProperty imply Property = '*'
2. Don't return property named '*'
@iSazonov
Copy link
Copy Markdown
Collaborator Author

iSazonov commented Oct 6, 2016

@PowerShellTeam please review the code.

if (expressionResults.Count == 0)
if (expressionResults.Count == 0 && !ex.HasWildCardCharacters)
{
//Commented out for bug 1107600
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please remove the commented-out code snippet here? It's useless and there is no way to figure out what bug 1107600 is now :)

Copy link
Copy Markdown
Member

@daxian-dbw daxian-dbw Oct 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And it would be better if you can add some comments here, explaining your purpose (allow Select-Object -Property noexist-name to return a PSObject with property noexist-name, unless noexist-name itself contains wildcards).
I find the implementation of Select-Object is so poorly commented (near to zero comment) that it becomes a pain to read the code. So let's add some when we make changes in this file.

Copy link
Copy Markdown
Collaborator Author

@iSazonov iSazonov Oct 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I generally see little comments throughout the Powershell code and tests and thought it was best practice. I will make more comments.
I think @PowerShellTeam needs to mark this moment in documentation: "make more comments in your code".

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think @PowerShellTeam needs to mark this moment in documentation: "make more comments in your code".

I absolutely agree! I will update coding-conventions to include this.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed.

# Issue #2420
It "Select-Object with implicit Property = '*' don't return property named '*'"{
$results = [pscustomobject]@{Thing="thing1"} | Select-Object -ExcludeProperty thing
$results.psobject.Properties.Item("*").Name | Should Be $null
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Item("*").Name

.Name seems not necessary here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed.

{
_exclusionFilter = new MshExpressionFilter(ExcludeProperty);
if ((Property == null) || (Property.Length == 0))
{
Copy link
Copy Markdown
Member

@daxian-dbw daxian-dbw Oct 7, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will result a breaking change -- the scirpt below runs successfully before this change; but with this change a bunch errors will be thrown out.

$s = Get-Process -Id $pid | Select-Object -ExcludeProperty ProcessName -ExpandProperty Modules

However, I don't feel this would break any existing scripts practically. It's documented that -ExcludeProperty has no effect without -Property, so I don't think any existing script would only specify -ExcludeProperty.

Maybe we can analyze the powershell scripts on GitHub to get some data. We can borrow @lzybkr's AnalyzeCurlUsage.ps1.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.The current tests do not catch it. I think we should add this in tests.

2.There is no difference between:

 $s = Get-Process -Id $pid | Select-Object -ExpandProperty Modules
$s[0] | fl *

and

$s = Get-Process -Id $pid | Select-Object -ExcludeProperty FileName -ExpandProperty Modules
$s[0] | fl *

i.e. ExpandProperty skip ExcludeProperty. So the change could be corrected without breaking.

3.The cmdlet is very intuitive to the user UX and very controversial:
ExcludeProperty is skipped w/o Property
ExpandProperty skip ExcludeProperty
ExpandProperty with Property throw exception
Compare:

1 | Select-Object
"1" | Select-Object
1 | Select-Object -Property *
"1" | Select-Object -Property *

and many more.
And it is a tricky code, and any even slightly change this code can easily break down.

(In general I think this cmdlet should be replaced with a newer, which meets modern requirements to cmdlets.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean that it's very unintuitive 😕

If the intention is (to maintain the current expected behavior) that -ExpandProperty ignores -ExcludeProperty wouldn't it be better to have these switches in separate parameter sets? I'd certainly rather have it be obvious that they can't be used together than to allow them together but ignore one (or worse, produce runtime errors if they're used together)...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean that it's very unintuitive 😕

Under "intuitive" I mean that we use the cmdlet 10 years "as is" without many complaints (In other words, users get results they expect).
All completely different if you look on the inner side of the cmdlet. I guess it was one of the first cmdlets of Powershell. Today such a design would be immediately rejected. The code is tricky and any chip change results in multiple test crush.
And we absolutely cannot add parameter sets (and moreover we cannot add new exceptions) because this is breaking change.
As I said above, time to replace this cmdlet to a new one with stringent modern design, better UX and better performance.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daxian-dbw I fix breaking change and add your test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The conclusion is to take your changes to ProcessExpressionParameter() in your second commit -- always add "*" to -Property when -ExcludeProperty is specified but -Property is not : 70c3038

I think you implemented the pseudo code I listed above to avoid the breaking change, but as we discussed here, that will raise new confusion about how -ExlcudeProperty works. So I believe it's reasonable to take your original changes to ProcessExpressionParameter() to make it simple for users to understand.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that I hadn't actually concluded anything after my discussion w/ @daxian-dbw, but after some of my own experiments, I do agree. The existing behavior is surprising and not useful, anyone potentially hit by the breaking change wasn't getting what they wanted anyway.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@daxian-dbw @lzybkr Thanks for the clarification and the final conclusion! I'll make the rollback.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @iSazonov
#Closed

# Issue #2420
It "Select-Object with explicit Property = '*' don't return property named '*'"{
$results = [pscustomobject]@{Thing="thing1"} | Select-Object -Property * -ExcludeProperty thing
$results.psobject.Properties.Item("*").Name | Should Be $null
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Name seems not necessary.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed.

# Issue #2351
It "Select-Object with implicit Property = '*' exclude not single prperty"{
$results = [pscustomobject]@{Thing="thing1";Param2="param2"} | Select-Object -ExcludeProperty Param2
$results.Param2 | Should Be $null
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed.

# Issue #2351
It "Select-Object with explicit Property = '*' exclude not single prperty"{
$results = [pscustomobject]@{Thing="thing1";Param2="param2"} | Select-Object -Property * -ExcludeProperty Param2
$results.Param2 | Should Be $null
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please fix the indentation here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed.

@RichardSiddaway
Copy link
Copy Markdown

Having separate parameter sets would be a great idea

Sent from my iPad

On 9 Oct 2016, at 20:30, Joel Bennett <[email protected]mailto:[email protected]> wrote:

@Jaykul commented on this pull request.


In src/Microsoft.PowerShell.Commands.Utility/commands/utility/select-object.cshttps://github.com//pull/2421:

@@ -337,6 +337,11 @@ private void ProcessExpressionParameter()
if (ExcludeProperty != null)
{
_exclusionFilter = new MshExpressionFilter(ExcludeProperty);

  •            if ((Property == null) || (Property.Length == 0))
    
  •            {
    

I think you mean that it's very unintuitive ?

If the intention is (to maintain the current expected behavior) that -ExpandProperty ignores -ExcludeProperty wouldn't it be better to have these switches in separate parameter sets? I'd certainly rather have it be obvious that they can't be used together than to allow them together but ignore one (or worse, produce runtime errors if they're used together)...

You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHubhttps://github.com//pull/2421, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AHgYUaGr7eou2GSu_7Q0m2-iosO0xvc0ks5qyUDjgaJpZM4KNXvs.

Restore ExpandProperty skip ExcludeProperty
Add new test
Add new comments
Remove old comment
@iSazonov
Copy link
Copy Markdown
Collaborator Author

@RichardSiddaway Sorry, this is the right decision but it is impossible to add parameter sets w/o breaking change. See my comment above.


if (ExcludeProperty != null)
// ExpandProperty skip processing ExcludeProperty
if (ExcludeProperty != null && string.IsNullOrEmpty(ExpandProperty))
Copy link
Copy Markdown
Member

@daxian-dbw daxian-dbw Oct 10, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot ignore -ExcludeProperty just because -ExpandProperty is specified. See the script below:

PS:88> $s = Get-Process -Id $pid | Select-Object -Property Process* -ExpandProperty Modules
PS:89> $s[0].ProcessName
powershell
PS:90> $s[0].ProcessorAffinity
255
PS:91> $p = Get-Process -Id $pid | Select-Object -Property Process* -ExcludeProperty ProcessorAffinity
-ExpandProperty Modules
PS:92> $p[0].ProcessName
powershell
PS:93> $p[0].ProcessorAffinity
PS:94>

-ExcludeProperty took effect and excluded the property ProcessorAffinity, so only ProcessName got added to each Module object.

I feel it's OK to break the Select-Object -ExcludeProperty value1 -ExpandProperty value2 usage based on my analysis of the usage of Select-Object in GitHub (please see my comment above).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, waiting team approve above then revert the change.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While waiting I made refactoring. See comment above.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed

}
}

// allow Select-Object -Property noexist-name to return a PSObject with property noexist-name,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be clearer if you add quotes around Select-Object -Property noexist-name.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed

1. Refactoring ProcessExpressionParameter() to make explicit logic for
processing Property, ExcludeProperty and ExpandProperty
2. Add new test
3. Correct comment
1. Revert ProcessExpressionParameter() to second commit
2. Remove unneeded test
}

# Issue #2351
It "Select-Object with implicit Property = '*' exclude not single prperty"{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prperty

A typo, should be 'property'

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed

}

# Issue #2351
It "Select-Object with explicit Property = '*' exclude not single prperty"{
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prperty

Same typo :)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fate :)
Fixed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#Closed

$p = Get-Process -Id $pid | Select-Object -Property Process* -ExcludeProperty ProcessorAffinity -ExpandProperty Modules
$p[0].psobject.Properties.Item("ProcessorAffinity") | Should Be $null
}
} No newline at end of file
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add a new line?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. #Closed

@daxian-dbw
Copy link
Copy Markdown
Member

Thanks @iSazonov for the updates! Once the typos in tests are fixed, the PR will be ready to merge.

if ((Property == null) || (Property.Length == 0))
{
Property = new Object[]{"*"};
_propertyMshParameterList = processor.ProcessParameters(Property, invocationContext); }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iSazonov sorry that I missed this one this morning. Can you please fix the indentation of the opening '{' and move the closing '}' to a new line? And please also remove the extra newline at line#348.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Copy Markdown
Member

@daxian-dbw daxian-dbw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@daxian-dbw daxian-dbw merged commit 5aee4ba into PowerShell:master Nov 1, 2016
@iSazonov
Copy link
Copy Markdown
Collaborator Author

iSazonov commented Nov 2, 2016

@daxian-dbw Thanks very much!

@iSazonov iSazonov deleted the selectobject branch November 2, 2016 11:09
@daxian-dbw
Copy link
Copy Markdown
Member

@iSazonov Thank you for your patience and the great contribution 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants