2021-07-18

psake の Task 名を自動補完する

ほぼ趣味レベルなのだが、所謂タスクランナーとしてpsakeを使っている。趣味レベルなのは、Go とか Python とかでは make を使うので psake を製品コードでは使ったことなくて、自分の細々とした面倒な処理をスクリプト化してまとめるのに psake を使ってるからだ。

そんな訳で利用頻度も高くなかったのだが、なんか最近は AWS のリソースを操作するニッチなスクリプト(例えば開発環境とかステージング環境だけに使うようなやつ)が大量にあって、それをまとめるのに使い出した。 その御蔭で利用頻度が高まり、いやーよくできたツールやな~などと改めて思っていたが、今まで不満に感じなかった自動補完がないことがストレスになってきた。タスクが増え過ぎて名前が覚えられないのだ。

ギッハブの repo を確認すると、古のTabExpansion版はあれど、今どきのRegister-ArgumentCompleter版がない。 psake/PsakeTabExpansion.ps1 at master · psake/psake

今更TabExpansion使いたくないので、Register-ArgumentCompleter用に合わせてこしらえた。

This is Register-ArgumentCompleter version of https://github.com/psake/psake/blob/master/tabexpansion/PsakeTabExpansion.ps1.

使ってみていまんとこ良さそうな感じ。問題なさそうなら本家に PRO ぶん投げてみてもいいかもね。


以下はRegister-ArgumentCompleterのスクリプトブロックをデバッグするときの個人的メモ。

その時の入力でトリガーされたスクリプトブロックの引数を確認するのに Write-Host とか使うと厄介だと思うので、ログファイル的なものをこしらえておき、別窓でtailしてあげると見易くなる(と思っている)。

Register-ArgumentCompleter -CommandName Invoke-Psake -ParameterName taskList -ScriptBlock {
param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
"$commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters" >> test.log
if ($commandAst -match '(?<file>[^\.]*\.ps1)') {
$file = $Matches.file
"YEAH" >> test.log
}
else {
$file = 'psakefile.ps1'
"DEFAULT" >> test.log
}
& $commandName -buildFile $file -docs -nologo | Out-String -Stream | ForEach-Object { if ($_ -match "^[^ ]*") { $matches[0] } } | `
Where-Object { $_ -notin ('Name', '----', '') } | Where-Object { !$wordToComplete -or $_ -like "$wordToComplete*" }
}
Get-Content .\test.log -Wait -Tail 10
# Invoke-psake, taskList, I, invoke-psake -buildFile .\psakefile.ps1 -taskList I, System.Collections.Hashtable
# Invoke-psake, taskList, In, invoke-psake -taskList In, System.Collections.Hashtable
# DEFAULT
# Invoke-psake, taskList, I, invoke-psake -buildFile .\psakefile.ps1 -taskList I, System.Collections.Hashtable
# YEAH

どーでもいーけどこの日記の deploy をギッハブアクション化したい。


追記。

デバッグ中に気づいたのだが、プロファイル内で $psake という変数を作ると Invoke-psake が壊れるという事に気づいた。

🤖 takatoshi  invoke-psake -nologo
Test-Path: C:\Program Files\PowerShell\Modules\psake\4.9.0\private\Get-DefaultBuildFile.ps1:9
Line |
9 | if (test-path $psake.config_default.buildFileName -pathType Leaf) …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Value cannot be null. (Parameter 'The provided Path argument was null or an empty collection.')

Test-Path: C:\Program Files\PowerShell\Modules\psake\4.9.0\private\Get-DefaultBuildFile.ps1:11
Line |
11 | … } elseif (test-path $psake.config_default.legacyBuildFileName -path
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Value cannot be null. (Parameter 'The provided Path argument was null or an empty collection.')

InvalidOperation: C:\Program Files\PowerShell\Modules\psake\4.9.0\public\Invoke-psake.ps1:327
Line |
327 | $psake.build_success = $false
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| The property 'build_success' cannot be found on this object. Verify that the property exists and can be set.

罠すぎる...