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 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, :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!
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 location="Singapore", stdin={:parser=>{:failures=>0, :successes=>41}}, jekyll_dir=#<Pathname:/var/lib/vhs/jekyll>, csv_dir=#<Pathname:csv>>
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.3.0
1
+ 0.4.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "cli"
8
- s.version = "0.3.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-21"
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 = [
@@ -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
 
@@ -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: 19
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 3
8
+ - 4
9
9
  - 0
10
- version: 0.3.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-21 00:00:00 Z
18
+ date: 2011-12-30 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  type: :development