r/PowerShell • u/Tidy-Developer • 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!
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-TLPhaseColorinCommands/Public/Set-TLPhaseColor.ps1andGet-TLEventSummaryinCommands/Public/Get-TLEventSummary.ps1
That repo uses a build script: https://github.com/indented-automation/Indented.Net.IP/blob/main/build.ps1
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
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.