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.
-
#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. -
#msgopts ⇒ Object
Add message options (TODO).
-
#name ⇒ Object
readonly
Name of program.
-
#spec ⇒ Object
readonly
Specification (String).
-
#tokens ⇒ Object
readonly
Debug: Internal variables made public.
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, msgopts: false, 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.
-
#version ⇒ Object
Version of client program.
Constructor Details
#initialize(name: nil, help: true, version: true, msgopts: false, float: true, exception: false) ⇒ ShellOpts
Returns a new instance of ShellOpts.
124 125 126 127 128 129 130 |
# File 'lib/shellopts.rb', line 124 def initialize(name: nil, help: true, version: true, msgopts: false, float: true, exception: false) @name = name || File.basename($PROGRAM_NAME) @help = help @use_version = version ? true : false @version = @use_version && @version != true ? @version : nil @msgopts, @float, @exception = msgopts, float, exception end |
Instance Attribute Details
#args ⇒ Object (readonly)
Array of remaining arguments. Initialized by #interpret
93 94 95 |
# File 'lib/shellopts.rb', line 93 def args @args end |
#argv ⇒ Object (readonly)
Array of arguments. Initialized by #interpret
83 84 85 |
# File 'lib/shellopts.rb', line 83 def argv @argv end |
#exception ⇒ Object
True if ShellOpts lets exceptions through instead of writing an error message and exit
115 116 117 |
# File 'lib/shellopts.rb', line 115 def exception @exception end |
#file ⇒ Object (readonly)
File of source
118 119 120 |
# File 'lib/shellopts.rb', line 118 def file @file end |
#float ⇒ Object
Floating options
111 112 113 |
# File 'lib/shellopts.rb', line 111 def float @float end |
#grammar ⇒ Object (readonly) Also known as: ast
Grammar. Grammar::Program object. Initialized by #compile
86 87 88 |
# File 'lib/shellopts.rb', line 86 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
96 97 98 |
# File 'lib/shellopts.rb', line 96 def help @help end |
#msgopts ⇒ Object
Add message options (TODO)
108 109 110 |
# File 'lib/shellopts.rb', line 108 def msgopts @msgopts end |
#name ⇒ Object (readonly)
Name of program. Defaults to the name of the executable
77 78 79 |
# File 'lib/shellopts.rb', line 77 def name @name end |
#spec ⇒ Object (readonly)
Specification (String). Initialized by #compile
80 81 82 |
# File 'lib/shellopts.rb', line 80 def spec @spec end |
#tokens ⇒ Object (readonly)
Debug: Internal variables made public
121 122 123 |
# File 'lib/shellopts.rb', line 121 def tokens @tokens end |
Class Method Details
.brief ⇒ Object
233 |
# File 'lib/shellopts.rb', line 233 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
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 |
# File 'lib/shellopts.rb', line 266 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
234 |
# File 'lib/shellopts.rb', line 234 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
184 185 186 187 188 |
# File 'lib/shellopts.rb', line 184 def self.process(spec, argv, **opts) ::ShellOpts.instance = shellopts = ShellOpts.new(**opts) shellopts.process(spec, argv) [shellopts.program, shellopts.args] end |
.usage ⇒ Object
232 |
# File 'lib/shellopts.rb', line 232 def self.usage() ::ShellOpts.instance.usage end |
Instance Method Details
#brief ⇒ Object
Print brief help
221 |
# File 'lib/shellopts.rb', line 221 def brief() Formatter.brief(@grammar) end |
#compile(spec) ⇒ Object
Compile source and return grammar object. Also sets #spec and #grammar. Returns the grammar
134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/shellopts.rb', line 134 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) ast.add_version_option if @use_version ast. if @help @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
195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/shellopts.rb', line 195 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
212 213 214 215 |
# File 'lib/shellopts.rb', line 212 def failure() $stderr.puts "#{name}: #{message}" exit 1 end |
#find_spec_in_file ⇒ Object
299 300 301 |
# File 'lib/shellopts.rb', line 299 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
312 313 314 315 316 317 318 319 320 321 |
# File 'lib/shellopts.rb', line 312 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
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/shellopts.rb', line 151 def interpret(argv) handle_exceptions { @argv = argv.dup @program, @args = Interpreter.interpret(grammar, argv, float: float, exception: exception) if @program.version? puts version exit elsif @program.help? if @program[:help].name == "-h" ShellOpts.brief else ShellOpts.help end exit end } self end |
#lookup(name) ⇒ Object
303 304 305 306 307 308 309 310 |
# File 'lib/shellopts.rb', line 303 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
173 174 175 176 177 |
# File 'lib/shellopts.rb', line 173 def process(spec, argv) compile(spec) interpret(argv) self end |
#program ⇒ Object
Resulting ShellOpts::Program object containing options and optional subcommand. Initialized by #interpret
90 |
# File 'lib/shellopts.rb', line 90 def program() @program end |
#usage ⇒ Object
Print usage
218 |
# File 'lib/shellopts.rb', line 218 def usage() Formatter.usage(@grammar) end |
#version ⇒ Object
Version of client program. If not nil a –version option is added to the program
99 100 101 102 103 104 105 |
# File 'lib/shellopts.rb', line 99 def version return @version if @version exe = caller.find { |line| line =~ /`<top \(required\)>'$/ }&.sub(/:.*/, "") file = Dir.glob(File.dirname(exe) + "/../lib/*/version.rb").first @version = IO.read(file).sub(/^.*VERSION\s*=\s*"(.*?)".*$/m, '\1') or raise ArgumentError, "ShellOpts needs an explicit version" end |