pickled_optparse 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|