🚚

外部モジュールの静的リンクツール

に公開

なんちゃって静的リンクを行うための dotnet tool です。
GitHub アクションで使えば git submodule の代わりになるかも?

できること

ざっくり言うと xcopyrobocopy に以下の機能を追加したツールです。

  • GitHub や公開 URL からのダウンロード
  • C# スクリプト編集機能(型のアクセス範囲/名前空間の変更)

C# スクリプト専用の機能が付いていますが、それ以外の種類のファイルにも対応しています。

https://github.com/sator-imaging/DotnetTool-StaticImport

つかいかた

まずはコマンドラインからインストールを行います。(.NET SDK 8.0 以上が必要です)

dotnet tool install -g SatorImaging.DotnetTool.StaticImport

インストールすると以下の要領でコピーが行えるようになります。

# Windows なら \ を ^ にする(改行なしでも可)
static-import -o "." -i \
    "local-file.cs" \
    "github:user@repo/BRANCH_TAG_OR_COMMIT/path/to/file.cs" \
    "https://gist.githubusercontent.com/..." \  # gist からのダウンロードには Raw リンクを使う
    "https://inter.net/path/to/file.cs"

static-import --help でその他のオプションを確認できます。

GitHub オプション

GitHub リポジトリの https: アドレスからもダウンロードできますが、github: を使うと正確な更新日時を取得できるので不要なコピーを防ぐことが出来ます。

github:<USER_NAME>@<REPO_NAME>/<REF>/path/to/file.ext
  • REF: ブランチ名、タグ、コミットハッシュ

環境変数 GH_TOKEN または GITHUB_TOKEN が設定されている場合は API アクセスに使用します。(時間 60 のレート制限が緩和されます)

env:
  # GitHub CLI と共通の環境変数(片方だけでおk)
  GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

https://docs.github.com/ja/actions/how-tos/security-for-github-actions/security-guides/automatic-token-authentication

C# スクリプト編集オプション

静的リンク(ただのコピー)する際に、合わせて C# スクリプトの編集を行うことが出来ます。

  • --internal
    • 全ての public 型の可視性を internal に変更 ※ ネスト型はそのまま
  • --namespace <NAME>
    • 名前空間を指定したものに変更 ※ ネストされた namespace 構文はそのまま
    • 新しい名前が . で終わっている場合は接頭辞として追加
namespace FileScoped;  // 👈 変更される

namespace Foo.Bar.Baz  // 👈 変更される
{
    namespace Quuuuux  // 変更されない
    {
        public class MyClass  // 👈 変更される
        {
            // 変更されない
            public enum MyEnum { }
            public struct MyStruct { }
            public record MyRecord { }
            public interface IMyInterface { }
        }
    }
}

GitHub アクションでの利用

以前、コピー元からコピー先へファイルを送って PR を作るアクションを作ったのですが、トークンをコピー元のリポジトリ単位で管理する必要があり非常に面倒でした。

https://github.com/sator-imaging/Copy-to-Another-Repository

static-import はコピー先がファイルを集めるスタイルになっているので、コピー元が公開リポジトリならトークン不要で集約できます。また、プライベートなリポジトリへのアクセスもトークンをコピー先に付与するだけでおkになります。

👇 GitHub アクションでの利用サンプル

https://github.com/sator-imaging/DotnetTool-StaticImport/blob/main/.github/workflows/tests.yml

GitHub アクションで簡単・確実に PR を作る方法

static-import でファイルを集めた後に PR したいですよね。結構面倒な PR 作成処理を簡単に行う方法は以下の通り。

まずは GitHub CLI 用にアクセストークンを設定します。static-import と共通の設定です。

env:
  GH_TOKEN: ${{ github.token }}

次に GitHub CLI 用のおまじないを行います。

git config --global user.name  "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"

# プッシュしたら自動的にリモートリポジトリを追跡するように設定する
git config --global --add --bool push.autoSetupRemote true

とにかく面倒なのがファイルがあったら~~とかあーだこーだの場合は~~って条件分岐ですが、

  • 更新されたファイルがあったら PR を作る
  • 無ければエラーなしで終了

という条件であれば || を駆使すればおkです。

ちゃんとやるために色々と調べても git のバージョンが違ったりなんだりで動かないことの方が多いので、結局この方法がベストの選択です。

git fetch

# リポジトリのスイッチに失敗したら新しく作る(-c)
git switch release/${{ inputs.release_ver }} || git switch -c release/${{ inputs.release_ver }}

# リモートからプル(新しく作った場合は失敗するので || true する)
git pull || true

# リポジトリ操作
#git add **/*

# 失敗しても全部正常終了させる!
git commit -m "Precompiled Assembly for Unity" || true
git push || true
gh pr create -B main --title 'release/${{ inputs.release_ver }}' --body '' || true

https://qiita.com/sator_imaging/items/28765e4107a80eb3cd18

おわりに

System.CommandLine 2.0 ベータ版を使ってみました。.NET 10.0 の .cs ファイル直接実行と組み合わせると便利なんじゃないでしょうか。(破壊的リニューアルの理由?)

https://learn.microsoft.com/ja-jp/dotnet/standard/commandline/migration-guide-2.0.0-beta5

本当はこういうツールは全部 AI に作らせたいんですが、ワークフローが未だ定まらず Roslyn について調べる手間を無くす程度にしか活用できませんでした。

コレを作る暇があったら、、、って感じですね。

以上です。お疲れ様でした。

Discussion