PowerShell / PSScriptAnalyzer

Download ScriptAnalyzer from PowerShellGallery
https://www.powershellgallery.com/packages/PSScriptAnalyzer/
MIT License
1.81k stars 366 forks source link

It is a best practice for PowerShell modules to contain help topics #259

Open raghushantha opened 9 years ago

raghushantha commented 9 years ago

A module must contain the following help depending on the type of the module:

Cmdlet Help. The Help topics that describe cmdlets in a module are XML files that use the command help schema. For more information about writing cmdlet Help, see Writing Windows PowerShell Cmdlet Help.

Provider Help. The Help topics that describe providers in a module are XML files that use the provider help schema. For information about writing provider Help files, see Writing Windows PowerShell Provider Help.

Function Help. The Help topics that describe functions in a module can be XML files that use the command help schema or comment-based Help topics within the function, or the script or script module. For more information about comment-based Help, see about_Comment_Based_Help.

Script Help. The Help topics that describe scripts in a module can be XML files that use the command help schema or comment-based Help topics in the script or script module. For more information about comment-based Help, see about_Comment_Based_Help

Conceptual ("About") Help. You can use a conceptual ("about") Help topic to describe the module and its members and to explain how the members can be used together to perform tasks. Conceptual Help topics are text files with Unicode (UTF-8) encoding. The file name must use the about_.help.txt format, such as about_MyModule.help.txt. By default, Windows PowerShell includes over 100 of these conceptual About Help topics, and they are formatted like the following example.

https://msdn.microsoft.com/en-us/library/dd878343(v=vs.85).aspx

rkeithhill commented 9 years ago

+1 for more modules shipping with an about_<modulename>.help.txt file!!

joeyaiello commented 9 years ago

Based on the community meeting: this rule would be best as a pre-requisite for submitting to the Gallery. It probably makes sense as a warning, and it would be a lot more useful with prescriptive guidance on why documentation helps with user adoption.

Jaykul commented 8 years ago

For what it's worth, I think it's a waste of time to require a file be present as a pre-req for submitting to the Gallery -- you're just going to create a lot of noise as people drop stupid, useless (nearly) empty files in there just to pass your test.

rkeithhill commented 8 years ago

@Jaykul Perhaps but for that matter they can use the SuppressMessageAttribute to hide most (all?) of their module's sins. :-) I think it's worth a warning to get folks to think about providing help. Yeah, they may just side-step the warning with a bogus help file but that will probably catch up with the module sooner or later from word of mouth/social media. I'm thinking more about folks that got a bit excited about publishing their cool new module and legitimately forgot all about help. :-)

Jaykul commented 8 years ago
It's this easy to generate one:
gcm -mo PSScriptAnalyzer | help -full | select Name, Description | ft -HideTableHeaders > about_PSScriptAnalyzer.help.txt

And yet, PSScriptAnalyzer does not have one.

How many modules do? What's the point? Who reads them?

Jaykul commented 8 years ago

As an exercise, I counted how many modules on my system have about_* text.

I have about one hundred and fifty-sixty unique modules. Seventy-five of them are Microsoft's built-in modules in C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ ... of those seventy-five, only five have even one single ".help.txt" file, and none has a about_modulename file.

My conclusion is that considering how rare they are, it's not really worth writing a help.txt file unless I actually have something to say (e.g.: about_Pester, about_PSReadLine), because people aren't going to even think to look for it.

Of the remaining 93 non-Microsoft modules I've got handy (many of which are my own, but I can't be bothered to filter those out for the sake of this comparison), only eight have help.txt, and of those, four of them have about_{mymodule}.help.txt which is pretty surprising. However, the one for ShowUI is a completely useless throw-away file created to please a previous incarnation of PSScriptAnalyzer, so it's actually a counter-example ;-)

If you could expose the about_modulename file in the module gallery, that would make it worth writing, but otherwise, I think you're just going to provoke module authors to generate junk files (they'll have every intention of "writing a real one when I get a chance", but they won't ever do it).

It would be more useful to focus efforts on things where the quality is less dubious, and making the existing tests more accurate. For instance, how about requiring command help to include a sentence in the Description field (PSScriptAnalyzer doesn't!).

rkeithhill commented 8 years ago

And yet, PSScriptAnalyzer does not have one.

I wrote one and submitted it as a PR which was accepted. The about topic should show up in a feature release.

rkeithhill commented 8 years ago

@Jaykul A good example of a module that really needs a module level help file is ShowUI. There are hundreds of commands. I have no idea where to even start.

I suggest that you take the contents of this page http://show-ui.com/Getting%20started%20with%20ShowUI/ and massage it down into an about_ShowUI help file for this module.

joeyaiello commented 8 years ago

I'd argue that, of all the types of help listed in the OP, cmdlet/function help is really the only one that should be "required" in the sense that it is a really bad practice not to include it. While @rkeithhill makes some great points about modules that could use about topics, I also think @Jaykul is right in that many modules aren't large enough to necessitate them.

As a side note, I do want to make a clarification on the "point" of Script Analyzer. While we do use many of the rules as hard or soft gates for submitting modules/scripts to the PowerShell Gallery, the primary goal of PSSA is to enable PowerShell developers to write high quality modules and scripts. After reading all of your feedback here, I think @Jaykul is probably right that, as a prerequisite to submitting to the Gallery, people will simply do the bare minimum to submit their stuff (and that doesn't provide much value).

However, that doesn't necessarily mean that it shouldn't be a rule. I'd still like to alert good faith developers to the fact that they haven't written documentation, and the onus should be on them to decide if it's worth their time or if they should simply ignore the rule.

juneb commented 8 years ago

PSScriptAnalyzer is designed to enforce best practices, not most-frequently-used practices.

I think the scarcity of About topics, or any other help, is proof of the need for this rule. If owners create empty files or unhelpful topics, users will (and should) complain. (For evidence, see Azure PowerShell.) As a frequent end-user, it is very difficult to understand how the commands in a module work together without an About topic.

Help is an integral part of PowerShell and it's critical to its continued success. As we move to open-source, third-parties need to maintain the quality bar that we established.

If people don't want to take the time to write help or Pester tests, or something else that we require, they don't need to put their module in PSGallery. They can keep it on GitHub or create an alternate repository.

kilasuit commented 8 years ago

Modules and the functions included within should at minimum contain a form of Comment based help.

Yes its irritating as hell to go back and add that help into modules once you've been working on them but without any of the help functionality the modules and the functions have the potential to become next to useless for the end user.

If Modules are correctly open sourced and there is a psd1 module manifest then there will be those out there that are willing to help add any missing help as required to existing modules.

However I for one have pulled a Module because I realised I hadn't included help in there and I am revisiting this one (and others too) to ensure that they have the help required. It may need further Improvements but at least it will be there for the end users of the modules to consume if required.

We need to make the End to End process for newcomers (and the oldies that have been sitting thinking that they can bypass learning this aswell) to PowerShell smoother which includes Default PSScriptAnalyzer RuleSets which help making scripts and modules easier to build and then publish, some will need to learn/re-learn source control methodologies and also how to write unit tests as well.

All of that is as "Core" as requiring help on a shared module - even if it doesnt leave the organisation that you are currently at.

Just my 2p worth :-)

Jaykul commented 8 years ago

Nobody disagrees that command help should be required, particularly for submission to the gallery.

However, @juneb, I emphatically insist that the absence of about files in existing modules from Microsoft and other third parties indicates that writing them is not an accepted best practice by any definition of the term.

If there is a demand for more documentation of a specific module, that's great -- file issues with that specific module. However, it is unreasonable to demand more documentation of community-provided modules than what Microsoft itself usually provides for their own in-box modules.

Microsoft only provides about topics in about 6% of modules

As far as I can tell, Microsoft have never shipped an about_ModuleName help file (certainly there aren't any in the built-in modules). The existence of these about_ModuleName files is basically a myth. They don't exist, and so, if they did exist, nobody would read them because they would not know to look for them.

There is no way to get a list of conceptual help topics filtered by module

Additionally, running a command line get-help about_* takes an extremely long time, and the results are not ordered or organized or grouped at all (on my dev systems, with SSD disks and approximately 150 modules available, it takes over 90 seconds on first run in each session).

Unless you actually have a significant new concept that needs documenting, this sort of help is therefore significantly less useful than command help, and is less likely to be read than even ReadMe documents on GitHub repositories.

Help requirements are likely to produce noise

The only useful way to test help is with human beings. While I agree that ever exposed command from a module should have help, I don't agree that it's worth preventing modules from appearing in the gallery without it.

On top of that, documentation-generating scripts and tools are common, and automated tests can't tell the difference. If you start requiring anything beyond the basics, you're going to get a lot of modules with useless crap like this:

function Get-Something {
#.Synopsis
# Gets the Something
#.Description
# Gets the Something, depending on parameters
[CmdletBinding()]
...

Personally, I'd rather not have help than have useless copy-paste or auto-generated help which forces me to read it in order to discover it's uselessness.

These are minor quality issues.

You should deal with stuff like that by having "star ratings" and reviews and comments, not by blocking the module.

Automated requirements for help are just a bad idea.

rkeithhill commented 8 years ago

@Jaykul Where did you get the impression this would be a requirement? I thought we were talking about a warning only for PSGallery submissions in this thread - not a requirement.

Regarding getting about topics for a module, it would be a nice enhancement to Get-Help to have a -Module parameter e.g. Get-Help -Module PSCX and have that list all help topics including about topics that come with the module. BTW how else are folks documenting their custom providers except via an about topic?

FWIW I get it that modules with just a handful of commands probably doesn't warrant an about topic. Then again, how hard is it to copy the text contents of your repo's readme.md file into it? Just because you don't read about topics doesn't mean that other folks don't. :-) Besides, with tools like PowerShellGet's Install-Module, I'm much less likely to bother tracking down the source of the module to look at docs there.

Jaykul commented 8 years ago

@rkeithhill re-read the first three posts on this thread. They're very clear that they must exist, and about making it a pre-requisite (although I don't understand very well the relationship between this project and the gallery).

I think providers are one case where an about_provider is the only option (and one case where people should know to look for them).

I also agree with you about copying the ReadMe (assuming you have one worth reading). I'm working on automating that for the modules I build from github.

However, although I'm sure people read about_topics, I feel fairly certain nobody looks for them in modules -- how long would they keep looking for something that doesn't exist? Especially when looking for something that doesn't exist can take several minutes!

juneb commented 8 years ago

Just a few points to respond to the long posts here, although I can't quite believe that I need to defend a best-practice requirement for good documentation.

-- PSScriptAnalyzer is a tool to encourage best practices, not common practices, so the statistics are not relevant. Many modules on PSGallery are completely untested (e.g. errors in module manifest). That would never lead us to suggest that we abandon testing.

-- Microsoft should never be used as standard for documentation best practices. Many of the Microsoft modules were written by interns or test teams, or teams that had no support from the professional writers at Microsoft.

Also, the first few modules were not small collections of commands designed to be used together for a single purpose. A topic like "about_Microsoft.PowerShell.Utility" would be rather silly. Instead, we wrote more than 80 About topics to support the content of those first snap-ins (later converted to modules).

-- PSScriptAnalyzer is a best-practice tool. Help topics, named and formatted so that Get-Help can find and display them, are a quintessential best practice.

-- About topics for modules tell the user how to use the commands in the module together to solve a problem or perform a task. They provide a starting point for looking at the commands and their help topics. Without them, every single user has to do unnecessary analysis; truly inefficient. Experienced users can figure out how to use a cmdlet and how it works. But, code can only tell you how something works -- not why. It can't tell you design and intent. That has to come from the authoring team.

-- "I'm sure people read about_topics, I feel fairly certain nobody looks for them in modules." <-- Can you please provide the data to support these claims about user behavior? The UX teams at Microsoft who gathered data in 2007 and 2009 found almost universal use of help topics in PowerShell.

KirkMunro commented 8 years ago

I agree with both @jaykul and @juneb to varying extents.

Having some sort of "getting started" guide for modules would be useful. But pushing module authors to create about files is of very questionable value. About files for modules are just raw text with no defined structure or format or content and their value would very like vary greatly from module to module, with the majority of modules being very light on content, especially given that most modules don't include about files today. I don't think they should be the target product to solve the problem that getting started with modules can be hard.

Modules, and the commands they contain, have metadata. People already get the best practice of providing documentation for commands (even if they don't always do it, myself included). Even when you don't provide that documentation though, there is still metadata. Verbs. Nouns. Syntax for parameter sets. Plus details that can be pulled from a module itself. I would prefer by far a programming product (new cmdlet, or extension to existing cmdlet) as the solution to this that would help all modules, rather than documentation which requires dividing the work across every module author. Allow me to invoke Get-Help ModuleName just like I can invoke Get-Help ProviderName today, or give me a new cmdlet (Get-ModuleHelp -Name ModuleName or something similar). Instead of some text file that has no structure, give me an automatically generated "document" (formatted PowerShell object output that I could choose to dump into a text file if I wanted to, that has properties so that other programmers can do things with it in a tool like VS Code, PowerShell ISE, or PowerShell Studio in a consistent way) that lists the commands the module contains, sorted by noun then verb and grouped by noun, with the command name, type, and synopsis (which ends up being the syntax for commands that don't have help written for them). Add to that module metadata, that includes the module description (pulled from the manifest), version, dependencies (also both from manifest), copyright, project page, license, (also from manifest for gallery-hosted modules), PowerShell requirements, etc. Also add whether or not it defines a provider, and interrogate the module metadata to identify which core cmdlets are extended for that provider and what help documentation the dynamic parameters have. Cache all of that data, for each version of each module, on my file system so that the next time I run it, it not only gets the new data, but it compares it against the old data to have a section that clearly identifies what is new when compared with the previous version, so that post Update-Module I can very quickly see what has changed. Maybe provide a getting started guide that contains the first example for each public Get- and Import- cmdlet, if examples are provided for them. Perhaps include other verbs that are "starting" verbs as well as far as pipelines are concerned. Most if not all of that can already be pulled from metadata today, without about files having to be written, and it would ensure that all modules have a starting point for newcomers that is consistent, well structured, and easily supported in the tools that those newcomers happen to be using. That is what should be done to solve the getting started with module problem in my opinion, not pushing each author to manually create and manage over time some text that would pale in comparison when considering the value offered. Plus, while it would be a decent amount of work to produce, it could be done once, and then enhanced over time, so every module gets the improvements that are added automatically. Automate the documentation by leveraging existing documentation and metadata, make this a non-issue with code, and keep plain text about files for PowerShell language and PowerShell provider help IMHO. Heck, with this as a solution, even a module that had no documentation written for it whatsoever would be much easier to consume and use because everything it can do would be put right in front of you, and as long as the names (commands, parameters) were intuitive/meaningful to you because you work in that domain, you could dive in and get started using it (not that I'm advocating that...I'm just saying this sort of functionality would go a long way to help people out when handwritten documentation isn't there).

That's my $0.02 worth.

rkeithhill commented 8 years ago

@KirkMunro I like the thinking, I just don't know how feasible that is. As PowerShellers, by definition, we love it when we can "automate" a task. But some documentation, such as how to get started with a module, can't be generated by tool IMO. That said, in PSCX we do have a script that does some of what you suggest in auto-generating the about topic. And for some modules that "might" be enough. However other modules really, really need the authors hand in crafting a good "getting started" experience. For examples see the about topics for Pester, PSReadLine and PSScriptAnalyzer.

I get that those modules are somewhat unique but I'll point to another module that really needs a good about topic and that is ShowUI. There are 100 hundreds of commands. I don't even know where to start.

Even a module with a dozen commands may have two or three "primary" commands and the other commands are "satellite" commands that serve the primary commands e.g. Invoke-Command is primary while I would consider New-PSSession a satellite command.

It would be nice for the module author to indicate what are the "common/primary" commands and which are the "satellite" commands. That would be much more convenient for me, the user, than to have to wade through help on dozens of commands. If I know which two or three commands are primary, I can start looking at their help pages.

BTW while about topics are indeed free form text there are some conventions e.g.:

TOPIC
    about_Automatic_Variables

SHORT DESCRIPTION
    Describes variables that store state information for Windows PowerShell.
    These variables are created and maintained by Windows PowerShell.

LONG DESCRIPTION
    Here is a list of the automatic variables in Windows PowerShell:
...

After that it becomes more free form but I think that is necessary to give different types of modules the ability to provide a getting started experience that works best for that module.

KirkMunro commented 8 years ago

@rkeithhill Great points. For Pester, PSReadline and PSScriptAnalyzer, those modules define new PowerShell features/tools, and I think it is very appropriate for them to include about help files since the are expanding on the overall PowerShell experience. That makes good sense And you're right, some modules that have hundreds of commands are just intimidating, so documentation of some sort is in order. For ShowUI, I think brief docs with good examples as external, runnable ps1 files that would hopefully ship with the module and run on any machine would be the best place to start. Other modules with many commands (NetApp, SharePoint, Exchange, etc.) should have docs, but those types of modules typically come from commercial entities that want documentation anyway since they are commercial product. In those examples (the huge module examples), should they have an about file? Or html/online documentation? Or a pdf? I don't think forcing an about file for them is the way to go. And proper tooling could generate html documentation using techniques like I described, with collapsable sections to keep it consumable, even for larger modules. Said tooling could even pull examples and/or demo scripts that ship with modules and that are stored in standardized locations (more metadata). There are a lot of options, and varying needs. I think automation is part of the solution and would help a lot. Documentation is probably part of it as well. But labeling about files for all modules as a best practice isn't warranted. Documentation/guidance as a best practice makes sense, but even with PowerShell being the language, about files are not the one-size-fits-all best practice that should be applied for every module that is out there. For language features or "core" functionality that is provided via module, sure. But for modules in general, not in my opinion as an author of many very small modules (although I may write an about file for a few of them), and it wasn't my opinion when I was PM for various PowerShell authoring tools in the past either (I wanted objects so that I could build reliable tools with consistent data sources, not unstructured or lightly structured text files that may have annoying differences that need to be special cased).

More evidence that there needs to be more structure when it comes to documentation in PowerShell: I recently thought it would be useful to have a Find-Example command that would take a command name (function, script, alias), resolve it if it is an alias, and find examples that show that command in use. It's useful to look at examples attached to a command, but it's also useful to look at how a command is used in conjunction with other commands in examples that they use. Example MAML is largely unstructured, so what I hoped would be a simple matter of AST parsing became a task I put on the shelf until "I have more time to look at it" (aka never).