options 2.0.0 → 2.1.1

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/README CHANGED
@@ -26,6 +26,7 @@ INSTALL
26
26
  gem install options
27
27
 
28
28
  SAMPLES
29
+
29
30
 
30
31
  <========< samples/a.rb >========>
31
32
 
@@ -33,7 +34,7 @@ SAMPLES
33
34
 
34
35
  require 'options'
35
36
 
36
- # options.rb makes is super easy to deal with keyword options in a safe and
37
+ # options.rb makes it super easy to deal with keyword options in a safe and
37
38
  # easy way.
38
39
  #
39
40
 
@@ -149,3 +150,30 @@ SAMPLES
149
150
  {:options=>{:k=>:v}}
150
151
 
151
152
 
153
+ <========< samples/d.rb >========>
154
+
155
+ ~ > cat samples/d.rb
156
+
157
+ require 'options'
158
+
159
+ # options.rb makes it easy to provide good error messages when people
160
+ # misuse a method.
161
+ #
162
+
163
+ def method(*args)
164
+ args, options = Options.parse(args)
165
+ options.validate(:force)
166
+
167
+ force = options.getopt(:force, default=false)
168
+ p force
169
+ end
170
+
171
+ method(:foo, :bar, :force => true)
172
+
173
+
174
+
175
+ ~ > ruby samples/d.rb
176
+
177
+ true
178
+
179
+
@@ -0,0 +1,35 @@
1
+ NAME
2
+ options.rb
3
+
4
+ DESCRIPTION
5
+ options.rb simplifies the common idiom of dealing with keyword options in
6
+ ruby functions. it also deals correctly with symbol vs string keywords and
7
+ prevents many subtle programming errors that can arise from doing so
8
+ incorrectly. options.rb doesn't hack ruby's core with one exception: the
9
+ method Array#options.
10
+
11
+ SYNOPSIS
12
+ require 'options'
13
+
14
+ def method(*args, &block)
15
+ args, options = Options.parse(args)
16
+
17
+ a = args.shift
18
+ b = args.shift
19
+
20
+ force = options.getopt(:force, default = false)
21
+ verbose = options.getopt([:verbose, :VERBOSE])
22
+ foo, bar = options.getopt(:foo, :bar)
23
+ end
24
+
25
+ INSTALL
26
+ gem install options
27
+
28
+ HISTORY
29
+ 2.1.0:
30
+ - 1.9 compatibility
31
+ - Validation of passed options
32
+
33
+ SAMPLES
34
+
35
+ <%= samples %>
@@ -0,0 +1,235 @@
1
+
2
+ This.rubyforge_project = 'codeforpeople'
3
+ This.author = "Ara T. Howard"
4
+ This.email = "ara.t.howard@gmail.com"
5
+ This.homepage = "http://github.com/ahoward/#{ This.lib }/tree/master"
6
+
7
+
8
+ task :default do
9
+ puts(Rake::Task.tasks.map{|task| task.name} - ['default'])
10
+ end
11
+
12
+ task :spec do
13
+ require 'spec/rake/spectask'
14
+ Spec::Rake::SpecTask.new do |t|
15
+ t.spec_files = FileList['spec/*_spec.rb']
16
+ end
17
+ end
18
+
19
+
20
+ task :gemspec do
21
+ ignore_extensions = 'git', 'svn', 'tmp', /sw./, 'bak', 'gem'
22
+ ignore_directories = 'pkg'
23
+ ignore_files = 'test/log'
24
+
25
+ shiteless =
26
+ lambda do |list|
27
+ list.delete_if do |entry|
28
+ next unless test(?e, entry)
29
+ extension = File.basename(entry).split(%r/[.]/).last
30
+ ignore_extensions.any?{|ext| ext === extension}
31
+ end
32
+ list.delete_if do |entry|
33
+ next unless test(?d, entry)
34
+ dirname = File.expand_path(entry)
35
+ ignore_directories.any?{|dir| File.expand_path(dir) == dirname}
36
+ end
37
+ list.delete_if do |entry|
38
+ next unless test(?f, entry)
39
+ filename = File.expand_path(entry)
40
+ ignore_files.any?{|file| File.expand_path(file) == filename}
41
+ end
42
+ end
43
+
44
+ lib = This.lib
45
+ version = This.version
46
+ files = shiteless[Dir::glob("**/**")]
47
+ executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
48
+ has_rdoc = true #File.exist?('doc')
49
+ test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
50
+
51
+ extensions = This.extensions
52
+ if extensions.nil?
53
+ %w( Makefile configure extconf.rb ).each do |ext|
54
+ extensions << ext if File.exists?(ext)
55
+ end
56
+ end
57
+ extensions = [extensions].flatten.compact
58
+
59
+ template =
60
+ if test(?e, 'gemspec.erb')
61
+ Template{ IO.read('gemspec.erb') }
62
+ else
63
+ Template {
64
+ <<-__
65
+ ## #{ lib }.gemspec
66
+ #
67
+
68
+ Gem::Specification::new do |spec|
69
+ spec.name = #{ lib.inspect }
70
+ spec.version = #{ version.inspect }
71
+ spec.platform = Gem::Platform::RUBY
72
+ spec.summary = #{ lib.inspect }
73
+
74
+ spec.files = #{ files.inspect }
75
+ spec.executables = #{ executables.inspect }
76
+
77
+ spec.require_path = "lib"
78
+
79
+ spec.has_rdoc = #{ has_rdoc.inspect }
80
+ spec.test_files = #{ test_files.inspect }
81
+ #spec.add_dependency 'lib', '>= version'
82
+ #spec.add_dependency 'fattr'
83
+
84
+ spec.extensions.push(*#{ extensions.inspect })
85
+
86
+ spec.rubyforge_project = #{ This.rubyforge_project.inspect }
87
+ spec.author = #{ This.author.inspect }
88
+ spec.email = #{ This.email.inspect }
89
+ spec.homepage = #{ This.homepage.inspect }
90
+ end
91
+ __
92
+ }
93
+ end
94
+
95
+ open("#{ lib }.gemspec", "w"){|fd| fd.puts template}
96
+ This.gemspec = "#{ lib }.gemspec"
97
+ end
98
+
99
+ task :gem => [:clean, :gemspec] do
100
+ Fu.mkdir_p This.pkgdir
101
+ before = Dir['*.gem']
102
+ cmd = "gem build #{ This.gemspec }"
103
+ `#{ cmd }`
104
+ after = Dir['*.gem']
105
+ gem = ((after - before).first || after.first) or abort('no gem!')
106
+ Fu.mv gem, This.pkgdir
107
+ This.gem = File.basename(gem)
108
+ end
109
+
110
+ task :readme do
111
+ samples = ''
112
+ prompt = '~ > '
113
+ lib = This.lib
114
+ version = This.version
115
+
116
+ Dir['sample*/*'].sort.each do |sample|
117
+ samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
118
+
119
+ cmd = "cat #{ sample }"
120
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
121
+ samples << Util.indent(`#{ cmd }`, 4) << "\n"
122
+
123
+ cmd = "ruby #{ sample }"
124
+ samples << Util.indent(prompt + cmd, 2) << "\n\n"
125
+
126
+ cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
127
+ samples << Util.indent(`#{ cmd } 2>&1`, 4) << "\n"
128
+ end
129
+
130
+ template =
131
+ if test(?e, 'readme.erb')
132
+ Template{ IO.read('readme.erb') }
133
+ else
134
+ Template {
135
+ <<-__
136
+ NAME
137
+ #{ lib }
138
+
139
+ DESCRIPTION
140
+
141
+ INSTALL
142
+ gem install #{ lib }
143
+
144
+ SAMPLES
145
+ #{ samples }
146
+ __
147
+ }
148
+ end
149
+
150
+ open("README", "w"){|fd| fd.puts template}
151
+ end
152
+
153
+
154
+ task :clean do
155
+ Dir[File.join(This.pkgdir, '**/**')].each{|entry| Fu.rm_rf(entry)}
156
+ end
157
+
158
+
159
+ task :release => [:clean, :gemspec, :gem] do
160
+ gems = Dir[File.join(This.pkgdir, '*.gem')].flatten
161
+ raise "which one? : #{ gems.inspect }" if gems.size > 1
162
+ raise "no gems?" if gems.size < 1
163
+ cmd = "rubyforge login && rubyforge add_release #{ This.rubyforge_project } #{ This.lib } #{ This.version } #{ This.pkgdir }/#{ This.gem }"
164
+ puts cmd
165
+ system cmd
166
+ end
167
+
168
+
169
+
170
+
171
+
172
+ BEGIN {
173
+ $VERBOSE = nil
174
+
175
+ require 'ostruct'
176
+ require 'erb'
177
+ require 'fileutils'
178
+
179
+ Fu = FileUtils
180
+
181
+ This = OpenStruct.new
182
+
183
+ This.file = File.expand_path(__FILE__)
184
+ This.dir = File.dirname(This.file)
185
+ This.pkgdir = File.join(This.dir, 'pkg')
186
+
187
+ lib = ENV['LIB']
188
+ unless lib
189
+ lib = File.basename(Dir.pwd)
190
+ end
191
+ This.lib = lib
192
+
193
+ version = ENV['VERSION']
194
+ unless version
195
+ name = lib.capitalize
196
+ require "./lib/#{ lib }"
197
+ version = eval(name).send(:version)
198
+ end
199
+ This.version = version
200
+
201
+ abort('no lib') unless This.lib
202
+ abort('no version') unless This.version
203
+
204
+ module Util
205
+ def indent(s, n = 2)
206
+ s = unindent(s)
207
+ ws = ' ' * n
208
+ s.gsub(%r/^/, ws)
209
+ end
210
+
211
+ def unindent(s)
212
+ indent = nil
213
+ s.each do |line|
214
+ next if line =~ %r/^\s*$/
215
+ indent = line[%r/^\s*/] and break
216
+ end
217
+ indent ? s.gsub(%r/^#{ indent }/, "") : s
218
+ end
219
+ extend self
220
+ end
221
+
222
+ class Template
223
+ def initialize(&block)
224
+ @block = block
225
+ @template = block.call.to_s
226
+ end
227
+ def expand(b=nil)
228
+ ERB.new(Util.unindent(@template)).result(b||@block)
229
+ end
230
+ alias_method 'to_s', 'expand'
231
+ end
232
+ def Template(*args, &block) Template.new(*args, &block) end
233
+
234
+ Dir.chdir(This.dir)
235
+ }
@@ -1,5 +1,5 @@
1
1
  module Options
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.1'
3
3
 
4
4
  class << Options
5
5
  def version
@@ -46,8 +46,15 @@ module Options
46
46
  end
47
47
 
48
48
  def parse(args)
49
- args.extend(Arguments) unless args.is_a?(Arguments)
50
- args.options.pop
49
+ case args
50
+ when Array
51
+ args.extend(Arguments) unless args.is_a?(Arguments)
52
+ [args, args.options.pop]
53
+ when Hash
54
+ Options.for(args)
55
+ else
56
+ raise ArgumentError, "`args` should be and Array or Hash"
57
+ end
51
58
  end
52
59
  end
53
60
 
@@ -131,13 +138,13 @@ module Options
131
138
  def normalize!
132
139
  Options.normalize!(self)
133
140
  end
134
- alias_method 'normalized!', 'normalized!'
141
+ alias_method 'normalized!', 'normalize!'
135
142
  alias_method 'to_options!', 'normalize!'
136
143
 
137
144
  def normalize
138
145
  Options.normalize(self)
139
146
  end
140
- alias_method 'normalized', 'normalized'
147
+ alias_method 'normalized', 'normalize'
141
148
  alias_method 'to_options', 'normalize'
142
149
 
143
150
  def stringify!
@@ -163,6 +170,23 @@ module Options
163
170
  def pop!
164
171
  @popped = arguments.pop
165
172
  end
173
+
174
+ # Validates that the options provided are acceptable.
175
+ #
176
+ # @param [Symbol] *acceptable_options List of options that are
177
+ # allowed
178
+ def validate(*acceptable_options)
179
+ remaining = (provided_options - acceptable_options).map{|opt| opt.to_s}.sort
180
+ raise ArgumentError, "Unrecognized options: #{remaining.join(', ')}" unless remaining.empty?
181
+
182
+ self
183
+ end
184
+
185
+ protected
186
+
187
+ def provided_options
188
+ normalize!.keys
189
+ end
166
190
  end
167
191
 
168
192
  module Arguments
@@ -1,26 +1,26 @@
1
- ### gemspec: options-2.0.0
1
+ ## options.gemspec
2
+ #
2
3
 
3
- Gem::Specification::new do |spec|
4
- spec.name = "options"
5
- spec.version = "2.0.0"
6
- spec.platform = Gem::Platform::RUBY
7
- spec.summary = "options"
4
+ Gem::Specification::new do |spec|
5
+ spec.name = "options"
6
+ spec.version = "2.1.1"
7
+ spec.platform = Gem::Platform::RUBY
8
+ spec.summary = "options"
8
9
 
9
- spec.files = ["gemspec.rb", "lib", "lib/options.rb", "options.gemspec", "README", "README.rb", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb"]
10
- spec.executables = []
11
-
12
- spec.require_path = "lib"
10
+ spec.files = ["lib", "lib/options.rb", "options.gemspec", "Rakefile", "README", "README.erb", "samples", "samples/a.rb", "samples/b.rb", "samples/c.rb", "samples/d.rb", "spec", "spec/options_spec.rb", "spec/spec_helper.rb"]
11
+ spec.executables = []
12
+
13
+ spec.require_path = "lib"
13
14
 
14
- spec.has_rdoc = true
15
- spec.test_files = nil
16
- #spec.add_dependency 'lib', '>= version'
17
- #spec.add_dependency 'fattr'
15
+ spec.has_rdoc = true
16
+ spec.test_files = nil
17
+ #spec.add_dependency 'lib', '>= version'
18
+ #spec.add_dependency 'fattr'
18
19
 
19
- spec.extensions.push(*[])
20
-
21
- spec.rubyforge_project = 'codeforpeople'
22
- spec.author = "Ara T. Howard"
23
- spec.email = "ara.t.howard@gmail.com"
24
- spec.homepage = "http://github.com/ahoward/options/tree/master"
25
- end
20
+ spec.extensions.push(*[])
26
21
 
22
+ spec.rubyforge_project = "codeforpeople"
23
+ spec.author = "Ara T. Howard"
24
+ spec.email = "ara.t.howard@gmail.com"
25
+ spec.homepage = "http://github.com/ahoward/options/tree/master"
26
+ end
@@ -1,6 +1,6 @@
1
1
  require 'options'
2
2
 
3
- # options.rb makes is super easy to deal with keyword options in a safe and
3
+ # options.rb makes it super easy to deal with keyword options in a safe and
4
4
  # easy way.
5
5
  #
6
6
 
@@ -0,0 +1,17 @@
1
+ require 'options'
2
+
3
+ # options.rb makes it easy to provide good error messages when people
4
+ # misuse a method.
5
+ #
6
+
7
+ def method(*args)
8
+ args, options = Options.parse(args)
9
+ options.validate(:force)
10
+
11
+ force = options.getopt(:force, default=false)
12
+ p force
13
+ end
14
+
15
+ method(:foo, :bar, :force => true)
16
+
17
+
@@ -0,0 +1,38 @@
1
+ require File.dirname(__FILE__) + "/spec_helper"
2
+ require 'options'
3
+
4
+ describe Options do
5
+ describe "parsing" do
6
+ it "should be able to handle an options hash" do
7
+ opts = Options.parse({:this => 'that'})
8
+ opts.getopt(:this).should eql('that')
9
+ end
10
+
11
+ it "should be able to handle args list w/ options hash" do
12
+ args, opts = Options.parse([:foo, {:this => 'that'}])
13
+ opts.getopt(:this).should eql('that')
14
+ args.should eql([:foo])
15
+ end
16
+ end
17
+
18
+ describe "validation" do
19
+ it "should be able to detect extraneous options" do
20
+ lambda{
21
+ Options.parse({:this => 'test'}).validate(:foo, :bar)
22
+ }.should raise_error(ArgumentError, "Unrecognized options: this")
23
+ end
24
+
25
+ it "should list all extraneous options in message" do
26
+ lambda{
27
+ Options.parse({:this => 'test', :that => 'test'}).validate(:foo)
28
+ }.should raise_error(ArgumentError, "Unrecognized options: that, this")
29
+ end
30
+
31
+ it "should accept options from simple list" do
32
+ lambda{
33
+ Options.parse({:foo => 'this', :bar => 'that'}).validate(:foo, :bar)
34
+ }.should_not raise_error
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'pathname'
4
+ require 'pp'
5
+
6
+ $LOAD_PATH.unshift Pathname(__FILE__).dirname + "../lib"
7
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: options
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ara T. Howard
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-31 00:00:00 -06:00
12
+ date: 2009-08-19 00:00:00 -06:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -22,16 +22,20 @@ extensions: []
22
22
  extra_rdoc_files: []
23
23
 
24
24
  files:
25
- - gemspec.rb
26
25
  - lib
27
26
  - lib/options.rb
28
27
  - options.gemspec
28
+ - Rakefile
29
29
  - README
30
- - README.rb
30
+ - README.erb
31
31
  - samples
32
32
  - samples/a.rb
33
33
  - samples/b.rb
34
34
  - samples/c.rb
35
+ - samples/d.rb
36
+ - spec
37
+ - spec/options_spec.rb
38
+ - spec/spec_helper.rb
35
39
  has_rdoc: true
36
40
  homepage: http://github.com/ahoward/options/tree/master
37
41
  post_install_message:
data/README.rb DELETED
@@ -1,80 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- template = <<-__
4
- NAME
5
- options.rb
6
-
7
- DESCRIPTION
8
- options.rb simplifies the common idiom of dealing with keyword options in
9
- ruby functions. it also deals correctly with symbol vs string keywords and
10
- prevents many subtle programming errors that can arise from doing so
11
- incorrectly. options.rb doesn't hack ruby's core with one exception: the
12
- method Array#options.
13
-
14
- SYNOPSIS
15
- require 'options'
16
-
17
- def method(*args, &block)
18
- args, options = Options.parse(args)
19
-
20
- a = args.shift
21
- b = args.shift
22
-
23
- force = options.getopt(:force, default = false)
24
- verbose = options.getopt([:verbose, :VERBOSE])
25
- foo, bar = options.getopt(:foo, :bar)
26
- end
27
-
28
- INSTALL
29
- gem install options
30
-
31
- SAMPLES
32
- <%= samples %>
33
- __
34
-
35
-
36
- require 'erb'
37
- require 'pathname'
38
-
39
- $VERBOSE=nil
40
-
41
- def indent(s, n = 2)
42
- s = unindent(s)
43
- ws = ' ' * n
44
- s.gsub(%r/^/, ws)
45
- end
46
-
47
- def unindent(s)
48
- indent = nil
49
- s.each do |line|
50
- next if line =~ %r/^\s*$/
51
- indent = line[%r/^\s*/] and break
52
- end
53
- indent ? s.gsub(%r/^#{ indent }/, "") : s
54
- end
55
-
56
- samples = ''
57
- prompt = '~ > '
58
-
59
- Dir.chdir(File.dirname(__FILE__))
60
-
61
- Dir['sample*/*'].sort.each do |sample|
62
- samples << "\n" << " <========< #{ sample } >========>" << "\n\n"
63
-
64
- cmd = "cat #{ sample }"
65
- samples << indent(prompt + cmd, 2) << "\n\n"
66
- samples << indent(`#{ cmd }`, 4) << "\n"
67
-
68
- cmd = "ruby #{ sample }"
69
- samples << indent(prompt + cmd, 2) << "\n\n"
70
-
71
- cmd = "ruby -e'STDOUT.sync=true; exec %(ruby -Ilib #{ sample })'"
72
- #cmd = "ruby -Ilib #{ sample }"
73
- samples << indent(`#{ cmd } 2>&1`, 4) << "\n"
74
- end
75
-
76
- erb = ERB.new(unindent(template))
77
- result = erb.result(binding)
78
- #open('README', 'w'){|fd| fd.write result}
79
- #puts unindent(result)
80
- puts result
data/gemspec.rb DELETED
@@ -1,62 +0,0 @@
1
- #! /usr/bin/env ruby
2
-
3
- lib, version, *ignored = ARGV
4
-
5
- unless lib
6
- lib = File.basename(Dir.pwd)
7
- end
8
-
9
- unless version
10
- mod = lib.capitalize
11
- require "./lib/#{ lib }"
12
- version = eval(mod).send(:version)
13
- end
14
-
15
- abort('no lib') unless lib
16
- abort('no version') unless version
17
-
18
- puts "### gemspec: #{ lib }-#{ version }"
19
-
20
- $VERBOSE = nil
21
-
22
- shiteless = lambda{|list| list.delete_if{|file| file =~ %r/\.(git|svn|tmp|sw.|bak|gem)$/}}
23
-
24
- files = shiteless[Dir::glob("**/**")]
25
- executables = shiteless[Dir::glob("bin/*")].map{|exe| File.basename(exe)}
26
- has_rdoc = true #File.exist?('doc')
27
- test_files = "test/#{ lib }.rb" if File.file?("test/#{ lib }.rb")
28
-
29
- extensions = []
30
- %w( Makefile configure extconf.rb rakefile Rakefile mkrf_conf ).each do |ext|
31
- extensions << ext if File.exists?(ext)
32
- end
33
-
34
- template = <<-__
35
-
36
- Gem::Specification::new do |spec|
37
- spec.name = #{ lib.inspect }
38
- spec.version = #{ version.inspect }
39
- spec.platform = Gem::Platform::RUBY
40
- spec.summary = #{ lib.inspect }
41
-
42
- spec.files = #{ files.inspect }
43
- spec.executables = #{ executables.inspect }
44
-
45
- spec.require_path = "lib"
46
-
47
- spec.has_rdoc = #{ has_rdoc.inspect }
48
- spec.test_files = #{ test_files.inspect }
49
- #spec.add_dependency 'lib', '>= version'
50
- #spec.add_dependency 'fattr'
51
-
52
- spec.extensions.push(*#{ extensions.inspect })
53
-
54
- spec.rubyforge_project = 'codeforpeople'
55
- spec.author = "Ara T. Howard"
56
- spec.email = "ara.t.howard@gmail.com"
57
- spec.homepage = "http://github.com/ahoward/#{ lib }/tree/master"
58
- end
59
-
60
- __
61
-
62
- puts template