pickled_optparse 0.1.0
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/LICENSE +20 -0
- data/README.rdoc +35 -0
- data/Rakefile +44 -0
- data/VERSION +1 -0
- data/autotest/discover.rb +1 -0
- data/lib/example.rb +43 -0
- data/lib/pickled_optparse.rb +156 -0
- data/spec/pickled_optparse/pickled_optparse_spec.rb +52 -0
- data/spec/spec_helper.rb +5 -0
- metadata +92 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Mike Bethany
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
= pickled_optparse
|
2
|
+
|
3
|
+
Allows a programmer to easily add required switches to a Ruby app using the built-in OptionParser class.
|
4
|
+
|
5
|
+
To make a switch required simple add the symbol :required anywhere in the list of options like so:
|
6
|
+
|
7
|
+
opts.on("-f [foo]", String, :required, "Required option") do |option|
|
8
|
+
@options[:foo] = option
|
9
|
+
end
|
10
|
+
|
11
|
+
Then at the end of your OptionParser block add something like this:
|
12
|
+
|
13
|
+
if opts.missing_switches?
|
14
|
+
puts opts.missing_switches
|
15
|
+
puts opts
|
16
|
+
exit
|
17
|
+
end
|
18
|
+
|
19
|
+
You of course need to require the "pickled_optparse" gem but that's it. You don't need to require the opt_parse file because that's already handled for you.
|
20
|
+
|
21
|
+
For a complete usage example see the lib/example.rb file.
|
22
|
+
|
23
|
+
== Note on Patches/Pull Requests
|
24
|
+
|
25
|
+
* Fork the project.
|
26
|
+
* Make your feature addition or bug fix.
|
27
|
+
* Add tests for it. This is important so I don't break it in a
|
28
|
+
future version unintentionally.
|
29
|
+
* Commit, do not mess with rakefile, version, or history.
|
30
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
31
|
+
* Send me a pull request. Bonus points for topic branches.
|
32
|
+
|
33
|
+
== Copyright
|
34
|
+
|
35
|
+
Copyright (c) 2010 Mike Bethany. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.required_ruby_version = '~> 1.9.2' # Everyone should upgrade, now!
|
8
|
+
gem.name = "pickled_optparse"
|
9
|
+
gem.summary = %Q{Adds required switches to the OptionParser class}
|
10
|
+
gem.description = %Q{Adds the ability to easily specify and test for required switches in Ruby's built-in OptionParser class}
|
11
|
+
gem.email = "picklepumpers@gmail.com"
|
12
|
+
gem.homepage = "http://github.com/PicklePumpers/pickled_optparse"
|
13
|
+
gem.authors = ["Mike Bethany"]
|
14
|
+
gem.add_development_dependency "rspec", ">= 2.0.1"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'rspec/core/rake_task'
|
23
|
+
RSpec::Core::RakeTask.new do |t|
|
24
|
+
t.rspec_opts = ["-c", "-f progress", "-r ./spec/spec_helper.rb"]
|
25
|
+
t.pattern = 'spec/*/*_spec.rb'
|
26
|
+
end
|
27
|
+
|
28
|
+
RSpec::Core::RakeTask.new(:rcov) do |t|
|
29
|
+
t.rcov_opts = %q[--exclude "spec"]
|
30
|
+
end
|
31
|
+
|
32
|
+
task :spec => :check_dependencies
|
33
|
+
|
34
|
+
task :default => :spec
|
35
|
+
|
36
|
+
require 'rake/rdoctask'
|
37
|
+
Rake::RDocTask.new do |rdoc|
|
38
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
39
|
+
|
40
|
+
rdoc.rdoc_dir = 'rdoc'
|
41
|
+
rdoc.title = "pickled_optparse #{version}"
|
42
|
+
rdoc.rdoc_files.include('README*')
|
43
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
44
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1 @@
|
|
1
|
+
Autotest.add_discovery {"rspec2"}
|
data/lib/example.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require_relative 'pickled_optparse'
|
3
|
+
|
4
|
+
# Configure options based on command line options
|
5
|
+
@options = {}
|
6
|
+
OptionParser.new do |opts|
|
7
|
+
opts.banner = "Usage: test [options] in_file[.srt] out_file[.srt]"
|
8
|
+
|
9
|
+
# Note that :required can be anywhere in the parameters
|
10
|
+
|
11
|
+
# Also note that OptionParser is bugged and will only check
|
12
|
+
# for required parameters on the last option, not my bug.
|
13
|
+
|
14
|
+
# required switch, required parameter
|
15
|
+
opts.on("-s Short", String, :required, "a required switch with just a short") do |operation|
|
16
|
+
@options[:operation] = operation
|
17
|
+
end
|
18
|
+
|
19
|
+
# required switch, optional parameter
|
20
|
+
opts.on(:required, "--long [Long]", String, "a required switch with just a long") do |operation|
|
21
|
+
@options[:operation] = operation
|
22
|
+
end
|
23
|
+
|
24
|
+
# required switch, required parameter
|
25
|
+
opts.on("-b", "--both ShortAndLong", String, "a required switch with short and long", :required) do |operation|
|
26
|
+
@options[:operation] = operation
|
27
|
+
end
|
28
|
+
|
29
|
+
# optional switch, optional parameter
|
30
|
+
opts.on("-o", "--optional [Whatever]", String, "an optional switch with short and long") do |operation|
|
31
|
+
@options[:operation] = operation
|
32
|
+
end
|
33
|
+
|
34
|
+
# Now we can see if there are any missing required
|
35
|
+
# switches so we can alert the user to what they
|
36
|
+
# missed and how to use the program properly.
|
37
|
+
if opts.missing_switches?
|
38
|
+
puts opts.missing_switches
|
39
|
+
puts opts
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
end.parse!
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
# Add the ability to specify switches as required to OptionParser
|
4
|
+
class OptionParser
|
5
|
+
|
6
|
+
# An array of messages describing any missing required switches
|
7
|
+
attr_reader :missing_switches
|
8
|
+
|
9
|
+
# Convenience method to test if we're missing any required switches
|
10
|
+
def missing_switches?
|
11
|
+
!@missing_switches.nil?
|
12
|
+
end
|
13
|
+
|
14
|
+
def make_switch(opts, block = nil)
|
15
|
+
short, long, nolong, style, pattern, conv, not_pattern, not_conv, not_style = [], [], []
|
16
|
+
ldesc, sdesc, desc, arg = [], [], []
|
17
|
+
default_style = Switch::NoArgument
|
18
|
+
default_pattern = nil
|
19
|
+
klass = nil
|
20
|
+
n, q, a = nil
|
21
|
+
|
22
|
+
# Check for required switches
|
23
|
+
required = opts.delete(:required)
|
24
|
+
|
25
|
+
opts.each do |o|
|
26
|
+
|
27
|
+
# argument class
|
28
|
+
next if search(:atype, o) do |pat, c|
|
29
|
+
klass = notwice(o, klass, 'type')
|
30
|
+
if not_style and not_style != Switch::NoArgument
|
31
|
+
not_pattern, not_conv = pat, c
|
32
|
+
else
|
33
|
+
default_pattern, conv = pat, c
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# directly specified pattern(any object possible to match)
|
38
|
+
if (!(String === o || Symbol === o)) and o.respond_to?(:match)
|
39
|
+
pattern = notwice(o, pattern, 'pattern')
|
40
|
+
if pattern.respond_to?(:convert)
|
41
|
+
conv = pattern.method(:convert).to_proc
|
42
|
+
else
|
43
|
+
conv = SPLAT_PROC
|
44
|
+
end
|
45
|
+
next
|
46
|
+
end
|
47
|
+
|
48
|
+
# anything others
|
49
|
+
case o
|
50
|
+
when Proc, Method
|
51
|
+
block = notwice(o, block, 'block')
|
52
|
+
when Array, Hash
|
53
|
+
case pattern
|
54
|
+
when CompletingHash
|
55
|
+
when nil
|
56
|
+
pattern = CompletingHash.new
|
57
|
+
conv = pattern.method(:convert).to_proc if pattern.respond_to?(:convert)
|
58
|
+
else
|
59
|
+
raise ArgumentError, "argument pattern given twice"
|
60
|
+
end
|
61
|
+
o.each {|pat, *v| pattern[pat] = v.fetch(0) {pat}}
|
62
|
+
when Module
|
63
|
+
raise ArgumentError, "unsupported argument type: #{o}", ParseError.filter_backtrace(caller(4))
|
64
|
+
when *ArgumentStyle.keys
|
65
|
+
style = notwice(ArgumentStyle[o], style, 'style')
|
66
|
+
when /^--no-([^\[\]=\s]*)(.+)?/
|
67
|
+
q, a = $1, $2
|
68
|
+
o = notwice(a ? Object : TrueClass, klass, 'type')
|
69
|
+
not_pattern, not_conv = search(:atype, o) unless not_style
|
70
|
+
not_style = (not_style || default_style).guess(arg = a) if a
|
71
|
+
default_style = Switch::NoArgument
|
72
|
+
default_pattern, conv = search(:atype, FalseClass) unless default_pattern
|
73
|
+
ldesc << "--no-#{q}"
|
74
|
+
long << 'no-' + (q = q.downcase)
|
75
|
+
nolong << q
|
76
|
+
when /^--\[no-\]([^\[\]=\s]*)(.+)?/
|
77
|
+
q, a = $1, $2
|
78
|
+
o = notwice(a ? Object : TrueClass, klass, 'type')
|
79
|
+
if a
|
80
|
+
default_style = default_style.guess(arg = a)
|
81
|
+
default_pattern, conv = search(:atype, o) unless default_pattern
|
82
|
+
end
|
83
|
+
ldesc << "--[no-]#{q}"
|
84
|
+
long << (o = q.downcase)
|
85
|
+
not_pattern, not_conv = search(:atype, FalseClass) unless not_style
|
86
|
+
not_style = Switch::NoArgument
|
87
|
+
nolong << 'no-' + o
|
88
|
+
when /^--([^\[\]=\s]*)(.+)?/
|
89
|
+
q, a = $1, $2
|
90
|
+
if a
|
91
|
+
o = notwice(NilClass, klass, 'type')
|
92
|
+
default_style = default_style.guess(arg = a)
|
93
|
+
default_pattern, conv = search(:atype, o) unless default_pattern
|
94
|
+
end
|
95
|
+
ldesc << "--#{q}"
|
96
|
+
long << (o = q.downcase)
|
97
|
+
when /^-(\[\^?\]?(?:[^\\\]]|\\.)*\])(.+)?/
|
98
|
+
q, a = $1, $2
|
99
|
+
o = notwice(Object, klass, 'type')
|
100
|
+
if a
|
101
|
+
default_style = default_style.guess(arg = a)
|
102
|
+
default_pattern, conv = search(:atype, o) unless default_pattern
|
103
|
+
end
|
104
|
+
sdesc << "-#{q}"
|
105
|
+
short << Regexp.new(q)
|
106
|
+
when /^-(.)(.+)?/
|
107
|
+
q, a = $1, $2
|
108
|
+
if a
|
109
|
+
o = notwice(NilClass, klass, 'type')
|
110
|
+
default_style = default_style.guess(arg = a)
|
111
|
+
default_pattern, conv = search(:atype, o) unless default_pattern
|
112
|
+
end
|
113
|
+
sdesc << "-#{q}"
|
114
|
+
short << q
|
115
|
+
when /^=/
|
116
|
+
style = notwice(default_style.guess(arg = o), style, 'style')
|
117
|
+
default_pattern, conv = search(:atype, Object) unless default_pattern
|
118
|
+
else
|
119
|
+
desc.push(o)
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
default_pattern, conv = search(:atype, default_style.pattern) unless default_pattern
|
125
|
+
if !(short.empty? and long.empty?)
|
126
|
+
s = (style || default_style).new(pattern || default_pattern, conv, sdesc, ldesc, arg, desc, block)
|
127
|
+
elsif !block
|
128
|
+
if style or pattern
|
129
|
+
raise ArgumentError, "no switch given", ParseError.filter_backtrace(caller)
|
130
|
+
end
|
131
|
+
s = desc
|
132
|
+
else
|
133
|
+
short << pattern
|
134
|
+
s = (style || default_style).new(pattern, conv, nil, nil, arg, desc, block)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Make sure required switches are given
|
138
|
+
if required && !(default_argv.include?("-#{short[0]}") || default_argv.include?("--#{long[0]}"))
|
139
|
+
@missing_switches ||= [] # Should be placed in initialize if incorporated into Ruby proper
|
140
|
+
|
141
|
+
# This is ugly, long, and not very DRY but it is easy to understand
|
142
|
+
#missing = "-#{short[0]}" if !short.empty?
|
143
|
+
#missing = "#{missing} or " if !short.empty? && !long.empty?
|
144
|
+
#missing = "#{missing}--#{long[0]}" if !long.empty?
|
145
|
+
|
146
|
+
# This is even uglier, and really hard to read, but it is shorter and
|
147
|
+
# as DRY as I could figure out how to make it... but it still stinks.
|
148
|
+
@missing_switches << "Missing switch: #{"-#{short[0]}" if !short.empty?}#{" or " if !short.empty? && !long.empty?}#{"--#{long[0]}" if !long.empty?}"
|
149
|
+
end
|
150
|
+
|
151
|
+
return s, short, long,
|
152
|
+
(not_style.new(not_pattern, not_conv, sdesc, ldesc, nil, desc, block) if not_style),
|
153
|
+
nolong
|
154
|
+
end
|
155
|
+
|
156
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe "Pickled OptionParse" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@op = OptionParser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "added properites" do
|
10
|
+
it "should have a missing_switches? parameter to indicate there are missing ones" do
|
11
|
+
@op.should respond_to(:missing_switches?)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have a missing_switches parameter to describe the missing switches" do
|
15
|
+
@op.should respond_to(:missing_switches)
|
16
|
+
end
|
17
|
+
end # added properites
|
18
|
+
|
19
|
+
describe "no required switches missing" do
|
20
|
+
|
21
|
+
it "should not have :missing_switches? set to true" do
|
22
|
+
ARGV << "-r"
|
23
|
+
op = OptionParser.new
|
24
|
+
op.on("-r", "--required_switch", String, :required, "a required switch")
|
25
|
+
op.parse!
|
26
|
+
op.missing_switches?.should_not == true
|
27
|
+
end
|
28
|
+
|
29
|
+
end # no required switches missing
|
30
|
+
|
31
|
+
describe "required switches are missing" do
|
32
|
+
before do
|
33
|
+
@op.on("-r", "--required_switch", String, :required, "a required switch")
|
34
|
+
@op.on("-s pickle_type", String, :required, "a required switch")
|
35
|
+
@op.on("--third_required_switch [blah]", String, :required, "a required switch")
|
36
|
+
@op.parse!
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should have :missing_switches? set to true" do
|
40
|
+
@op.missing_switches?.should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should store information about the missing switches" do
|
44
|
+
@op.missing_switches.to_s.downcase.should include('missing switch',
|
45
|
+
'-r', '--required_switch',
|
46
|
+
'-s',
|
47
|
+
'--third_required_switch')
|
48
|
+
end
|
49
|
+
|
50
|
+
end # required switches are missing
|
51
|
+
|
52
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pickled_optparse
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Mike Bethany
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-10-30 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 0
|
31
|
+
- 1
|
32
|
+
version: 2.0.1
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
description: Adds the ability to easily specify and test for required switches in Ruby's built-in OptionParser class
|
36
|
+
email: picklepumpers@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.rdoc
|
44
|
+
files:
|
45
|
+
- .document
|
46
|
+
- .rspec
|
47
|
+
- LICENSE
|
48
|
+
- README.rdoc
|
49
|
+
- Rakefile
|
50
|
+
- VERSION
|
51
|
+
- autotest/discover.rb
|
52
|
+
- lib/example.rb
|
53
|
+
- lib/pickled_optparse.rb
|
54
|
+
- spec/pickled_optparse/pickled_optparse_spec.rb
|
55
|
+
- spec/spec_helper.rb
|
56
|
+
has_rdoc: true
|
57
|
+
homepage: http://github.com/PicklePumpers/pickled_optparse
|
58
|
+
licenses: []
|
59
|
+
|
60
|
+
post_install_message:
|
61
|
+
rdoc_options: []
|
62
|
+
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ~>
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
segments:
|
71
|
+
- 1
|
72
|
+
- 9
|
73
|
+
- 2
|
74
|
+
version: 1.9.2
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
none: false
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
version: "0"
|
83
|
+
requirements: []
|
84
|
+
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.3.7
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Adds required switches to the OptionParser class
|
90
|
+
test_files:
|
91
|
+
- spec/pickled_optparse/pickled_optparse_spec.rb
|
92
|
+
- spec/spec_helper.rb
|