coulis 0.2.0 → 0.2.5
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/lib/coulis.rb +55 -8
- data/test/coulis_test.rb +90 -0
- metadata +4 -4
data/lib/coulis.rb
CHANGED
@@ -2,7 +2,8 @@ require "timeout"
|
|
2
2
|
|
3
3
|
class Coulis
|
4
4
|
class << self
|
5
|
-
attr_accessor :_definitions, :
|
5
|
+
attr_accessor :_definitions, :_safe_args, :_help
|
6
|
+
attr_accessor :bin, :timeout, :no_double_dash, :safe_mode
|
6
7
|
|
7
8
|
def exec(*args, &block)
|
8
9
|
self.new.exec *args, &block
|
@@ -16,6 +17,10 @@ class Coulis
|
|
16
17
|
@bin = p.to_s
|
17
18
|
end
|
18
19
|
|
20
|
+
def _safe_mode(bool=true)
|
21
|
+
@safe_mode = bool
|
22
|
+
end
|
23
|
+
|
19
24
|
def _timeout(t)
|
20
25
|
@timeout = t
|
21
26
|
end
|
@@ -27,6 +32,30 @@ class Coulis
|
|
27
32
|
def adef(name, option=nil, &block)
|
28
33
|
(@_definitions||={})[name.to_sym] = (option || block )
|
29
34
|
end
|
35
|
+
|
36
|
+
def help(help_arg="--help")
|
37
|
+
return @_help if @_help && !@_help.empty?
|
38
|
+
|
39
|
+
@_help = options { @args = [help_arg] }.
|
40
|
+
exec.split("\n").map(&:strip)
|
41
|
+
end
|
42
|
+
|
43
|
+
def _safe_args(&block)
|
44
|
+
return @_safe_args if @_safe_args
|
45
|
+
@_safe_args ||= []
|
46
|
+
if block_given?
|
47
|
+
@_safe_args = instance_eval(&block)
|
48
|
+
else
|
49
|
+
help.each do |l|
|
50
|
+
args = l.scan(/(\-{1,2}[\w\-]+)[\W]/)
|
51
|
+
unless args.empty?
|
52
|
+
args.each{|a| @_safe_args << a.to_s}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
return @_safe_args.uniq!
|
58
|
+
end
|
30
59
|
end
|
31
60
|
|
32
61
|
attr_accessor :args
|
@@ -148,13 +177,19 @@ class Coulis
|
|
148
177
|
return self
|
149
178
|
end
|
150
179
|
|
151
|
-
|
152
|
-
|
153
|
-
|
180
|
+
if args[0].is_a?(Hash) # no value but options
|
181
|
+
full_arg = [ definition || arg_name ]
|
182
|
+
opts = args[0]
|
183
|
+
else
|
184
|
+
q = ""
|
185
|
+
q = "'" if args[0].to_s[0..0] != "'"
|
186
|
+
full_arg = [ definition || arg_name , "#{q}#{args[0]}#{q}" ]
|
187
|
+
opts = args[1]
|
188
|
+
end
|
154
189
|
|
155
|
-
insert_arg(full_arg,
|
190
|
+
insert_arg(full_arg, opts)
|
156
191
|
# delete doublon
|
157
|
-
if
|
192
|
+
if opts && opts.has_key?(:uniq)
|
158
193
|
uniq_arg(definition || arg_name)
|
159
194
|
end
|
160
195
|
self
|
@@ -167,7 +202,17 @@ class Coulis
|
|
167
202
|
self
|
168
203
|
end
|
169
204
|
|
205
|
+
def safe_arg?(argname)
|
206
|
+
# help parsing issue, so safe mode is off
|
207
|
+
return true if(self.class._safe_args || []).empty?
|
208
|
+
!self.class._safe_args.find{|a| a.to_s == argname.to_s}.nil?
|
209
|
+
end
|
210
|
+
|
170
211
|
def insert_arg(arg, opts=nil)
|
212
|
+
if self.class.safe_mode || (opts && opts[:safe] == true)
|
213
|
+
return unless safe_arg?(arg[0])
|
214
|
+
end
|
215
|
+
|
171
216
|
if !opts
|
172
217
|
@args << arg
|
173
218
|
return self
|
@@ -175,10 +220,12 @@ class Coulis
|
|
175
220
|
|
176
221
|
if arg_to_find = opts[:before] || opts[:after]
|
177
222
|
found = @args.find{|a|
|
178
|
-
a[0] == self.class._definitions[arg_to_find.to_sym] || arg_to_find
|
223
|
+
a[0] == (self.class._definitions[arg_to_find.to_sym] || arg_to_find)
|
179
224
|
}
|
225
|
+
|
180
226
|
if found && index = @args.index(found)
|
181
|
-
|
227
|
+
index+=1 if opts[:after]
|
228
|
+
@args.insert(index, arg)
|
182
229
|
end
|
183
230
|
else
|
184
231
|
@args << arg
|
data/test/coulis_test.rb
CHANGED
@@ -2,6 +2,8 @@ require "test/unit"
|
|
2
2
|
require "coulis"
|
3
3
|
|
4
4
|
class Ls < Coulis
|
5
|
+
_safe_args { help.to_s.match(/ls \[-([\w]+)\]/)[1].chars.to_a }
|
6
|
+
|
5
7
|
adef :all, "-a"
|
6
8
|
adef :human, "-h"
|
7
9
|
adef :full, "-a -h"
|
@@ -13,6 +15,7 @@ class FFMpeg < Coulis
|
|
13
15
|
end
|
14
16
|
|
15
17
|
class Ping < Coulis
|
18
|
+
_safe_args { ["-c"] }
|
16
19
|
_bin `whereis ping`.strip
|
17
20
|
adef :count, "-c"
|
18
21
|
end
|
@@ -25,6 +28,10 @@ class NSLookup < Coulis
|
|
25
28
|
end
|
26
29
|
end
|
27
30
|
|
31
|
+
class Curl < Coulis
|
32
|
+
_safe_mode
|
33
|
+
end
|
34
|
+
|
28
35
|
class SimpleCliTest < Test::Unit::TestCase
|
29
36
|
def teardown
|
30
37
|
#Ls.new.reset
|
@@ -33,6 +40,9 @@ class SimpleCliTest < Test::Unit::TestCase
|
|
33
40
|
|
34
41
|
def test_shit
|
35
42
|
#p Ls.options { full }
|
43
|
+
ls = Ls.options {
|
44
|
+
all :uniq => true
|
45
|
+
}
|
36
46
|
end
|
37
47
|
|
38
48
|
def test_default_bin
|
@@ -243,4 +253,84 @@ class SimpleCliTest < Test::Unit::TestCase
|
|
243
253
|
ffmpeg.input "video2.mp4", :before => "-y", :uniq => true
|
244
254
|
assert_equal "ffmpeg -i 'video2.mp4' -y 'out.avi'", ffmpeg.command
|
245
255
|
end
|
256
|
+
|
257
|
+
def test_arg_with_no_value_but_options
|
258
|
+
ls = Ls.options {
|
259
|
+
human
|
260
|
+
all :before => :human
|
261
|
+
}
|
262
|
+
assert_equal "ls -a -h", ls.command
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_list_safe_args
|
266
|
+
args = Ls._safe_args
|
267
|
+
assert_instance_of Array, args
|
268
|
+
assert args.size > 0
|
269
|
+
#p args
|
270
|
+
|
271
|
+
args = FFMpeg._safe_args
|
272
|
+
assert_instance_of Array, args
|
273
|
+
assert args.size > 0
|
274
|
+
#p args
|
275
|
+
|
276
|
+
args = Ping._safe_args
|
277
|
+
assert_instance_of Array, args
|
278
|
+
assert args.size > 0
|
279
|
+
#p args
|
280
|
+
|
281
|
+
args = Curl._safe_args
|
282
|
+
assert_instance_of Array, args
|
283
|
+
assert args.size > 0
|
284
|
+
#p args
|
285
|
+
end
|
286
|
+
|
287
|
+
def test_safe_mode_is_true_per_arg
|
288
|
+
ffmpeg = FFMpeg.options {
|
289
|
+
input "video.mp4"
|
290
|
+
nonexistingarg "nio", :safe => true
|
291
|
+
}
|
292
|
+
ffmpeg.fake_arg :safe => true
|
293
|
+
ffmpeg.fake_but_ok
|
294
|
+
|
295
|
+
args = [["nope1", "1"], ["nope2", "2"], ["-y", "output.avi"]]
|
296
|
+
args.each{|k,v| ffmpeg.send(k,v, :safe => true)}
|
297
|
+
assert_equal "ffmpeg -i 'video.mp4' -fake_but_ok -y 'output.avi'", ffmpeg.command
|
298
|
+
|
299
|
+
ping = Ping.options {
|
300
|
+
count 2, :safe => true
|
301
|
+
nope "no", :safe => true
|
302
|
+
nope2 "no2"
|
303
|
+
}
|
304
|
+
assert_equal "/sbin/ping -c '2' --nope2 'no2'", ping.command
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_safe_mode_is_true_per_class
|
308
|
+
FFMpeg._safe_mode
|
309
|
+
ffmpeg = FFMpeg.options {
|
310
|
+
input "video.mp4"
|
311
|
+
nonexistingarg "nio"
|
312
|
+
}
|
313
|
+
assert_equal "ffmpeg -i 'video.mp4'", ffmpeg.command
|
314
|
+
|
315
|
+
curl = Curl.options {
|
316
|
+
request "POST"
|
317
|
+
data "test=ok"
|
318
|
+
url "http://mysite.com/test"
|
319
|
+
fake_arg "ok"
|
320
|
+
}
|
321
|
+
|
322
|
+
assert_equal "curl --request 'POST' --data 'test=ok' --url 'http://mysite.com/test'", curl.command
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_safe_mode_is_off_if_help_parsing_issue
|
326
|
+
FFMpeg._safe_args = nil
|
327
|
+
FFMpeg._help = "ffmpeg help broken"
|
328
|
+
FFMpeg._safe_mode
|
329
|
+
|
330
|
+
ffmpeg = FFMpeg.options {
|
331
|
+
input "video.mp4"
|
332
|
+
nonexistingarg "nio"
|
333
|
+
}
|
334
|
+
assert_equal "ffmpeg -i 'video.mp4' -nonexistingarg 'nio'", ffmpeg.command
|
335
|
+
end
|
246
336
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: coulis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 29
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 5
|
10
|
+
version: 0.2.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Bruno Celeste
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-07-
|
18
|
+
date: 2012-07-04 00:00:00 Z
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Simple but powerful CLI Wrapper
|