cli 0.3.0 → 0.4.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.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
|