scout-essentials 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.vimproject +78 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +18 -0
  7. data/Rakefile +47 -0
  8. data/VERSION +1 -0
  9. data/lib/scout/cmd.rb +348 -0
  10. data/lib/scout/concurrent_stream.rb +284 -0
  11. data/lib/scout/config.rb +168 -0
  12. data/lib/scout/exceptions.rb +77 -0
  13. data/lib/scout/indiferent_hash/case_insensitive.rb +30 -0
  14. data/lib/scout/indiferent_hash/options.rb +115 -0
  15. data/lib/scout/indiferent_hash.rb +96 -0
  16. data/lib/scout/log/color.rb +224 -0
  17. data/lib/scout/log/color_class.rb +269 -0
  18. data/lib/scout/log/fingerprint.rb +69 -0
  19. data/lib/scout/log/progress/report.rb +244 -0
  20. data/lib/scout/log/progress/util.rb +173 -0
  21. data/lib/scout/log/progress.rb +106 -0
  22. data/lib/scout/log/trap.rb +107 -0
  23. data/lib/scout/log.rb +441 -0
  24. data/lib/scout/meta_extension.rb +100 -0
  25. data/lib/scout/misc/digest.rb +63 -0
  26. data/lib/scout/misc/filesystem.rb +25 -0
  27. data/lib/scout/misc/format.rb +255 -0
  28. data/lib/scout/misc/helper.rb +31 -0
  29. data/lib/scout/misc/insist.rb +56 -0
  30. data/lib/scout/misc/monitor.rb +66 -0
  31. data/lib/scout/misc/system.rb +73 -0
  32. data/lib/scout/misc.rb +10 -0
  33. data/lib/scout/named_array.rb +138 -0
  34. data/lib/scout/open/lock/lockfile.rb +587 -0
  35. data/lib/scout/open/lock.rb +68 -0
  36. data/lib/scout/open/remote.rb +135 -0
  37. data/lib/scout/open/stream.rb +491 -0
  38. data/lib/scout/open/util.rb +244 -0
  39. data/lib/scout/open.rb +170 -0
  40. data/lib/scout/path/find.rb +204 -0
  41. data/lib/scout/path/tmpfile.rb +8 -0
  42. data/lib/scout/path/util.rb +127 -0
  43. data/lib/scout/path.rb +51 -0
  44. data/lib/scout/persist/open.rb +17 -0
  45. data/lib/scout/persist/path.rb +15 -0
  46. data/lib/scout/persist/serialize.rb +157 -0
  47. data/lib/scout/persist.rb +104 -0
  48. data/lib/scout/resource/open.rb +8 -0
  49. data/lib/scout/resource/path.rb +80 -0
  50. data/lib/scout/resource/produce/rake.rb +69 -0
  51. data/lib/scout/resource/produce.rb +151 -0
  52. data/lib/scout/resource/scout.rb +3 -0
  53. data/lib/scout/resource/software.rb +178 -0
  54. data/lib/scout/resource/util.rb +59 -0
  55. data/lib/scout/resource.rb +40 -0
  56. data/lib/scout/simple_opt/accessor.rb +54 -0
  57. data/lib/scout/simple_opt/doc.rb +126 -0
  58. data/lib/scout/simple_opt/get.rb +57 -0
  59. data/lib/scout/simple_opt/parse.rb +67 -0
  60. data/lib/scout/simple_opt/setup.rb +26 -0
  61. data/lib/scout/simple_opt.rb +5 -0
  62. data/lib/scout/tmpfile.rb +129 -0
  63. data/lib/scout-essentials.rb +10 -0
  64. data/scout-essentials.gemspec +143 -0
  65. data/share/color/color_names +507 -0
  66. data/share/color/diverging_colors.hex +12 -0
  67. data/share/software/install_helpers +523 -0
  68. data/test/scout/indiferent_hash/test_case_insensitive.rb +16 -0
  69. data/test/scout/indiferent_hash/test_options.rb +46 -0
  70. data/test/scout/log/test_color.rb +0 -0
  71. data/test/scout/log/test_progress.rb +108 -0
  72. data/test/scout/misc/test_digest.rb +30 -0
  73. data/test/scout/misc/test_filesystem.rb +30 -0
  74. data/test/scout/misc/test_insist.rb +13 -0
  75. data/test/scout/misc/test_system.rb +21 -0
  76. data/test/scout/open/test_lock.rb +52 -0
  77. data/test/scout/open/test_remote.rb +25 -0
  78. data/test/scout/open/test_stream.rb +676 -0
  79. data/test/scout/open/test_util.rb +73 -0
  80. data/test/scout/path/test_find.rb +110 -0
  81. data/test/scout/path/test_util.rb +22 -0
  82. data/test/scout/persist/test_open.rb +37 -0
  83. data/test/scout/persist/test_path.rb +37 -0
  84. data/test/scout/persist/test_serialize.rb +114 -0
  85. data/test/scout/resource/test_path.rb +58 -0
  86. data/test/scout/resource/test_produce.rb +94 -0
  87. data/test/scout/resource/test_software.rb +24 -0
  88. data/test/scout/resource/test_util.rb +38 -0
  89. data/test/scout/simple_opt/test_doc.rb +16 -0
  90. data/test/scout/simple_opt/test_get.rb +11 -0
  91. data/test/scout/simple_opt/test_parse.rb +10 -0
  92. data/test/scout/simple_opt/test_setup.rb +77 -0
  93. data/test/scout/test_cmd.rb +85 -0
  94. data/test/scout/test_concurrent_stream.rb +29 -0
  95. data/test/scout/test_config.rb +66 -0
  96. data/test/scout/test_indiferent_hash.rb +26 -0
  97. data/test/scout/test_log.rb +32 -0
  98. data/test/scout/test_meta_extension.rb +80 -0
  99. data/test/scout/test_misc.rb +6 -0
  100. data/test/scout/test_named_array.rb +43 -0
  101. data/test/scout/test_open.rb +146 -0
  102. data/test/scout/test_path.rb +54 -0
  103. data/test/scout/test_persist.rb +186 -0
  104. data/test/scout/test_resource.rb +26 -0
  105. data/test/scout/test_tmpfile.rb +53 -0
  106. data/test/test_helper.rb +50 -0
  107. metadata +247 -0
@@ -0,0 +1,127 @@
1
+ module Path
2
+ def no_method_missing
3
+ class << self
4
+ undef_method :method_missing
5
+ end
6
+ end
7
+
8
+ def self.is_filename?(string, need_to_exists = true)
9
+ return false if string.nil?
10
+ return true if Path === string
11
+ return true if String === string and ! string.include?("\n") and string.split("/").select{|p| p.length > 265 }.empty? and (! need_to_exists || File.exist?(string))
12
+ return false
13
+ end
14
+
15
+ def self.sanitize_filename(filename, length = 254)
16
+ if filename.length > length
17
+ if filename =~ /(\..{2,9})$/
18
+ extension = $1
19
+ else
20
+ extension = ''
21
+ end
22
+
23
+ post_fix = "--#{filename.length}@#{length}_#{Misc.digest(filename)[0..4]}" + extension
24
+
25
+ filename = filename[0..(length - post_fix.length - 1)] << post_fix
26
+ else
27
+ filename
28
+ end
29
+ filename
30
+ end
31
+
32
+ def directory?
33
+ return nil unless self.exist?
34
+ File.directory?(self.find)
35
+ end
36
+
37
+ def dirname
38
+ self.annotate(File.dirname(self))
39
+ end
40
+
41
+ def basename
42
+ self.annotate(File.basename(self))
43
+ end
44
+
45
+ def glob(pattern = '*')
46
+ if self.include? "*"
47
+ self.glob_all
48
+ else
49
+ return [] unless self.exist?
50
+ found = self.find
51
+ exp = File.join(found, pattern)
52
+ paths = Dir.glob(exp).collect{|f| self.annotate(f) }
53
+
54
+ paths.each do |p|
55
+ p.original = File.join(found.original, p.sub(/^#{found}/, ''))
56
+ end if found.original
57
+
58
+ paths
59
+ end
60
+ end
61
+
62
+ def glob_all(pattern = nil, caller_lib = nil, search_paths = nil)
63
+ search_paths ||= Path.path_maps
64
+ search_paths = search_paths.dup
65
+
66
+ search_paths.keys.collect do |where|
67
+ found = find(where)
68
+ paths = pattern ? Dir.glob(File.join(found, pattern)) : Dir.glob(found)
69
+
70
+ paths = paths.collect{|p| self.annotate p }
71
+
72
+ paths = paths.each do |p|
73
+ p.original = File.join(found.original, p.sub(/^#{found}/, ''))
74
+ p.where = where
75
+ end if found.original and pattern
76
+
77
+ paths
78
+ end.flatten.uniq
79
+ end
80
+
81
+ def set_extension(extension)
82
+ self.annotate(self + ".#{extension}")
83
+ end
84
+
85
+ def unset_extension
86
+ self.annotate(self.split(".")[0..-2] * ".")
87
+ end
88
+
89
+ def remove_extension(extension = nil)
90
+ if extension.nil?
91
+ unset_extension
92
+ else
93
+ self.annotate(self.sub(/\.#{extension}$/,''))
94
+ end
95
+ end
96
+
97
+ def replace_extension(new_extension = nil, multiple = false)
98
+ if String === multiple
99
+ new_path = self.sub(/(\.[^\.\/]{1,5})(.#{multiple})?$/,'')
100
+ elsif multiple
101
+ new_path = self.sub(/(\.[^\.\/]{1,5})+$/,'')
102
+ else
103
+ new_path = self.sub(/\.[^\.\/]{1,5}$/,'')
104
+ end
105
+ new_path = new_path + "." + new_extension.to_s
106
+ self.annotate(new_path)
107
+ end
108
+
109
+
110
+ # Is 'file' newer than 'path'? return non-true if path is newer than file
111
+ def self.newer?(path, file, by_link = false)
112
+ return true if not Open.exists?(file)
113
+ path = path.find if Path === path
114
+ file = file.find if Path === file
115
+ if by_link
116
+ patht = File.exist?(path) ? File.lstat(path).mtime : nil
117
+ filet = File.exist?(file) ? File.lstat(file).mtime : nil
118
+ else
119
+ patht = Open.mtime(path)
120
+ filet = Open.mtime(file)
121
+ end
122
+ return true if patht.nil? || filet.nil?
123
+ diff = patht - filet
124
+ return diff if diff < 0
125
+ return false
126
+ end
127
+ end
data/lib/scout/path.rb ADDED
@@ -0,0 +1,51 @@
1
+ require_relative 'meta_extension'
2
+ require_relative 'path/find'
3
+ require_relative 'path/util'
4
+ require_relative 'path/tmpfile'
5
+
6
+ module Path
7
+ extend MetaExtension
8
+ extension_attr :pkgdir, :libdir, :path_maps
9
+
10
+ def self.default_pkgdir
11
+ @@default_pkgdir ||= 'scout'
12
+ end
13
+
14
+ def self.default_pkgdir=(pkgdir)
15
+ @@default_pkgdir = pkgdir
16
+ end
17
+
18
+ def pkgdir
19
+ @pkgdir ||= Path.default_pkgdir
20
+ end
21
+
22
+ def libdir
23
+ @libdir || Path.caller_lib_dir
24
+ end
25
+
26
+ def path_maps
27
+ @path_maps ||= Path.path_maps.dup
28
+ end
29
+
30
+ def join(subpath, prevpath = nil)
31
+ subpath = subpath.to_s if Symbol === subpath
32
+ prevpath = prevpath.to_s if Symbol === prevpath
33
+
34
+ subpath = File.join(prevpath.to_s, subpath) if prevpath
35
+ new = self.empty? ? subpath.dup : File.join(self, subpath)
36
+ self.annotate(new)
37
+ new
38
+ end
39
+
40
+ alias [] join
41
+ alias / join
42
+
43
+ def method_missing(name, prev = nil, *args, &block)
44
+ if block_given? || name.to_s.start_with?('to_')
45
+ super name, prev, *args, &block
46
+ else
47
+ join(name, prev)
48
+ end
49
+ end
50
+
51
+ end
@@ -0,0 +1,17 @@
1
+ require_relative '../open'
2
+ require 'json'
3
+ require 'yaml'
4
+
5
+ module Open
6
+ def self.json(file)
7
+ Open.open(file){|f| JSON.load(f) }
8
+ end
9
+
10
+ def self.yaml(file)
11
+ Open.open(file){|f| YAML.load(f) }
12
+ end
13
+
14
+ def self.marshal(file)
15
+ Open.open(file){|f| Marshal.load(f) }
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'open'
2
+
3
+ module Path
4
+ def yaml(*rest, &block)
5
+ Open.yaml(self, *rest, &block)
6
+ end
7
+
8
+ def json(*rest, &block)
9
+ Open.json(self, *rest, &block)
10
+ end
11
+
12
+ def marshal(*rest, &block)
13
+ Open.marshal(self, *rest, &block)
14
+ end
15
+ end
@@ -0,0 +1,157 @@
1
+ require_relative '../open'
2
+ require_relative 'open'
3
+ require 'set'
4
+
5
+ module Persist
6
+ TRUE_STRINGS = Set.new ["true", "True", "TRUE", "t", "T", "1", "yes", "Yes", "YES", "y", "Y", "ON", "on"] unless defined? TRUE_STRINGS
7
+ SERIALIZER = :json
8
+
9
+ class << self
10
+ attr_accessor :save_drivers, :load_drivers
11
+ def save_drivers
12
+ @save_drivers ||= {}
13
+ end
14
+ def load_drivers
15
+ @load_drivers ||= {}
16
+ end
17
+ end
18
+
19
+ def self.serialize(content, type)
20
+ type = type.to_sym if String === type
21
+ type = SERIALIZER if type == :serializer
22
+ case type
23
+ when nil, :string, :text, :integer, :float, :boolean, :file, :path, :select, :folder, :binary
24
+ if IO === content || StringIO === content
25
+ content.read
26
+ else
27
+ content.to_s
28
+ end
29
+ when :array
30
+ content * "\n"
31
+ when :yaml
32
+ content.to_yaml
33
+ when :json
34
+ content.to_json
35
+ when :marshal
36
+ Marshal.dump(content)
37
+ else
38
+ if m = type.to_s.match(/(.*)_array/)
39
+ type = m[1].to_sym
40
+ content.collect{|c| serialize(c, type) } * "\n"
41
+ else
42
+ raise "Persist does not know #{Log.fingerprint type}"
43
+ end
44
+ end
45
+ end
46
+
47
+ def self.deserialize(serialized, type)
48
+ type = type.to_sym if String === type
49
+ type = SERIALIZER if type == :serializer
50
+
51
+ case type
52
+ when nil, :string, :text, :file, :stream, :select, :folder
53
+ serialized
54
+ when :path
55
+ Path.setup(serialized)
56
+ when :integer
57
+ serialized.to_i
58
+ when :float
59
+ serialized.to_f
60
+ when :boolean
61
+ TRUE_STRINGS.include? serialized.strip
62
+ when :array
63
+ serialized.split("\n")
64
+ when :yaml
65
+ YAML.parse(serialized)
66
+ when :json
67
+ JSON.parse(serialized)
68
+ when :marshal
69
+ Marshal.load(serialized)
70
+ else
71
+ if m = type.to_s.match(/(.*)_array/)
72
+ type = m[1].to_sym
73
+ new_content = serialized.split("\n")
74
+ new_content.collect{|c| deserialize(c, type) }
75
+ else
76
+ raise "Persist does not know #{Log.fingerprint type}"
77
+ end
78
+ end
79
+ end
80
+
81
+ MEMORY = {}
82
+ def self.save(content, file, type = :serializer)
83
+ type = :serializer if type.nil?
84
+ type = type.to_sym if String === type
85
+ type = SERIALIZER if type == :serializer
86
+ type = MEMORY if type == :memory
87
+ return if content.nil?
88
+ type = MEMORY if type == :memory
89
+ type = :serializer if type.nil?
90
+
91
+ if Hash === type
92
+ type[file] = content
93
+ return
94
+ end
95
+
96
+ Log.debug "Save #{Log.fingerprint type} on #{file}"
97
+ if save_drivers[type]
98
+ if save_drivers[type].arity == 1
99
+ return Open.sensible_write(file, save_drivers[type].call(content))
100
+ else
101
+ return save_drivers[type].call(file, content)
102
+ end
103
+ end
104
+
105
+ if type == :binary
106
+ content.force_encoding("ASCII-8BIT") if content.respond_to? :force_encoding
107
+ Open.open(file, :mode => 'wb') do |f|
108
+ f.puts content
109
+ end
110
+ content
111
+ else
112
+ serialized = serialize(content, type)
113
+ Open.sensible_write(file, serialized, :force => true)
114
+ return nil
115
+ end
116
+ end
117
+
118
+ def self.load(file, type = :serializer)
119
+ file = file.find if Path === file
120
+ type = :serializer if type.nil?
121
+ type = type.to_sym if String === type
122
+ type = SERIALIZER if type == :serializer
123
+ type = MEMORY if type == :memory
124
+ return unless Hash === type || Open.exist?(file)
125
+
126
+ Log.debug "Load #{Log.fingerprint type} on #{file}"
127
+ if load_drivers[type]
128
+ return load_drivers[type].call(file)
129
+ end
130
+
131
+ case type
132
+ when :binary
133
+ Open.read(file, :mode => 'rb')
134
+ when :yaml
135
+ Open.yaml(file)
136
+ when :json
137
+ Open.json(file)
138
+ when :marshal, :serializer
139
+ Open.marshal(file)
140
+ when :stream
141
+ Open.open(file)
142
+ when :file
143
+ value = Open.read(file)
144
+ value.sub!(/^\./, File.dirname(file)) if value.start_with?("./")
145
+ value
146
+ when :file_array
147
+ Open.read(file).split("\n").collect do |f|
148
+ f.sub!(/^\./, File.dirname(file)) if f.start_with?("./")
149
+ f
150
+ end
151
+ when Hash
152
+ type[file]
153
+ else
154
+ deserialize(Open.read(file), type)
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,104 @@
1
+ require_relative 'persist/serialize'
2
+ require_relative 'persist/open'
3
+ require_relative 'persist/path'
4
+
5
+ module Persist
6
+ class << self
7
+ attr :cache_dir
8
+ def cache_dir=(cache_dir)
9
+ @cache_dir = Path === cache_dir ? cache_dir : Path.setup(cache_dir)
10
+ end
11
+ def cache_dir
12
+ @cache_dir ||= Path.setup("var/cache/persistence")
13
+ end
14
+
15
+ attr_writer :lock_dir
16
+ def lock_dir
17
+ @lock_dir ||= Path.setup("tmp/persist_locks").find
18
+ end
19
+ end
20
+
21
+ def self.persistence_path(name, options = {})
22
+ options = IndiferentHash.add_defaults options, :dir => Persist.cache_dir
23
+ other_options = IndiferentHash.pull_keys options, :other
24
+ name = name.filename if name.respond_to?(:filename) && name.filename
25
+ persist_options = {}
26
+ TmpFile.tmp_for_file(name, options.merge(persist_options), other_options)
27
+ end
28
+
29
+ MEMORY_CACHE = {}
30
+ CONNECTIONS = {}
31
+ def self.persist(name, type = :serializer, options = {}, &block)
32
+ persist_options = IndiferentHash.pull_keys options, :persist
33
+ return yield if FalseClass === persist_options[:persist]
34
+ file = persist_options[:path] || options[:path] || persistence_path(name, options)
35
+
36
+ if type == :memory
37
+ repo = options[:memory] || options[:repo] || MEMORY_CACHE
38
+ repo[file] ||= yield
39
+ return repo[file]
40
+ end
41
+
42
+ update = options[:update] || persist_options[:update]
43
+ update = Open.mtime(update) if Path === update
44
+ update = Open.mtime(file) >= update ? false : true if Time === update
45
+
46
+ lockfile = persist_options[:lockfile] || options[:lockfile] || Persist.persistence_path(file + '.persist', {:dir => Persist.lock_dir})
47
+
48
+ Open.lock lockfile do |lock|
49
+ if Open.exist?(file) && ! update
50
+ Persist.load(file, type)
51
+ else
52
+ begin
53
+ file = file.find if Path === file
54
+ return yield(file) if block.arity == 1
55
+ res = yield
56
+
57
+ if res.nil?
58
+ return Persist.load(file, type)
59
+ end
60
+
61
+ Open.rm(file)
62
+
63
+ if IO === res || StringIO === res
64
+ tee_copies = options[:tee_copies] || 1
65
+ main, *copies = Open.tee_stream_thread_multiple res, tee_copies + 1
66
+ main.lock = lock
67
+ t = Thread.new do
68
+ Thread.current.report_on_exception = false
69
+ Thread.current["name"] = "file saver: " + file
70
+ Open.sensible_write(file, main)
71
+ end
72
+ Thread.pass until t["name"]
73
+ copies.each_with_index do |copy,i|
74
+ next_stream = copies[i+1] if copies.length > i
75
+ ConcurrentStream.setup copy, :threads => t, :filename => file, :autojoin => true, :next => next_stream
76
+ end
77
+ res = copies.first
78
+ raise KeepLocked.new(res)
79
+ else
80
+ pres = Persist.save(res, file, type)
81
+ res = pres unless pres.nil?
82
+ end
83
+ rescue Exception
84
+ Thread.handle_interrupt(Exception => :never) do
85
+ if Open.exist?(file)
86
+ Log.debug "Failed persistence #{file} - erasing"
87
+ Open.rm file
88
+ else
89
+ Log.debug "Failed persistence #{file}"
90
+ end
91
+ end
92
+ raise $! unless options[:canfail]
93
+ end
94
+ res
95
+ end
96
+ end
97
+ end
98
+
99
+ def self.memory(name, options = {}, &block)
100
+ options[:persist_path] ||= options[:path] ||= [name, options[:key]].compact * ":"
101
+ self.persist(name, :memory, options, &block)
102
+ end
103
+
104
+ end
@@ -0,0 +1,8 @@
1
+ class << Open
2
+ alias _just_open open
3
+
4
+ def open(file, *args, **kwargs, &block)
5
+ file.produce if Path === file
6
+ _just_open(file, *args, **kwargs, &block)
7
+ end
8
+ end
@@ -0,0 +1,80 @@
1
+ module Path
2
+ def produce(force = false)
3
+ return self if ! force && (Open.exist?(self) || @produced)
4
+ begin
5
+ if Resource === self.pkgdir
6
+ self.pkgdir.produce self, force
7
+ else
8
+ false
9
+ end
10
+ rescue ResourceNotFound
11
+ false
12
+ rescue
13
+ message = $!.message
14
+ message = "No exception message" if message.nil? || message.empty?
15
+ Log.warn "Error producing #{self}: #{message}"
16
+ raise $!
17
+ ensure
18
+ @produced = true
19
+ end
20
+ end
21
+
22
+ def produce_with_extension(extension, *args)
23
+ begin
24
+ self.produce(*args)
25
+ rescue Exception
26
+ exception = $!
27
+ begin
28
+ self.set_extension(extension).produce(*args)
29
+ rescue Exception
30
+ raise exception
31
+ end
32
+ end
33
+ end
34
+
35
+ def produce_and_find(extension = nil, *args)
36
+ found = if extension
37
+ found = find_with_extension(extension, *args)
38
+ found.exists? ? found : produce_with_extension(extension, *args)
39
+ else
40
+ found = find
41
+ found.exists? ? found : produce(*args)
42
+ end
43
+ raise "Not found: #{self}" unless found
44
+
45
+ found
46
+ end
47
+
48
+ def relocate
49
+ return self if Open.exists?(self)
50
+ Resource.relocate(self)
51
+ end
52
+
53
+ def identify
54
+ Resource.identify(self)
55
+ end
56
+
57
+ def open(*args, &block)
58
+ produce
59
+ Open.open(self, *args, &block)
60
+ end
61
+
62
+ def read
63
+ produce
64
+ Open.read(self)
65
+ end
66
+
67
+ def write(*args, &block)
68
+ Open.write(self.find, *args, &block)
69
+ end
70
+
71
+ def list
72
+ found = produce_and_find('list')
73
+ Open.list(found)
74
+ end
75
+
76
+ def exists?
77
+ return true if Open.exists?(self.find)
78
+ self.produce
79
+ end
80
+ end
@@ -0,0 +1,69 @@
1
+ require_relative '../../misc'
2
+ require_relative '../../path'
3
+ require 'rake'
4
+
5
+ class Rake::FileTask
6
+ class << self
7
+ alias_method :old_define_task, :define_task
8
+ end
9
+
10
+ def self.define_task(file, *args, &block)
11
+ @@files ||= []
12
+ @@files << file
13
+ old_define_task(file, *args, &block)
14
+ end
15
+
16
+ def self.files
17
+ @@files
18
+ end
19
+
20
+ def self.clear_files
21
+ @@files = []
22
+ end
23
+ end
24
+
25
+ module ScoutRake
26
+ class TaskNotFound < StandardError; end
27
+ def self.run(rakefile, dir, task, &block)
28
+ old_pwd = FileUtils.pwd
29
+
30
+ Rake::Task.clear
31
+ Rake::FileTask.clear_files
32
+
33
+ t = nil
34
+ pid = Process.fork{
35
+ if block_given?
36
+ TOPLEVEL_BINDING.receiver.instance_exec &block
37
+ else
38
+ if Path.is_filename? rakefile
39
+ rakefile = rakefile.produce.find
40
+ load rakefile
41
+ else
42
+ TmpFile.with_file(rakefile) do |tmpfile|
43
+ load tmpfile
44
+ end
45
+ end
46
+ end
47
+
48
+ raise TaskNotFound if Rake::Task[task].nil?
49
+
50
+ #Misc.pre_fork
51
+ begin
52
+ Misc.in_dir(dir) do
53
+ Rake::Task[task].invoke
54
+
55
+ Rake::Task.clear
56
+ Rake::FileTask.clear_files
57
+ end
58
+ rescue Exception
59
+ Log.error "Error in rake: #{$!.message}"
60
+ Log.exception $!
61
+ Kernel.exit! -1
62
+ end
63
+ Kernel.exit! 0
64
+ }
65
+ Process.waitpid(pid)
66
+ raise "Rake failed" unless $?.success?
67
+
68
+ end
69
+ end