提案 #1484
完了CLIコマンドのプラグインサポート
説明
プラグインからCLIコマンドを提供し、実行できるようにする手段が欲しいです。
これがあると、GUIなしでWorldを生成するインタラクティブ処理が提供できたりします。(昔の account サブコマンドみたいな)
以前に #1238 などを見て、需要はあるけどユーザからは簡単に手が出せないから諦めになってるのかなと思っています。
雑に考えた感じだと、プラグインのロードを伴わずにCLIコマンドを列挙するための仕組みとか、実際にプラグインに処理を渡す時にはコアルーチンと最低限の依存関係のロードが済んだ状態の作りこみなんかは必要かなと。
今ある core/boot/shell だとその辺はかなり割り切っているので、ちゃんと仕組みにしないといけないですね…
関連するチケット
Shibafu Midorino さんがほぼ4年前に更新
とりあえず思いつきで作ったドラフト版をブランチ topic/1484-cli-draft
として共有しておきます。名前は適当。
最低限のコアルーチンを読みながら列挙処理を走らせて実行するくらいしかしてないので、プラグインの依存関係解決とかは明示的な命令が必要。
.mikutter.yml に prelude
というキーを追加し、ここにプラグインロードに先駆けて読み込むファイルを列挙します。
~/.mikutter/plugin/test/.mikutter.yml と、同じディレクトリにCLI定義用スクリプト prelude.rb があるとして、こんな風に。
---
slug: :test
depends:
mikutter: 4.1.4
plugin: []
version: '1.0'
author:
name: test
description: ''
prelude:
- prelude.rb
そして、prelude.rb はこんな風に。
# frozen_string_literal: true
Prelude.namespace :test do
command :sample do
puts 'プラグインレベルで定義されたCLIコマンドです'
end
command :worlds, description: 'Worldを列挙' do
# プラグインの実装に依存したコードを使うためには明示的にロードする
load_plugin :activity, :world
Plugin.collect(:worlds).each do |w|
pp w
end
end
end
これで ruby mikutter.rb test:sample
と ruby mikutter.rb test:worlds
でそれぞれ呼び出せるといった感じですね。
toshi_a 初音 さんがほぼ4年前に更新
- ステータス を 分類待ち から 実装待ち に変更
これ良いですね。標準のコマンド類もこの仕組みでプラグイン化したいくらい(特に依存関係グラフの出力とか)
DSLも良い感じですが、現在のサブコマンドは、指定されたコマンドのみがロードされて実行される仕組みなので、通常起動時にはコマンドに関するコードが一切読み込まれないようになっているので、同じようにしたいです。
名前空間自体には賛成ですが、任意に決定できるようにはせず、プラグインスラッグを名前として用いることを強制して、どのプラグインが提供しているものかを名前から確実に判断できるようにしたいです。
--helpなどでコマンド一覧を取得する時には全ファイルをロードして、 Prelude.commands
を呼ぶのが楽そう。specファイルにそのへんも記述させてもいいかもしれないけれど、コマンド一覧を出したあとはどうせすぐにmikutter終了するので、読み込んじゃっていいかな
Shibafu Midorino さんがほぼ3年前に更新
toshi_a 初音 さんは #note-2 で書きました:
名前空間自体には賛成ですが、任意に決定できるようにはせず、プラグインスラッグを名前として用いることを強制して、どのプラグインが提供しているものかを名前から確実に判断できるようにしたいです。
0cb49d837d4617de721f80886cd8ec0b4d933a6c で、名前空間および名前空間を伴わないトップレベルコマンドにおいてプラグインスラッグと同名であることを必須としました。
違反した場合は例外で落とします。
また、これを前提としてコマンド実行時の読み込みの最適化を少しだけ行いました。(cf36446a569d08c7d91970870b71eefa435b6e54)
Shibafu Midorino さんがほぼ3年前に更新
01e6210f370171fa996773a15933879261fbb17f を見て、command(nil)
は流石にエラーにしたほうがいいかな……という気持ちになりました。
私としては、この場合はトップレベルで Prelude.command :slug
で書くのを推したいです。
toshi_a 初音 さんがほぼ3年前に更新
- ステータス を 実装待ち から レビュー待ち に変更
- 担当者 を Shibafu Midorino にセット
- 対象バージョン を 5.1 にセット
- ブランチ を topic/1484-cli-draft にセット
merge OKです。5.1のリリースに含めたいです。
command(nil) は流石にエラーにしたほうがいいかな……という気持ちになりました。
b48a52b7 適用前でも普通に動いてたんですが、意図通りですか?
Shibafu Midorino さんがほぼ3年前に更新
- 担当者 を Shibafu Midorino から toshi_a 初音 に変更
command(nil) は流石にエラーにしたほうがいいかな……という気持ちになりました。
どうしても気になったので ec8f4f5c168c76d86712fffd5a016f46eb5e2a28 でnil/空文字列を禁止しました。
お手数ですが、再度確認をお願いします。