rubycli 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f9809e4d2f9c1ddb0b97f7c7cede2d665888726952e96ed5b14584e9230c617b
4
+ data.tar.gz: 538af61eb924c66fdd0bf26df5bdcfaba66fbec76daa70ddbfcef943d2cfa654
5
+ SHA512:
6
+ metadata.gz: efc21b5eddfb00f727ae0a056c7507ee36e27cc3da47c7bad0d68f310862f6cb3f7511328ec9bc2ac40f1493fa9b340892482a858623c57ec6ff8a9069ea9f73
7
+ data.tar.gz: 1f21f11831d6b90b4981034827c33ac9a27a48385fae73cf22e806b7d5728835209f231977c1ca6f609cecd7bdfe12cae30d74adeaf409e0231e616262ced993
data/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## [0.1.0] - Unreleased
4
+
5
+ ### Added
6
+ - Initial public release of Rubycli with the `rubycli` executable for running documented Ruby classes and modules.
7
+ - Documentation-driven argument parsing with strict mode validation, JSON coercion, and optional eval hooks.
8
+ - English and Japanese README guides outlining installation, quick start, and project philosophy ahead of the RubyGems publish.
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 inakaegg
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.ja.md ADDED
@@ -0,0 +1,404 @@
1
+ # Rubycli — Python Fire 風の Ruby 向け CLI
2
+
3
+ Rubycli は Ruby のクラス/モジュールに書いたコメントから CLI を自動生成する小さなフレームワークです。Python Fire にインスパイアされていますが、互換や公式ポートを目指すものではありません。Ruby のコメント記法と型アノテーションに合わせて設計しています。
4
+
5
+ > English guide is available in [README.md](README.md).
6
+
7
+ ### 1. Rubycli を意識しない既存スクリプト
8
+
9
+ ```ruby
10
+ # hello_app.rb
11
+ module HelloApp
12
+ module_function
13
+
14
+ def greet(name)
15
+ puts "Hello, #{name}!"
16
+ end
17
+ end
18
+ ```
19
+
20
+ > リポジトリには `examples/hello_app.rb` を同梱しているので、プロジェクト直下で `rubycli examples/hello_app.rb` を実行すると公開コマンドをすぐに確認できます。
21
+
22
+ ```bash
23
+ rubycli examples/hello_app.rb
24
+ ```
25
+
26
+ ```text
27
+ Usage: hello_app.rb COMMAND [arguments]
28
+
29
+ Available commands:
30
+ Class methods:
31
+ greet <name>
32
+
33
+ Detailed command help: hello_app.rb COMMAND help
34
+ Enable debug logging: --debug or RUBYCLI_DEBUG=true
35
+ ```
36
+
37
+ ```bash
38
+ rubycli examples/hello_app.rb greet
39
+ ```
40
+
41
+ ```text
42
+ Error: wrong number of arguments (given 0, expected 1)
43
+ Usage: hello_app.rb greet <NAME>
44
+
45
+ Positional arguments:
46
+ NAME
47
+ ```
48
+
49
+ ```bash
50
+ rubycli examples/hello_app.rb greet Hanako
51
+ #=> Hello, Hanako!
52
+ ```
53
+
54
+ `rubycli examples/hello_app.rb --help` を実行しても同じヘルプが表示されます。
55
+
56
+ ### 2. コメントのヒントを足してオプションを有効化
57
+
58
+ > まだ `require "rubycli"` は不要です。コメントでオプション解析とヘルプを制御します。
59
+
60
+ **簡潔なプレースホルダ記法**
61
+
62
+ ```ruby
63
+ # hello_app.rb
64
+ module HelloApp
65
+ module_function
66
+
67
+ # NAME [String] 挨拶対象
68
+ # --shout [Boolean] 大文字で出力
69
+ def greet(name, shout: false)
70
+ message = "Hello, #{name}!"
71
+ message = message.upcase if shout
72
+ puts message
73
+ end
74
+ end
75
+ ```
76
+
77
+ **YARD タグでも同様に動作**
78
+
79
+ ```ruby
80
+ # hello_app.rb
81
+ module HelloApp
82
+ module_function
83
+
84
+ # @param name [String] 挨拶対象
85
+ # @param shout [Boolean] 大文字で出力
86
+ def greet(name, shout: false)
87
+ message = "Hello, #{name}!"
88
+ message = message.upcase if shout
89
+ puts message
90
+ end
91
+ end
92
+ ```
93
+
94
+ > README に合わせたドキュメント付きの版は `examples/hello_app_with_docs.rb` として同梱しています。
95
+
96
+ ```bash
97
+ rubycli examples/hello_app_with_docs.rb
98
+ ```
99
+
100
+ ```text
101
+ Usage: hello_app_with_docs.rb COMMAND [arguments]
102
+
103
+ Available commands:
104
+ Class methods:
105
+ greet <name> [--shout=<value>]
106
+
107
+ Detailed command help: hello_app_with_docs.rb COMMAND help
108
+ Enable debug logging: --debug or RUBYCLI_DEBUG=true
109
+ ```
110
+
111
+ ```bash
112
+ rubycli examples/hello_app_with_docs.rb greet --help
113
+ ```
114
+
115
+ ```text
116
+ Usage: hello_app_with_docs.rb greet <NAME> [--shout]
117
+
118
+ Positional arguments:
119
+ NAME [String] 挨拶対象
120
+
121
+ Options:
122
+ --shout [Boolean] 大文字で出力 (default: false)
123
+ ```
124
+
125
+ ```bash
126
+ rubycli examples/hello_app_with_docs.rb greet --shout Hanako
127
+ #=> HELLO, HANAKO!
128
+ ```
129
+
130
+ CLI に公開したくないヘルパーは、特異クラス側で `private` として定義してください:
131
+
132
+ ```ruby
133
+ module HelloApp
134
+ class << self
135
+ private
136
+
137
+ def internal_ping(url)
138
+ # CLI コマンドとしては露出しない
139
+ end
140
+ end
141
+ end
142
+ ```
143
+
144
+ ### 3. (任意)スクリプト内にランナーを組み込む
145
+
146
+ `ruby hello_app.rb ...` の形で呼び出したい場合だけ `require "rubycli"` を追加し、`Rubycli.run` に制御を渡します(後述のクイックスタート参照)。
147
+
148
+ ## 開発方針
149
+
150
+ - **便利さが最優先** – 既存の Ruby スクリプトを最小の手間で CLI 化できることを目的にしており、Python Fire の完全移植は目指していません。
151
+ - **インスパイアであってポートではない** – アイデアの出自は Fire ですが、同等機能を揃える予定は基本的にありません。Fire 由来の未実装機能は仕様です。
152
+ - **コードが一次情報、コメントは補助** – メソッド定義こそが真実であり、コメントはヘルプを豊かにする付加情報です。コメントと実装のズレを観測したいときだけ `RUBYCLI_STRICT=ON` で厳格モードを有効化し、警告を受け取ります。
153
+ - **軽量メンテナンス** – 実装の多くは AI 支援で作られており、深い Ruby メタプログラミングを伴う大規模拡張は想定外です。Fire 互換を求める PR は事前相談をお願いします。
154
+
155
+ ## 特徴
156
+
157
+ - コメントベースで CLI オプションやヘルプを自動生成
158
+ - YARD 形式と `NAME [Type] 説明…` の簡潔記法を同時サポート
159
+ - `--json-args` で渡された引数を自動的に JSON パース
160
+ - `--pre-script`(エイリアス: `--init`)で任意の Ruby コードを評価し、その結果オブジェクトを公開
161
+ - `RUBYCLI_STRICT=ON` で有効化できる厳格モードにより、コメントとシグネチャの矛盾を警告として検知可能
162
+
163
+ ## Python Fire との違い
164
+
165
+ - **コメント対応のヘルプ生成**: コメントがあればヘルプに反映しつつ、最終的な判断は常にライブなメソッド定義に基づきます。
166
+ - **型に基づく解析**: `NAME [String]` や YARD タグから型を推論し、真偽値・配列・数値などを自動変換します。
167
+ - **厳密な整合性チェック**: 厳格モードを有効にすれば、コメントとメソッド定義が食い違う際に警告を出して保守性を高められます。
168
+ - **Ruby 向け拡張**: キーワード引数やブロック (`@yield*`) といった Ruby 固有の構文に合わせたパーサや `RUBYCLI_*` 環境変数を用意しています。
169
+
170
+ | 機能 | Python Fire | Rubycli |
171
+ | ---- | ----------- | -------- |
172
+ | 属性の辿り方 | オブジェクトを辿ってプロパティ/属性を自動公開 | 対象オブジェクトの公開メソッドをそのまま公開(暗黙の辿りは無し) |
173
+ | クラス初期化 | `__init__` 引数を CLI で自動受け取りインスタンス化 | `--new` を指定した明示的な初期化のみ。引数はコメントで宣言 |
174
+ | インタラクティブシェル | コマンド未指定時に Fire REPL を提供 | インタラクティブモード無し。コマンド実行専用 |
175
+ | 情報源 | 反射で引数・プロパティを解析 | ライブなメソッド定義を基点にしつつコメントをヘルプへ反映 |
176
+ | 辞書/配列 | dict/list を自動でサブコマンド化 | クラス/モジュールのメソッドに特化(辞書自動展開なし) |
177
+
178
+ ## インストール
179
+
180
+ まだ RubyGems で公開していません。リポジトリをクローンしてローカルパスを Bundler に指定するか、`.gemspec` 追加後に `gem build` で `.gem` を作成してインストールしてください。
181
+
182
+ ```bash
183
+ git clone https://github.com/inakaegg/rubycli.git
184
+ cd rubycli
185
+ # gem build rubycli.gemspec
186
+ gem build rubycli.gemspec
187
+ gem install rubycli-<version>.gem
188
+ ```
189
+
190
+ Bundler 例:
191
+
192
+ ```ruby
193
+ # Gemfile
194
+ gem "rubycli", path: "path/to/rubycli"
195
+ ```
196
+
197
+ ## クイックスタート(Rubycli をスクリプトに組み込む)
198
+
199
+ ステップ3では `require "rubycli"` を追加し、スクリプト自身から CLI を起動できるようにします。
200
+
201
+ ```ruby
202
+ # hello_app.rb
203
+ require "rubycli"
204
+
205
+ module HelloApp
206
+ module_function
207
+
208
+ # NAME [String] 挨拶対象
209
+ # --shout [Boolean] 大文字で出力
210
+ # => [String] 出力したメッセージ
211
+ def greet(name, shout: false)
212
+ message = "Hello, #{name}!"
213
+ message = message.upcase if shout
214
+ puts message
215
+ message
216
+ end
217
+ end
218
+
219
+ Rubycli.run(HelloApp)
220
+ ```
221
+
222
+ 実行例:
223
+
224
+ ```bash
225
+ ruby hello_app.rb greet Taro
226
+ #=> Hello, Taro!
227
+
228
+ ruby hello_app.rb greet Taro --shout
229
+ #=> HELLO, TARO!
230
+ ```
231
+
232
+ `require "rubycli"` を書かなくても、付属コマンドから同じファイルを実行できます:
233
+
234
+ ```bash
235
+ rubycli path/to/hello_app.rb greet --shout Hanako
236
+ ```
237
+
238
+ クラス/モジュール名を省略した場合でも、ファイル名に対応する定義を自動で推測し、ネストした `Module1::Inner::Runner` のようなクラスも見つけ出します。CLI から実行するとメソッドの戻り値は常に標準出力へ表示されます。
239
+
240
+ 別の定数を明示的に指定したい場合は、ファイルパスの後ろに続けてください:
241
+
242
+ ```bash
243
+ rubycli scripts/multi_runner.rb Admin::Runner list --active
244
+ ```
245
+
246
+ 1つのファイルに複数の候補がある場合や、ファイル名と異なるネストした定義を選びたいときに便利です。
247
+
248
+ ## コメント記法
249
+
250
+ | 用途 | YARD 互換 | 簡潔記法 |
251
+ | ---- | --------- | -------- |
252
+ | 位置引数 | `@param name [Type] 説明` | `NAME [Type] 説明`(NAME は大文字) |
253
+ | キーワード引数 | 同上 | `--flag -f FLAG [Type] 説明` |
254
+ | 戻り値 | `@return [Type] 説明` | `=> [Type] 説明` |
255
+
256
+ 型は `String` や `Integer` のほか、`String[]` や `Array<String>`, `String | nil` なども利用できます。`[VALUE]` や `[VALUE...]` といったプレースホルダ表現で、真偽値や可変長引数を推論させられます。型名を省略した大文字プレースホルダ(例: `--quiet`)は自動的に Boolean フラグとして扱われます。
257
+
258
+ 代表的な推論例:
259
+
260
+ - `ARG1` のように型ラベルを省略した大文字プレースホルダは既定で `String` として扱われます。
261
+ - `--name ARG1` のようにオプションへ大文字プレースホルダだけを指定しても同じく `String` が推論されます。
262
+ - `--verbose` のように値プレースホルダを省略したオプションは Boolean フラグとして扱われます。
263
+
264
+ `@example` や `@raise`, `@see`, `@deprecated` などその他の YARD タグは、現状ヘルプ出力には反映されません。
265
+
266
+ 従来の `@param` 記法も既定で利用できます。簡潔なプレースホルダ記法だけに限定したい場合は `RUBYCLI_ALLOW_PARAM_COMMENT=OFF` を設定してください(厳格モードでの検証は継続されます)。
267
+
268
+ ### コメントが不足している場合のフォールバック
269
+
270
+ Rubycli は常に実装中のメソッドシグネチャを信頼します。コメントに書いていない引数やオプションがあっても、定義そのものから名前や初期値を推論して CLI に表示します。
271
+
272
+ ```ruby
273
+ # fallback_example.rb
274
+ module FallbackExample
275
+ module_function
276
+
277
+ # AMOUNT [Integer] 処理対象の数値
278
+ def scale(amount, factor = 2, clamp: nil, notify: false)
279
+ result = amount * factor
280
+ result = [result, clamp].min if clamp
281
+ puts "Scaled to #{result}" if notify
282
+ result
283
+ end
284
+ end
285
+ ```
286
+
287
+ ```bash
288
+ rubycli examples/fallback_example.rb
289
+ ```
290
+
291
+ ```text
292
+ Usage: fallback_example.rb COMMAND [arguments]
293
+
294
+ Available commands:
295
+ Class methods:
296
+ scale <amount> [<factor>] [--clamp=<value>] [--notify=<value>]
297
+
298
+ Detailed command help: fallback_example.rb COMMAND help
299
+ Enable debug logging: --debug or RUBYCLI_DEBUG=true
300
+ ```
301
+
302
+ ```bash
303
+ rubycli examples/fallback_example.rb scale --help
304
+ ```
305
+
306
+ ```text
307
+ Usage: fallback_example.rb scale <AMOUNT> [<FACTOR>] [--clamp=<value>] [--notify]
308
+
309
+ Positional arguments:
310
+ AMOUNT [Integer] 処理対象の数値
311
+ [FACTOR] (default: 2)
312
+
313
+ Options:
314
+ --clamp CLAMP (type: String) (default: nil)
315
+ --notify (type: Boolean) (default: false)
316
+ ```
317
+
318
+ `AMOUNT` だけがドキュメント化されていますが、`factor` や `clamp`, `notify` も自動的に補完され、既定値や型が推論されていることがわかります。コメントとシグネチャの矛盾を早期に検知したい場合は `RUBYCLI_STRICT=ON` で厳格モードを有効化してください。
319
+
320
+ #### 存在しない引数やオプションをコメントに書いた場合
321
+
322
+ - **整合しないコメントは詳細テキストへフォールバック** – 実装に存在しないオプション(例: `--ghost`)や位置引数(例: `EXTRA`)を記述すると、その行はヘルプ末尾の詳細セクションに素のテキストとして表示され、実際の引数としては機能しません。厳格モードなら `Extra positional argument comments were found: EXTRA` のような警告が出て、位置引数のズレにも気付きやすくなります。
323
+
324
+ > 実際に確認したい場合は `rubycli examples/fallback_example_with_extra_docs.rb scale --help` を試してみてください。
325
+
326
+ コメントだけでは実装を拡張できません。メソッドシグネチャとコメントを一致させておくことで、ヘルプと挙動の整合性を保てます。
327
+
328
+ ### YARD 互換コメントを併用する際の注意点
329
+
330
+ - `**kwargs` を受け取るメソッドでも、Rubycli は個別のキーワードコメント(`--config-path ...` など)が無い限りヘルプへ露出させません。CLI で使わせたいキーはすべて `--LONG-NAME PLACEHOLDER [Type] 説明` の行として明示してください。
331
+ - `@param` で位置引数を記述した場合も解析できますが、位置引数・キーワード引数を同じ行形式で列挙する必要があります。`@param source Path` のように書いても、キーワード向けのロングオプションが自動生成されるわけではありません。
332
+ - `@param` の行に続く箇条書きや補足行は CLI の自動生成には使われません。補足情報を表示したい場合は、`--flag ...` 行の説明に含めるか、README など別のドキュメントで扱ってください。
333
+ - `RUBYCLI_ALLOW_PARAM_COMMENT=OFF` にすると `@param`/`@return` などのタグは警告扱いになります。プロジェクト内で簡潔記法へ統一するときはこの環境変数で段階的に移行できます。
334
+
335
+ ## JSON モード
336
+
337
+ CLI 実行時に `--json-args` を付けると、後続の引数が JSON として解釈され Ruby オブジェクトに変換されます。
338
+
339
+ ```bash
340
+ rubycli --json-args my_cli.rb MyCLI run '["--config", "{\"foo\":1}"]'
341
+ ```
342
+
343
+ プログラム側では `Rubycli.with_json_mode(true) { … }` で同じ効果を得られます。
344
+
345
+ ## Eval モード
346
+
347
+ `--eval-args` を使うと、後続の引数を Ruby コードとして評価した結果を CLI に渡せます。JSON では表現しづらいオブジェクトを扱いたいときに便利です。
348
+
349
+ ```bash
350
+ rubycli --eval-args scripts/data_cli.rb DataCLI run '(1..10).to_a'
351
+ ```
352
+
353
+ 評価は `Object.new.instance_eval { binding }` に対して行われるため、信頼できる環境でのみ利用してください。プログラム側からは `Rubycli.with_eval_mode(true) { … }` で有効化できます。
354
+
355
+ `--eval-args` と `--json-args` は同時指定できません。両方付けた場合はエラーになります。
356
+
357
+ ## Pre-script ブートストラップ
358
+
359
+ 付属 CLI を起動するときに `--pre-script SRC`(別名: `--init`)を指定すると、公開メソッドを呼び出す前に任意の Ruby コードを評価できます。評価は隔離された binding 内で行われ、以下のローカル変数があらかじめ用意されています。
360
+
361
+ - `target` – `--new` を適用する前のクラス/モジュール
362
+ - `current` / `instance` – 現在公開予定のオブジェクト(`--new` を指定した場合は生成済みインスタンス)
363
+
364
+ スクリプトの最後に評価された値が新しい公開対象になります。`nil` を返した場合は直前のオブジェクトを維持します。
365
+
366
+ インラインで書く例:
367
+
368
+ ```bash
369
+ rubycli --pre-script 'InitArgRunner.new(source: "cli", retries: 2)' \
370
+ lib/init_arg_runner.rb summarize --verbose
371
+ ```
372
+
373
+ ファイルに切り出す例:
374
+
375
+ ```ruby
376
+ # scripts/bootstrap_runner.rb
377
+ instance = InitArgRunner.new(source: "preset")
378
+ instance.logger = Logger.new($stdout)
379
+ instance
380
+ ```
381
+
382
+ ```bash
383
+ rubycli --pre-script scripts/bootstrap_runner.rb \
384
+ lib/init_arg_runner.rb summarize --verbose
385
+ ```
386
+
387
+ この仕組みを使えば、`--new` のシンプルさを保ったまま、DI 風の初期化やラッパーオブジェクトの準備といった高度な前処理を CLI で行えます。
388
+
389
+ ## 環境変数とフラグ
390
+
391
+ | 変数 / フラグ | 説明 | 既定値 |
392
+ | ------------- | ---- | ------ |
393
+ | `--debug` / `RUBYCLI_DEBUG=true` | デバッグログ表示 | `false` |
394
+ | `RUBYCLI_STRICT=ON` | 厳格モードを有効化(コメントとシグネチャの矛盾を警告) | `OFF` |
395
+ | `RUBYCLI_ALLOW_PARAM_COMMENT=OFF` | レガシーな `@param` 記法を無効化(互換性のため既定では ON) | `ON` |
396
+
397
+ ## Rubycli API
398
+
399
+ - `Rubycli.parse_arguments(argv, method)` – コメント情報を考慮した引数解析
400
+ - `Rubycli.available_commands(target)` – 公開 CLI コマンド一覧
401
+ - `Rubycli.usage_for_method(name, method)` – 指定メソッドのヘルプ生成
402
+ - `Rubycli.method_description(method)` – 構造化されたドキュメント取得
403
+
404
+ ご意見・フィードバックは Issue や Pull Request でお寄せください。