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
File of source.
-
#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.
-
#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, help: true, version: true, 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, help: true, version: true, quiet: nil, verbose: nil, debug: nil, version_number: nil, float: true, exception: false) ⇒ ShellOpts
Returns a new instance of ShellOpts.
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/shellopts.rb', line 139 def initialize(name: nil, # Options help: true, version: true, quiet: nil, verbose: nil, debug: nil, # Version number (usually detected) version_number: nil, # Floating options float: true, # Let exceptions through exception: false ) @name = name || File.basename($PROGRAM_NAME) @help = help @version = version || (version.nil? && !version_number.nil?) @quiet = quiet @verbose = verbose @debug = debug @version_number = version_number || find_version_number @float = float @exception = exception end |
Instance Attribute Details
#args ⇒ Object (readonly)
Array of remaining arguments. Initialized by #interpret
105 106 107 |
# File 'lib/shellopts.rb', line 105 def args @args end |
#argv ⇒ Object (readonly)
Array of arguments. Initialized by #interpret
95 96 97 |
# File 'lib/shellopts.rb', line 95 def argv @argv end |
#debug ⇒ Object (readonly)
Automatically add a –debug option if true
120 121 122 |
# File 'lib/shellopts.rb', line 120 def debug @debug end |
#exception ⇒ Object
True if ShellOpts lets exceptions through instead of writing an error message and exit
130 131 132 |
# File 'lib/shellopts.rb', line 130 def exception @exception end |
#file ⇒ Object (readonly)
File of source
133 134 135 |
# File 'lib/shellopts.rb', line 133 def file @file end |
#float ⇒ Object
Floating options
126 127 128 |
# File 'lib/shellopts.rb', line 126 def float @float end |
#grammar ⇒ Object (readonly) Also known as: ast
Grammar. Grammar::Program object. Initialized by #compile
98 99 100 |
# File 'lib/shellopts.rb', line 98 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
108 109 110 |
# File 'lib/shellopts.rb', line 108 def help @help end |
#name ⇒ Object (readonly)
Name of program. Defaults to the name of the executable
89 90 91 |
# File 'lib/shellopts.rb', line 89 def name @name end |
#quiet ⇒ Object (readonly)
Automatically add a -q and a –quiet option if true
114 115 116 |
# File 'lib/shellopts.rb', line 114 def quiet @quiet end |
#spec ⇒ Object (readonly)
Specification (String). Initialized by #compile
92 93 94 |
# File 'lib/shellopts.rb', line 92 def spec @spec end |
#tokens ⇒ Object (readonly)
Debug: Internal variables made public
136 137 138 |
# File 'lib/shellopts.rb', line 136 def tokens @tokens end |
#verbose ⇒ Object (readonly)
Automatically add a -v and a –verbose option if true
117 118 119 |
# File 'lib/shellopts.rb', line 117 def verbose @verbose end |
#version ⇒ Object (readonly)
Version of client program. If not nil, a –version option is added to the program
111 112 113 |
# File 'lib/shellopts.rb', line 111 def version @version end |
#version_number ⇒ Object (readonly)
Version number (this is usually detected dynamically)
123 124 125 |
# File 'lib/shellopts.rb', line 123 def version_number @version_number end |
Class Method Details
.brief ⇒ Object
298 |
# File 'lib/shellopts.rb', line 298 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
338 339 340 341 342 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 |
# File 'lib/shellopts.rb', line 338 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
299 |
# File 'lib/shellopts.rb', line 299 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
249 250 251 252 253 |
# File 'lib/shellopts.rb', line 249 def self.process(spec, argv, **opts) ::ShellOpts.instance = shellopts = ShellOpts.new(**opts) shellopts.process(spec, argv) [shellopts.program, shellopts.args] end |
Instance Method Details
#brief ⇒ Object
Print brief help
286 |
# File 'lib/shellopts.rb', line 286 def brief() Formatter.brief(@grammar) end |
#compile(spec) ⇒ Object
Compile source and return grammar object. Also sets #spec and #grammar. Returns the grammar
170 171 172 173 174 175 176 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 |
# File 'lib/shellopts.rb', line 170 def compile(spec) handle_exceptions { @oneline = spec.index("\n").nil? @spec = spec.sub(/^\s*\n/, "") @file = find_caller_file @tokens = Lexer.lex(name, @spec, @oneline) ast = Parser.parse(tokens) help_spec = (@help == true ? "-h,help" : @help) version_spec = (@version == true ? "--version" : @version) quiet_spec = (@quiet == true ? "-q,quiet" : @quiet) verbose_spec = (@verbose == true ? "+v,verbose" : @verbose) debug_spec = (@debug == true ? "--debug" : @debug) @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
260 261 262 263 264 265 266 267 268 269 270 |
# File 'lib/shellopts.rb', line 260 def error(subject = nil, ) $stderr.puts "#{name}: #{}" 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
277 278 279 280 |
# File 'lib/shellopts.rb', line 277 def failure() $stderr.puts "#{name}: #{}" exit 1 end |
#find_spec_in_file ⇒ Object
371 372 373 |
# File 'lib/shellopts.rb', line 371 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
384 385 386 387 388 389 390 391 392 393 |
# File 'lib/shellopts.rb', line 384 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
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/shellopts.rb', line 210 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) if @program.__send__(:"#{@help_option.ident}?") if @program[:help].name =~ /^--/ ShellOpts.help else ShellOpts.brief end exit elsif @program.__send__(:"#{@version_option.ident}?") puts version_number exit else @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
375 376 377 378 379 380 381 382 |
# File 'lib/shellopts.rb', line 375 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
238 239 240 241 242 |
# File 'lib/shellopts.rb', line 238 def process(spec, argv) compile(spec) interpret(argv) self end |
#program ⇒ Object
Resulting ShellOpts::Program object containing options and optional subcommand. Initialized by #interpret
102 |
# File 'lib/shellopts.rb', line 102 def program() @program end |