Class: ShellOpts::ShellOpts
- Inherits:
-
Object
- Object
- ShellOpts::ShellOpts
- Defined in:
- lib/shellopts.rb
Instance Attribute Summary collapse
-
#args ⇒ Object
readonly
Array of remaining arguments.
-
#argv ⇒ Object
readonly
Array of arguments.
-
#debug ⇒ Object
readonly
Automatically add a –debug option if true.
-
#exception ⇒ Object
True if ShellOpts lets exceptions through instead of writing an error message and exit.
-
#file ⇒ Object
readonly
Executable.
-
#float ⇒ Object
Floating options.
-
#grammar ⇒ Object
(also: #ast)
readonly
Grammar.
-
#help(subject = nil, clear: true) ⇒ Object
readonly
Print help for the given subject or the full documentation if
subjectis nil. -
#name ⇒ Object
readonly
Name of program.
-
#quiet ⇒ Object
readonly
Automatically add a -q and a –quiet option if true.
-
#silent ⇒ Object
readonly
Automatically add a -s and a –silent option if true.
-
#spec ⇒ Object
readonly
Specification (String).
-
#tokens ⇒ Object
readonly
Debug: Internal variables made public.
-
#verbose ⇒ Object
readonly
Automatically add a -v and a –verbose option if true.
-
#version ⇒ Object
readonly
Version of client program.
-
#version_number ⇒ Object
readonly
Version number (this is usually detected dynamically).
Class Method Summary collapse
- .brief ⇒ Object
-
.find_spec_in_text(text, spec, oneline) ⇒ Object
Find line and char index of spec in text.
- .help(subject = nil) ⇒ Object
-
.process(spec, argv, **opts) ⇒ Object
Create a ShellOpts object and sets the global instance, then process the spec and arguments.
- .usage ⇒ Object
Instance Method Summary collapse
-
#brief ⇒ Object
Print brief help.
-
#compile(spec) ⇒ Object
Compile source and return grammar object.
-
#error(subject = nil, message) ⇒ Object
Write short usage and error message to standard error and terminate program with status 1.
-
#failure(message) ⇒ Object
Write error message to standard error and terminate program with status 1.
- #find_spec_in_file ⇒ Object
- #find_subject(obj) ⇒ Object
-
#initialize(name: nil, file: $PROGRAM_NAME, help: true, version: true, silent: nil, quiet: nil, verbose: nil, debug: nil, version_number: nil, float: true, exception: false) ⇒ ShellOpts
constructor
A new instance of ShellOpts.
-
#interpret(argv) ⇒ Object
Use grammar to interpret arguments.
- #lookup(name) ⇒ Object
-
#process(spec, argv) ⇒ Object
Compile
specand interpretargv. -
#program ⇒ Object
Resulting ShellOpts::Program object containing options and optional subcommand.
-
#usage ⇒ Object
Print usage.
Constructor Details
#initialize(name: nil, file: $PROGRAM_NAME, help: true, version: true, silent: nil, quiet: nil, verbose: nil, debug: nil, version_number: nil, float: true, exception: false) ⇒ ShellOpts
Returns a new instance of ShellOpts.
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/shellopts.rb', line 143 def initialize(name: nil, file: $PROGRAM_NAME, # Options help: true, version: true, silent: nil, quiet: nil, verbose: nil, debug: nil, # Version number (auto-detected for gem packages) version_number: nil, # Floating options float: true, # Let exceptions through exception: false ) @name = name || File.basename(file) @file = file @help = help @version_number = version_number || (version && find_version_number) @version = !@version_number.nil? && version @silent = silent @quiet = quiet @verbose = verbose @debug = debug @float = float @exception = exception end |
Instance Attribute Details
#args ⇒ Object (readonly)
Array of remaining arguments. Initialized by #interpret
109 110 111 |
# File 'lib/shellopts.rb', line 109 def args @args end |
#argv ⇒ Object (readonly)
Array of arguments. Initialized by #interpret
99 100 101 |
# File 'lib/shellopts.rb', line 99 def argv @argv end |
#debug ⇒ Object (readonly)
Automatically add a –debug option if true
127 128 129 |
# File 'lib/shellopts.rb', line 127 def debug @debug end |
#exception ⇒ Object
True if ShellOpts lets exceptions through instead of writing an error message and exit
137 138 139 |
# File 'lib/shellopts.rb', line 137 def exception @exception end |
#file ⇒ Object (readonly)
Executable. Default $PROGRAM_NAME
93 94 95 |
# File 'lib/shellopts.rb', line 93 def file @file end |
#float ⇒ Object
Floating options
133 134 135 |
# File 'lib/shellopts.rb', line 133 def float @float end |
#grammar ⇒ Object (readonly) Also known as: ast
Grammar. Grammar::Program object. Initialized by #compile
102 103 104 |
# File 'lib/shellopts.rb', line 102 def grammar @grammar end |
#help(subject = nil, clear: true) ⇒ Object (readonly)
Print help for the given subject or the full documentation if subject is nil. Clears the screen beforehand if :clear is true
112 113 114 |
# File 'lib/shellopts.rb', line 112 def help @help end |
#name ⇒ Object (readonly)
Name of program. Defaults to the name of the executable
90 91 92 |
# File 'lib/shellopts.rb', line 90 def name @name end |
#quiet ⇒ Object (readonly)
Automatically add a -q and a –quiet option if true
121 122 123 |
# File 'lib/shellopts.rb', line 121 def quiet @quiet end |
#silent ⇒ Object (readonly)
Automatically add a -s and a –silent option if true
118 119 120 |
# File 'lib/shellopts.rb', line 118 def silent @silent end |
#spec ⇒ Object (readonly)
Specification (String). Initialized by #compile
96 97 98 |
# File 'lib/shellopts.rb', line 96 def spec @spec end |
#tokens ⇒ Object (readonly)
Debug: Internal variables made public
140 141 142 |
# File 'lib/shellopts.rb', line 140 def tokens @tokens end |
#verbose ⇒ Object (readonly)
Automatically add a -v and a –verbose option if true
124 125 126 |
# File 'lib/shellopts.rb', line 124 def verbose @verbose end |
#version ⇒ Object (readonly)
Version of client program. If not nil, a –version option is added to the program
115 116 117 |
# File 'lib/shellopts.rb', line 115 def version @version end |
#version_number ⇒ Object (readonly)
Version number (this is usually detected dynamically)
130 131 132 |
# File 'lib/shellopts.rb', line 130 def version_number @version_number end |
Class Method Details
.brief ⇒ Object
309 |
# File 'lib/shellopts.rb', line 309 def self.brief() ::ShellOpts.instance.brief end |
.find_spec_in_text(text, spec, oneline) ⇒ Object
Find line and char index of spec in text. Returns [nil, nil] if not found
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 |
# File 'lib/shellopts.rb', line 343 def self.find_spec_in_text(text, spec, oneline) text_lines = text.split("\n") spec_lines = spec.split("\n") spec_lines.pop_while { |line| line =~ /^\s*$/ } if oneline line_i = nil char_i = nil char_z = 0 (0 ... text_lines.size).each { |text_i| curr_char_i, curr_char_z = LCS.find_longest_common_substring_index(text_lines[text_i], spec_lines.first.strip) if curr_char_z > char_z line_i = text_i char_i = curr_char_i char_z = curr_char_z end } line_i ? [line_i, char_i] : [nil, nil] else spec_string = spec_lines.first.strip line_i = (0 ... text_lines.size - spec_lines.size + 1).find { |text_i| (0 ... spec_lines.size).all? { |spec_i| compare_lines(text_lines[text_i + spec_i], spec_lines[spec_i]) } } or return [nil, nil] char_i, char_z = LCS.find_longest_common_substring_index(text_lines[line_i], spec_lines.first.strip) [line_i, char_i || 0] end end |
.help(subject = nil) ⇒ Object
310 |
# File 'lib/shellopts.rb', line 310 def self.help(subject = nil) ::ShellOpts.instance.help(subject) end |
.process(spec, argv, **opts) ⇒ Object
Create a ShellOpts object and sets the global instance, then process the spec and arguments. Returns a tuple of a ShellOpts::Program with the options and subcommands and a ShellOpts::Args object with the remaining arguments
260 261 262 263 264 |
# File 'lib/shellopts.rb', line 260 def self.process(spec, argv, **opts) ::ShellOpts.instance = shellopts = ShellOpts.new(**opts) shellopts.process(spec, argv) [shellopts.program, shellopts.args] end |
.usage ⇒ Object
308 |
# File 'lib/shellopts.rb', line 308 def self.usage() ::ShellOpts.instance.usage end |
Instance Method Details
#brief ⇒ Object
Print brief help
297 |
# File 'lib/shellopts.rb', line 297 def brief() Formatter.brief(@grammar) end |
#compile(spec) ⇒ Object
Compile source and return grammar object. Also sets #spec and #grammar. Returns the grammar
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/shellopts.rb', line 177 def compile(spec) handle_exceptions { @oneline = spec.index("\n").nil? @spec = spec.sub(/^\s*\n/, "") @tokens = Lexer.lex(name, @spec, @oneline) ast = Parser.parse(tokens) help_spec = (@help == true ? "-h,help" : @help) version_spec = (@version == true ? "--version" : @version) silent_spec = (@silent == true ? "--silent" : @silent) quiet_spec = (@quiet == true ? "-q,quiet" : @quiet) verbose_spec = (@verbose == true ? "+v,verbose" : @verbose) debug_spec = (@debug == true ? "--debug" : @debug) @silent_option = ast.inject_option(silent_spec, "Silent", "Do not write anything to standard output/error") if @silent @quiet_option = ast.inject_option(quiet_spec, "Quiet", "Do not write anything to standard output") if @quiet @verbose_option = ast.inject_option(verbose_spec, "Increase verbosity", "Write verbose output") if @verbose @debug_option = ast.inject_option(debug_spec, "Write debug information") if @debug @help_option = ast.inject_option(help_spec, "Write short or long help") { |option| short_option = option.short_names.first long_option = option.long_names.first [ short_option && "#{short_option} prints a brief help text", long_option && "#{long_option} prints a longer man-style description of the command" ].compact.join(", ") } if @help @version_option = ast.inject_option(version_spec, "Write version number and exit") if @version @grammar = Analyzer.analyze(ast) } self end |
#error(subject = nil, message) ⇒ Object
Write short usage and error message to standard error and terminate program with status 1
#error is supposed to be used when the user made an error and the usage is written to help correcting the error
271 272 273 274 275 276 277 278 279 280 281 |
# File 'lib/shellopts.rb', line 271 def error(subject = nil, ) $stderr.puts "#{name}: #{message}" saved = $stdout begin $stdout = $stderr Formatter.usage(grammar) exit 1 ensure $stdout = saved end end |
#failure(message) ⇒ Object
Write error message to standard error and terminate program with status 1
#failure doesn’t print the program usage because is supposed to be used when the user specified the correct arguments but something else went wrong during processing
288 289 290 291 |
# File 'lib/shellopts.rb', line 288 def failure() $stderr.puts "#{name}: #{message}" exit 1 end |
#find_spec_in_file ⇒ Object
376 377 378 |
# File 'lib/shellopts.rb', line 376 def find_spec_in_file self.class.find_spec_in_text(IO.read(@file), @spec, @oneline).map { |i| (i || 0) + 1 } end |
#find_subject(obj) ⇒ Object
389 390 391 392 393 394 395 396 397 398 |
# File 'lib/shellopts.rb', line 389 def find_subject(obj) case obj when String; lookup(obj) when Ast::Command; Command.grammar(obj) # FIXME when Grammar::Command; obj when NilClass; grammar else raise Internal, "Illegal object: #{obj.class}" end end |
#interpret(argv) ⇒ Object
Use grammar to interpret arguments. Return a ShellOpts::Program and ShellOpts::Args tuple
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/shellopts.rb', line 219 def interpret(argv) handle_exceptions { @argv = argv.dup @program, @args = Interpreter.interpret(grammar, argv, float: float, exception: exception) # Process standard options that may have been renamed or be deactivated if @help && @program.__send__(:"#{@help_option.ident}?") if @program[:help].name =~ /^--/ ShellOpts.help else ShellOpts.brief end exit elsif @version && @program.__send__(:"#{@version_option.ident}?") puts version_number exit else # Assign standard options. The targets doesn't change if the option is renamed @program.__silent__ = @program.__send__(:"#{@silent_option.ident}?") if @silent @program.__quiet__ = @program.__send__(:"#{@quiet_option.ident}?") if @quiet @program.__verbose__ = @program.__send__(:"#{@verbose_option.ident}") if @verbose @program.__debug__ = @program.__send__(:"#{@debug_option.ident}?") if @debug end } self end |
#lookup(name) ⇒ Object
380 381 382 383 384 385 386 387 |
# File 'lib/shellopts.rb', line 380 def lookup(name) a = name.split(".") cmd = grammar while element = a.shift cmd = cmd.commands[element] end cmd end |
#process(spec, argv) ⇒ Object
Compile spec and interpret argv. Returns a tuple of a ShellOpts::Program and ShellOpts::Args object
249 250 251 252 253 |
# File 'lib/shellopts.rb', line 249 def process(spec, argv) compile(spec) interpret(argv) self end |
#program ⇒ Object
Resulting ShellOpts::Program object containing options and optional subcommand. Initialized by #interpret
106 |
# File 'lib/shellopts.rb', line 106 def program() @program end |
#usage ⇒ Object
Print usage
294 |
# File 'lib/shellopts.rb', line 294 def usage() Formatter.usage(@grammar) end |