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.
125 126 127 128 129 130 131 |
# File 'lib/shellopts.rb', line 125 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
94 95 96 |
# File 'lib/shellopts.rb', line 94 def args @args end |
#argv ⇒ Object (readonly)
Array of arguments. Initialized by #interpret
84 85 86 |
# File 'lib/shellopts.rb', line 84 def argv @argv end |
#exception ⇒ Object
True if ShellOpts lets exceptions through instead of writing an error message and exit
116 117 118 |
# File 'lib/shellopts.rb', line 116 def exception @exception end |
#file ⇒ Object (readonly)
File of source
119 120 121 |
# File 'lib/shellopts.rb', line 119 def file @file end |
#float ⇒ Object
Floating options
112 113 114 |
# File 'lib/shellopts.rb', line 112 def float @float end |
#grammar ⇒ Object (readonly) Also known as: ast
Grammar. Grammar::Program object. Initialized by #compile
87 88 89 |
# File 'lib/shellopts.rb', line 87 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
97 98 99 |
# File 'lib/shellopts.rb', line 97 def help @help end |
#msgopts ⇒ Object
Add message options (TODO)
109 110 111 |
# File 'lib/shellopts.rb', line 109 def msgopts @msgopts end |
#name ⇒ Object (readonly)
Name of program. Defaults to the name of the executable
78 79 80 |
# File 'lib/shellopts.rb', line 78 def name @name end |
#spec ⇒ Object (readonly)
Specification (String). Initialized by #compile
81 82 83 |
# File 'lib/shellopts.rb', line 81 def spec @spec end |
#tokens ⇒ Object (readonly)
Debug: Internal variables made public
122 123 124 |
# File 'lib/shellopts.rb', line 122 def tokens @tokens end |
Class Method Details
.brief ⇒ Object
234 |
# File 'lib/shellopts.rb', line 234 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
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 298 |
# File 'lib/shellopts.rb', line 267 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
235 |
# File 'lib/shellopts.rb', line 235 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
185 186 187 188 189 |
# File 'lib/shellopts.rb', line 185 def self.process(spec, argv, **opts) ::ShellOpts.instance = shellopts = ShellOpts.new(**opts) shellopts.process(spec, argv) [shellopts.program, shellopts.args] end |
.usage ⇒ Object
233 |
# File 'lib/shellopts.rb', line 233 def self.usage() ::ShellOpts.instance.usage end |
Instance Method Details
#brief ⇒ Object
Print brief help
222 |
# File 'lib/shellopts.rb', line 222 def brief() Formatter.brief(@grammar) end |
#compile(spec) ⇒ Object
Compile source and return grammar object. Also sets #spec and #grammar. Returns the grammar
135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/shellopts.rb', line 135 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
196 197 198 199 200 201 202 203 204 205 206 |
# File 'lib/shellopts.rb', line 196 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
213 214 215 216 |
# File 'lib/shellopts.rb', line 213 def failure() $stderr.puts "#{name}: #{message}" exit 1 end |
#find_spec_in_file ⇒ Object
300 301 302 |
# File 'lib/shellopts.rb', line 300 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
313 314 315 316 317 318 319 320 321 322 |
# File 'lib/shellopts.rb', line 313 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
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/shellopts.rb', line 152 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
304 305 306 307 308 309 310 311 |
# File 'lib/shellopts.rb', line 304 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
174 175 176 177 178 |
# File 'lib/shellopts.rb', line 174 def process(spec, argv) compile(spec) interpret(argv) self end |
#program ⇒ Object
Resulting ShellOpts::Program object containing options and optional subcommand. Initialized by #interpret
91 |
# File 'lib/shellopts.rb', line 91 def program() @program end |
#usage ⇒ Object
Print usage
219 |
# File 'lib/shellopts.rb', line 219 def usage() Formatter.usage(@grammar) end |
#version ⇒ Object
Version of client program. If not nil a –version option is added to the program
100 101 102 103 104 105 106 |
# File 'lib/shellopts.rb', line 100 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 |