Skip to content
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

Read-Host : Add Trim Option #19680

Closed
aksarben opened this issue May 19, 2023 · 62 comments
Closed

Read-Host : Add Trim Option #19680

aksarben opened this issue May 19, 2023 · 62 comments
Labels
Issue-Enhancement the issue is more of a feature request than a bug PowerShell-Docs needed The PR was reviewed and a PowerShell Docs update is needed Resolution-Declined The proposed feature is declined. WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module

Comments

@aksarben
Copy link

Summary of the new feature / enhancement

Can you add an optional parameter to Read-Host to automatically remove leading & trailing whitespace (string.trim())?

Sometimes users accidentally add white space that can cause string comparisons to fail. Since whitespace is invisible, it sometimes can take a few minutes to figure out why the failure is happening.

Proposed technical implementation details (optional)

No response

@aksarben aksarben added Issue-Enhancement the issue is more of a feature request than a bug Needs-Triage The issue is new and needs to be triaged by a work group. labels May 19, 2023
@mklement0
Copy link
Contributor

I agree that this would be helpful, but just to note the workaround: $userInput = (Read-Host 'Enter something').Trim()

@aksarben
Copy link
Author

aksarben commented May 19, 2023 via email

@mklement0
Copy link
Contributor

@rhubarb-geek-nz, from that perspective nothing that can be implemented in PowerShell code - no matter how cumbersome and non-obvious - constitutes a workaround.

The point here is that wanting to trim user input is the typical use case, yet:

  • Read-Host doesn't even support this functionality as an opt-in - implementing one is what this proposal is about.

  • Absent direct support, the next best thing is to have the documentation directly address this typical use case, by spelling out the (Read-Host ...).Trim() implementation - and not making users infer this implementation via multiple levels of indirection.

@jhoneill
Copy link

It would be silly if every command that returned a string then has to have all the additional options to uppercase it , lowercase it, trim it, pad it and split it etc.

Very much this.

see #16660 (comment) for why I think the vast majority of the time read-host should not be used at all. It's correct/incorrect usage ratio is worse than write-host

The point here is that wanting to trim user input is the typical use case

I think that about 99% of the time Read-Host is used because the author is writing like 1970s basic and asking the user to type things in when they should, in fact, be asking for parameters.

e.g.

param (
 [parameter(HelpMessage='Enter the X dimension of the thing we're calculating' , Mandatory=$true)]
$x
)

not

$x = Read-host 'Enter the X dimension of the thing we're calculating' 

How often in practice does the user type spaces which should not form part of the input? we're probably more concerned that user doesn't give empty input
so we do

do {$x = Read-host "Please input X"} until ($x -ne "")

but no one is asking for an option for that, nor to ensure that input is numeric nor split comma separated input into multiple items or any of the many other things which might be bolted on Read-Host and benefit someone.

Adding -MethodProvidedByReturnType is generally not done. The usual thing is to do (command).MethodProvidedByReturnType(xx) or even Read-Host "Enter x" | % trim (discouraged for scripts)

We might well say Get-Content should have -Trim or -Split or -Replace and they'd be more useful than in Read-Host, but we don't because we expect people to be able to do those operations on strings and demand it of things which get strings.

@mklement0
Copy link
Contributor

Read-Host and Write-Host are essential for creating terminal-based user interfaces, primarily - but not exclusively - for non-technical end users (who may not know or care that PowerShell is being used to implement the script).

This is completely unrelated to what you're talking about (parameters for technical users familiar with PowerShell), and this conflation - especially if used to argue against Read-Host and Write-Host as commands - is unhelpful.

The argument re not providing a switch for something that can also be done manually, after the fact, is specious:
While separation of concerns is important, there are many examples of convenience parameters that reduce the verbosity and repetitiveness of code, and possibly help performance; case in point:

Why have Get-Content -First 10 ... when you can do Get-Content ... | Select-Object -First 10? Because it is more concise, more convenient (and performs better, though that's not the most important aspect).

@jhoneill
Copy link

@mklement0 I wonder if you are just playing devil's advocate,

There are a few cases where we display a menu or ask the user for a selection, or pause until the user hits enter which need Read-Host. But when someone not very experienced with PowerShell uses read-host it's usually because they're writing to that 1970s BASIC paradigm of getting users to type parameters after the program starts and having it produce formatted strings written to the console. We need Write-Host to separate output from stuff for people to look at, which is a distinction those programs don't make. The commands are needed but also facilitate worst practice - imagine if the only way you could use man was to run man with no parameters and then answer a prompt for what you wanted help on - that would be a dreadful bit of coding.

Where the dividing line lies between "use two cmdlets" like gci | sort-object length and "we'll give it to the user in one as a convenience" like get-content -first seems to be what seemed like a good idea at the time to the original designers. Generally the principles of
(1) move selection of what goes down the pipeline as far to the left as possible and then
(2) don't do in the cmdlet something that the returned objects can do
seem to be fairly consistent. Generally "command -only-return-the-first n" is better than "command | stop-command-after n"

@mklement0
Copy link
Contributor

The commands are needed but also facilitate worst practice

This is a completely separate debate - bringing it up here is inappropriate and only causes confusion.

@jhoneill
Copy link

Generally "command -only-return-the-first n" is better than "command | stop-command-after n"

Even that may not be true. Consider a directory listing where technically there is no order to the files in a directory, they are just a set of files.

I only know for sure with FAT, but I think it is true of all file systems, the directory keeps the files in creation order. I think .NET (and possibly the windows API) sorts before returning. But I don't think the API has a "Ask the file system for 10 files in this directory", we get all the files and if we only want 10 the work has been done.

If you had a Get-ChildItem stop after n you could get a different set each time. If you let the Cmdlet on the left focus on the getting of the data but the cmdlets to the right do the filtering and sorting then you make the cmdlets that get the data much simpler, and end up with more consistent sorting for data from different sources.

Yes that is generally true. But if I can call a rest api which returns 1,000,000 items and apply a where on the client side, or I can call the API with the where condition and return 1 item. It's plainly better not to bring the other 999,999 over the wire and send them down the pipeline. If I have a function which calls an API which usually returns about 100 items I'll probably sort by name rather than tell users to do it, because 9 times out of 10 they want that order, and for the 10th the cost of the extra sort doesn't matter.

It is worth comparing with SQL, where selecting rows just gives you the rows and they could be in any order, it is not until you do WHERE and ORDER BY and LIMIT that then you get the filtering and restriction in number of rows. Of course the difference with a database query engine is that it constructs a plan across the whole statement in order to be the most efficient. With cmdlets we don't have that luxury. For instance we have no mechanism for a Cmdlet on the right to tell a Cmdlet on the left that it has provided enough pipeline elements, the Cmdlet on the left will just keep on going.

Actually there is a mechanism and Select-Object uses it. try dir / -rec -ea 0 | Select -first 2 and dir / -rec -ea 0 | out-null

AIUI it raises a special terminating error, which is not available to other things. If it is a the SQL query or rest API that gets a ton of stuff, it only stops that going down the pipeline but for something like get-content on a million line file, it does stop the rest being read So gc foo | select -first 10 is better than (gc foo)[0..9] but Get-Sql $sql | select -first 10 going to get all the data and we'd be better ensuring $sql had "top 10"

I am more in favour of keeping the data providers as simple as possible, and then make the sorting and filtering cmdlets the most powerful and flexible because both the reuse and consistency will be so much better,

Not over-complicating is good :-) If you think of get-process the API lets us get processes by name or ID, so it would be silly to get all processes and apply a where-object. But there is no need to have get-process able to select or sort based on memory used, that's why commands are composed from cmdlets in the first place.

The commands are needed but also facilitate worst practice

This is a completely separate debate - bringing it up here is inappropriate and only causes confusion.

If anyone wants to know why I'm not taking this to the cmdlet working group, and why if another member does I'd argue it's not even something we should accept a community PR on, then I've laid out why. Sorry for confusing you.

@mklement0
Copy link
Contributor

mklement0 commented May 23, 2023

Sorry for confusing you.

Glad to hear it. I encourage you and @rhubarb-geek-nz to hide all your comments here as "Off Topic." (I'm happy to hide my responses thereafter.)

@rhubarb-geek-nz
Copy link

rhubarb-geek-nz commented May 23, 2023

it's not part of the official documentation and many people won't think of it.

The 'workaround' is part of the official documentation;

PS> help Read-Host
..snip..
OUTPUTS
System.String
System.Security.SecureString

And System.String.Trim.

The new option may do a disservice to the very audience you are trying to help.

If people think they are writing pure, portable PowerShell script may find either

PS> Read-Host -Trim   
-Trim: 

or

PS> Read-Host -Prompt "hello" -Trim
Read-Host: A parameter cannot be found that matches parameter name 'Trim'.

If they run their script on a previous version of PowerShell.

So they now need to be aware that their script will only run on PowerShell 7.4.0

If they publish their script in PSGallery, likewise they will need a PowerShellVersion field in their module manifest.

So unless Publish-Module parses the scripts for unsupported parameters you may end up with published modules, while tested and working with one version fail on previous versions of PowerShell Core or on WindowsPowerShell.

@mklement0
Copy link
Contributor

@rhubarb-geek-nz, since the off-topic ship has sailed, allow me to summarize your arguments - I do hope I got the gist right:

  • "Typical use cases aren't worth documenting (with examples), because what you need to implement them can be gleaned, piece by piece, from other documentation."

  • "New features aren't worth introducing, because old language versions won't have them."

@rhubarb-geek-nz
Copy link

rhubarb-geek-nz commented May 23, 2023

Not quite

  • What was called a workaround isn't really a workaround, being able to use dotnet directly is fundamental part of how PowerShell works
  • New features can certainly be added but be aware of the backward compatibility issues that may arise, so certainly add the Trim option, but it isn't going to solve every problem.

@mklement0
Copy link
Contributor

  • Workaround is a relative term that pertains to the inability to implement a task as intended, due to a (perceived) limitation or a bug: that limitation / bug must then be worked around to achieve the desired result.

  • Of course backward compatibility issues can arise, but that is no reason to halt the progress of the language.

    • Such issues apply to any new feature, and are therefore not worth discussing in the context of a particular feature request.
    • A feature request should be discussed on its own merits and - if deemed a worthwhile addition in principle - only then, potentially, a discussion of when to introduce it can be had (e.g., bundled with similar new features, hold until the next major release, ...)

@jhoneill
Copy link

Sorry for confusing you.

Glad to hear it. I encourage you and @rhubarb-geek-nz to hide all your comments here as "Off Topic." (I'm happy to hide my responses thereafter.)

If I see additional people who are confused I'll be sure to do that.

  • Workaround is a relative term that pertains to the inability to implement a task as intended, due to a (perceived) limitation or a bug: that limitation / bug must then be worked around to achieve the desired result.

While true, this does not really help matters. Read-Host does not convert to upper/lower, split, validate, trim, or do other replacements on the string it returns nor (AFAIK) do other analogs of the BASIC'S INPUT command (which I think mirrors one in Fortran). These are considered normal things to do to a string once it has been fetched. Someone thinking that it would those string operations were merged into commands (and why stop at Read-Host) doesn't mean the normal way of doing things is a problem to be worked around.

  • A feature request should be discussed on its own merits and - if deemed a worthwhile addition in principle - only then

As the only person from the cmdlets wg who has given this any time I haven't seen anything to persuade me - after an extensive discussion - that it is worth discussing in the wg. @aksarben can we close this now ?

@jhoneill jhoneill removed the Needs-Triage The issue is new and needs to be triaged by a work group. label May 23, 2023
@mklement0
Copy link
Contributor

If I see additional people who are confused I'll be sure to do that.

Given how this thread has unfolded, I'm sure those who stumble upon this will be - you may simply never hear from them.
Not hearing from others is no justification to let off-topic comments stand.

As the only person from the cmdlets wg who has given this any time
@aksarben can we close this now ?

It is inappropriate to speculate about the intent of other workgroup members (without having received actual feedback).
It is inappropriate to unilaterally lobby for closure of a feature request.


Read-Host does not convert to upper/lower, split, validate, trim, or do other replacements

That - unlike many other comments in this thread - is an on-topic argument; it has been addressed before, but let me try to clarify:

  • No one is asking for arbitrary string transformations / operations to be baked into Read-Host, though common ones are worth considering, such as -Trim, if they're relevant to interactive prompting:

  • Users, especially non-technical ones, accidentally typing spaces before or after the input is a real-world pitfall that anyone writing robust user interfaces must guard against (this doesn't preclude having to perform additional operations on the string returned).

    • Ideally, the logic would be reversed: Read-Host should trim leading and trailing whitespace by default, unless explicitly asked not to; that ship has sailed for reasons of backward compatibility.
    • $userInput = Read-Host -Trim 'Enter something' is the next best thing.

@rhubarb-geek-nz
Copy link

rhubarb-geek-nz commented May 23, 2023

  • No one is asking for arbitrary string transformations / operations to be baked into Read-Host, though common ones are worth considering, such as -Trim, if they're relevant to interactive prompting:

Me! Me! I am. The comparison with param was made and how it will translate to given type and also provide autocompletion. It would be really useful for interactive applications to have the same capability, eg at a top level menu to use Read-Host to return an enum value of the valid options, likewise with numbers only accept numerical input, ideally with ranges, or values from a ValidateSet.
Similarly a consistent way of aborting a current data entry session to return to the main menu by using control-C.
Or provide my own Luhn check validation class or script block.

@mklement0
Copy link
Contributor

@rhubarb-geek-nz, yes, there is a lot of room for improvement, but what you're suggesting is (commendably) not arbitrary:

  • Improving and constraining the user's editing experience (tab-completion, limiting input to certain characters and/or a given length, custom keyboard hooks, ...)

  • Validating user input as part of the Read-Host call (via a script block, as you suggest), to avoid cumbersome and visually noisy loop implementations, where Read-Host returns, and, if the user input is found to be invalid, it must be called again, possibly multiple times.

At least some of this functionality could be provided if Read-Host used PSReadLine's PSConsoleHostReadLine function behind the scenes, as proposed in PowerShell/PSReadLine#881 - this, however, would require the function to be modified so as to support general-purpose, open-ended input.

A fundamental question is how sophisticated the currently bare-bones Read-Host should become (as opposed to requiring use of specialty libraries focused on TUIs), but I encourage you to open new issues for features you'd like to see.

@santisq
Copy link

santisq commented May 24, 2023

There is nothing stopping you from replacing Read-Host with your own wrapper function that handles trimming, it could even be in your $profile. I think developers time would much better invested in other issues.

function Read-Host {
    [CmdletBinding(
        DefaultParameterSetName = 'AsString',
        HelpUri = 'https://go.microsoft.com/fwlink/?LinkID=2096610'
    )]
    param(
        [Parameter(Position = 0, ValueFromRemainingArguments = $true)]
        [AllowNull()]
        [System.Object]
        ${Prompt},

        [Parameter(ParameterSetName = 'AsSecureString')]
        [switch]
        ${AsSecureString},

        [Parameter(ParameterSetName = 'AsString')]
        [switch]
        ${MaskInput},

        [Parameter(ParameterSetName = 'AsString')]
        [switch]
        ${Trim}
    )

    begin {
        $withTrim = $PSBoundParameters.Remove('Trim')
        $scriptCmd = { Microsoft.PowerShell.Utility\Read-Host @PSBoundParameters }
        $steppablePipeline = $scriptCmd.GetSteppablePipeline($myInvocation.CommandOrigin)
        $steppablePipeline.Begin($true)
    }

    process {
        if($withTrim) {
            return ([string] $steppablePipeline.Process()).Trim()
        }
        $steppablePipeline.Process()
    }

    end {
        $steppablePipeline.End()
    }

    clean {
        if ($null -ne $steppablePipeline) {
            $steppablePipeline.Clean()
        }
    }
}

@mklement0
Copy link
Contributor

mklement0 commented May 24, 2023

Thanks for the code, @santisq - I encourage you to publish it as a self-answered question on Stack Overflow to give it wider exposure, along with a link to this issue: that may draw more users who'd be interested in seeing this implemented as part of Read-Host itself (and therefore thumbs-ups, which are a gauge of community interest).

Anyone who'd put such a proxy function in their $PROFILE would clearly prefer that this functionality be part of the language (the built-in commands). And anyone wanting to write reusable scripts relying on it would have to bundle the proxy function with their code, which is obviously a pain.

I think developers time would much better invested in other issues.

Given how trivial this would be to implement, I think that's a false dichotomy - there is no either-or here.
More time was wasted in off-topic discussions here than it probably would have taken to implement the feature.

Again, the only question should be: is this a worthwhile addition to Read-Host?
If deemed so, prioritization of developer time may then come into play, reflected in when the green-lit enhancement is actually implemented (and if it becomes an up-for-grabs issue, which this one is definitely a candidate for, no core developers' time is needed).

Whether a given feature is worthwhile is - at least initially, pending a potential appeal, as codified here - is to be decided by the relevant working group (and how much time passes before that happens is also a reflection of priorities, I suppose).

It certainly shouldn't be decided unilaterally by a single member of a working group, especially in an underhanded manner (removal of the "Needs-Triage" tag, withholding of the relevant "WG-*" tag, badgering the OP to close their issue).

@jhoneill
Copy link

jhoneill commented May 24, 2023

It certainly shouldn't be decided unilaterally by a single member of a working group, especially in an underhanded manner (removal of the "Needs-Triage" tag, withholding of the relevant "WG-*" tag, badgering the OP to close their issue).

@mklement0 leave the ad-hominems out. You might also want to rethink whether the definition of badger "repeatedly ask (someone) to do something; pester:", fits with a single "Is it ok if" question.
Based on the sample of wg members who have looked and voiced an opinion (1) it has had a 100% down vote. By all means ask other members of the WG to take a look, but I would advise you to think about the terms "disruptive" and "trolling" as used by the code of conduct before continuing to argue.

  1. At the end of day we're talking about facilitating -StringMethod on one or more cmdlets. The differences between supporting only (cmdlet).StringMethod() and additionally supporting cmdlet -stringmethod is 3 keystrokes. @mklement0 you alone have many open issues, most of which would bring greater benefit if they were addressed.
  2. The functionality has been unchanged over the history of PowerShell. Demands for cmdlets which output strings to optionally apply string methods first have been few (if any) in that time and I can't think of a case where this is done currently. If there had been many such demands we could say it is a small benefit, but to many people, however it looks like a small benefit to a few.
  3. Compatibility would doubtless raise its head. If a -StringMethod switch were added to PowerShell 7 any script which used it would error at that line in Windows PowerShell. Therefore the limited set of people who would benefit is further reduced to those whose code does not need to run on older versions. We prefer not to create situations where scripts written for the latest version can do harm on the version supplied with Windows - which is a risk here.
  4. Opening up -StringMethod switches for one cmdlet immediately begs the question which other switches and which other commands. I would expect to hear "we don't want to set a precedent" in a meeting of the WG.
  5. And on Read-Host specifically, I have about 1.2 million lines of PowerShell on my laptop. I have two menus which I wrote around the release of PowerShell 2 which have hundreds of Read-Host calls. In everyone else's code and all the rest of mine it appears a few dozen times. So even if adding -StringMethod switches were not considered to be unnecessary, potentially harmful, and/or setting a bad precedent, it is unlikely improving Read-Host would be seen as sufficiently important to not do something else.

@doctordns
Copy link
Contributor

doctordns commented May 24, 2023

Just a small point. I have always taught that All user input is dangerous and evil until you prove otherwise (and even then...)..
Speaking personally, I have learned long ago that in a few cases, trailing (or leading) spaces can be problematic, and quite happily use .trim() in the PowerShell code.

I have not seen a huge demand for this kind of feature either. I may be looking in the wrong place! ;-)

I learned long ago that there is no such thing as "trivial to implement". And the implantation is not the only cost involved. Anything that unnecessarily adds to the PowerShell package is to be avoided. I am not convinced of the need for such a switch.

I will add this issue to the Cmdlet WG's agenda, although I can't promise how quickly we can get to it.

@mklement0
Copy link
Contributor

@doctordns

I will add this issue to the Cmdlet WG's agenda although I can't promise how quickly we can get to it.

Thank you.
That is all I was asking for - please don't forget to tag the issue accordingly.

(I won't defend the merits of this proposal further - I think all angles have been covered.)

@doctordns doctordns added the WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module label May 24, 2023
@doctordns
Copy link
Contributor

@mklement0 thanks for the reminder - I have labeled this issue accordingly.

@mklement0
Copy link
Contributor

@jhoneill

leave the ad-hominems out.

There was no ad hominem. It was an accurate description of your actions - save for "badgering" being too strong, given the lack of repeated action; does "urging" work?

Based on the sample of wg members who have looked and voiced an opinion (1) it has had a 100% down vote.

It is inappropriate to bypass the official procedures the way you did and seem to be defending now.
Your private conversations and personal opinions are no substitute for following the proper protocol.

I would advise you to think about the terms "disruptive" and "trolling"

While I wouldn't characterize your conduct here as "trolling", "disruptive" seems apt.

More importantly, that your unilateral actions were inappropriate is implied by the following statement from the Working Groups definition:

It's worth noting that Working Group members who repeatedly speak on behalf of the Working Group without consensus, they may be censured or removed from the team.

@jhoneill
Copy link

@mklement0 I'm going to disengage from your comments , as it appears others have had the wisdom to do before me.

The post no longer need triaging. I removed that label. I did not close it because (a) the OP might want to keep it open, (b) other members of the WG might have a different view to mine as @doctordns has now shown. It is very clear from everything I have said where my opinion as a one member of that WG, ends and where other members need to speak for themselves. But my opinion (which will now go to WG) is as in the 5 points above. I will also have a word with the powers that be about the definition of trolling and possible ways forward.

@SteveL-MSFT
Copy link
Member

@PowerShell/wg-powershell-cmdlets reviewed this proposal and rejects the proposed addition to Read-Host. Users are expected to validate any external input before use which includes, but not limited to, trimming whitespace. Since we do not believe this scenario is sufficiently common, it does not make sense to add general string methods to this cmdlet. It may make sense to have an updated example in the docs for validating input which includes trimming whitespace.

@SteveL-MSFT SteveL-MSFT added the PowerShell-Docs needed The PR was reviewed and a PowerShell Docs update is needed label Jun 7, 2023
@mklement0
Copy link
Contributor

@SteveL-MSFT , re documentation:

@mklement0
Copy link
Contributor

@SteveL-MSFT:

I assume you've come across my complaint about inappropriate unilateral behavior in this thread, summarized here, so there's need for me to report it separately anymore.

I think said behavior is at odds with the mandates of working-group members, as already implied by the existing documents describing the WG duties.

However, one additional inappropriate behavior that unfolded in the wake of this thread strikes me as worth adding as a DO NOT to Working Groups (WGs):

  • It is inappropriate for WG members to block community members, as it robs them of the ability to respond / react to those members' posts / comments and - last but not least - also from being notified of @-mentions in comments by said members.

  • Case in point: Due to being blocked by @jhoneill, I was not notified of his comment at Meta issue: How/where should complaints about working-group members be lodged? #19730 (comment), which explicitly @-mentions me - and made the issue about a general complaint mechanism personal. I discovered it only accidentally, and had no one else ever responded there again, I could have missed it altogether.


To address said comment:

  • It is a problematic for a WG member not to be able to tell the difference between arguments and personal attacks.

  • It is even more problematic to then make accusations of such attacks, threaten the other with the Code of Conduct, and generally project their own disruptive behavior onto others.

  • There is clearly no awareness of the inappropriateness of the unilateral actions, as the following sentence attests:

    • I only take things to the WG which I think are worth the time of its members.

  • @SteveL-MSFT, if - to my surprise - you think it is appropriate for a single WG member to decide what does and doesn't even jointly get triaged as a feature request, i.e. to act as the sole gatekeeper, do let us know.

    • If so - which, needless to say, I oppose - perhaps that should be added to the WG document, for future clarity.

@aksarben
Copy link
Author

aksarben commented Jun 8, 2023 via email

@jhoneill
Copy link

jhoneill commented Jun 8, 2023

@mklement0 - I previously blocked you, but github does not implement block as I thought so I have removed it and you should see this mention.

The cmdlets working group met yesterday and this occupied some of the meeting. In due course you will see something on how to complain if something is done in the name of a group, whether that is one person saying "As a member of the group I think..." or "The working group feels..." (i.e. a quorum has discussed it and concluded and I am reporting back on their behalf). My take away from that was that everyone is aware of the need not to muddy the waters between those two (although I should say "as one member of the WG I think that, the rest of the WG haven't mandated me to say so").

There is a general presumption that working groups should see all issues which relate to their area. However there is a very large backlog and for many groups this is growing . Any "committee" takes longer to work through issues as it gets bigger and the only way for WGs to process more is with more time from their current set of unpaid volunteers. So despite what we would all wish, the practicalities mean working groups can't see all issues. One of the tasks of group members is selecting which ones are seen.
There are requests where it is obvious that the answer will be "No". For example " > should function as a greater than operator" , does not need to go to the engine working group. In such cases someone with the github rights would be doing the right thing by closing the issue, sometimes they should take soundings first, but not always. Often no-one wants to consume other people's time or summarily close the issue so it remains open on the pile of things which will never get attention.

It is valid for someone to say "As a member of A working group, this isn't something I'd pursue but experience tells me X might feel differently so let's see if X has a comment" or to say "As a member of A working group, this isn't something I'd pursue. I believe my fellow members of A would feel the same if asked, so I will not be trying to get it on the WG's agenda". Which leaves the door open for someone else on the wg to say "Actually James I think we should talk it through".
If someone gets a response of that kind from an individual they can close their issue, or they can leave it open hoping to get attention, but with the expectation set that its unlikely to. In future I'll try to be clearer if when I'm giving such responses This issue was talked through and if you want to know if the other wg members feel it was always a 'dead' issue, or whether it is good to discuss 'dead' issues they will need to answer for themselves .

Because of a procedural hiccup I have been on the WG for a longer time than I have had the github authorization to change tags and close issues. It did not feel right to me to close this issue, since I wasn't going to put in front of the cmdlet group I didn't tag it as belonging to that group, and I thought it had been sufficiently triaged so I removed that tag. In hindsight my understanding of how things should be tagged may have let me down. This could have been tagged as "falls under the auspices of this wg", while knowing it is in a large pile of things which won't even be considered. Hopefully your other issue on the triage tag will come to a conclusion - if it says "don't remove to-be-triaged without a replacement tag to say what the triage outcome was" that may be for the best. I'll admit that it may have been said already and I may have missed it in which case fault would lie with me, but reminding people would still be a good thing.

On this specific case. There is a general presumption in PowerShell that if a cmdlet returns an object of type X, then things done with the properties and methods of X are done with the returned object outside the cmdlet. We teach people once that string has .Trim, .Split .Replace, ToUpper etc and for any command (cmdlet, function, script, external exe) returning a string ( command ).method() is normal. and some people know they can do command | foreach-object method or command |% method at the command line. The default assumption for any request to provide access to a return-object's method(s) via one or more cmdlet-parameters would be "no".

One can argue that a need is so great that an exception should be made. Experience has taught me things about Read-Host which make think it has a particularly weak case for exceptions, but other people could say "No, there are all these people using read-host and they need to use trim (and only trim) in all these places and there would be HUGE upside". I was fairly sure the lack of visible evidence for that was because the need was small. .

This could have been answered with something as simple as

OP: "Hi, I'm new and maybe all the old hands have learned to tolerate something that should be fixed, but it seems to me Read-Host should have a switch for this thing that strings need to do afterwards "
Responder: "Yeah, PowerShell makes cmdlets lightweight, and leaves those things to be done by/with/to the return object. Is this causing you a massive problem ? Or do you think there are lots of other people feeling the same ? "
OP: "No, it's a small issue and I don't hear others complaining, I guess I'll get used to it. Issue closed"

What we have had instead has wasted many hours. I see that in a pretty bad light, but if I make code-of-conduct complaints it's simply going to prolong things, and anyone investigating will probably say it's six of one and half a dozen of the other, and I shouldn't feel the obligation to respond which I appear to.

@mklement0
Copy link
Contributor

@jhoneill, by and large I appreciate the measured response and the accountability regarding the label, but let me address some important points:

On the meta aspects:

What we have had instead has wasted many hours

Fundamentally, if a better way forward emerges from this, the effort wasn't wasted.
The effort certainly could have been reduced, however, if you had shown accountability earlier, instead of ignoring my arguments and blocking me.

if I make code-of-conduct complaints

Frankly, the only code-of-conduct complaint that would have been appropriate in the context of this thread is against yourself, for unwarranted threats with the code of conduct and accusations of trolling.

It is indeed your choice whether to respond, though doing so in good faith is always preferable, as long as there actual differences to resolve (as opposed to something having devolved into bickering).


I can fully appreciate the need to weed out issues ahead of time, so they don't require discussion in a quorum, which includes:

  • Closing as a duplicate.
  • Closing as an answered question.
  • Closure by the user themselves, of their own volition, after a respectful and constructive discussion.

Clearly, the latter has not happened here.

The default assumption for any request to provide access to a return-object's method(s) via one or more cmdlet-parameters would be "no"

I've addressed this before, but let me try again:

  • The framing isn't correct: it's not about access to methods it's about adding functionality that is a sensible part of the cmdlet's purpose - that it involves something that can be also be done later and that the proposed parameter name matches the name of a method on the object returned is incidental.

  • Clearly, such "convenience duplication" of functionality is both common in the existing cmdlets and, if I were to guess, frequently used (certainly by me).

    • It gave us such things as Get-Content -First, Sort-Object -Top (a fairly recent addition), Select-String -Raw, and there are probably many more examples.

It is precisely because what are to me misreadings of a feature request can occur that it is important not to operate on such general rules, especially not unilaterally.


To recap: The larger issue here is not that you expressed an opinion on the feature request at hand, but that:

  • You deliberately withheld the WG-* label.
  • You removed the Needs-Triage label.

The combination of these two actions in effect would have made this feature request die on the vine, with you as the sole arbiter.

Even if the removal of Needs-Triage was an honest mistake (and it sounds like that was the case) - and clarifying the proper use of this label is what made me open #19731 (and I'm glad to hear that you now want clarity there too) - the withholding of the WG-* label alone is problematic, especially based on how you framed this decision:

If anyone wants to know why I'm not taking this to the cmdlet working group

Is there any other way to read this than that you're thinking of yourself as the gatekeeper of what does and doesn't get discussed by the quorum of members?

Sure, there's no obligation for any single WG member to be in charge of assigning the WG-* label.
In fact, the working-group document suggests that maintainers do it (the "Area label" link referred to below includes WG-* labels):

The issue gets triaged into an Area label by Maintainers.

What I think is inappropriate is to use deliberate withholding of the WG*- as a way of prejudging a feature request (whether or not other WG members jump in and assign the label), and I think it is important to get clarity on that aspect and amend the WG document accordingly.

My reading of the WG document is that WG-* labeling should happen unconditionally, as the first step, as a formal act - and that makes perfect sense to me:

  • Once the label is assigned, all members of the relevant WG(s) can weigh in (I presume they have notifications set up for their WG label(s)), ahead of any quorum decision (which may or may not be necessary).

  • Then it's perfectly fine to voice opinions on whether a given feature request is "quorum-worthy", but it should never be up to a single WG member to make that call:

    • If such a pre-quorum conversation is conducted in good faith, including allowing for different opinions, closure may well be achieved for requests if the poster comes to realize themselves that the request isn't worth pursuing.

    • If not, then the opinions already voiced by WG members should aid in making a quick decision in the quorum.

@jhoneill
Copy link

jhoneill commented Jun 8, 2023

Another 750 words. It is time to ask those who determine what is and is not trolling to give an opinion.

@mklement0
Copy link
Contributor

@SteveL-MSFT, I'd like to add the following to my complaint above:

  • It is inappropriate for WG members to make unwarranted accusations of trolling in response to carefully crafted arguments proffered in good faith.

  • It is inappropriate for WG members to consider themselves the arbiters of who gets to speak when and with how many words (actual violations of the CoC are an entirely unrelated matter).

@jhoneill
Copy link

jhoneill commented Jun 8, 2023

Code of conduct talks about

  • Trolling, insulting or derogatory comments,
  • harassment
  • Disruptive behavior
  • conduct which could reasonably be considered inappropriate in a professional setting

Let's just leave repo maintainers to decide what qualifies and what does not. I feel like I am the subject of vendetta, and they can tell me if I am right or wrong to feel that way.

WG members do not decide who speaks - that is neither practical nor desirable -but they do decide who the WG listens to and which topics are put before their fellow members. Somewhere I saw "Gatekeeper" used in its pejorative sense. We are portiers, commissionaires our job is to get people in, but we can't do that for everyone. I feel like the nightclub door man who turns one customer away only to be glassed by someone who happened to be passing looking for a fight. In hindsight the initial " from that perspective nothing that can be implemented in PowerShell code - no matter how cumbersome and non-obvious - constitutes a workaround." should have been a warning that the issue was being trolled.

WG membership does not prevent anyone observing that at some volume "carefully crafted arguments" serve no purpose other than to disrupt, and remarking when in their view that volume has been passed.

If those in charge of the WG think I acted in bad faith they will fire me. The repeated complaint that my actions with tags were not taken in good faith has not resulted in my being told I should have done anything differently, so to the best of my knowledge what I did was legitimate. I have asked the repo maintainers to rule on whether I have good cause to feel harassed (e.g. the opening of two other issues as thinly veiled, but clearly directed attacks), and if sufficient volume of sufficiently argumentative posts amounts to disruptive behaviour, whether that has been passed. They may say no to both. As I said already I'm leaving it to them.

@mklement0
Copy link
Contributor

  • I've made specific arguments as to what behaviors by and interpretations of the mandate of a WG member that were exhibited in this thread were inappropriate.

  • Since these arguments weren't engaged with, I wanted to find a way to complain about what had unfolded here, because it is important to either stop these behaviors / correct these interpretations, or at least get clarity on what is and isn't appropriate, and amend the WG document accordingly.

  • Realizing that there was no complaint mechanism at the appropriate level (the CoC is too broad, not handled at the specific community level, and doesn't really apply to a discussion of what is appropriate in fulfilling a community-specific role), I opened Meta issue: How/where should complaints about working-group members be lodged? #19730 in the hopes that such a complaint mechanism will be established. I deliberately avoided linking to this (or any specific issue), as that was irrelevant. I think such a complaint mechanism is important, to avoid public and protracted spats such as this one. As noted, it is only for when reaching a consensus one-on-one failed.

  • Realizing that there was inconsistency around the use of the "Needs-Triage" label, I thought it important to seek clarification there, too: Meta issue: Clarify the intent of the "Needs-Triage" label, notably with respect to "Issue-Enhancement", and use it consistently going forward. #19731. Similarly, a link to any specific issue - including this one - is irrelevant.

  • Interpreting any of the above as a "vendetta" is not only the wrong thing to focus on, it is also a non sequitur.

The repeated complaint that my actions with tags were not taken in good faith

  • The action with respect to the "Needs-Triage" label was taken in good faith, after you took responsibility (the relevant quote is above).

  • The argument with respect to the "WG-*" label isn't a matter of good faith: My arguments challenge your reasons for withholding that label. I have no doubt that you think that was the right thing to do and meant well, but that is irrelevant, and I've laid out my arguments why it isn't the right thing to do.

@jhoneill
Copy link

jhoneill commented Jun 8, 2023

. It is time to ask those who determine what is and is not trolling to give an opinion.

@mklement0

This comment was marked as resolved.

@jhoneill
Copy link

jhoneill commented Jun 8, 2023

. I have asked the repo maintainers to rule on whether I have good cause to feel harassed (e.g. the opening of two other issues as thinly veiled, but clearly directed attacks), and if sufficient volume of sufficiently argumentative posts amounts to disruptive behaviour, whether that has been passed. They may say no to both. As I said already I'm leaving it to them.

@mklement0

This comment was marked as resolved.

@doctordns
Copy link
Contributor

@jhoneill, indeed, you've said that - three times now. Is there a good reason to keep repeating this?

Is there a good reason for your continued trolling?

Please stop. If you can’t, then maybe it is time to block you. Your comments in this thread are unhelpful,passive agressive trolling. This really needs to stop.

@mklement0
Copy link
Contributor

mklement0 commented Jun 9, 2023

@doctordns

Not only was their no continued trolling, there was never any trolling to begin with (more on that below).

I firmly believe my comments in this thread to be helpful to the community at large, long-term, as they raise important question about tagging, issue triaging, complaint resolution on which community consensus should be reached, and the conclusions should be added to the WG document.

By contrast, unhelpful and passive aggressive does describe your comment and several ones you made in #19730, culminating in this defiant, argument-free comment. But I generally don't think blocking you or anyone else would be the right answer, and, as argued before, it is inappropriate for WG members to block community members, just because these members post comments they dislike and/or misconstrue them as personal attacks. (If members engage in actual CoC violations, then those violations must be dealt with as such.)

@jhoneill's re-posting of his decision not to engage anymore is - to me - inherently unhelpful as well, so I pointed that out and I offered to clean the unnecessary comments up. When that offer wasn't taken, I hid my comments, which is the next best thing - you may have noticed that the comments were already hidden at the time you commented.

@mklement0
Copy link
Contributor

@SteveL-MSFT

I know this isn't pleasant, and it wasn't my preference to continue this publicly after no shared understanding about WG-member conduct could be reached here, hence my request in #19730.

Since #19730 may take a while to resolve and I knew you had seen this thread, I decided to complain somewhat publicly here, as to me the matter has some urgency. It is unfortunate that #19730 and #19731 are now linked to this issue (one by explicit comments, the other by link only), but that wasn't my choice - in fact, I deliberately wanted to avoid it.

So here we are, with my asking to add another complaint to the list:

  • It is inappropriate for WG members to threaten community members with blocking.

As noted, I'm also hoping that the behaviors I have complained about here are added as DO NOTs to the WG document.

@doctordns

This comment was marked as abuse.

@doctordns doctordns added the Resolution-Declined The proposed feature is declined. label Jun 9, 2023
@mklement0
Copy link
Contributor

@SteveL-MSFT, to bring closure to this issue:

As noted in #19730, I do hope that additional DON'Ts proscribing the behaviors complained about in this thread are added to the WG section of the governance document.

@mklement0
Copy link
Contributor

One more thing, unfortunately: @doctordns has now inappropriately blocked me too.

@Andrew74L
Copy link

Just a small point. I have always taught that All user input is dangerous and evil until you prove otherwise (and even then...).. Speaking personally, I have learned long ago that in a few cases, trailing (or leading) spaces can be problematic, and quite happily use .trim() in the PowerShell code.

So perhaps Read-Host should trim by default, and the switch to be added to the command is -NoTrim

@mklement0
Copy link
Contributor

@Andrew74L, on a quick meta note: Unless someone formally appeals the WG decision to decline this request (by @-mentioning the committee and making a focused argument), this request is in effect dead (Given what unfolded here, I definitely won't do that.)
That said, continuing the discussion - now without fear of creating a distraction - may still be worthwhile, so that general insights and insights for conceptually related future issues may be gained.

perhaps Read-Host should trim by default

I fully agree, and I've mentioned it before, but the reason I didn't suggest it as a solution is that it is technically a breaking change; from that perspective, a -Trim switch is the next best thing.

That said, at least potentially - I don't have a good sense of whether it would apply here - it could be considered a breaking change that falls into bucket 3: Unlikely Grey Area which would make it acceptable.

@ghost
Copy link

ghost commented Jun 13, 2023

This issue has been marked as declined and has not had any activity for 1 day. It has been closed for housekeeping purposes.

@ghost ghost closed this as completed Jun 13, 2023
@SteveL-MSFT
Copy link
Member

@PowerShell/powershell-committee discussed the topic of a number of reported abuses (10 incidents) and whether they broke the Code of Conduct and what appropriate action should be taken.

We do not take the Code of Conduct lightly and letting conversations that break the Conduct may be impacting our ability to attract new community members who only see the negativity that is presumed to be passively allowed. We want our community and our GitHub repos to be a safe place for professional discourse.

We reviewed each individually reported comment (across different issues) and agreed that the comments violated the Code of Conduct. Each violator has been blocked from the PowerShell org on GitHub for 30 days.

@mklement0
Copy link
Contributor

@SteveL-MSFT, please see #19730 (comment)

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement the issue is more of a feature request than a bug PowerShell-Docs needed The PR was reviewed and a PowerShell Docs update is needed Resolution-Declined The proposed feature is declined. WG-Cmdlets-Management cmdlets in the Microsoft.PowerShell.Management module
Projects
None yet
Development

No branches or pull requests

8 participants