optopus 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/README +49 -0
- data/lib/optopus.rb +189 -0
- metadata +68 -0
data/README
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
= optopus
|
2
|
+
|
3
|
+
== Description
|
4
|
+
|
5
|
+
Enhanced option parser.
|
6
|
+
|
7
|
+
== Install
|
8
|
+
|
9
|
+
gem install optopus
|
10
|
+
|
11
|
+
== Example
|
12
|
+
|
13
|
+
require 'rubygems'
|
14
|
+
require 'optopus'
|
15
|
+
|
16
|
+
opts = optopus do
|
17
|
+
desc 'print lots of debugging information'
|
18
|
+
option :debug, '-d', '--debug'
|
19
|
+
|
20
|
+
desc 'log messages to FILE.'
|
21
|
+
option :output_file, '-o', '--output-file FILE', :default => '/var/log/xxx.log'
|
22
|
+
|
23
|
+
desc 'set number of retries to NUMBER (0 unlimits)'
|
24
|
+
option :tries, '-t', '--tries NUMBER', :type => Integer, :default => 0 do
|
25
|
+
# custom validation
|
26
|
+
invalid_argument if @value < 0
|
27
|
+
end
|
28
|
+
|
29
|
+
desc 'comma-separated list of accepted extensions'
|
30
|
+
option :accept, '-A', '--accept LIST', :type => Array, :default => []
|
31
|
+
|
32
|
+
desc 'access timestamp'
|
33
|
+
option :timestamp, '-T', '--timestamp TIME', :type => Time
|
34
|
+
|
35
|
+
# read yaml config file and overwrite options
|
36
|
+
file '-c', '--config-file FILE'
|
37
|
+
|
38
|
+
after do
|
39
|
+
# postprocessing
|
40
|
+
# @options.each { ... }
|
41
|
+
end
|
42
|
+
|
43
|
+
exception do |e|
|
44
|
+
$stderr.puts e.message
|
45
|
+
exit 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
p opts
|
data/lib/optopus.rb
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
require 'optparse/date'
|
3
|
+
require 'optparse/shellwords'
|
4
|
+
require 'optparse/time'
|
5
|
+
require 'optparse/uri'
|
6
|
+
require 'yaml'
|
7
|
+
|
8
|
+
module Optopus
|
9
|
+
class DefinerContext
|
10
|
+
def self.evaluate(opts, &block)
|
11
|
+
self.new(opts).instance_eval(&block)
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(opts)
|
15
|
+
@opts = opts
|
16
|
+
end
|
17
|
+
|
18
|
+
def desc(str)
|
19
|
+
@desc = str
|
20
|
+
end
|
21
|
+
|
22
|
+
def option(name, args_hd, *args_tl, &block)
|
23
|
+
@opts.add(name, [args_hd] + args_tl, @desc, block)
|
24
|
+
@desc = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def file(args_hd, *args_tl)
|
28
|
+
@desc ||= 'reading config file'
|
29
|
+
@opts.add_file([args_hd] + args_tl, @desc)
|
30
|
+
@desc = nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def after(&block)
|
34
|
+
@opts.add_after(block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def exception(&block)
|
38
|
+
@opts.add_exception(block)
|
39
|
+
end
|
40
|
+
end # DefinerContext
|
41
|
+
|
42
|
+
class CheckerContext
|
43
|
+
def self.evaluate(args, vars = {}, &block)
|
44
|
+
self.new(args, vars).instance_eval(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(value, vars = {})
|
48
|
+
@args = value ? [value] : []
|
49
|
+
|
50
|
+
vars.each do |name, value|
|
51
|
+
instance_variable_set("@#{name}", value)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def parse_error(reason)
|
56
|
+
e = OptionParser::ParseError.new(*@args)
|
57
|
+
e.reason = reason
|
58
|
+
raise e
|
59
|
+
end
|
60
|
+
|
61
|
+
def ambiguous_option
|
62
|
+
raise OptionParser::AmbiguousOption.new(*@args)
|
63
|
+
end
|
64
|
+
|
65
|
+
def needless_argument
|
66
|
+
raise OptionParser::NeedlessArgument.new(*@args)
|
67
|
+
end
|
68
|
+
|
69
|
+
def missing_argument
|
70
|
+
raise OptionParser::MissingArgument.new(*@args)
|
71
|
+
end
|
72
|
+
|
73
|
+
def invalid_option
|
74
|
+
raise OptionParser::InvalidOption.new(*@args)
|
75
|
+
end
|
76
|
+
|
77
|
+
def invalid_argument
|
78
|
+
raise OptionParser::InvalidArgument.new(*@args)
|
79
|
+
end
|
80
|
+
|
81
|
+
def ambiguous_argument
|
82
|
+
raise OptionParser::AmbiguousArgument.new(*@args)
|
83
|
+
end
|
84
|
+
end # CheckerContext
|
85
|
+
|
86
|
+
class Options
|
87
|
+
def initialize
|
88
|
+
@opts_args = []
|
89
|
+
end
|
90
|
+
|
91
|
+
def add(name, args, desc, block)
|
92
|
+
args, defval = fix_args(args, desc)
|
93
|
+
@opts_args << [name.to_sym, args, defval, block]
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_file(args, desc)
|
97
|
+
args, defval = fix_args(args, desc)
|
98
|
+
@file_args = args
|
99
|
+
end
|
100
|
+
|
101
|
+
def add_after(block)
|
102
|
+
@on_after = block
|
103
|
+
end
|
104
|
+
|
105
|
+
def add_exception(block)
|
106
|
+
@on_exception = block
|
107
|
+
end
|
108
|
+
|
109
|
+
def parse!
|
110
|
+
parser = OptionParser.new
|
111
|
+
options = {}
|
112
|
+
has_arg_h = false
|
113
|
+
|
114
|
+
@opts_args.each do |name, args, defval, block|
|
115
|
+
options[name] = defval
|
116
|
+
has_arg_h = (args.first == '-h')
|
117
|
+
|
118
|
+
parser.on(*args) do |*v|
|
119
|
+
value = v.first || true
|
120
|
+
options[name] = value
|
121
|
+
CheckerContext.evaluate(v, {:value => value}, &block) if block
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
if @file_args
|
126
|
+
parser.on(*@file_args) do |v|
|
127
|
+
config = YAML.load_file(v)
|
128
|
+
|
129
|
+
@opts_args.each do |name, args, defval, block|
|
130
|
+
value = config[name] || config[name.to_s]
|
131
|
+
|
132
|
+
next unless value
|
133
|
+
|
134
|
+
value = value.to_s
|
135
|
+
type = args.find {|i| i.kind_of?(Class) }
|
136
|
+
pat, conv = OptionParser::DefaultList.atype[type]
|
137
|
+
|
138
|
+
if pat and pat !~ value
|
139
|
+
raise OptionParser::InvalidArgument.new("(#{name}: #{value})")
|
140
|
+
end
|
141
|
+
|
142
|
+
value = conv.call(value) if conv
|
143
|
+
|
144
|
+
options[name] = value
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
unless has_arg_h
|
150
|
+
parser.on_tail('-h', '--help', 'Show this message') do
|
151
|
+
puts parser.help
|
152
|
+
exit
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
parser.parse!(ARGV)
|
157
|
+
CheckerContext.evaluate([], {:options => options},&@on_after) if @on_after
|
158
|
+
|
159
|
+
return options
|
160
|
+
rescue => e
|
161
|
+
if @on_exception
|
162
|
+
@on_exception.call(e)
|
163
|
+
else
|
164
|
+
raise e
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
private
|
169
|
+
def fix_args(args, desc)
|
170
|
+
defval = nil
|
171
|
+
|
172
|
+
if args.last.kind_of?(Hash)
|
173
|
+
hash = args.pop
|
174
|
+
args = (args.slice(0, 2) + [hash[:type], hash[:desc] || desc]).select {|i| i }
|
175
|
+
defval = hash[:default]
|
176
|
+
elsif desc
|
177
|
+
args = args + [desc]
|
178
|
+
end
|
179
|
+
|
180
|
+
return [args, defval]
|
181
|
+
end
|
182
|
+
end # Options
|
183
|
+
end # Optopus
|
184
|
+
|
185
|
+
def optopus(&block)
|
186
|
+
opts = Optopus::Options.new
|
187
|
+
Optopus::DefinerContext.evaluate(opts, &block)
|
188
|
+
opts.parse!
|
189
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: optopus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- winebarrel
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-05-31 00:00:00 +09:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description:
|
23
|
+
email: sgwr_dts@yahoo.co.jp
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files: []
|
29
|
+
|
30
|
+
files:
|
31
|
+
- README
|
32
|
+
- lib/optopus.rb
|
33
|
+
has_rdoc: true
|
34
|
+
homepage: https://bitbucket.org/winebarrel/optopus
|
35
|
+
licenses: []
|
36
|
+
|
37
|
+
post_install_message:
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
require_paths:
|
41
|
+
- lib
|
42
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
hash: 3
|
48
|
+
segments:
|
49
|
+
- 0
|
50
|
+
version: "0"
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
hash: 3
|
57
|
+
segments:
|
58
|
+
- 0
|
59
|
+
version: "0"
|
60
|
+
requirements: []
|
61
|
+
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 1.4.2
|
64
|
+
signing_key:
|
65
|
+
specification_version: 3
|
66
|
+
summary: Enhanced option parser.
|
67
|
+
test_files: []
|
68
|
+
|