Dynamic Nested Commands #85
Replies: 6 comments 4 replies
-
I hate the say I solved the common options problem by using a #!/usr/bin/env ruby
# nested.rb
# gets common options from a text file via class_eval
require "tty-option"
module App
class Command
include TTY::Option
class_eval File.open(__dir__ + '/common_options.txt').read
class << self
@@commands_available = []
def names
'['+ @@commands_available.join('|')+']'
end
def inherited(subclass)
@@commands_available << subclass.to_s.downcase.split('::').last
end
end
end
class One < Command
include TTY::Option
usage do
desc "Do Number One"
end
flag :one_flag_to_rule_them_all do
long "--one"
desc "Number One's Flag"
end
example "app one --one"
class_eval File.open(__dir__ + '/common_options.txt').read
end
class Two < Command
include TTY::Option
usage do
desc "Do Number Two"
end
flag :number_two do
long '--two'
desc "Flag Number Two"
end
example "app two --two"
class_eval File.open(__dir__ + '/common_options.txt').read
end
end
# Load TTY-Option's command content with available commands
App::Command.command App::Command.names
cmds = App::Command.new
puts cmds.help
puts "="*42
one = App::One.new
puts one.help
puts "="*42
two = App::Two.new
puts two.help This is the # common_options.txt
header "** Useful?? **"
footer "Another questionable experiment by the MadBomber"
usage do
program "app"
end
flag :verbse do
short "-v"
long "--verbose"
desc "Talk alot"
end
flag :debug do
short "-d"
long "--debug"
desc "Use Native Intelligence (NI) to solve the problem"
end
flag :help do
short "-h"
long "--help"
desc "Display help information"
end When you run the main app.rb file you get this output: 17:28:29 3.2.2 master venus:tty_option $ ./nested.rb ** Useful?? ** Usage: nested [one|two] [OPTIONS] Options: -d, --debug Use Native Intelligence (NI) to solve the problem -h, --help Display help information -v, --verbose Talk alot Another questionable experiment by the MadBomber ========================================== ** Useful?? ** Usage: nested one [OPTIONS] Do Number One Options: -d, --debug Use Native Intelligence (NI) to solve the problem -h, --help Display help information --one Number One's Flag -v, --verbose Talk alot Examples: app one --one Another questionable experiment by the MadBomber ========================================== ** Useful?? ** Usage: nested two [OPTIONS] Do Number Two Options: -d, --debug Use Native Intelligence (NI) to solve the problem -h, --help Display help information --two Flag Number Two -v, --verbose Talk alot Examples: app two --two Another questionable experiment by the MadBomber |
Beta Was this translation helpful? Give feedback.
-
Hi Dewayne 👋 Again, thanks for sharing your experiments in using At heart, the
So what you're trying to do, namely inherit common options works out of the box. However, you have overridden the On the subject of nested commands. I have started the tty-runner project to provide this functionality. It is not finished. Why? There were some fundamental issues I have found that require more thought and a different approach. I plan to resume work on this as it is a crucial piece for the tty suite. |
Beta Was this translation helpful? Give feedback.
-
My experiment with nested optional commands with command descriptions in the base command help block with common options is over thanks to @piotrmurach for the push telling me to get out of the way and let TTY::Option do its normal common options thing. Here is the final code. Note the use of class veriables and additional class methods in the top-level command. #!/usr/bin/env ruby
# nested.rb with optional commands desc in help block
require "tty-option"
module App
class Command
include TTY::Option
header "** Useful?? **"
footer "Another questionable experiment by the MadBomber"
usage do
program "app"
end
flag :verbse do
short "-v"
long "--verbose"
desc "Talk alot"
end
flag :debug do
short "-d"
long "--debug"
desc "Use Native Intelligence (NI) to solve the problem"
end
flag :help do
short "-h"
long "--help"
desc "Display help information"
end
class << self
@@subclasses = []
@@commands_available = []
def names
'['+ @@commands_available.join('|')+']'
end
def inherited(subclass)
super
@@subclasses << subclass
@@commands_available << subclass.to_s.downcase.split('::').last
end
def command_descriptions
help_block = "Optional Command Available:"
@@commands_available.size.times do |x|
klass = @@subclasses[x]
help_block << "\n " + @@commands_available[x] + " - "
help_block << klass.class_variable_get(:@@desc).join("\n")
end
help_block
end
end
end
class One < Command
include TTY::Option
usage do
# NOTE: Did not see where TTY::Option made its
# properties available so used own class veriable
@@desc = desc "Do Number One"
end
flag :one_flag_to_rule_them_all do
long "--one"
desc "Number One's Flag"
end
example "app one --one"
end
class Two < Command
include TTY::Option
usage do
@@desc = desc "Do Number Two"
end
flag :number_two do
long '--two'
desc "Flag Number Two"
end
example "app two --two"
end
end
# First Load TTY-Option's command content with all available commands
# then these have access to the entire ObjectSpace ...
App::Command.command App::Command.names
App::Command.example App::Command.command_descriptions
# Demo the Help Content ...
cmds = App::Command.new
puts cmds.help
puts "="*42
one = App::One.new
puts one.help
puts "="*42
two = App::Two.new
puts two.help Here is the output ...
|
Beta Was this translation helpful? Give feedback.
-
Thank you for the feedback. I've incorporated your simplifications into my
experiment.
https://github.com/MadBomber/experiments/blob/master/cli_options/tty_option/nested.rb
Dewayne
o-*
…On Wed, Aug 30, 2023 at 4:12 PM Piotr Murach ***@***.***> wrote:
I had a play with your solution. There are a couple of tweaks that may
improve it. Essentially, you don't need to use the usage and you can skip
it and use various DSL methods like command and desc directly within the
scope of a class. Also, I discovered that there is probably some bug with
the usage helper. Another thing is that these methods double as writers
and readers. Therefore you can simplify some calls.
For example, call command on a subclass like so:
def inherited(subclass)
super
@@subclasses << subclass
@@commands_available << subclass.command.join # need to join as it is always an array
end
Or, call desc on a subclass to retrieve the command description(provided
the desc is not inside usage - this seems a bug as it works for the command
fine):
@@commands_available.size.times do |x|
klass = @@subclasses[x]
help_block << "\n " + @@commands_available[x] + " - "
help_block << klass.desc.join # need to join as it is always an arrayend
This should remove the need for tracking command descriptions.
—
Reply to this email directly, view it on GitHub
<#85 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAFE3I3CDKK5NV3LURSRATXX6UEDANCNFSM6AAAAAA3ZCPYCE>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
@MadBomber Shall we close this discussion? I believe we pushed it as far as possible. The only thing I'd add is that |
Beta Was this translation helpful? Give feedback.
-
Yes. It cam be closed. When |
Beta Was this translation helpful? Give feedback.
-
You can continue to add subclasses of the Command class without having to update the previously static text in the
command
DSL method.Here is the output this code productes:
Still to be solved:
Beta Was this translation helpful? Give feedback.
All reactions