clive 0.2.3 → 0.3.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.
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+
3
+ class TestCommand < Test::Unit::TestCase
4
+
5
+ context "A new command" do
6
+
7
+ setup do
8
+ @c = Clive.new do
9
+ command(:add, "Add something") {puts "called!"}
10
+ end
11
+ end
12
+
13
+ context "with multiple names" do
14
+ setup do
15
+ @c = Clive.new do
16
+ command(:add, :init, :new, "Add something") {puts "called!"}
17
+ end
18
+ end
19
+
20
+ should "be called with first name" do
21
+ mock($stdout).puts("called!")
22
+ @c.parse ["add"]
23
+ end
24
+
25
+ should "be called with second name" do
26
+ mock($stdout).puts("called!")
27
+ @c.parse ["init"]
28
+ end
29
+
30
+ should "be called with third name" do
31
+ mock($stdout).puts("called!")
32
+ @c.parse ["new"]
33
+ end
34
+ end
35
+
36
+
37
+ should "only execute it's block when called" do
38
+ mock($stdout).puts("called!")
39
+ @c.parse(["a"])
40
+ @c.parse(["add"])
41
+ end
42
+
43
+ end
44
+ end
@@ -6,7 +6,7 @@ class TestFlag < Test::Unit::TestCase
6
6
 
7
7
  setup do
8
8
  @c = Clive.new do
9
- flag(:t, :type, "Choose type") {|i| $stdout.puts(i)}
9
+ flag(:t, :type, "TEXT", "Change type to TYPE") {|i| $stdout.puts(i)}
10
10
  end
11
11
  end
12
12
 
@@ -15,5 +15,44 @@ class TestFlag < Test::Unit::TestCase
15
15
  @c.parse(["--type", "text"])
16
16
  end
17
17
 
18
+ should "have an arg name" do
19
+ assert_equal "TEXT", @c.flags["t"].arg_name
20
+ end
21
+
22
+ should "not be optional" do
23
+ assert_equal false, @c.flags["t"].optional
24
+ end
25
+
18
26
  end
27
+
28
+ context "A new flag with default" do
29
+
30
+ setup do
31
+ @c = Clive.new do
32
+ flag(:t, :type, "[TEXT]", "Change type to TYPE") do |i|
33
+ i ||= 'dog'
34
+ $stdout.puts(i)
35
+ end
36
+ end
37
+ end
38
+
39
+ should "have an arg name" do
40
+ assert_equal "TEXT", @c.flags["t"].arg_name
41
+ end
42
+
43
+ should "be optional" do
44
+ assert_equal true, @c.flags["t"].optional
45
+ end
46
+
47
+ should "pass an argument to block" do
48
+ mock($stdout).puts("text")
49
+ @c.parse(["--type", "text"])
50
+ end
51
+
52
+ should "pass nil to the block if no argument" do
53
+ mock($stdout).puts("dog")
54
+ @c.parse(["--type"])
55
+ end
56
+ end
57
+
19
58
  end
@@ -10,8 +10,7 @@ class TestToken < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  should "convert an array to tokens" do
13
- t = Clive::Tokens.new(@array)
14
- assert_equal @tokens, t.tokens
13
+ assert_equal @tokens, Clive::Tokens.to_tokens(@array)
15
14
  end
16
15
 
17
16
  should "convert tokens to an array" do
@@ -25,9 +24,6 @@ class TestToken < Test::Unit::TestCase
25
24
  @array = ["add", "-al", "--verbose"]
26
25
  @array_split = ["add", "-a", "-l", "--verbose"]
27
26
  @tokens = [[:word, "add"], [:short, "a"], [:short, "l"], [:long, "verbose"]]
28
-
29
- @t = Clive::Tokens.new
30
- @t << "add" << "-al" << "--verbose"
31
27
  end
32
28
 
33
29
  should "be created from an array" do
@@ -41,13 +37,30 @@ class TestToken < Test::Unit::TestCase
41
37
  assert_equal @tokens, t.tokens
42
38
  assert_equal @array_split, t.array
43
39
  end
44
-
45
- should "have tokens" do
46
-
40
+
41
+ should "tell whether an array is a token" do
42
+ t = Clive::Tokens.new
43
+ assert_equal false, t.token?(["a", "normal", "array"])
44
+ assert_equal true, t.token?([:word, "help"])
47
45
  end
48
46
 
49
- should "have an array" do
47
+ should "turn token to string" do
48
+ t = Clive::Tokens.new
49
+ assert_equal "-v", t.token_to_string([:short, "v"])
50
+ assert_equal "--verbose", t.token_to_string([:long, "verbose"])
51
+ assert_equal "word", t.token_to_string([:word, "word"])
52
+ end
50
53
 
54
+ should "add new string values" do
55
+ t = Clive::Tokens.new
56
+ t << "add" << "-al" << "--verbose"
57
+ assert_equal @tokens, t.tokens
58
+ end
59
+
60
+ should "add new token values" do
61
+ t = Clive::Tokens.new
62
+ t << [:word, "add"] << [:short, "a"] << [:short, "l"] << [:long, "verbose"]
63
+ assert_equal @array_split, t.array
51
64
  end
52
65
 
53
66
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clive
3
3
  version: !ruby/object:Gem::Version
4
- hash: 17
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
8
  - 3
10
- version: 0.2.3
9
+ - 0
10
+ version: 0.3.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Joshua Hawxwell
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-17 00:00:00 +01:00
18
+ date: 2010-08-21 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -64,16 +64,19 @@ files:
64
64
  - VERSION
65
65
  - clive.gemspec
66
66
  - lib/clive.rb
67
- - lib/clive/booleans.rb
68
- - lib/clive/commands.rb
67
+ - lib/clive/bool.rb
68
+ - lib/clive/command.rb
69
+ - lib/clive/exceptions.rb
69
70
  - lib/clive/ext.rb
70
- - lib/clive/flags.rb
71
- - lib/clive/switches.rb
71
+ - lib/clive/flag.rb
72
+ - lib/clive/option.rb
73
+ - lib/clive/switch.rb
72
74
  - lib/clive/tokens.rb
73
75
  - test/bin_test
74
76
  - test/helper.rb
75
77
  - test/test_boolean.rb
76
78
  - test/test_clive.rb
79
+ - test/test_command.rb
77
80
  - test/test_exceptions.rb
78
81
  - test/test_flag.rb
79
82
  - test/test_switch.rb
@@ -116,6 +119,7 @@ test_files:
116
119
  - test/helper.rb
117
120
  - test/test_boolean.rb
118
121
  - test/test_clive.rb
122
+ - test/test_command.rb
119
123
  - test/test_exceptions.rb
120
124
  - test/test_flag.rb
121
125
  - test/test_switch.rb
@@ -1,37 +0,0 @@
1
- class Clive
2
-
3
- # A switch which can be triggered with either --no-verbose or --verbose
4
- # for example.
5
- class Boolean < Switch
6
- attr_accessor :truth
7
-
8
- def initialize(short, long, desc, truth, &block)
9
- @short = short
10
- @long = long
11
- @desc = desc
12
- @truth = truth
13
- @block = block
14
- end
15
-
16
- def run
17
- @block.call(@truth)
18
- end
19
-
20
- # @return [String] summary for help or nil if +@truth = false+
21
- def summary(width=30, prepend=5)
22
- return nil unless @truth
23
- a = ""
24
- a << "-#{@short}" if @short
25
- a << ", " if @short && @long
26
- a << "--[no-]#{@long}" if @long
27
- b = @desc
28
- s, p = '', ''
29
- # want at least one space between name and desc
30
- spaces = width-a.length < 0 ? 1 : width-a.length
31
- (0...spaces).each {s << ' '}
32
- (0...prepend).each {p << ' '}
33
- "#{p}#{a}#{s}#{b}"
34
- end
35
-
36
- end
37
- end
@@ -1,317 +0,0 @@
1
- class Clive
2
-
3
- # A string which describes the command to execute
4
- # eg. git add
5
- # git pull
6
- #
7
- class Command
8
-
9
- attr_accessor :switches, :flags, :commands
10
- attr_accessor :name, :desc, :block, :argv
11
- attr_accessor :base
12
- attr_accessor :banner
13
-
14
- # Create a new Command instance
15
- #
16
- # @overload initialize(base, &block)
17
- # Creates a new base Command to house everything else
18
- # @param [Boolean] base whether the command is the base
19
- #
20
- # @overload initialize(name, desc, &block)
21
- # Creates a new Command as part of the base Command
22
- # @param [Symbol] name the name of the command
23
- # @param [String] desc the description of the command
24
- #
25
- # @yield A block to run, containing switches, flags and commands
26
- #
27
- def initialize(*args, &block)
28
- @argv = []
29
- @switches = Clive::Array.new
30
- @flags = Clive::Array.new
31
- @commands = Clive::Array.new
32
-
33
- if args.length == 1 && args[0] == true
34
- @base = true
35
- self.instance_eval(&block)
36
- else
37
- @base = false
38
- args.each do |i|
39
- case i
40
- when Symbol
41
- @name = i.to_s
42
- when String
43
- @desc = i
44
- end
45
- end
46
- @block = block
47
- end
48
-
49
- @banner = "Usage: #{File.basename($0, '.*')} "
50
- @banner << (@base ? "[commands]" : @name)
51
- @banner << " [options]"
52
-
53
- self.build_help
54
- end
55
-
56
- # Getter to find booleans
57
- def booleans
58
- @switches.find_all {|i| i.is_a?(Boolean)}
59
- end
60
-
61
- # Run the block that was passed to find switches, flags, etc.
62
- #
63
- # This should only be called if the command has been called
64
- # as the block could contain other actions to perform only
65
- # when called.
66
- #
67
- def find
68
- return nil if @base
69
- self.instance_eval(&@block)
70
- end
71
-
72
- # Parse the ARGV passed from the command line, and run
73
- #
74
- # @param [Array] argv the command line input, usually just ARGV
75
- # @return [Array] any arguments that were present in the input but not used
76
- #
77
- def run(argv=[])
78
- tokens = argv
79
- tokens = tokenize(argv) if @base
80
-
81
- r = []
82
- tokens.each do |i|
83
- k, v = i[0], i[1]
84
- case k
85
- when :command
86
- v.run(i[2])
87
- when :switch
88
- v.run
89
- when :flag
90
- raise MissingArgument.new(v.long||v.short) unless i[2]
91
- v.run(i[2])
92
- when :argument
93
- r << v
94
- end
95
- end
96
- r
97
- end
98
-
99
- # Turns the command line input into a series of tokens.
100
- # It will only raise errors if this is the base command instance.
101
- #
102
- # @param [Array] argv the command line input
103
- # @return [Array] a series of tokens
104
- #
105
- # @example
106
- #
107
- # c.tokenize(["add", "-al", "--verbose"])
108
- # #=> [[:command, #<Clive::Command>, ...args...], [:switch, "a",
109
- # #<Clive::Switch>], [:switch, "l", #<Clive::Switch>], [:switch,
110
- # "verbose", #<Clive::Switch>]]
111
- #
112
- def tokenize(argv)
113
- tokens = []
114
- pre = Tokens.to_tokens(argv)
115
- command = nil
116
- @argv = argv unless @base
117
-
118
- pre.each do |i|
119
- k, v = i[0], i[1]
120
- case k
121
- when :word
122
- if @commands[v]
123
- command = @commands[v]
124
- pre -= [[:word, v]]
125
- end
126
- end
127
- end
128
-
129
- if command
130
- command.find
131
- # tokenify the command
132
- tokens << [:command, command, command.tokenize(Tokens.to_array(pre))]
133
- pre = Tokens.to_tokens(command.argv)
134
- end
135
-
136
- pre.each do |i|
137
- k, v = i[0], i[1]
138
- case k
139
- when :short, :long
140
- if switch = @switches[v]
141
- tokens << [:switch, switch]
142
- pre -= [[k, v]] unless @base
143
- elsif flag = @flags[v]
144
- tokens << [:flag, flag]
145
- pre -= [[k, v]] unless @base
146
- else
147
- raise InvalidOption.new(v) if @base
148
- end
149
- when :word
150
- if tokens.last
151
- case tokens.last[0]
152
- when :flag
153
- tokens.last[2] = v
154
- else
155
- tokens << [:argument, v] if @base
156
- end
157
- end
158
- end
159
- end
160
- @argv = Tokens.to_array(pre)
161
-
162
- tokens
163
- end
164
-
165
- #### CREATION HELPERS ####
166
-
167
- # Add a new switch to +@switches+
168
- #
169
- # @overload switch(short, long, desc, &block)
170
- # Creates a new switch
171
- # @param [Symbol] short single character for short switch, eg. +:v+ => +-v+
172
- # @param [Symbol] long longer switch to be used, eg. +:verbose+ => +--verbose+
173
- # @param [String] desc the description for the switch
174
- #
175
- # @yield A block to run if the switch is triggered
176
- #
177
- def switch(*args, &block)
178
- short, long, desc = nil
179
- args.each do |i|
180
- if i.is_a? String
181
- desc = i
182
- elsif i.length == 1
183
- short = i.to_s
184
- else
185
- long = i.to_s
186
- end
187
- end
188
- @switches << Switch.new(short, long, desc, &block)
189
- end
190
-
191
- # Add a new command to +@commands+
192
- #
193
- # @overload command(name, desc, &block)
194
- # Creates a new command
195
- # @param [Symbol] name the name of the command, eg. +:add+ for +git add+
196
- # @param [String] desc description of the command
197
- #
198
- # @yield A block to run when the command is called, can contain switches
199
- # and flags
200
- #
201
- def command(*args, &block)
202
- name, desc = nil
203
- args.each do |i|
204
- if i.is_a? String
205
- desc = i
206
- else
207
- name = i
208
- end
209
- end
210
- @commands << Command.new(name, desc, &block)
211
- end
212
-
213
- # Add a new flag to +@flags+
214
- #
215
- # @overload flag(short, long, desc, &block)
216
- # Creates a new flag
217
- # @param [Symbol] short single character for short flag, eg. +:t+ => +-t 10+
218
- # @param [Symbol] long longer switch to be used, eg. +:tries+ => +--tries=10+
219
- # @param [String] desc the description for the flag
220
- #
221
- # @yield [String] A block to be run if switch is triggered
222
- def flag(*args, &block)
223
- short, long, desc = nil
224
- args.each do |i|
225
- if i.is_a? String
226
- desc = i
227
- elsif i.length == 1
228
- short = i.to_s
229
- else
230
- long = i.to_s
231
- end
232
- end
233
- @flags << Flag.new(short, long, desc, &block)
234
- end
235
-
236
- # Creates a boolean switch. This is done by adding two switches of
237
- # Boolean type to +@switches+, one is created normally the other has
238
- # "no-" appended to the long name and has no short name.
239
- #
240
- # @overload boolean(short, long, desc, &block)
241
- # Creates a new boolean switch
242
- # @param [Symbol] short single character for short label
243
- # @param [Symbol] long longer name to be used
244
- # @param [String] desc the description of the boolean
245
- #
246
- # @yield [Boolean] A block to be run if switch is triggered
247
- def boolean(*args, &block)
248
- short, long, desc = nil
249
- args.each do |i|
250
- if i.is_a? String
251
- desc = i
252
- elsif i.length == 1
253
- short = i.to_s
254
- else
255
- long = i.to_s
256
- end
257
- end
258
- raise "Boolean switch must have long name" unless long
259
- @switches << Boolean.new(short, long, desc, true, &block)
260
- @switches << Boolean.new(nil, "no-#{long}", desc, false, &block)
261
- end
262
-
263
- #### HELP STUFF ####
264
-
265
- # This actually creates a switch with "-h" and "--help" that control
266
- # the help on this command. If this is the base class it will also
267
- # creates a "help [command]" command.
268
- def build_help
269
- @switches << Switch.new("h", "help", "Display help") do
270
- puts self.help
271
- exit 0
272
- end
273
- end
274
-
275
- # Set the banner
276
- def banner(val)
277
- @banner = val
278
- end
279
-
280
- def summary(width=30, prepend=5)
281
- a = @name
282
- b = @desc
283
- s, p = '', ''
284
- (0..width-a.length).each {s << ' '}
285
- (0..prepend).each {p << ' '}
286
- "#{p}#{a}#{s}#{b}"
287
- end
288
-
289
- # Generate the summary for help, show all flags and switches, but do not
290
- # show the flags and switches within each command. Should also prepend the
291
- # banner.
292
- def help(width=30, prepend=5)
293
- summary = "#{@banner}\n"
294
-
295
- if @switches.length > 0 || @flags.length > 0
296
- summary << "\n Options:\n"
297
- @switches.each do |i|
298
- summary << i.summary(width, prepend) << "\n" if i.summary
299
- end
300
- @flags.each do |i|
301
- summary << i.summary(width, prepend) << "\n"
302
- end
303
- end
304
-
305
- if @commands.length > 0
306
- summary << "\nCommands:\n"
307
- @commands.each do |i|
308
- summary << i.summary(width, prepend) << "\n"
309
- end
310
- end
311
-
312
- summary
313
- end
314
-
315
-
316
- end
317
- end