optsparser_generator 2.6 → 4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -3
  3. data/lib/optsparser_generator.rb +86 -32
  4. metadata +46 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0dc1cb64554d69901c4cd9a2e70495f188c9f486
4
- data.tar.gz: 44b4d8c5c8d5999edf292ce4ddfdc8971b757361
3
+ metadata.gz: 5121915ca357fd8dfa3d8bfb7c292bc435e46fce
4
+ data.tar.gz: 218b5d132ab436ae1595b510f51e96d07d261ebf
5
5
  SHA512:
6
- metadata.gz: 9a0ea186c5015ec27fc9101bad09a1f4cde26935258ece98bedc75cd00f3996da57f23641defe5066e5c2f9b33937a115d3fe66be7cfcc03e4c65b0e9c51a693
7
- data.tar.gz: 4d488ecf57e3e7fadf6739f836942b2a8b781dea76a37be36270523ab81ee1bca9401699d327e56feb6071953e58f330968a4c862deb67c80244732a15d6625d
6
+ metadata.gz: 2ee9faa906c0d85efc1f83f03ba58067869c17f3750bf268900724f57888fe4438b2c9a6c44c3ec24446cd8833e47ddb994aa47f21ed185cc2873fe6eefb55b1
7
+ data.tar.gz: e9835ec3a8e9a6fb1fcbad12b25b392b2968a6ef1a91198b76f89accf80343ef3d6a3055e6ee7098d824e605cfa0ca884f5796048095d27cd0bfba36be0af726
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # OptionParser Generator
2
- [![Inline docs](http://inch-ci.org/github/madblobfish/optionparser-generator.svg?branch=master)](http://inch-ci.org/github/madblobfish/optionparser-generator)
3
2
  [![Build Status](https://travis-ci.org/madblobfish/optionparser-generator.svg?branch=master)](https://travis-ci.org/madblobfish/optionparser-generator)
3
+ [![Dependency Status](https://gemnasium.com/badges/github.com/madblobfish/optionparser-generator.svg)](https://gemnasium.com/github.com/madblobfish/optionparser-generator)
4
+ [![Inline docs](http://inch-ci.org/github/madblobfish/optionparser-generator.svg?branch=master)](http://inch-ci.org/github/madblobfish/optionparser-generator)
4
5
 
5
6
  Small gem which generates an OptionParser object from an OpenStruct.
6
7
 
@@ -10,7 +11,7 @@ Small gem which generates an OptionParser object from an OpenStruct.
10
11
  # Usage
11
12
  ```ruby
12
13
  require 'optsparser_generator'
13
- # step one define OpenStruct with default values
14
+ # step one define OpenStruct with default and special values
14
15
  os = OpenStruct.new
15
16
  os.default = 'value'
16
17
  os.val = 123
@@ -19,11 +20,19 @@ os.val__class = Numeric
19
20
  os.bool = true
20
21
  os.bool__help = 'description of argument'
21
22
  os.bool__short = 'b'
23
+ os.test = "don't know"
24
+ os.test_proc = Proc.new do |value|
25
+ puts value
26
+ "some-#{value}-conversion"
27
+ end
22
28
  os.freeze
23
29
 
24
30
  # step two generate OptionParser
25
31
  opt_parser = OptParseGen(os)
26
32
  opt_parser = OptionParserGenerator(os)
33
+ opt_parser.parse!(ARGV)
34
+ # or parse options directly
35
+ OptParseGen.parse(os) # takes ARGV or an array
27
36
  ```
28
37
 
29
38
  ## Special values
@@ -31,11 +40,11 @@ opt_parser = OptionParserGenerator(os)
31
40
  * __values defines possible values in an Array
32
41
  * __short defines the short trigger
33
42
  * __class defines the Class which OptionParser then tries to coerce to
43
+ * __proc a Proc which will be executed to compute the value
34
44
 
35
45
  # Version numbers
36
46
  I choose two digit version numbers.
37
47
  The first digit indicates breaking changes.
38
48
  Second digit increases per release.
39
49
 
40
-
41
50
  Enjoy
@@ -3,6 +3,15 @@ require 'optparse'
3
3
 
4
4
  # Small lib for generating an OptionParser from an OpenStruct
5
5
  module OptionParserGenerator
6
+ # Special postfixes for Hash keys
7
+ SPECIAL_POSTFIXES = [
8
+ '--help',
9
+ '--values',
10
+ '--short',
11
+ '--class',
12
+ '--proc'
13
+ ].freeze
14
+
6
15
  # Raised when not given an OpenStruct
7
16
  class WrongArgumentType < ArgumentError
8
17
  end
@@ -13,6 +22,16 @@ module OptionParserGenerator
13
22
  class OptionCollision < ArgumentError
14
23
  end
15
24
 
25
+ # utility methods
26
+ # @api private
27
+ module OpenStructExtension
28
+ # extracts a special value from the openstruct
29
+ def special_value(key, string)
30
+ self["#{key}__#{string}"]
31
+ end
32
+ end
33
+ private_constant :OpenStructExtension
34
+
16
35
  # Does some sanity checks and prepares the OpenStruct
17
36
  # @todo preprocess data here instead of doing it adhoc
18
37
  # @todo raise more exceptions
@@ -21,8 +40,11 @@ module OptionParserGenerator
21
40
  unless ostruct.is_a?(OpenStruct)
22
41
  raise WrongArgumentType, 'needs an OpenStruct'
23
42
  end
24
- ostruct.dup.freeze # not needed but makes development easier
43
+ ostruct = ostruct.dup
44
+ ostruct.extend(OpenStructExtension)
45
+ ostruct.freeze # freeze is not needed but makes development easier
25
46
  end
47
+ private_class_method :handle_arguments
26
48
 
27
49
  # Does the magic
28
50
  #
@@ -30,60 +52,91 @@ module OptionParserGenerator
30
52
  # @todo split this up
31
53
  # @param ostruct [OpenStruct] Default values with special values
32
54
  # @param options [Hash]
33
- # @option options [Boolean] :ignore_collisions ignore bool key collisions see OptionCollision
55
+ # @option options [Boolean]
56
+ # :ignore_collisions ignore bool key collisions see OptionCollision
57
+ # :generate_no_help when set to true donesn't generates help command
34
58
  def self.[](ostruct, **options)
35
59
  defaults = handle_arguments(ostruct)
36
60
 
37
61
  optparser = OptionParser.new do |opts|
38
62
  defaults.each_pair do |key, val|
39
63
  trigger = key.to_s.tr('_', '-')
40
- next if trigger.end_with?('--help', '--values', '--short', '--class')
41
-
42
- help = "#{defaults["#{key}__help"]} (Default: #{val})"
43
- values = defaults["#{key}__values"] || []
44
- short = defaults["#{key}__short"] || ''
45
- arguments = []
46
- arguments << help
47
- arguments << "-#{short}" unless short.empty?
64
+ next if trigger.end_with?(*SPECIAL_POSTFIXES)
65
+
66
+ arguments = generate_arguments(defaults, key, val)
48
67
  case val
49
68
  when FalseClass, TrueClass
69
+ uneven_no = /\Ano(-no-no)*-(?!no)/ =~ trigger
50
70
  if trigger.start_with?('no-')
51
- trigger[0..2] = ''
52
- if defaults.each_pair.map { |v| v.first.to_s }.include?(trigger) && !options[:ignore_collisions]
53
- raise OptionCollision, "on #{key}"
54
- end
71
+ trigger.gsub!(/\A(no-)+/, '') # removes no- prefixes
72
+ check_collisions(trigger, key, defaults) unless options[:ignore_collisions]
55
73
  end
56
- opts.on("--[no-]#{trigger}", *arguments) do |b|
57
- out = opts.instance_variable_get(:@out)
58
- out[key] =
59
- if key.to_s.start_with?('no_')
60
- !b
61
- else
62
- b
63
- end
74
+ arguments.unshift "--[no-]#{trigger}"
75
+ block = lambda do |bool|
76
+ # inverted when it starts with no_
77
+ bool ^ uneven_no
64
78
  end
65
79
  else
66
- arguments.push defaults["#{key}__class"] || (val.class.equal?(Fixnum) ? Integer : val.class)
67
- arguments << values if values.any?
68
- opts.on("--#{trigger}=ARG", *arguments) do |str|
69
- out = opts.instance_variable_get(:@out)
70
- out[key] = str
80
+ klass = val.class
81
+ klass = klass.equal?(Fixnum) ? Integer : klass
82
+ klass = defaults.special_value(key, 'class') || klass
83
+ arguments.push klass
84
+
85
+ values = defaults.special_value(key, 'values')
86
+ arguments.push values if values
87
+ arguments.unshift "--#{trigger}=ARG"
88
+ block = lambda do |str|
89
+ str
71
90
  end
72
91
  end
92
+ if (proc = defaults.special_value(key, 'proc'))
93
+ block = proc
94
+ end
95
+ opts.on(*arguments) do |arg|
96
+ opts.instance_variable_get(:@out)[key] = block.call(arg)
97
+ end
73
98
  end
74
99
 
75
- opts.on('-h', '--help') do
76
- puts opts
77
- exit
100
+ unless options[:generate_no_help]
101
+ opts.on('-h', '--help') do
102
+ puts opts
103
+ exit
104
+ end
78
105
  end
79
106
  end
80
107
 
81
108
  # add default values
82
109
  optparser.instance_variable_set(:@defaults, defaults)
83
110
  optparser.extend(OptParsePatch)
84
- optparser
85
111
  end
86
112
 
113
+ # returns an array of helptext and
114
+ # if set the short version of trigger
115
+ # @api private
116
+ def self.generate_arguments(defaults, key, val)
117
+ short = defaults.special_value(key, 'short') || ''
118
+ if short.length > 1
119
+ raise ArgumentError, 'short is too long, it has to be only one character'
120
+ end
121
+
122
+ help = "#{defaults.special_value(key, 'help')} (Default: #{val})"
123
+
124
+ if short.empty?
125
+ [help]
126
+ else
127
+ [help, "-#{short}"]
128
+ end
129
+ end
130
+ private_class_method :generate_arguments
131
+
132
+ # @api private
133
+ def self.check_collisions(trigger, key, defaults)
134
+ if defaults.each_pair.map{ |v| v.first.to_s }.include?(trigger)
135
+ raise OptionCollision, "on #{key}"
136
+ end
137
+ end
138
+ private_class_method :check_collisions
139
+
87
140
  # patch for OptionParser redefines parse and parse!
88
141
  # @api private
89
142
  module OptParsePatch
@@ -101,13 +154,14 @@ module OptionParserGenerator
101
154
  @out
102
155
  end
103
156
  end
157
+ private_constant :OptParsePatch
104
158
 
105
159
  # Shorthand when parsing is only needed once.
106
160
  #
107
161
  # Generates an OptionParser and calls parse on it
108
162
  # @see OptionParserGenerator#[]
109
163
  # @return [OpenStruct]
110
- def self.parse(ostruct, argv = nil, **opt)
164
+ def self.parse(ostruct, argv, **opt)
111
165
  self[ostruct, opt].parse(argv)
112
166
  end
113
167
 
metadata CHANGED
@@ -1,85 +1,109 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: optsparser_generator
3
3
  version: !ruby/object:Gem::Version
4
- version: '2.6'
4
+ version: '4.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marvin Zerulla
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-08-26 00:00:00.000000000 Z
11
+ date: 2016-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rspec
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
+ - - "<"
18
+ - !ruby/object:Gem::Version
19
+ version: '12'
17
20
  - - ">="
18
21
  - !ruby/object:Gem::Version
19
- version: 3.5.0
22
+ version: 11.2.0
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
27
+ - - "<"
28
+ - !ruby/object:Gem::Version
29
+ version: '12'
24
30
  - - ">="
25
31
  - !ruby/object:Gem::Version
26
- version: 3.5.0
32
+ version: 11.2.0
27
33
  - !ruby/object:Gem::Dependency
28
- name: simplecov
34
+ name: rspec
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - ">="
37
+ - - "<"
32
38
  - !ruby/object:Gem::Version
33
- version: '0'
39
+ version: '4'
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: 3.5.0
34
43
  type: :development
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - ">="
47
+ - - "<"
39
48
  - !ruby/object:Gem::Version
40
- version: '0'
49
+ version: '4'
50
+ - - "~>"
51
+ - !ruby/object:Gem::Version
52
+ version: 3.5.0
41
53
  - !ruby/object:Gem::Dependency
42
- name: yard
54
+ name: rubocop
43
55
  requirement: !ruby/object:Gem::Requirement
44
56
  requirements:
45
- - - ">="
57
+ - - "~>"
46
58
  - !ruby/object:Gem::Version
47
- version: '0.8'
59
+ version: '0'
48
60
  type: :development
49
61
  prerelease: false
50
62
  version_requirements: !ruby/object:Gem::Requirement
51
63
  requirements:
52
- - - ">="
64
+ - - "~>"
53
65
  - !ruby/object:Gem::Version
54
- version: '0.8'
66
+ version: '0'
55
67
  - !ruby/object:Gem::Dependency
56
- name: rubocop
68
+ name: simplecov
57
69
  requirement: !ruby/object:Gem::Requirement
58
70
  requirements:
71
+ - - "<"
72
+ - !ruby/object:Gem::Version
73
+ version: '1'
59
74
  - - ">="
60
75
  - !ruby/object:Gem::Version
61
- version: '0'
76
+ version: 0.12.0
62
77
  type: :development
63
78
  prerelease: false
64
79
  version_requirements: !ruby/object:Gem::Requirement
65
80
  requirements:
81
+ - - "<"
82
+ - !ruby/object:Gem::Version
83
+ version: '1'
66
84
  - - ">="
67
85
  - !ruby/object:Gem::Version
68
- version: '0'
86
+ version: 0.12.0
69
87
  - !ruby/object:Gem::Dependency
70
- name: rake
88
+ name: yard
71
89
  requirement: !ruby/object:Gem::Requirement
72
90
  requirements:
91
+ - - "<"
92
+ - !ruby/object:Gem::Version
93
+ version: '1'
73
94
  - - ">="
74
95
  - !ruby/object:Gem::Version
75
- version: 11.2.0
96
+ version: '0.8'
76
97
  type: :development
77
98
  prerelease: false
78
99
  version_requirements: !ruby/object:Gem::Requirement
79
100
  requirements:
101
+ - - "<"
102
+ - !ruby/object:Gem::Version
103
+ version: '1'
80
104
  - - ">="
81
105
  - !ruby/object:Gem::Version
82
- version: 11.2.0
106
+ version: '0.8'
83
107
  description:
84
108
  email:
85
109
  executables: []
@@ -111,7 +135,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
135
  version: '0'
112
136
  requirements: []
113
137
  rubyforge_project:
114
- rubygems_version: 2.6.6
138
+ rubygems_version: 2.5.1
115
139
  signing_key:
116
140
  specification_version: 4
117
141
  summary: Generates OptionParser using an OpenStruct