標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

PowerShellスクリプトの scoop用パッケージのマニフェストを作ろうとしたら make-scoop-manifest が対応していなかったが、scoop 本体はバッチリ対応していた件

自作の PowerShell スクリプトを scoop でインストールできるように、make-scoop-manifest を改造した (v0.8.0)

PowerShell で最近作った Download-Count.ps1 や Update-Exe-All.ps1 を scoop でインストールできるようにしようと思ったら、make-scoop-manifest が実行ファイルと認識できるのが EXE ファイルだけでした!

ということで改造しました。

  • Release v0.9.0 · hymkor/make-scoop-manifest

    • git remote show でレポジトリの場所を得る場合、ssh プロトコルでクローンしたレポジトリしかサポートしていなかったが、https もサポートした。
  • Release v0.8.0 · hymkor/make-scoop-manifest

    • 実行ファイルのパターンを指定するオプション -binpattern PATTERN を追加 (例:-binpattern "*.exe,*.ps1,*.cmd"
    • レポジトリ名が . (ドット) を含んでいる時にレポジトリの検出ができない問題を修正
    • 与えられたパラメータの添付ファイル名が見つからなかった時、パニックが起きる問題を修正

PowerShell のレポジトリのマニフェストを作るためには、次のように呼び出します。

  • CASE 1: make-scoop-manifest -binpattern "*.ps1" -anycpu パッケージZIP... > JSONファイル名
  • CASE 2: make-scoop-manifest -binpattern "*.ps1" -anycpu -g アカウント/レポジトリ名 パッケージZIP... > JSONファイル名
  • CASE 3: make-scoop-manifest -binpattern "*.ps1" -anycpu -D -g アカウント/レポジトリ名 > JSONファイル名

-binpattern はカンマで区切って複数のパターンをワイルドカードを指定できますので、公開したいファイルだけを個別に指定することも可能です。

make-scoop-manifest の既存バグ対応 (v0.9.0)

あと、この対応をした後、気がついたのですが、CASE 1 の場合、カレントディレクトリからレポジトリ情報を得る処理に対応もれがありました。

元々の処理では

C:> git remote show -n origin
* remote origin
  Fetch URL: git@github.com:nyaosorg/nyagos.git
  Push  URL: git@github.com:nyaosorg/nyagos.git
  HEAD branch: (not queried)
  Remote branches: (status not queried)
    :

の Push URL 行を解析してアカウント名とレポジトリ名を得ていたんですが、

Push +URL: \w+@github.com:([\w\.-]+)/([\w\.-]+)\.git

という形式でしか照合していなかったので

  • git clone https://github.com/hymkor/make-scoop-manifest.git
  • git clone https://github.com/hymkor/make-scoop-manifest

という形式で clone したレポジトリでは、検出にできないという問題がありました。

それに気付き、急遽、検出パターンに

Push +URL: https://github.com/([\w\.-]+)/([\w\.-]+?)(\.git)?$

を加えて対応した次第です。

scoop はパッケージの PowerShell スクリプトをどう呼び出すか

新版 make-scoop-manifest で作成した PowerShell スクリプトは次のとおりです。

例によって

scoop bucket add hymkor https://github.com/hymkor/scoop-bucket
scoop install Download-Count.ps1

でインストールできるのですが、ここで疑問が湧きました。scoop 側の呼び出しの転送プログラムは対応しているのかな?と。

普通の実行ファイルの場合は

  • %USERPROFILE%\scoop\app\アプリ名\バージョン\ 以下の各パッケージの各バージョンのコンテンツ一式
  • %USERPROFILE%\scoop\app\アプリ名\current が最新バージョンへのジャンクション
  • %PATH% には %USERPROFILE%\scoop\shims\ だけが加えられており、このディレクトリの実行ファイル(EXEファイル)はアプリ本物の実行ファイルではなく、%USERPROFILE%\scoop\app\アプリ名\current\ 以下の実行ファイルを呼び出すだけの小さな C# モジュール

となっています。これ、もしかして、C# モジュールは EXEファイルにしか対応していないのではないのでは?

確認しました。

C:> dir %USERPROFILE%\scoop\shims\download-count*
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 0229-7A5A です

 C:\Users\hymkor\scoop\shims のディレクトリ

2024/01/27 土  13:40               400 download-count
2024/01/27 土  13:40               399 download-count.cmd
2024/01/27 土  13:40               272 download-count.ps1
               3 個のファイル               1,071 バイト
               0 個のディレクトリ  653,396,140,032 バイトの空き領域

EXEファイルがありません!そのかわりバッチファイルや PowerShell スクリプト、そして謎の拡張子なしファイルがありました。

まず、バッチファイルdownload-count.cmd:

@rem C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1
@echo off
where /q pwsh.exe
if %errorlevel% equ 0 (
    pwsh -noprofile -ex unrestricted -file "C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1"  %*
) else (
    powershell -noprofile -ex unrestricted -file "C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1"  %*
)

どうやら、最新の PowerShell: pwsh.exe がインストールされていたら、pwsh でスクリプトを呼び出し、そうでなければ OS にインストールされている PowerShell.exe を使うようになっているようです。ということは、もしや…

download-count.ps1:

# C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1
$path = Join-Path $PSScriptRoot "..\apps\download-count.ps1\current\Download-Count.ps1"
if ($MyInvocation.ExpectingInput) { $input | & $path  @args } else { & $path  @args }
exit $LASTEXITCODE

download-count (拡張子なし)

#!/bin/sh
# C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1
if command -v pwsh.exe > /dev/null 2>&1; then
    pwsh.exe -noprofile -ex unrestricted -file "C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1"  "$@"
else
    powershell.exe -noprofile -ex unrestricted -file "C:\Users\hymkor\scoop\apps\download-count.ps1\current\Download-Count.ps1"  "$@"
fi

なんと、CMD.EXE、PowerShellbash (WSL もしくは MSYS, Cygwin ?)、それぞれの実行シェル環境ごとに用意されてるようです。さすがですねー