Class: Clive::Parser
- Inherits:
-
Object
- Object
- Clive::Parser
- Defined in:
- lib/clive/parser.rb
Defined Under Namespace
Classes: MissingArgumentError, MissingOptionError
Constant Summary collapse
- DEFAULTS =
{ :state => ::Clive::StructHash }
Instance Method Summary collapse
-
#initialize(base, config) ⇒ Parser
constructor
A new instance of Parser.
-
#parse(argv, pre_state) ⇒ Object
The parser should work how you expect.
Constructor Details
Instance Method Details
#parse(argv, pre_state) ⇒ Object
The parser should work how you expect. It allows you to put global options before and after a command section (if it exists, which it doesn’t), so you have something like.
app [global] [command] [global]
Where the [global] sections are made of options and arguments and
- command
-
is made of
- command
- options/args
Only one command can be run, if you attempt to use two the other will be caught as an argument.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/clive/parser.rb', line 47 def parse(argv, pre_state) @argv = argv @i = 0 @state = @config[:state].new(pre_state) @state.store :args, [] # Pull out 'help' command immediately if found if @argv[0] == 'help' if @argv[1] if @base.has?(@argv[1]) command = @base.find(@argv[1]) command.run_block({}) puts command.help else puts "Error: command #{@argv[1]} could not be found. Try `help` to see the available commands." end else puts @base.help end Kernel.exit 0 end until ended? # does +curr+ exist? (and also check that if it is a command a command hasn't been run yet if @base.has?(curr) && ((@base.find(curr).kind_of?(Command) && !command_ran?) || @base.find(curr).kind_of?(Option)) found = @base.find(curr) # is it a command? if found.kind_of?(Command) @command_ran = true @state.store found.names, found.run_block(@config[:state].new) inc args = [] until ended? if found.has?(curr) run_option found.find(curr), found else break unless found.args.possible?(args + [curr]) args << curr end inc end dec found.run @state, validate_arguments(found, args), found # otherwise it is an option else run_option found end # it's a no- option elsif curr[0..4] == '--no-' && @base.find("--#{curr[5..-1]}").config[:boolean] == true @base.find("--#{curr[5..-1]}").run @state, [false] # it's one (or more) short options elsif curr[0..0] == '-' && curr.size > 2 && @base.has?("-#{curr[1..1]}") currs = curr[1..-1].split('').map {|i| "-#{i}" } currs.each do |c| opt = @base.find(c) raise MissingOptionError.new(c) unless opt if c == currs.last run_option opt else # can't take any arguments as an option is next to it if opt.args.min > 0 raise MissingArgumentError.new(opt, [], opt.args) else opt.run @state, [true] end end end # otherwise it is an argument else @state.args << curr end inc end @state end |