Closed rchady closed 6 years ago
Hi,
The approach that I use in Nanoc is the following.
To define a command, read it and call .define
with the code and filename (the filename is useful because it ensures any back traces are sensible):
code = File.read(filename, encoding: 'UTF-8')
cmd = Cri::Command.define(code, filename)
I realised that .define
used this way is not documented — will fix.
You can infer the name of the command from the filename, if you wish:
command_name = File.basename(filename, '.rb')
cmd.modify { name command_name }
You can stick that code in a helper function e.g. load_command
, and then use it as follows to load subcommands:
root_cmd = load_command('commands/nanoc.rb')
root_cmd.add_cmd(load_command('commands/compile.rb'))
root_cmd.add_cmd(load_command('commands/view.rb'))
root_cmd.add_cmd(load_command('commands/deploy.rb'))
You can additionally use something like Dir[…]
to remove the repetition, if you want.
Does this solve your concern?
The upcoming release of Cri will add .load_file
, so you’ll be able to do
root_cmd = Cri::Command.load_file('commands/nanoc.rb')
root_cmd.add_command(Cri::Command.load_file('commands/comile.rb'))
root_cmd.add_command(Cri::Command.load_file('commands/view.rb'))
root_cmd.add_command(Cri::Command.load_file('commands/check.rb'))
It is a convenient wrapper around Cri::Command.define
with a string containing code.
… and an infer_name
option as well, e.g.
cmd = Cri::Command.load_file('commands/check.rb', infer_name: true)
cmd.name
will be check
.
This is now released in v2.14.0.
Perfect, thanks!
Trying to split my command up in to separate files with the sub-commands each in their own file. However, this seems to not work as you can't pass in root_cmd when you require (so you could do the add_command in each file) and if you set a variable in the sub-command file it won't exist in the root_cmd file...
So, is it possible to create classes instead, or am I missing something else obvious?