cli 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +27 -7
- data/VERSION +1 -1
- data/cli.gemspec +2 -2
- data/examples/processor +4 -1
- data/lib/cli.rb +38 -18
- data/spec/cli_spec.rb +41 -0
- metadata +4 -4
data/README.md
CHANGED
@@ -103,11 +103,16 @@ require 'yaml'
|
|
103
103
|
|
104
104
|
options = CLI.new do
|
105
105
|
description 'Generate blog posts in given Jekyll directory from input statistics'
|
106
|
-
stdin :log_data,
|
107
|
-
option :location,
|
108
|
-
option :csv_dir,
|
109
|
-
argument :jekyll_dir,
|
110
|
-
end.parse!
|
106
|
+
stdin :log_data, :cast => YAML, :description => 'statistic data in YAML format'
|
107
|
+
option :location, :short => :l, :description => 'location name (ex. Dublin, Singapore, Califorina)'
|
108
|
+
option :csv_dir, :short => :c, :cast => Pathname, :default => 'csv', :description => 'directory name where CSV file will be storred (relative to jekyll-dir)'
|
109
|
+
argument :jekyll_dir, :cast => Pathname, :default => '/var/lib/vhs/jekyll', :description => 'directory where site source is located'
|
110
|
+
end.parse! do |options|
|
111
|
+
fail 'jekyll-dir is not a directory' unless options.jekyll_dir.directory?
|
112
|
+
fail '--csv-dir is not a directory (relative to jekyll-dir)' unless (options.jekyll_dir + options.csv_dir).directory?
|
113
|
+
end
|
114
|
+
|
115
|
+
p options
|
111
116
|
|
112
117
|
# do your stuff
|
113
118
|
```
|
@@ -126,7 +131,7 @@ Example help message:
|
|
126
131
|
Arguments:
|
127
132
|
jekyll-dir - directory where site source is located
|
128
133
|
|
129
|
-
With this example usage:
|
134
|
+
With this example usage (assuming /var/lib/vhs/jekyll/csv dir exist):
|
130
135
|
|
131
136
|
examples/processor --location Singapore <<EOF
|
132
137
|
:parser:
|
@@ -136,7 +141,22 @@ With this example usage:
|
|
136
141
|
|
137
142
|
The `options` variable will contain:
|
138
143
|
|
139
|
-
#<CLI::Values
|
144
|
+
#<CLI::Values stdin={:parser=>{:successes=>41, :failures=>0}}, jekyll_dir=#<Pathname:/var/lib/vhs/jekyll>, csv_dir=#<Pathname:csv>, help=nil, location="Singapore">
|
145
|
+
|
146
|
+
Output if jekyll-dir does not exist:
|
147
|
+
|
148
|
+
Error: jekyll-dir is not a directory
|
149
|
+
Usage: processor [switches|options] [--] jekyll-dir < log-data
|
150
|
+
Generate blog posts in given Jekyll directory from input statistics
|
151
|
+
Input:
|
152
|
+
log-data - statistic data in YAML format
|
153
|
+
Switches:
|
154
|
+
--help (-h) - display this help message
|
155
|
+
Options:
|
156
|
+
--location (-l) - location name (ex. Dublin, Singapore, Califorina)
|
157
|
+
--csv-dir (-c) [csv] - directory name where CSV file will be storred (relative to jekyll-dir)
|
158
|
+
Arguments:
|
159
|
+
jekyll-dir [/var/lib/vhs/jekyll] - directory where site source is located
|
140
160
|
|
141
161
|
### Ls like utility
|
142
162
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/cli.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "cli"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.4.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Jakub Pastuszek"]
|
12
|
-
s.date = "2011-12-
|
12
|
+
s.date = "2011-12-30"
|
13
13
|
s.description = "Provides DSL for command-line options, switches and arguments parser and stdin handling with generated usage printer"
|
14
14
|
s.email = "jpastuszek@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
data/examples/processor
CHANGED
@@ -9,7 +9,10 @@ options = CLI.new do
|
|
9
9
|
option :location, :short => :l, :description => 'location name (ex. Dublin, Singapore, Califorina)'
|
10
10
|
option :csv_dir, :short => :c, :cast => Pathname, :default => 'csv', :description => 'directory name where CSV file will be storred (relative to jekyll-dir)'
|
11
11
|
argument :jekyll_dir, :cast => Pathname, :default => '/var/lib/vhs/jekyll', :description => 'directory where site source is located'
|
12
|
-
end.parse!
|
12
|
+
end.parse! do |options|
|
13
|
+
fail 'jekyll-dir is not a directory' unless options.jekyll_dir.directory?
|
14
|
+
fail '--csv-dir is not a directory (relative to jekyll-dir)' unless (options.jekyll_dir + options.csv_dir).directory?
|
15
|
+
end
|
13
16
|
|
14
17
|
p options
|
15
18
|
|
data/lib/cli.rb
CHANGED
@@ -87,6 +87,9 @@ class CLI
|
|
87
87
|
super("failed to cast: '#{arg}' to type: #{cast_name}: #{error}")
|
88
88
|
end
|
89
89
|
end
|
90
|
+
|
91
|
+
class UsageError < ParsingError
|
92
|
+
end
|
90
93
|
end
|
91
94
|
|
92
95
|
class Values < OpenStruct
|
@@ -148,34 +151,19 @@ class CLI
|
|
148
151
|
|
149
152
|
def switch(name, options = {})
|
150
153
|
switch_dsl = DSL::Switch.new(name, options)
|
151
|
-
|
152
|
-
raise ParserError::LongNameSpecifiedTwiceError.new('switch', switch_dsl) if @switches.has_long?(switch_dsl)
|
153
|
-
raise ParserError::LongNameSpecifiedTwiceError.new('option and switch', switch_dsl) if @options.has_long?(switch_dsl)
|
154
|
-
raise ParserError::ShortNameSpecifiedTwiceError.new('switch', switch_dsl) if @switches.has_short?(switch_dsl)
|
155
|
-
raise ParserError::ShortNameSpecifiedTwiceError.new('option and switch', switch_dsl) if @options.has_short?(switch_dsl)
|
156
|
-
|
154
|
+
check_switch_collision!(switch_dsl)
|
157
155
|
@switches << switch_dsl
|
158
156
|
end
|
159
157
|
|
160
158
|
def option(name, options = {})
|
161
159
|
option_dsl = DSL::Option.new(name, options)
|
162
|
-
|
163
|
-
raise ParserError::LongNameSpecifiedTwiceError.new('option', option_dsl) if @options.has_long?(option_dsl)
|
164
|
-
raise ParserError::LongNameSpecifiedTwiceError.new('switch and option', option_dsl) if @switches.has_long?(option_dsl)
|
165
|
-
raise ParserError::ShortNameSpecifiedTwiceError.new('option', option_dsl) if @options.has_short?(option_dsl)
|
166
|
-
raise ParserError::ShortNameSpecifiedTwiceError.new('switch and option', option_dsl) if @switches.has_short?(option_dsl)
|
167
|
-
|
160
|
+
check_switch_collision!(option_dsl)
|
168
161
|
@options << option_dsl
|
169
162
|
end
|
170
163
|
|
171
164
|
def options(name, options = {})
|
172
165
|
option_dsl = DSL::Options.new(name, options)
|
173
|
-
|
174
|
-
raise ParserError::LongNameSpecifiedTwiceError.new('option', option_dsl) if @options.has_long?(option_dsl)
|
175
|
-
raise ParserError::LongNameSpecifiedTwiceError.new('switch and option', option_dsl) if @switches.has_long?(option_dsl)
|
176
|
-
raise ParserError::ShortNameSpecifiedTwiceError.new('option', option_dsl) if @options.has_short?(option_dsl)
|
177
|
-
raise ParserError::ShortNameSpecifiedTwiceError.new('switch and option', option_dsl) if @switches.has_short?(option_dsl)
|
178
|
-
|
166
|
+
check_switch_collision!(option_dsl)
|
179
167
|
@options << option_dsl
|
180
168
|
end
|
181
169
|
|
@@ -198,6 +186,15 @@ class CLI
|
|
198
186
|
end
|
199
187
|
end
|
200
188
|
|
189
|
+
# initialize values
|
190
|
+
@options.each do |o|
|
191
|
+
values.value(o, nil)
|
192
|
+
end
|
193
|
+
|
194
|
+
@switches.each do |o|
|
195
|
+
values.value(o, nil)
|
196
|
+
end
|
197
|
+
|
201
198
|
# initialize multi options
|
202
199
|
@options.multiple.each do |o|
|
203
200
|
values.value(o, [])
|
@@ -274,6 +271,14 @@ class CLI
|
|
274
271
|
stdout.write pp.version
|
275
272
|
exit 0
|
276
273
|
end
|
274
|
+
|
275
|
+
if block_given?
|
276
|
+
begin
|
277
|
+
yield pp
|
278
|
+
rescue RuntimeError => e
|
279
|
+
raise ParsingError::UsageError, e.message
|
280
|
+
end
|
281
|
+
end
|
277
282
|
pp
|
278
283
|
rescue ParsingError => pe
|
279
284
|
usage!(pe, stderr)
|
@@ -353,5 +358,20 @@ class CLI
|
|
353
358
|
io.write usage(msg)
|
354
359
|
exit 42
|
355
360
|
end
|
361
|
+
|
362
|
+
private
|
363
|
+
|
364
|
+
def check_switch_collision!(switch_dsl)
|
365
|
+
type = switch_dsl.class.name.downcase.sub(/.*::/, '')
|
366
|
+
{
|
367
|
+
'switch' => @switches,
|
368
|
+
'option' => @options
|
369
|
+
}.each_pair do |collection_type, collection|
|
370
|
+
what = (type == collection_type ? type : collection_type + ' and ' + type)
|
371
|
+
|
372
|
+
raise ParserError::LongNameSpecifiedTwiceError.new(what, switch_dsl) if collection.has_long?(switch_dsl)
|
373
|
+
raise ParserError::ShortNameSpecifiedTwiceError.new(what, switch_dsl) if collection.has_short?(switch_dsl)
|
374
|
+
end
|
375
|
+
end
|
356
376
|
end
|
357
377
|
|
data/spec/cli_spec.rb
CHANGED
@@ -41,6 +41,47 @@ describe CLI do
|
|
41
41
|
ps.code.should == 'hello'
|
42
42
|
end
|
43
43
|
|
44
|
+
it "should return value structure where all values are set" do
|
45
|
+
h = CLI.new do
|
46
|
+
option :location, :short => :l
|
47
|
+
switch :debug
|
48
|
+
end.parse!([]).marshal_dump
|
49
|
+
|
50
|
+
h.member?(:location).should be_true
|
51
|
+
h[:location].should be_nil
|
52
|
+
|
53
|
+
h.member?(:debug).should be_true
|
54
|
+
h[:debug].should be_nil
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should take a block that can be used to verify passed values" do
|
58
|
+
lambda {
|
59
|
+
ps = CLI.new do
|
60
|
+
option :location, :short => :l
|
61
|
+
switch :debug
|
62
|
+
switch :verbose
|
63
|
+
argument :code
|
64
|
+
end.parse!(['-l', 'singapore', '--debug', 'hello']) do |values|
|
65
|
+
fail '--debug can not be used with --verbose' if values.debug and values.verbose
|
66
|
+
end
|
67
|
+
}.should_not raise_error
|
68
|
+
|
69
|
+
out = stderr_read do
|
70
|
+
lambda {
|
71
|
+
ps = CLI.new do
|
72
|
+
option :location, :short => :l
|
73
|
+
switch :debug
|
74
|
+
switch :verbose
|
75
|
+
argument :code
|
76
|
+
end.parse!(['-l', 'singapore', '--debug', '--verbose', 'hello']) do |values|
|
77
|
+
fail '--debug can not be used with --verbose' if values.debug and values.verbose
|
78
|
+
end
|
79
|
+
}.should raise_error SystemExit
|
80
|
+
end
|
81
|
+
out.should include('Error: --debug can not be used with --verbose')
|
82
|
+
out.should include('Usage:')
|
83
|
+
end
|
84
|
+
|
44
85
|
it "should exit displaying usage and error message on standard error on usage error" do
|
45
86
|
out = stderr_read do
|
46
87
|
lambda {
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
8
|
+
- 4
|
9
9
|
- 0
|
10
|
-
version: 0.
|
10
|
+
version: 0.4.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jakub Pastuszek
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-12-
|
18
|
+
date: 2011-12-30 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
type: :development
|