optitron 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,18 @@ class Optitron
2
2
  class Dsl
3
3
 
4
4
  def initialize(parser, &blk)
5
- RootParserDsl.new(parser).configure_with(blk)
5
+ root = RootParserDsl.new(parser)
6
+ root.configure_with(blk)
7
+ root.unclaimed_opts.each do |opt_option|
8
+ name = opt_option.name
9
+ if !root.short_opts.key?(name[0].chr)
10
+ opt_option.short_name = name[0].chr
11
+ root.short_opts[name[0].chr] = opt_option
12
+ elsif !root.short_opts.key?(name.upcase[0].chr)
13
+ opt_option.short_name = name.upcase[0].chr
14
+ root.short_opts[name.upcase[0].chr] = opt_option
15
+ end
16
+ end
6
17
  end
7
18
 
8
19
  class AbstractDsl
@@ -12,13 +23,12 @@ class Optitron
12
23
 
13
24
  def opt(name, description = nil, opts = nil)
14
25
  opt_option = Option::Opt.new(name, description, opts)
15
- if !short_opts.include?(name[0])
16
- opt_option.short_name = name[0].chr
17
- short_opts << name[0]
18
- elsif !short_opts.include?(name.upcase[0])
19
- opt_option.short_name = name.upcase[0].chr
20
- short_opts << name.upcase[0]
26
+ if opt_option.short_name
27
+ short_opts[opt_option.short_name] = opt_option
28
+ else
29
+ unclaimed_opts << opt_option
21
30
  end
31
+
22
32
  @target.options << opt_option
23
33
  end
24
34
 
@@ -33,6 +43,10 @@ class Optitron
33
43
  def short_opts
34
44
  @root_dsl.short_opts
35
45
  end
46
+
47
+ def unclaimed_opts
48
+ @root_dsl.unclaimed_opts
49
+ end
36
50
  end
37
51
 
38
52
  class CmdParserDsl < AbstractDsl
@@ -43,12 +57,16 @@ class Optitron
43
57
  end
44
58
 
45
59
  class RootParserDsl < AbstractDsl
46
- attr_reader :short_opts
60
+ attr_reader :unclaimed_opts
47
61
  def initialize(parser)
48
- @short_opts = []
49
62
  @target = parser
63
+ @unclaimed_opts = []
50
64
  end
51
-
65
+
66
+ def short_opts
67
+ @target.short_opts
68
+ end
69
+
52
70
  def cmd(name, description = nil, opts = nil, &blk)
53
71
  command_option = Option::Cmd.new(name, description, opts)
54
72
  CmdParserDsl.new(self, command_option).configure_with(blk) if blk
@@ -68,6 +68,7 @@ class Optitron
68
68
  end
69
69
  @name, @desc = name, desc
70
70
  @type = opts && opts[:type] || :boolean
71
+ self.short_name = opts[:short_name] if opts && opts[:short_name]
71
72
  self.inclusion_test = opts[:in] if opts && opts[:in]
72
73
  self.default = opts && opts.key?(:default) ? opts[:default] : (@type == :boolean ? false : nil)
73
74
  end
@@ -1,11 +1,13 @@
1
1
  class Optitron
2
2
  class Parser
3
3
  attr_accessor :target
4
- attr_reader :commands, :options, :args
4
+ attr_reader :commands, :options, :args, :short_opts
5
+
5
6
  def initialize
6
7
  @options = []
7
8
  @commands = {}
8
9
  @args = []
10
+ @short_opts = {}
9
11
  @help = Help.new(self)
10
12
  end
11
13
 
@@ -14,7 +16,7 @@ class Optitron
14
16
  end
15
17
 
16
18
  def parse(args = ARGV)
17
- tokens = Tokenizer.new(args).tokens
19
+ tokens = Tokenizer.new(self, args).tokens
18
20
  response = Response.new(self, tokens)
19
21
  options = @options
20
22
  args = @args
@@ -1,8 +1,8 @@
1
1
  class Optitron
2
2
  class Tokenizer
3
3
  attr_reader :tokens
4
- def initialize(opts)
5
- @opts = opts
4
+ def initialize(parser, opts)
5
+ @parser, @opts = parser, opts
6
6
  tokenize
7
7
  end
8
8
 
@@ -16,12 +16,26 @@ class Optitron
16
16
  case t
17
17
  when /^--([^=]+)=([^=]+)$/ then NamedWithValue.new($1, $2)
18
18
  when /^--([^=]+)$/ then NamedWithValue.new($1, nil)
19
- when /^-(.*)/ then $1.split('').map{|letter| Named.new(letter)}
19
+ when /^-(.*)/ then find_names_values($1)
20
20
  else Value.new(t)
21
21
  end
22
22
  }
23
23
  @tokens.flatten!
24
24
  end
25
25
  end
26
+
27
+ def find_names_values(short)
28
+ toks = []
29
+ letters = short.split('')
30
+ while !letters.empty?
31
+ let = letters.shift
32
+ toks << Named.new(let)
33
+ if @parser.short_opts[let] && @parser.short_opts[let].type != :boolean && !letters.empty?
34
+ toks << Value.new(letters.join)
35
+ letters.clear
36
+ end
37
+ end
38
+ toks
39
+ end
26
40
  end
27
41
  end
@@ -1,3 +1,3 @@
1
1
  class Optitron
2
- VERSION = "0.0.7"
2
+ VERSION = "0.0.8"
3
3
  end
@@ -53,6 +53,22 @@ describe "Optitron::Parser options" do
53
53
  end
54
54
  end
55
55
 
56
+ context "auto assingment of short names" do
57
+ before(:each) do
58
+ @parser = Optitron.new {
59
+ opt "verbose", :short_name => 'v'
60
+ opt "vicious", :type => :string
61
+ opt "vendetta", :short_name => 'V'
62
+ }
63
+ end
64
+
65
+ it "should parse '-Vv --vicious=what'" do
66
+ response = @parser.parse(%w(-Vv --vicious=what))
67
+ response.valid?.should be_true
68
+ response.params
69
+ end
70
+ end
71
+
56
72
  context "multiple options" do
57
73
  before(:each) do
58
74
  @parser = Optitron.new {
@@ -63,6 +79,10 @@ describe "Optitron::Parser options" do
63
79
  }
64
80
  end
65
81
 
82
+ it "should parse '-otest'" do
83
+ @parser.parse(%w(-otest)).params.should == {'option' => 'test', '1' => false, '2' => false, '3' => false}
84
+ end
85
+
66
86
  it "should parse '-123o test'" do
67
87
  @parser.parse(%w(-123o test)).params.should == {'option' => 'test', '1' => true, '2' => true, '3' => true}
68
88
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optitron
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joshua Hull