Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
($Release: 0.1.0 $)
Benry::CLI is a MVC-like framework for command-line application.
It is suitable for command-line application such as git
, gem
or rails
.
Compared with Rake, Benry::CLI have a distinct advantage:
If you use Rake as command-line application framework instead of build tool, take account of Benry::CLI as an alternative of Rake.
(Benry::CLI requires Ruby >= 2.0)
ex1.rb:
require 'benry/cli'
##
## Define subclass of Benry::CLI::Action (= controller class).
##
class HelloAction < Benry::CLI::Action
##
## Define action (= sub-command) with @action.()
##
@action.(:hello, "print hello message")
def do_hello(name='World')
puts "Hello, #{name}!"
end
##
## When action name is nil then method name is used as action name instead.
##
@action.(nil, "print goodbye message")
def goodbye(name='World')
puts "Goodbye, #{name}!"
end
end
VERSION = "1.0"
def main()
##
## Create application object with desription, version and action classes.
## When 'action_classes' is nil, then all subclasses of Benry::CLI::Action
## are used instead.
##
classes = [
HelloAction,
]
app = Benry::CLI::Application.new("example script",
version: VERSION,
action_classes: classes)
app.main()
end
if __FILE__ == $0
main()
end
Example:
$ ruby ex1.rb hello
Hello, World!
$ ruby ex1.rb hello ruby
Hello, ruby!
$ ruby ex1.rb goodbye
Goodbye, World!
$ ruby ex1.rb goodbye sekai
Goodbye, sekai!
Help mesage:
$ ruby ex1.rb --help # or: ruby ex1.rb help
example script
Usage:
ex1.rb [<options>] <action> [<args>...]
Options:
-h, --help : print help message
--version : print version
Actions:
goodbye : print goodbye message
hello : print hello message
(Run `ex1.rb help <action>' to show help message of each action.)
ex2.rb:
require 'benry/cli'
class OptionTestAction < Benry::CLI::Action
##
## Define command-line options with @option.()
##
@action.(:hello1, "say hello")
@option.('-q, --quiet' , "quiet mode") # no argument
@option.('-f, --format=TYPE' , "'text' or 'html'") # required arg
@option.('-d, --debug[=LEVEL]', "debug level") # optional arg
def do_hello1(name='World', quiet: nil, format: nil, debug: nil)
puts "name=%p, quiet=%p, format=%p, debug=%p" % \
[name, quiet, format, debug]
end
##
## Long-only version
##
@action.(:hello2, "say hello")
@option.('--quiet' , "quiet mode") # no argument
@option.('--format=TYPE' , "'text' or 'html'") # required arg
@option.('--debug[=LEVEL]', "debug level") # optional arg
def do_hello2(name='World', quiet: nil, format: nil, debug: nil)
puts "name=%p, quiet=%p, format=%p, debug=%p" % \
[name, quiet, format, debug]
end
##
## Short-only version
##
@action.(:hello3, "say hello")
@option.('-q' , "quiet mode") # no argument
@option.('-f TYPE' , "'text' or 'html'") # required arg
@option.('-d[=LEVEL]', "debug level") # optional arg
def do_hello3(name='World', q: nil, f: nil, d: nil)
puts "name=%p, q=%p, f=%p, d=%p" % \
[name, q, f, d]
end
##
## Change keyword arg name without '--long' option
##
@action.(:hello4, "say hello")
@option.(:quiet, '-q ' , "quiet mode") # no argument
@option.(:format, '-f TYPE ' , "'text' or 'html'") # required arg
@option.(:debug, '-d[=LEVEL]' , "debug level") # optional arg
def do_hello4(name='World', quiet: nil, format: nil, debug: nil)
puts "name=%p, quit=%p, format=%p, debug=%p" % \
[name, quiet, format, debug]
end
end
def main()
app = Benry::CLI::Application.new(version: '1.0')
app.main()
end
if __FILE__ == $0
main()
end
Example:
## no options
$ ruby ex2.rb hello world
name="world", quiet=nil, format=nil, debug=nil
## with some options
$ ruby ex2.rb hello -d -f foo.txt -d2 world
name="world", quiet=nil, format="foo.txt", debug="2"
## notice that argument of '-d' is optional.
$ ruby ex2.rb hello -d
name="World", quiet=nil, format=nil, debug=true
$ ruby ex2.rb hello -d2
name="World", quiet=nil, format=nil, debug="2"
Help message:
$ ruby ex2.rb hello -h
Usage:
ex2.rb [<options>] <action> [<args>...]
Options:
-h, --help : print help message
--version : print version
Actions:
hello1 : say hello
hello2 : say hello
hello3 : say hello
hello4 : say hello
(Run `ex2.rb help <action>' to show help message of each action.)
ex3.rb:
require 'benry/cli'
class ValidationTestAction < Benry::CLI::Action
##
## @option.() can take a block argument which does both validation
## and data conversion.
##
@action.(:hello, "say hello")
@option.('-L, --log-level=N', "log level (1~5)") {|val|
val =~ /\A\d+\z/ or raise "positive integer expected."
val.to_i # convert string into integer
}
def do_hello(log_level: 1)
puts "log_level=#{log_level.inspect}"
end
end
if __FILE__ == $0
Benry::CLI::Application.new(version: '1.0').main()
end
Example:
$ ruby ex3.rb hello -L abc
ERROR: -L abc: positive integer expected.
ex-argname.rb:
require 'benry/cli'
class FooAction < Benry::CLI::Action
##
## parameter name -> in help message
## ----------------------------------------
## file_name -> <file-name>
## file_or_dir -> <file|dir>
## file_name=nil -> [<file-name>]
## *fil_namee -> [<file-name>...]
##
@action.(:bla_bla_bla, "test")
@option.('-v, --verbose-mode', "enable verbose mode")
def do_something(file_name, file_or_dir=nil, verbose_mode: nil)
# ...
end
end
if __FILE__ == $0
Benry::CLI::Application.new().main()
end
Example:
$ ruby ex-argname.rb help bla-bla-bla
test
Usage:
argname.rb bla-bla-bla [<options>] <file-name> [<file|dir>]
Options:
-h, --help : print help message
-v, --verbose-mode : enable verbose mode
self.prefix = "..."
sets prefix name of action.
mygit.rb:
require 'benry/cli'
class GitAction < Benry::CLI::Action
##
## add prefix 'git:' to each actions
##
self.prefix = 'git'
@action.(:stage, "same as 'git add -p'")
def do_stage(*filenames)
system 'git', 'add', '-p', *filenames
end
@action.(:staged, "same as 'git diff --cached'")
def do_staged(*filenames)
system 'git', 'diff', '--cached', *filenames
end
@action.(:unstaged, "same as 'git reset HEAD'")
def do_unstage(*filenames)
system 'git', 'reset', 'HEAD', *filenames
end
end
if __FILE__ == $0
Benry::CLI::Application.new("git wrapper", version: '1.0').main()
end
Example (prefix 'git:' is added to actions):
$ ruby mygit.rb --help
git wrapper
Usage:
mygit.rb [<options>] <action> [<args>...]
Options:
-h, --help : print help message
--version : print version
Actions:
git:stage : same as 'git add -p'
git:staged : same as 'git diff --cached'
git:unstaged : same as 'git reset HEAD'
(Run `mygit.rb help <action>' to show help message of each action.)
Of course, it is possible to specify prefix name with @action.(:'git:stage')
.
Validator callback can take option values as second argument.
Using it, you can define options which can be specified more than once
(such as -I
option of gcc).
ex-multival.rb:
require 'benry/cli'
class TestAction < Benry::CLI::Action
@action.(nil, "example of multi-value option")
@option.("-I, --include=path", "include path") {|val, opt|
opt['include'] ||= []
opt['include'] << val
opt['include']
}
def multival(include: nil)
p include
end
end
if __FILE__ == $0
Benry::CLI::Application.new("multi-value example", version: '1.0').main()
end
Example:
$ ruby ex-multival.rb multival -I /path1 -I /path2 -I /path3
["/path1", "/path2", "/path3"]
If you need just command-line option parser instead of application,
use Benry::CLI::OptionParser
class.
ex-parser.rb:
require 'benry/cli'
parser = Benry::CLI::OptionParser.new
parser.option("-h, --help", "print help")
parser.option("-f, --file=FILE", "load filename")
parser.option("-i, --indent=N", "indent") {|val|
val =~ /\A\d+\z/ or raise "integer expected." # validation
val.to_i # convertion (string -> integer)
}
args = ['-hftest.txt', '-i', '2', "x", "y"]
options = parser.parse(args)
puts options #=> {"help"=>true, "file"=>"test.txt", "indent"=>2}
puts args.inspect #=> ["x", "y"]
$License: MIT License $
$Copyright: copyright(c) 2016 kuwata-lab.com all rights reserved $
FAQs
Unknown package
We found that benry-cli demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.