2026-08-16
PowerShell Keep a Changelog tools Part 2
krymtkts/PSKeepAChangelogTools の 0.2.0 を公開した。
0.1.0 は AI Agent とざっと作ったのもあって New-ModuleManifest で出力させる Module Manifest の構造に依存してた。
具体的にいうと、書き換え対象の ReleaseNotes の位置を特定するのにテンプレ出力のコメントに依存して限定的なケースでしか使えず、手書きの Module manifest だと使えなかった。
流石にこれは良くないので、今回真面目に AST から ReleaseNotes の位置を見つけて書き換えるように直した。
わたしは全然知らなかったので AI Agent に色々教えてもらったのだけど、 PowerShell に備え付けの Parser class を使うことで AST を取得できる。
今回は Parser.ParseInput という渡した文字列を解析する method を使った。
以下のように AST が取得できる。
$content = '@{ PrivateData = @{ PSData = @{ ReleaseNotes = "note" } } }'
$tokens = $null
$parseErrors = $null
$manifestAst = [System.Management.Automation.Language.Parser]::ParseInput($content, [ref] $tokens, [ref] $parseErrors)
$manifestAst
# Attributes : {}
# UsingStatements : {}
# ParamBlock :
# BeginBlock :
# ProcessBlock :
# EndBlock : @{ PrivateData = @{ PSData = @{ ReleaseNotes = "note" } } }
# CleanBlock :
# DynamicParamBlock :
# ScriptRequirements :
# Extent : @{ PrivateData = @{ PSData = @{ ReleaseNotes = "note" } } }
# Parent :
$tokens | format-table
# Text TokenFlags Kind HasError Extent
# ---- ---------- ---- -------- ------
# @{ ParseModeInvariant AtCurly False @{
# PrivateData MemberName Identifier False PrivateData
# = AssignmentOperator Equals False =
# @{ ParseModeInvariant AtCurly False @{
# PSData MemberName Identifier False PSData
# = AssignmentOperator Equals False =
# @{ ParseModeInvariant AtCurly False @{
# ReleaseNotes MemberName Identifier False ReleaseNotes
# = AssignmentOperator Equals False =
# "note" ParseModeInvariant StringExpandable False "note"
# } ParseModeInvariant RCurly False }
# } ParseModeInvariant RCurly False }
# } ParseModeInvariant RCurly False }
# ParseModeInvariant EndOfInput False
これを使って Module manifest 中から PrivateData.PSData.ReleaseNotes を探し出し更新している。
万が一、要素が足りない場合は新規に作成される。
これでいったん機能的にはまともになったんではないかと思われる。
機能的にはもう自分の使いた機能の範囲では不足なさそう。 ただ一般的な用途における物足りなさはあるかも知れない。 またテストの漏れだとかコードの冗長さもあろうから、今後はその辺気が付いたら詰めていく感じかな。