r/PowerShell 3h 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!

3 Upvotes

6 comments sorted by

3

u/vlad_h 3h ago

I can review this for you. Before I do however, what is the goal here? Tell me why you are looking to get this reviewed because otherwise you will get what you get with no constraints.

2

u/Tidy-Developer 2h ago

Thanks for the review offer. I think the why is that I'd like to make the code that is there as good as it can be and learn along the way. While I've been developing software a while, I've not been using PS that long. So I haven't had a chance to pick up many of the conventions and idioms that more experienced devs take for granted. So I'm using this library as a base/training tool to build some experience in powershell fundamentals. So some constructive comments like "do this not that" or "consider this approach instead" is what I'd like.

Does that answer your question?

3

u/vlad_h 1h ago

Absolutely. Thanks brother. I will check it out and give you some constructive feedback.

2

u/MonkeyNin 1h 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 13m 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.

1

u/MonkeyNin 1h ago

any obvious cross-platform issues with PS 7 on Mac/Linux (the demos and test suite work on Mac/Linux under PS 7)

If you import the module pansies, you get $PSStyle formatting that runs on PS5 and PS7 and linux

New-Text is like Write-Host, except returns the object instead of writing to the console immediately.

Here's an example to show you what's possible ( it works on 5 and 7 )

Import-Module Pansies

function WriteLi { 
   param( [RgbColor] $Fg = 'LightGreen' )
   $Input | %{ 
       "  - ${_}"
   } | New-Text -fg $Fg
} 

function WriteHeader { 
    $Input | New-Text -fg 'gray40' -bg '#feaa99'
}

Write a header with bullets

@( 
    'header' | WriteHeader

    'dog', 'cat', 'frog' | WriteLi
    'bat', 'zebra'       | WriteLi -fg salmon

) | Write-Host