scout-gear 2.0.0 → 5.1.1
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.
- checksums.yaml +4 -4
- data/.vimproject +59 -2
- data/VERSION +1 -1
- data/bin/scout +231 -24
- data/lib/scout/cmd.rb +344 -0
- data/lib/scout/concurrent_stream.rb +259 -0
- data/lib/scout/exceptions.rb +15 -8
- data/lib/scout/indiferent_hash/options.rb +8 -26
- data/lib/scout/log/color.rb +2 -2
- data/lib/scout/log/fingerprint.rb +11 -1
- data/lib/scout/log/progress/report.rb +0 -1
- data/lib/scout/log/progress/util.rb +1 -1
- data/lib/scout/log/progress.rb +4 -4
- data/lib/scout/log.rb +10 -2
- data/lib/scout/meta_extension.rb +15 -1
- data/lib/scout/misc/digest.rb +56 -0
- data/lib/scout/misc/filesystem.rb +26 -0
- data/lib/scout/misc/format.rb +1 -2
- data/lib/scout/misc/insist.rb +56 -0
- data/lib/scout/misc.rb +4 -11
- data/lib/scout/open/lock.rb +61 -0
- data/lib/scout/open/remote.rb +120 -0
- data/lib/scout/open/stream.rb +372 -0
- data/lib/scout/open/util.rb +225 -0
- data/lib/scout/open.rb +169 -0
- data/lib/scout/path/find.rb +67 -21
- data/lib/scout/path/tmpfile.rb +8 -0
- data/lib/scout/path/util.rb +14 -1
- data/lib/scout/path.rb +6 -30
- data/lib/scout/persist/open.rb +17 -0
- data/lib/scout/persist/path.rb +15 -0
- data/lib/scout/persist/serialize.rb +140 -0
- data/lib/scout/persist.rb +54 -0
- data/lib/scout/resource/path.rb +15 -0
- data/lib/scout/resource/produce/rake.rb +69 -0
- data/lib/scout/resource/produce.rb +246 -0
- data/lib/scout/resource/scout.rb +3 -0
- data/lib/scout/resource.rb +37 -0
- data/lib/scout/simple_opt/accessor.rb +1 -1
- data/lib/scout/simple_opt/doc.rb +4 -22
- data/lib/scout/simple_opt/parse.rb +4 -3
- data/lib/scout/tmpfile.rb +39 -1
- data/lib/scout/workflow/definition.rb +72 -0
- data/lib/scout/workflow/documentation.rb +77 -0
- data/lib/scout/workflow/step/info.rb +77 -0
- data/lib/scout/workflow/step.rb +96 -0
- data/lib/scout/workflow/task/inputs.rb +112 -0
- data/lib/scout/workflow/task.rb +141 -0
- data/lib/scout/workflow/usage.rb +294 -0
- data/lib/scout/workflow/util.rb +11 -0
- data/lib/scout/workflow.rb +39 -0
- data/lib/scout-gear.rb +4 -0
- data/lib/scout.rb +1 -0
- data/lib/workflow-scout.rb +2 -0
- data/scout-gear.gemspec +66 -5
- data/scout_commands/alias +48 -0
- data/scout_commands/find +83 -0
- data/scout_commands/glob +0 -0
- data/scout_commands/rbbt +23 -0
- data/scout_commands/workflow/task +707 -0
- data/test/scout/indiferent_hash/test_options.rb +11 -1
- data/test/scout/misc/test_digest.rb +30 -0
- data/test/scout/misc/test_filesystem.rb +30 -0
- data/test/scout/misc/test_insist.rb +13 -0
- data/test/scout/open/test_lock.rb +52 -0
- data/test/scout/open/test_remote.rb +25 -0
- data/test/scout/open/test_stream.rb +515 -0
- data/test/scout/open/test_util.rb +73 -0
- data/test/scout/path/test_find.rb +28 -0
- data/test/scout/persist/test_open.rb +37 -0
- data/test/scout/persist/test_path.rb +37 -0
- data/test/scout/persist/test_serialize.rb +114 -0
- data/test/scout/resource/test_path.rb +40 -0
- data/test/scout/resource/test_produce.rb +62 -0
- data/test/scout/test_cmd.rb +85 -0
- data/test/scout/test_concurrent_stream.rb +29 -0
- data/test/scout/test_misc.rb +0 -7
- data/test/scout/test_open.rb +146 -0
- data/test/scout/test_path.rb +3 -1
- data/test/scout/test_persist.rb +83 -0
- data/test/scout/test_resource.rb +26 -0
- data/test/scout/test_workflow.rb +87 -0
- data/test/scout/workflow/step/test_info.rb +28 -0
- data/test/scout/workflow/task/test_inputs.rb +182 -0
- data/test/scout/workflow/test_step.rb +36 -0
- data/test/scout/workflow/test_task.rb +178 -0
- data/test/scout/workflow/test_usage.rb +26 -0
- data/test/scout/workflow/test_util.rb +17 -0
- data/test/test_helper.rb +17 -0
- data/test/test_scout-gear.rb +0 -0
- metadata +64 -3
data/lib/scout/log/color.rb
CHANGED
@@ -63,7 +63,7 @@ module Colorize
|
|
63
63
|
if percent
|
64
64
|
array = array.collect{|v| n = v.to_f; n = n > 100 ? 100 : n; n < 0.001 ? 0.001 : n}
|
65
65
|
else
|
66
|
-
array = array.collect{|v|
|
66
|
+
array = array.collect{|v| v.to_f }
|
67
67
|
end
|
68
68
|
max = array.max
|
69
69
|
min = array.min
|
@@ -103,7 +103,7 @@ module Colorize
|
|
103
103
|
|
104
104
|
value_color = Hash[*array.uniq.zip(all_colors).flatten]
|
105
105
|
|
106
|
-
value_color.values_at
|
106
|
+
value_color.values_at(*array)
|
107
107
|
end
|
108
108
|
|
109
109
|
def self.tsv(tsv, options = {})
|
@@ -19,8 +19,12 @@ module Log
|
|
19
19
|
else
|
20
20
|
"'" << obj << "'"
|
21
21
|
end
|
22
|
+
when ConcurrentStream
|
23
|
+
name = obj.inspect + " " + obj.object_id.to_s
|
24
|
+
name += " #{obj.filename}" if obj.filename
|
25
|
+
name
|
22
26
|
when IO
|
23
|
-
(obj.respond_to?(:filename) and obj.filename ) ? "<IO:" + (obj.filename || obj.inspect + rand(100000)) + ">" : obj.inspect
|
27
|
+
(obj.respond_to?(:filename) and obj.filename ) ? "<IO:" + (obj.filename || obj.inspect + rand(100000)) + ">" : obj.inspect + " " + obj.object_id.to_s
|
24
28
|
when File
|
25
29
|
"<File:" + obj.path + ">"
|
26
30
|
when Array
|
@@ -52,6 +56,12 @@ module Log
|
|
52
56
|
else
|
53
57
|
"%.6f" % obj
|
54
58
|
end
|
59
|
+
when Thread
|
60
|
+
if obj["name"]
|
61
|
+
obj["name"]
|
62
|
+
else
|
63
|
+
obj.inspect
|
64
|
+
end
|
55
65
|
else
|
56
66
|
obj.to_s
|
57
67
|
end
|
@@ -169,7 +169,6 @@ module Log
|
|
169
169
|
bar = bars.sort_by{|b| b.depth }.first
|
170
170
|
print(io, Log.color(:magenta ,bar.report_msg) << "\n")
|
171
171
|
else
|
172
|
-
length = Log::ProgressBar.cleanup_bars
|
173
172
|
print(io, Log.color(:magenta, "···Progress\n"))
|
174
173
|
bars.sort_by{|b| b.depth }.reverse.each do |bar|
|
175
174
|
if SILENCED.include? bar
|
data/lib/scout/log/progress.rb
CHANGED
@@ -17,12 +17,12 @@ module Log
|
|
17
17
|
attr_accessor :default_file
|
18
18
|
end
|
19
19
|
|
20
|
-
attr_accessor :max, :ticks, :frequency, :depth, :desc, :file, :bytes, :process, :callback
|
20
|
+
attr_accessor :max, :ticks, :frequency, :depth, :desc, :file, :bytes, :process, :callback, :severity
|
21
21
|
|
22
22
|
def initialize(max = nil, options = {})
|
23
|
-
depth,
|
24
|
-
IndiferentHash.process_options options, :depth, :
|
25
|
-
:depth => 0, :
|
23
|
+
depth, desc, file, bytes, frequency, process, callback =
|
24
|
+
IndiferentHash.process_options options, :depth, :desc, :file, :bytes, :frequency, :process, :callback,
|
25
|
+
:depth => 0, :frequency => 2
|
26
26
|
|
27
27
|
@max = max
|
28
28
|
@ticks = 0
|
data/lib/scout/log.rb
CHANGED
@@ -14,8 +14,8 @@ module Log
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class << self
|
17
|
-
attr_accessor :
|
18
|
-
attr_writer :tty_size
|
17
|
+
attr_accessor :severity
|
18
|
+
attr_writer :tty_size, :logfile
|
19
19
|
end
|
20
20
|
|
21
21
|
|
@@ -360,3 +360,11 @@ def eef(obj=nil, file = $stdout)
|
|
360
360
|
Log.log_obj_fingerprint(obj, :error, file)
|
361
361
|
end
|
362
362
|
|
363
|
+
def sss(level, &block)
|
364
|
+
if block_given?
|
365
|
+
Log.with_severity level, &block
|
366
|
+
else
|
367
|
+
Log.severity = level
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
data/lib/scout/meta_extension.rb
CHANGED
@@ -11,7 +11,13 @@ module MetaExtension
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
meta.define_method(:setup) do |
|
14
|
+
meta.define_method(:setup) do |*args,&block|
|
15
|
+
if block_given?
|
16
|
+
obj, rest = block, args
|
17
|
+
else
|
18
|
+
obj, *rest = args
|
19
|
+
end
|
20
|
+
obj = block if obj.nil?
|
15
21
|
obj.extend base
|
16
22
|
attrs = self.class_variable_get("@@extension_attrs")
|
17
23
|
|
@@ -33,6 +39,14 @@ module MetaExtension
|
|
33
39
|
obj
|
34
40
|
end
|
35
41
|
|
42
|
+
base.define_method(:extension_attr_hash) do
|
43
|
+
attr_hash = {}
|
44
|
+
meta.class_variable_get("@@extension_attrs").each do |name|
|
45
|
+
attr_hash[name] = self.instance_variable_get("@#{name}")
|
46
|
+
end
|
47
|
+
attr_hash
|
48
|
+
end
|
49
|
+
|
36
50
|
base.define_method(:annotate) do |other|
|
37
51
|
attr_values = meta.class_variable_get("@@extension_attrs").collect do |a|
|
38
52
|
self.instance_variable_get("@#{a}")
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Misc
|
2
|
+
def self.digest_str(obj)
|
3
|
+
if obj.respond_to?(:digest_str)
|
4
|
+
obj.digest_str
|
5
|
+
else
|
6
|
+
case obj
|
7
|
+
when String
|
8
|
+
#'\'' << obj << '\''
|
9
|
+
if Path === obj || ! Open.exists?(obj)
|
10
|
+
'\'' << obj << '\''
|
11
|
+
else
|
12
|
+
Misc.file_md5(obj)
|
13
|
+
end
|
14
|
+
when Integer, Symbol
|
15
|
+
obj.to_s
|
16
|
+
when Array
|
17
|
+
'[' << obj.inject(""){|acc,o| acc.empty? ? Misc.digest_str(o) : acc << ', ' << Misc.digest_str(o) } << ']'
|
18
|
+
when Hash
|
19
|
+
'{' << obj.inject(""){|acc,p| s = Misc.digest_str(p.first) << "=" << Misc.digest_str(p.last); acc.empty? ? s : acc << ', ' << s } << '}'
|
20
|
+
when Integer
|
21
|
+
obj.to_s
|
22
|
+
when Float
|
23
|
+
if obj % 1 == 0
|
24
|
+
obj.to_i
|
25
|
+
elsif obj.abs > 10
|
26
|
+
"%.1f" % obj
|
27
|
+
elsif obj.abs > 1
|
28
|
+
"%.3f" % obj
|
29
|
+
else
|
30
|
+
"%.6f" % obj
|
31
|
+
end
|
32
|
+
when TrueClass
|
33
|
+
"true"
|
34
|
+
when FalseClass
|
35
|
+
"false"
|
36
|
+
else
|
37
|
+
obj.inspect
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.digest(obj)
|
43
|
+
str = Misc.digest_str(obj)
|
44
|
+
hash = Digest::MD5.hexdigest(str)
|
45
|
+
Log.debug "Digest #{hash} - #{str}"
|
46
|
+
hash
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.file_md5(file)
|
50
|
+
file = file.find if Path === file
|
51
|
+
#md5file = file + '.md5'
|
52
|
+
Persist.persist("MD5:#{file}", :string) do
|
53
|
+
Digest::MD5.file(file).hexdigest
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Misc
|
2
|
+
def self.in_dir(dir)
|
3
|
+
old_pwd = FileUtils.pwd
|
4
|
+
begin
|
5
|
+
FileUtils.mkdir_p dir unless File.exist?(dir)
|
6
|
+
FileUtils.cd dir
|
7
|
+
yield
|
8
|
+
ensure
|
9
|
+
FileUtils.cd old_pwd
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.path_relative_to(basedir, path)
|
14
|
+
path = File.expand_path(path) unless path.slice(0,1) == "/"
|
15
|
+
basedir = File.expand_path(basedir) unless basedir.slice(0,1) == "/"
|
16
|
+
|
17
|
+
basedir += "/" unless basedir.slice(-2,-1) == "/"
|
18
|
+
|
19
|
+
if path.index(basedir) == 0
|
20
|
+
return path[basedir.length..-1]
|
21
|
+
else
|
22
|
+
return nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/scout/misc/format.rb
CHANGED
@@ -101,7 +101,7 @@ module Misc
|
|
101
101
|
string.
|
102
102
|
gsub(/([A-Z]{2,})([A-Z][a-z])/,'\1_\2').
|
103
103
|
gsub(/([a-z])([A-Z])/,'\1_\2').
|
104
|
-
gsub(/\s/,'_').gsub(/[^\
|
104
|
+
gsub(/\s/,'_').gsub(/[^\w]/, '').
|
105
105
|
split("_").collect{|p| p.match(/[A-Z]{2,}/) ? p : p.downcase } * "_"
|
106
106
|
end
|
107
107
|
|
@@ -223,5 +223,4 @@ module Misc
|
|
223
223
|
end
|
224
224
|
values
|
225
225
|
end
|
226
|
-
|
227
226
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Misc
|
2
|
+
def self.insist(times = 4, sleep = nil, msg = nil)
|
3
|
+
sleep_array = nil
|
4
|
+
|
5
|
+
try = 0
|
6
|
+
begin
|
7
|
+
begin
|
8
|
+
yield
|
9
|
+
rescue Exception
|
10
|
+
if Array === times
|
11
|
+
sleep_array = times
|
12
|
+
times = sleep_array.length
|
13
|
+
sleep = sleep_array.shift
|
14
|
+
end
|
15
|
+
|
16
|
+
if sleep.nil?
|
17
|
+
sleep_array = ([0] + [0.001, 0.01, 0.1, 0.5] * (times / 3)).sort[0..times-1]
|
18
|
+
sleep = sleep_array.shift
|
19
|
+
end
|
20
|
+
raise $!
|
21
|
+
end
|
22
|
+
rescue TryAgain
|
23
|
+
sleep sleep
|
24
|
+
retry
|
25
|
+
rescue StopInsist
|
26
|
+
raise $!.exception
|
27
|
+
rescue Aborted, Interrupt
|
28
|
+
if msg
|
29
|
+
Log.warn("Not Insisting after Aborted: #{$!.message} -- #{msg}")
|
30
|
+
else
|
31
|
+
Log.warn("Not Insisting after Aborted: #{$!.message}")
|
32
|
+
end
|
33
|
+
raise $!
|
34
|
+
rescue Exception
|
35
|
+
Log.exception $! if ENV["RBBT_LOG_INSIST"] == 'true'
|
36
|
+
if msg
|
37
|
+
Log.warn("Insisting after exception: #{$!.class} #{$!.message} -- #{msg}")
|
38
|
+
elsif FalseClass === msg
|
39
|
+
nil
|
40
|
+
else
|
41
|
+
Log.warn("Insisting after exception: #{$!.class} #{$!.message}")
|
42
|
+
end
|
43
|
+
|
44
|
+
if sleep and try > 0
|
45
|
+
sleep sleep
|
46
|
+
sleep = sleep_array.shift || sleep if sleep_array
|
47
|
+
else
|
48
|
+
Thread.pass
|
49
|
+
end
|
50
|
+
|
51
|
+
try += 1
|
52
|
+
retry if try < times
|
53
|
+
raise $!
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
data/lib/scout/misc.rb
CHANGED
@@ -1,14 +1,7 @@
|
|
1
1
|
require_relative 'misc/format'
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
begin
|
6
|
-
FileUtils.mkdir_p dir unless File.exist?(dir)
|
7
|
-
FileUtils.cd dir
|
8
|
-
yield
|
9
|
-
ensure
|
10
|
-
FileUtils.cd old_pwd
|
11
|
-
end
|
12
|
-
end
|
2
|
+
require_relative 'misc/insist'
|
3
|
+
require_relative 'misc/digest'
|
4
|
+
require_relative 'misc/filesystem'
|
13
5
|
|
6
|
+
module Misc
|
14
7
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative '../path'
|
2
|
+
require_relative '../log'
|
3
|
+
require_relative '../exceptions'
|
4
|
+
require 'lockfile'
|
5
|
+
|
6
|
+
module Open
|
7
|
+
def self.lock(file, unlock = true, options = {})
|
8
|
+
unlock, options = true, unlock if Hash === unlock
|
9
|
+
return yield if file.nil? and not Lockfile === options[:lock]
|
10
|
+
|
11
|
+
if Lockfile === file
|
12
|
+
lockfile = file
|
13
|
+
else
|
14
|
+
file = file.find if Path === file
|
15
|
+
FileUtils.mkdir_p File.dirname(File.expand_path(file)) unless File.exist? File.dirname(File.expand_path(file))
|
16
|
+
|
17
|
+
case options[:lock]
|
18
|
+
when Lockfile
|
19
|
+
lockfile = options[:lock]
|
20
|
+
when FalseClass
|
21
|
+
lockfile = nil
|
22
|
+
unlock = false
|
23
|
+
when Path, String
|
24
|
+
lock_path = options[:lock].find
|
25
|
+
lockfile = Lockfile.new(lock_path, options)
|
26
|
+
else
|
27
|
+
lock_path = File.expand_path(file + '.lock')
|
28
|
+
lockfile = Lockfile.new(lock_path, options)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
begin
|
33
|
+
lockfile.lock unless lockfile.nil? || lockfile.locked?
|
34
|
+
rescue Aborted, Interrupt
|
35
|
+
raise LockInterrupted
|
36
|
+
end
|
37
|
+
|
38
|
+
res = nil
|
39
|
+
|
40
|
+
begin
|
41
|
+
res = yield lockfile
|
42
|
+
rescue KeepLocked
|
43
|
+
unlock = false
|
44
|
+
res = $!.payload
|
45
|
+
ensure
|
46
|
+
if unlock
|
47
|
+
begin
|
48
|
+
if lockfile.locked?
|
49
|
+
lockfile.unlock
|
50
|
+
else
|
51
|
+
end
|
52
|
+
rescue Exception
|
53
|
+
Log.warn "Exception unlocking: #{lockfile.path}"
|
54
|
+
Log.exception $!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
res
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require_relative '../misc'
|
2
|
+
require_relative '../path'
|
3
|
+
require_relative '../cmd'
|
4
|
+
|
5
|
+
module Open
|
6
|
+
class << self
|
7
|
+
attr_accessor :remote_cache_dir
|
8
|
+
|
9
|
+
def remote_cache_dir
|
10
|
+
@remote_cache_dir ||= Path.setup("var/cache/open-remote/").find
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.remote?(file)
|
15
|
+
!! (file =~ /^(?:https?|ftp|ssh):\/\//)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.ssh?(file)
|
19
|
+
!! (file =~ /^ssh:\/\//)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.ssh(file, options = {})
|
23
|
+
m = file.match(/ssh:\/\/([^:]+):(.*)/)
|
24
|
+
server = m[1]
|
25
|
+
file = m[2]
|
26
|
+
CMD.cmd("ssh '#{server}' cat '#{file}'", :pipe => true, :autojoin => true)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.wget(url, options = {})
|
30
|
+
if ! (options[:force] || options[:nocache]) && cache_file = in_cache(url, options)
|
31
|
+
return file_open(cache_file)
|
32
|
+
end
|
33
|
+
|
34
|
+
Log.low "WGET:\n -URL: #{ url }\n -OPTIONS: #{options.inspect}"
|
35
|
+
options = IndiferentHash.add_defaults options, "--user-agent=" => 'rbbt', :pipe => true, :autojoin => true
|
36
|
+
|
37
|
+
wait(options[:nice], options[:nice_key]) if options[:nice]
|
38
|
+
options.delete(:nice)
|
39
|
+
options.delete(:nice_key)
|
40
|
+
|
41
|
+
pipe = options.delete(:pipe)
|
42
|
+
quiet = options.delete(:quiet)
|
43
|
+
post = options.delete(:post)
|
44
|
+
cookies = options.delete(:cookies)
|
45
|
+
nocache = options.delete(:nocache)
|
46
|
+
|
47
|
+
options["--quiet"] = quiet if options["--quiet"].nil?
|
48
|
+
options["--post-data="] ||= post if post
|
49
|
+
|
50
|
+
if cookies
|
51
|
+
options["--save-cookies"] = cookies
|
52
|
+
options["--load-cookies"] = cookies
|
53
|
+
options["--keep-session-cookies"] = true
|
54
|
+
end
|
55
|
+
|
56
|
+
stderr = case
|
57
|
+
when options['stderr']
|
58
|
+
options['stderr']
|
59
|
+
when options['--quiet']
|
60
|
+
false
|
61
|
+
else
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
begin
|
66
|
+
wget_options = options.dup
|
67
|
+
wget_options = wget_options.merge( '-O' => '-') unless options.include?('--output-document')
|
68
|
+
wget_options[:pipe] = pipe unless pipe.nil?
|
69
|
+
wget_options[:stderr] = stderr unless stderr.nil?
|
70
|
+
|
71
|
+
io = CMD.cmd("wget '#{ url }'", wget_options)
|
72
|
+
if nocache && nocache.to_s != 'update'
|
73
|
+
io
|
74
|
+
else
|
75
|
+
add_cache(url, io, options)
|
76
|
+
open_cache(url, options)
|
77
|
+
end
|
78
|
+
rescue
|
79
|
+
STDERR.puts $!.backtrace.inspect
|
80
|
+
raise OpenURLError, "Error reading remote url: #{ url }.\n#{$!.message}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.digest_url(url, options = {})
|
85
|
+
params = [url, options.values_at("--post-data", "--post-data="), (options.include?("--post-file")? Open.read(options["--post-file"]).split("\n").sort * "\n" : "")]
|
86
|
+
Misc.digest([url, params])
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.cache_file(url, options)
|
90
|
+
File.join(self.remote_cache_dir, digest_url(url, options))
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.in_cache(url, options = {})
|
94
|
+
filename = cache_file(url, options)
|
95
|
+
if File.exist? filename
|
96
|
+
return filename
|
97
|
+
else
|
98
|
+
nil
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.remove_from_cache(url, options = {})
|
103
|
+
filename = cache_file(url, options)
|
104
|
+
if File.exist? filename
|
105
|
+
FileUtils.rm filename
|
106
|
+
else
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.add_cache(url, data, options = {})
|
112
|
+
filename = cache_file(url, options)
|
113
|
+
Open.sensible_write(filename, data, :force => true)
|
114
|
+
end
|
115
|
+
|
116
|
+
def self.open_cache(url, options = {})
|
117
|
+
filename = cache_file(url, options)
|
118
|
+
Open.open(filename)
|
119
|
+
end
|
120
|
+
end
|