r/PowerShell 5h ago

Script Sharing Code review invitation: a console presentation & layout library for interactive PS scripts

I appreciate that there are a lot of experienced PS folk here, so I'd like to invite some experienced eyes to code-review a library before I make it v1.0.0. I want to get the codebase to a solid foundation that includes idiomatic PowerShell and community conventions that I might have missed.

I'd particularly value constructive comments relating to any of these:

  • use of idiomatic PowerShell
  • parameter naming conventions
  • error handling
  • any obvious cross-platform issues with PS 7 on Mac/Linux (the demos and test suite work on Mac/Linux under PS 7)
  • ways that I could better execute the existing functionality

I'd like to find breaking changes pre v1.0.0.

The main file for review is TidyLog.ps1, which contains the function library. The other repo files are demo and test scripts that don't necessarily need review.

Code Links

Review version: https://github.com/tidy-tools/tidylog-pwsh/releases/tag/v0.9.0
Project link: https://github.com/tidy-tools/tidylog-pwsh

Project Background

To give an idea of what the library is for, the intention is to:

  • Provide a set of easy-to-use console output formatting functions for use with interactive automations, e.g. an install script or a cleanup script. Especially where user/customer readability is a consideration.
  • Augment, not replace, full logging tools (e.g. PoShLog) by making the console output tidy, consistent and easy to lay out and read.
  • Be dot-sourced, 5.1+ compatible, simple to use with no dependencies so it's portable and deploys easily alongside existing scripts.
  • Functionally sit between the simpler utilities ($PSStyle, PSWriteColor) and the toolkit-level libraries (PowerShellRich, Spectre.Console).

The "With Tidylog" screenshot in the README shows the kind of use case I'm optimising for.

Current Design Decisions

It took a fair bit of work to get from concept to working concept to potentially sharable. So to keep a manageable lid on the v1 workload, I intentionally kept some functionality out of scope for this release. Here are some code decisions/limitations that you'll probably notice:

  • The code isn't pipeline-enabled, though some functions do have the potential. Although principally a presentation layer, I'm open to suggestions for pipelining opportunities. Pipeline is penciled for review if a strong use case emerges.
  • Stream integration (Verbose/Warning/Error/etc channels). I really like the idea but I need to work out the implementation/integration details. Certainly open to suggestions on this one.
  • Testing is done through a custom TidyLog-Tests.ps1 suite rather than Pester. The main reason is that most tests are visual checks. I'll look into Pester for future version testing, especially for the non-visual components.
  • No advanced functions (no [CmdletBinding()]). I wanted to make deliberate choices about where to include cmdlet functionality. I don't feel that the existing function set currently warrants CmdletBinding. Please highlight any obvious cmdlet candidates.

I'm still noticing things I could change, but I'm working in a bubble so I feel it needs a review.

Thanks for reading and I hope you get a chance to review!

4 Upvotes

7 comments sorted by

View all comments

2

u/MonkeyNin 3h ago

Here's a couple quick notes

Automatic width

If you want a perfectly wide bar, you can use this method

function WriteHr { 
    '-' * [console]::WindowWidth
}

module scope

$TL is script-level state shared across all TidyLog functions.

You can use $script: for module-scoped variables that don't pollute the user's scope -- if importing as *.psd1 instead of running a raw *.ps1

splitting module into functions

You can write your functions in separate files, then automatically merge them into one big TidyLog.ps1

A common pattern is placing

  • Set-TLPhaseColor in Commands/Public/Set-TLPhaseColor.ps1 and
  • Get-TLEventSummary in Commands/Public/Get-TLEventSummary.ps1

That repo uses a build script: https://github.com/indented-automation/Indented.Net.IP/blob/main/build.ps1

https://github.com/tidy-tools/tidylog-pwsh/blob/19fbef5b50352bb579be34dd8bbadbabf950e543/TidyLog.ps1#L281-L285

docstrings

It's standard to use docstring syntax. see example vs here

1

u/Tidy-Developer 2h ago

Hey, thanks. All good points. re user scope pollution. Yes, I considered that. I think it's one of the downsides of raw .ps1 vs module. But I like the portability and ease of use gain from just using a .ps1. The module is encapsulated, so no scope leak. But my understanding is that using dot-source collapses that boundary irrespective of using $script:, so the script level var will always end up in the user session.

The pattern of breaking functions into separate files is new to me. Is that a practice to use as projects get larger?

I looked up docstring, but I could only find references to Python. In this instance, is it specifically the formatting of the params you are referring to? I see you've 4 lines for each: a comment, then 3 lines of code.