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

Issues with PSAvoidUsingWriteHost #267

Closed
rkeithhill opened this issue Jul 11, 2015 · 8 comments
Closed

Issues with PSAvoidUsingWriteHost #267

rkeithhill opened this issue Jul 11, 2015 · 8 comments

Comments

@rkeithhill
Copy link
Contributor

The message guides folks to use Write-Output but Write-Output has no equivalent of -BackgroundColor/-ForegroundColor/-NoNewLine. Perhaps this rule shouldn't fire when any of these parameters are present? However when it does fire, shouldn't it be pointing folks to use Write-Information instead - at least when they are on PowerShell V5?

I have helped quite a few folks with PowerShell functions where they were using Write-Output (implicitly) in their function to notify users of what's going on in the function. Then they were confused by the fact that their function returned a collection instead of the single value they intended. They're usually even more surprised because they used "return $result" and expected that to be the only return value.

Telling a script analyzer user to use Write-Output instead of Write-Host, significantly changes semantics in a way that could break their script. Seems like this tool should obey that tenant of the Hippocratic oath - do no harm. :-)

@Jaykul
Copy link

Jaykul commented Jul 20, 2015

I thought we all agreed that Write-Host doesn't kill kittens after all ;-)

@raghushantha
Copy link
Member

The original purpose of this rule was to enable scripts to be used in an automated environment. Write-Host emits to the display and will interfere when used during a pipeline scenario.

Using Write-Host is ok when only UX is involved - in this case suppress the rule application using -ExcludeRule parameter/SuppressRule attribute/Profile

Write-Verbose would be a good candidate if Write-Output is confusing users with pipeline data.
Maybe we need to reword the warning to include usage of Write-Verbose, if the intent is to convey information to the user?

@rkeithhill
Copy link
Contributor Author

Write-Verbose would be a good candidate if Write-Output is confusing users with pipeline data.

You might also mention that Write-Information is the most direct replacement but that it is only available on PowerShell v5.

@Jaykul
Copy link

Jaykul commented Aug 6, 2015

No, @rkeithhill -- Write-Information is not a replacement for Write-Host -- EVER?

It doesn't have any output anywhere.

rantmode = ON
It's exists to provide a justification for how they re-engineered Write-Host, and so that third-party hosts can hypothetically implement cool things -- but since they prevent Write-Information from setting the tags that Write-Hosts sets, you cannot ever use Write-Information to replace Write-Host.
rantmode = OFF

In fact, as far as I have seen, there still isn't a (documented) way for third-party hosts to distinguish Write-Host output from other console text output (Out-Default), unless they completely replace the formatting sub-system starting with Out-Default.

@Jaykul
Copy link

Jaykul commented Aug 6, 2015

The bottom line here is that Write-Host is THE ONLY way to provide anything other than a blue-and-white text for user interface. If you want to highlight something, colorize output, etc., it is not only THE ONLY WAY -- it is THE RECOMMENDED WAY!!

Warning scripters to stop using it is just ridiculous.

TEACHING NEWBIES the difference between Write-Output and Write-Verbose and Write-Host is not the purpose of a linting tool.

@joeyaiello
Copy link
Contributor

We will discuss further in the meeting today, but I'd still like to capture my baseline thoughts:

Write-Host can be okay to use, but only in specific instances where are you very deliberately trying to build a UI of some kind, and can have a reasonable expectation of the host in which PowerShell is executing. For instance, PSReadline employs colored syntax highlighting as a feature of the module, but it can do some wonky stuff in the ISE (which is why we didn't enable it by default there in Windows 10). In these cases, global rule suppression makes the most sense, but it's still an edge case.

Generally speaking, scripts and modules should cater to a non-interactive context by default. (Obviously, there are some exceptions to this that use $ConfirmPreference = High, but we have -Force as a trapdoor to script writers.) We've built a set of functionality for capturing different kinds of outputs to appropriate places (e.g. Write-Progress is for long-running tasks without clogging up the pipeline, Write-Error will populate the error records, Write-Verbose only shows up when the user asks for it, etc., or you should be emitting a structured object to the pipeline) Therefore, the guidance that Write-Host should always be replaced by Write-Output is wrong because there's more nuance than that. It's not just that Write-Host shouldn't be used, but that string output should be used in different ways depending on the scenario.

I'm not exactly sure how to tackle that through our existing rules, but we should talk about it today.

@raghushantha
Copy link
Member

The guidance was updated in the rule output:
#349

@AndrewSav
Copy link

AndrewSav commented Nov 1, 2019

Here is the current wording after installing the module from the gallery:

File 'Test.ps1' uses Write-Host. Avoid using Write-Host because it might not work in all hosts, does not work when there is no host, and (prior to PS 5.0) cannot be suppressed, captured, or redirected. Instead, use Write-Output, Write-Verbose, or Write-Information.

If we run Write-Information -? in powershell 5 we will see:

Starting in Windows PowerShell 5.0, Write-Host is a wrapper for Write-Information . You can now use Write-Host to emit output to the information stream, but the $InformationPreference preference variable and InformationAction common parameter do not affect Write-Host messages

The message has a couple of problems. First it states that "Write-Host because it might not work in all hosts" and that one should use instead Write-Information. This sounds wrong, since Write-Host is a wrapper around Write-Information.

does not work when there is no host is dubious too for similar reasons.

Finally, if my script has #Requires -Version 5 the Analyzer may safely conclude that I am not interested in the warning at all, since it's not applicable to this version of Powershell.

@rkeithhill @Jaykul Do you think the wording needs to be re-considered again?

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

No branches or pull requests

5 participants