raven 1.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,84 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2006 Matthieu Riou
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'rubygems'
18
+ require 'fileutils'
19
+
20
+ module Gem
21
+ # Adding Gems Java platform
22
+ module Platform
23
+ JAVA = 'java'
24
+ end
25
+
26
+ # Unfortunately Maven artifacts have a rather free versioning scheme
27
+ class Version
28
+ def self.correct?(str)
29
+ true
30
+ end
31
+ end
32
+ end
33
+
34
+ begin
35
+ Gem.manage_gems
36
+ rescue NoMethodError => ex
37
+ # Using rubygems prior to 0.6.1
38
+ end
39
+
40
+ # Let the user add or redefine his sources (hopefully we'll be
41
+ # able to set a default one when a good soul will be able to
42
+ # donate us space and bandwidth to host a Raven Gems repository).
43
+ module Gem
44
+ def self.sources=(s)
45
+ @sources = s
46
+ end
47
+ end
48
+ require_gem("sources")
49
+ def sources; Gem.sources; end
50
+ def set_sources(s) Gem.sources = s; end
51
+ set_sources(["http://localhost:2233"])
52
+
53
+ # To avoid polluting the regular Gem repository, we store our gems
54
+ # under the user home directory.
55
+ GEMS_IN_HOME = true
56
+ USER_HOME = ENV['HOME'] ? ENV['HOME'] : ENV['USERPROFILE']
57
+ FileUtils.mkdir(USER_HOME + '/.raven_gems') unless File.exist?(USER_HOME + '/.raven_gems')
58
+ Dir.glob(USER_HOME + "/.raven_gems/specifications/*.gemspec").each do |file_name|
59
+ gemspec = Gem::SourceIndex.load_specification(file_name.untaint)
60
+ Gem::cache.add_spec(gemspec) if gemspec
61
+ end
62
+
63
+ module Gem
64
+ # Making the remote installer silent. Otherwise it always asks you to
65
+ # choose the version you want to install.
66
+ class RemoteInstaller
67
+ def find_gem_to_install(gem_name, version_requirement, caches)
68
+ specs_n_sources = []
69
+ caches.each do |source, cache|
70
+ cache.each do |name, spec|
71
+ if /^#{gem_name}$/i === spec.name &&
72
+ version_requirement.satisfied_by?(spec.version) then
73
+ specs_n_sources << [spec, source]
74
+ end
75
+ end
76
+ end
77
+ if specs_n_sources.empty? then
78
+ raise GemNotFoundException.new("Could not find #{gem_name} (#{version_requirement}) in the repository")
79
+ end
80
+ specs_n_sources = specs_n_sources.sort_by { |gs,| gs.version }.reverse
81
+ specs_n_sources[0]
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,284 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # This file has been copied from the RubyGems distribution and
4
+ # included in Raven for users convenience. See the RubyGems
5
+ # site for license and more.
6
+
7
+ #
8
+ # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
9
+ # All rights reserved.
10
+ # See LICENSE.txt for permissions.
11
+ #
12
+
13
+
14
+ # Generate the yaml/yaml.Z index files for a gem server directory.
15
+ #
16
+ # Usage: generate_yaml_index.rb --dir DIR [--verbose]
17
+
18
+ $:.unshift '~/rubygems' if File.exist? "~/rubygems"
19
+
20
+ require 'optparse'
21
+ require 'rubygems'
22
+ require 'zlib'
23
+ require 'digest/sha2'
24
+
25
+ Gem.manage_gems
26
+
27
+ ######################################################################
28
+ # Mixin that provides a +compress+ method for compressing files on
29
+ # disk.
30
+ #
31
+ module Compressor
32
+ # Compress the given file.
33
+ def compress(filename, ext="rz")
34
+ File.open(filename + ".#{ext}", "w") do |file|
35
+ file.write(zip(File.read(filename)))
36
+ end
37
+ end
38
+
39
+ # Return a compressed version of the given string.
40
+ def zip(string)
41
+ Zlib::Deflate.deflate(string)
42
+ end
43
+
44
+ # Return an uncompressed version of a compressed string.
45
+ def unzip(string)
46
+ Zlib::Inflate.inflate(string)
47
+ end
48
+ end
49
+
50
+ ######################################################################
51
+ # Announcer provides a way of announcing activities to the user.
52
+ #
53
+ module Announcer
54
+ # Announce +msg+ to the user.
55
+ def announce(msg)
56
+ puts msg if @options[:verbose]
57
+ end
58
+ end
59
+
60
+ ######################################################################
61
+ # Abstract base class for building gem indicies. Uses the template
62
+ # pattern with subclass specialization in the +begin_index+,
63
+ # +end_index+ and +cleanup+ methods.
64
+ #
65
+ class AbstractIndexBuilder
66
+ include Compressor
67
+ include Announcer
68
+
69
+ # Build a Gem index. Yields to block to handle the details of the
70
+ # actual building. Calls +begin_index+, # +end_index+ and +cleanup+
71
+ # at appropriate times to customize basic operations.
72
+ def build
73
+ if ! @enabled
74
+ yield
75
+ else
76
+ unless File.exist?(@directory)
77
+ FileUtils.mkdir_p(@directory)
78
+ end
79
+ fail "not a directory: #{@directory}" unless File.directory?(@directory)
80
+ File.open(File.join(@directory, @filename), "w") do |file|
81
+ @file = file
82
+ start_index
83
+ yield
84
+ end_index
85
+ end
86
+ cleanup
87
+ end
88
+ ensure
89
+ @file = nil
90
+ end
91
+
92
+ # Called immediately before the yield in build. The index file is
93
+ # open and availabe as @file.
94
+ def start_index
95
+ end
96
+
97
+ # Called immediately after the yield in build. The index file is
98
+ # still open and available as @file.
99
+ def end_index
100
+ end
101
+
102
+ # Called from within builder after the index file has been closed.
103
+ def cleanup
104
+ end
105
+ end
106
+
107
+ ######################################################################
108
+ # Construct the master Gem index file.
109
+ #
110
+ class MasterIndexBuilder < AbstractIndexBuilder
111
+ def initialize(filename, options)
112
+ @filename = filename
113
+ @options = options
114
+ @directory = options[:directory]
115
+ @enabled = true
116
+ end
117
+
118
+ def start_index
119
+ super
120
+ @file.puts "--- !ruby/object:Gem::Cache"
121
+ @file.puts "gems:"
122
+ end
123
+
124
+ def cleanup
125
+ super
126
+ index_file_name = File.join(@directory, @filename)
127
+ compress(index_file_name, "Z")
128
+ # Sometimes being paranoid isn't that good: there's a bug on Windows causing
129
+ # the failing of unzip.
130
+ # paranoid(index_file_name, "#{index_file_name}.Z")
131
+ end
132
+
133
+ def add(spec)
134
+ @file.puts " #{spec.full_name}: #{nest(spec.to_yaml)}"
135
+ end
136
+
137
+ def nest(yaml_string)
138
+ yaml_string[4..-1].gsub(/\n/, "\n ")
139
+ end
140
+
141
+ private
142
+
143
+ def paranoid(fn, compressed_fn)
144
+ data = File.read(fn)
145
+ compressed_data = File.read(compressed_fn)
146
+ if data != unzip(compressed_data)
147
+ fail "Compressed file #{compressed_fn} does not match uncompressed file #{fn}"
148
+ end
149
+ end
150
+ end
151
+
152
+ ######################################################################
153
+ # Construct a quick index file and all of the individual specs to
154
+ # support incremental loading.
155
+ #
156
+ class QuickIndexBuilder < AbstractIndexBuilder
157
+ def initialize(filename, options)
158
+ @filename = filename
159
+ @options = options
160
+ @directory = options[:quick_directory]
161
+ @enabled = options[:quick]
162
+ end
163
+
164
+ def cleanup
165
+ compress(File.join(@directory, @filename))
166
+ end
167
+
168
+ def add(spec)
169
+ return unless @enabled
170
+ @file.puts spec.full_name
171
+ fn = File.join(@directory, "#{spec.full_name}.gemspec.rz")
172
+ File.open(fn, "w") do |gsfile|
173
+ gsfile.write(zip(spec.to_yaml))
174
+ end
175
+ end
176
+ end
177
+
178
+ ######################################################################
179
+ # Top level class for building the repository index. Initialize with
180
+ # an options hash and call +build_index+.
181
+ #
182
+ class Indexer
183
+ include Compressor
184
+ include Announcer
185
+
186
+ # Create an indexer with the options specified by the options hash.
187
+ def initialize(options)
188
+ @options = options.dup
189
+ @directory = @options[:directory]
190
+ @options[:quick_directory] = File.join(@directory, "quick")
191
+ @master_index = MasterIndexBuilder.new("yaml", @options)
192
+ @quick_index = QuickIndexBuilder.new("index", @options)
193
+ end
194
+
195
+ # Build the index.
196
+ def build_index
197
+ announce "Building Server Index"
198
+ FileUtils.rm_r(@options[:quick_directory]) rescue nil
199
+ @master_index.build do
200
+ @quick_index.build do
201
+ gem_file_list.each do |gemfile|
202
+ spec = Gem::Format.from_file_by_path(gemfile).spec
203
+ abbreviate(spec)
204
+ announce " ... adding #{spec.full_name}"
205
+ @master_index.add(spec)
206
+ @quick_index.add(spec)
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ # List of gem file names to index.
213
+ def gem_file_list
214
+ Dir.glob(File.join(@directory, "gems", "*.gem"))
215
+ end
216
+
217
+ # Abbreviate the spec for downloading. Abbreviated specs are only
218
+ # used for searching, downloading and related activities and do not
219
+ # need deployment specific information (e.g. list of files). So we
220
+ # abbreviate the spec, making it much smaller for quicker downloads.
221
+ def abbreviate(spec)
222
+ spec.files = []
223
+ spec.test_files = []
224
+ spec.rdoc_options = []
225
+ spec.extra_rdoc_files = []
226
+ spec.cert_chain = []
227
+ spec
228
+ end
229
+ end
230
+
231
+ ######################################################################
232
+ # Top Level Functions
233
+ ######################################################################
234
+
235
+ def handle_options(args)
236
+ # default options
237
+ options = {
238
+ :directory => '.',
239
+ :verbose => false,
240
+ :quick => true,
241
+ }
242
+
243
+ args.options do |opts|
244
+ opts.on_tail("--help", "show this message") do
245
+ puts opts
246
+ exit
247
+ end
248
+ opts.on(
249
+ '-d', '--dir=DIRNAME', '--directory=DIRNAME',
250
+ "repository base dir containing gems subdir",
251
+ String) do |value|
252
+ options[:directory] = value
253
+ end
254
+ opts.on('--[no-]quick', "include quick index") do |value|
255
+ options[:quick] = value
256
+ end
257
+ opts.on('-v', '--verbose', "show verbose output") do |value|
258
+ options[:verbose] = value
259
+ end
260
+ opts.on('-V', '--version',
261
+ "show version") do |value|
262
+ puts Gem::RubyGemsVersion
263
+ exit
264
+ end
265
+ opts.parse!
266
+ end
267
+
268
+ if options[:directory].nil?
269
+ puts "Error, must specify directory name. Use --help"
270
+ exit
271
+ elsif ! File.exist?(options[:directory]) ||
272
+ ! File.directory?(options[:directory])
273
+ puts "Error, unknown directory name #{directory}."
274
+ exit
275
+ end
276
+ options
277
+ end
278
+
279
+ # Main program.
280
+ def main_index(args)
281
+ options = handle_options(args)
282
+ Indexer.new(options).build_index
283
+ end
284
+
@@ -0,0 +1,399 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Copyright 2006 Matthieu Riou
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'rake'
18
+ require 'fileutils'
19
+ require 'set'
20
+
21
+ # Monkey patching FileUtils to support filtering in copy.
22
+ module FileUtils
23
+ class Entry_
24
+ alias original copy
25
+ def copy(dest)
26
+ unless path['.svn'] || path['.cvs']
27
+ original(dest)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ module Raven
34
+ CP_SEP = PLATFORM['mswin'] ? ';' : ':'
35
+
36
+ # Executes Javac by passing it everything it needs. Stuff like a
37
+ # classpath and sources. The classpath is built by checking the
38
+ # prerequisites of the javac task. When a prerequisite is a dependency
39
+ # declaration (dependency task), it takes each declared Gems and
40
+ # adds the jar files found in them to the classpath.
41
+ #
42
+ # Can be customized by adding directories to the <em>build_path</em>
43
+ # using the << operator (if none defined, default is src/main/java).
44
+ class JavacTask < Rake::Task
45
+
46
+ def execute
47
+ super
48
+ classpath = Raven.build_cp(prerequisites)
49
+ classpath << "target/classes"
50
+ @build_path = ["src/main/java"] unless @build_path
51
+
52
+ puts "Building path #{@build_path.join(' ')}" if RakeFileUtils.verbose_flag
53
+
54
+ Dir.mkdir("target") unless File.exist?("target")
55
+ Dir.mkdir("target/classes") unless File.exist?("target/classes")
56
+ # Getting the source files to compile. Filtrating sources already
57
+ # compiled having a fresh enough class
58
+ source_files = @build_path.collect do |d|
59
+ Dir.glob("#{d}/**/*.java").select do |java|
60
+ classfile = 'target/classes/' + java[d.length, (java.length - 5 - d.length)] + '.class'
61
+ File.exist?(classfile) ? File.stat(java).ctime > File.stat(classfile).ctime : true
62
+ end
63
+ end.flatten
64
+
65
+ if (source_files.size > 0)
66
+ # Getting only package names, it shortens the command line
67
+ source_pkg = Set.new
68
+ source_files.each { |src| source_pkg << File.join(File.dirname(src), '*.java') }
69
+ # Executing javac
70
+ puts "javac -cp #{classpath.join(CP_SEP)} -sourcepath #{@build_path.join(CP_SEP)} -d target/classes #{source_pkg.to_a.join(' ')}" if RakeFileUtils.verbose_flag
71
+ `javac -cp #{classpath.join(CP_SEP)} -sourcepath #{@build_path.join(CP_SEP)} -d target/classes #{source_pkg.to_a.join(' ')}`
72
+ unless $? == 0
73
+ puts "Build failed, see above errors."
74
+ exit
75
+ end
76
+ else
77
+ puts 'All class files are up to date.' if RakeFileUtils.verbose_flag
78
+ end
79
+ end
80
+
81
+ def build_path
82
+ @build_path ||= []
83
+ end
84
+ end
85
+
86
+ # Builds a jar file from your compiled sources. The jarfile produced
87
+ # will have the same name as your jar task.
88
+ class JarTask < Rake::Task
89
+ def execute
90
+ super
91
+ latest = Raven.latest_file('target/classes')
92
+
93
+ if !File.exist?("target/#{name}") || File.stat("target/#{name}").ctime < latest
94
+ `jar -cf target/#{name} -C target/classes .`
95
+ else
96
+ puts 'Nothing to do, jar is fresh enough.' if RakeFileUtils.verbose_flag
97
+ end
98
+ end
99
+ end
100
+
101
+ # Builds a jar file from your sources. Customized by adding directories
102
+ # to the <em>source_path</em> just like the JavacTask.
103
+ class JarSourceTask < Rake::Task
104
+ def execute
105
+ super
106
+ # Checking if any of our prerequisites is a JavacTask, if
107
+ # so we'll just use the build path to construct the jar.
108
+ Raven.prereq_filter(prerequisites, :build_path) do |javac_task|
109
+ (@source_path ||= []) << javac_task.build_path
110
+ end
111
+
112
+ # Initializing source path
113
+ @source_path = ["src/main/java"] unless @source_path
114
+ @source_path.flatten!
115
+
116
+ latest = Time.at(0)
117
+ @source_path.each do |dir|
118
+ dir_latest = Raven.latest_file(dir)
119
+ latest = dir_latest if dir_latest > latest
120
+ end
121
+
122
+ # Building the jar from all sources
123
+ if !File.exist?("target/#{name}") || File.stat("target/#{name}").ctime < latest
124
+ `jar -cf target/#{name} -C #{@source_path.pop} .`
125
+ while (p = @source_path.pop)
126
+ `jar -uf target/#{name} -C #{p} .`
127
+ end
128
+ end
129
+ end
130
+
131
+ def source_path
132
+ @source_path ||= []
133
+ end
134
+ end
135
+
136
+ # Produces a WAR from a web application directory. Includes the libraries
137
+ # needed in WEB-INF/lib (as long as the corresponding dependency task is
138
+ # declared as a prerequisite) and the compiled classes (if there are).
139
+ #
140
+ # Can be customized by setting <em>webapp_dir</em> to the directory
141
+ # containing your web application resources (web.xml, jsp, images, ...).
142
+ # The default is src/main/webapp.
143
+ class WarTask < Rake::Task
144
+ DEFAULT_TARGET = 'target/webapp/'
145
+ LIB_SUBDIR = 'WEB-INF/lib/'
146
+ CLASSES_SUBDIR = 'WEB-INF/classes/'
147
+
148
+ def execute
149
+ super
150
+
151
+ # Build target structure
152
+ @webapp_dir = @webapp_dir || 'src/main/webapp'
153
+ Raven.mkdir_recurse(DEFAULT_TARGET)
154
+
155
+ puts "Using web application directory #{@webapp_dir}" if RakeFileUtils.verbose_flag
156
+
157
+ FileUtils.cp_r(@webapp_dir, DEFAULT_TARGET)
158
+
159
+ # Eventually add classes compiled by javac
160
+ if (File.exist?('target/classes'))
161
+ Raven.mkdir_recurse(DEFAULT_TARGET + CLASSES_SUBDIR)
162
+ FileUtils.cp_r('target/classes/.', DEFAULT_TARGET + CLASSES_SUBDIR)
163
+ end
164
+
165
+ # Make lib directory with all dependencies
166
+ Raven.mkdir_recurse(DEFAULT_TARGET + LIB_SUBDIR)
167
+ Raven.mk_libs(DEFAULT_TARGET + LIB_SUBDIR, prerequisites)
168
+
169
+ # Build the war
170
+ `jar -cf target/#{name} -C #{DEFAULT_TARGET} .`
171
+ end
172
+
173
+ def webapp_dir=(param)
174
+ @webapp_dir = param
175
+ end
176
+ end
177
+
178
+ # Places all the dependencies in a given directory (useful mostly to
179
+ # build a distribution). The dependencies are selected from the
180
+ # prerequisites (using declared dependency tasks). The default
181
+ # directory is lib. Can be customized by setting <em>target</em>.
182
+ class LibDirTask < Rake::Task
183
+ def execute
184
+ super
185
+ puts "Copying libraries in #{@target}" if RakeFileUtils.verbose_flag
186
+ @target = @target || 'lib'
187
+ Raven.mk_libs(@target, prerequisites)
188
+ end
189
+
190
+ def target=(param)
191
+ @target = param
192
+ end
193
+ end
194
+
195
+ # Executes JavaDoc by passing it everything it needs. Stuff like a
196
+ # classpath and sources. The result is generated in target/jdoc. Can
197
+ # be customized exactly in the same way as the javac task.
198
+ class JavaDocTask < Rake::Task
199
+
200
+ def execute
201
+ super
202
+ classpath = Raven.build_cp(prerequisites)
203
+ classpath << "target/classes"
204
+ @build_path = ["src/main/java"] unless @build_path
205
+
206
+ puts "Executing JavaDoc using source path #{@build_path.join(' ')}" if RakeFileUtils.verbose_flag
207
+
208
+ Dir.mkdir("target") unless File.exist?("target")
209
+ Dir.mkdir("target/jdoc") unless File.exist?("target/jdoc")
210
+
211
+ packages = Set[]
212
+ @build_path.each do |d|
213
+ Dir.glob("#{d}/**/*.java").each do |java|
214
+ packages << java[(d.length + 1)..(java.rindex('/') - 1)].gsub(%r{[\\/]}, '.')
215
+ end
216
+ end
217
+ packages = packages.to_a
218
+
219
+ if (packages.size > 0)
220
+ puts "javadoc -classpath #{classpath.join(CP_SEP)} -sourcepath #{@build_path.join(CP_SEP)} -d target/jdoc #{packages.join(' ')}" if RakeFileUtils.verbose_flag
221
+ `javadoc -classpath #{classpath.join(CP_SEP)} -sourcepath #{@build_path.join(CP_SEP)} -d target/jdoc #{packages.join(' ')}`
222
+ unless $? == 0
223
+ puts "Build failed, see above errors."
224
+ exit
225
+ end
226
+ end
227
+ end
228
+
229
+ def build_path
230
+ @build_path ||= []
231
+ end
232
+ end
233
+
234
+ # Wraps a jar file around a Gem. Useful for distributing it around.
235
+ # The jar is taken from the target directory. You must at least
236
+ # specify <em>version</em> to produce the Gem. The artifact name and
237
+ # group name default to the current directory name and its parent
238
+ # directory name respectively. Convenient if you follow the classic
239
+ # project/module directory structure. Otherwise, just set the
240
+ # <em>artifact</em> and <em>group</em> to any value that suits you.
241
+ class GemWrapTask < Rake::Task
242
+ attr_writer :version, :artifact, :group
243
+
244
+ def execute
245
+ super
246
+ puts "Wrapping jar in a Gem" if RakeFileUtils.verbose_flag
247
+ unless @version
248
+ puts "A version must be provided to produce a Gem!"
249
+ end
250
+ pwd = Dir.pwd
251
+ @artifact = pwd[(pwd.rindex('/') + 1)..pwd.length] unless @artifact
252
+ pwd = pwd[0..pwd.rindex('/') - 1]
253
+ @group = pwd[(pwd.rindex('/') + 1)..pwd.length] unless @group
254
+ Raven.mkdir_recurse('target/gem/ext')
255
+ FileUtils.cp(Dir.glob('target/*.jar'), 'target/gem/ext')
256
+
257
+ Dir.chdir('target/gem') do
258
+ spec = Gem::Specification.new do |s|
259
+ s.platform = Gem::Platform::JAVA
260
+ s.summary = "Raven wrapped library #{@artifact} from project #{@group}."
261
+ s.name = "#{@group}-#{@artifact}"
262
+ s.version = @version
263
+ s.requirements << 'none'
264
+ s.require_path = 'ext'
265
+ s.autorequire = 'rake'
266
+ s.files = Dir.glob("{ext}/**/*")
267
+ end
268
+ Gem::Builder.new(spec).build
269
+ end
270
+ FileUtils.mv("target/gem/#{@group}-#{@artifact}-#{@version}-java.gem", 'target')
271
+ end
272
+ end
273
+
274
+ # Wraps a jar file around a Gem and automatically installs it in your
275
+ # local Gem repository. See the gem wrap task for more info (same rules
276
+ # apply).
277
+ class GemInstallTask < GemWrapTask
278
+ def execute
279
+ super
280
+ params = [false]
281
+ params << USER_HOME + "/.raven_gems" if defined?(GEMS_IN_HOME)
282
+ Gem::Installer.new("target/#{@group}-#{@artifact}-#{@version}-java.gem").install(*params)
283
+ end
284
+ end
285
+
286
+ private
287
+
288
+ # Builds the classpath by getting the path to the jars bundled
289
+ # in each gem dependency.
290
+ def self.build_cp(prerequisites)
291
+ classpath = []
292
+ Raven.prereq_filter(prerequisites, :gem_deps) do |dep_task|
293
+ dep_task.gem_deps.each do |gempath|
294
+ Dir.foreach(gempath + '/ext') do |file|
295
+ next if file == '.' || file == '..'
296
+ classpath << gempath + '/ext/' + file
297
+ end
298
+ end
299
+ end
300
+ classpath
301
+ end
302
+
303
+ # Copies the jars corresponding to each Gem dependency to a given
304
+ # directory.
305
+ def self.mk_libs(target, prereq)
306
+ Raven.mkdir_recurse(target)
307
+ Raven.prereq_filter(prereq, :gem_deps) do |dep_task|
308
+ dep_task.gem_deps.each do |gempath|
309
+ Dir.foreach(gempath + '/ext') do |file|
310
+ next if file == '.' || file == '..'
311
+ FileUtils.copy(gempath + '/ext/' + file, target)
312
+ end
313
+ end
314
+ end
315
+ end
316
+
317
+ # Duck typing selection of prerequisites
318
+ def self.prereq_filter(prerequisites, respond_to)
319
+ prerequisites.each do |prereq|
320
+ prereq_task = Rake::Task[prereq]
321
+ if prereq_task.respond_to?(respond_to)
322
+ yield(prereq_task)
323
+ end
324
+ end
325
+ end
326
+
327
+ # Recursively creates a directory
328
+ def self.mkdir_recurse(dir)
329
+ if dir.rindex('/')
330
+ parent = dir[0, dir.rindex('/')]
331
+ mkdir_recurse(parent) unless File.exist?(parent)
332
+ end
333
+ Dir.mkdir(dir) unless File.exist?(dir)
334
+ end
335
+
336
+ # Receursively browse a directory yielding on each file found.
337
+ def self.browse_files(root)
338
+ queue = [root]
339
+ while !queue.empty?
340
+ filename = queue.pop
341
+ if File.file?(filename)
342
+ yield(filename)
343
+ else
344
+ Dir.new(filename).each do |child|
345
+ unless ['..', '.', '.svn', '.cvs'].include?(child)
346
+ queue.push(filename + "/" + child)
347
+ end
348
+ end
349
+ end
350
+ end
351
+ end
352
+
353
+ # Returns the latest file timestamp in a directory structure
354
+ def self.latest_file(dir)
355
+ latest = Time.at(0)
356
+ Raven.browse_files(dir) do |f|
357
+ change = File.stat(f).ctime
358
+ latest = change if change > latest
359
+ end
360
+ latest
361
+ end
362
+
363
+ end
364
+
365
+
366
+ # Shortcut to the Javac task creation. Makes it handy.
367
+ def javac(args, &block)
368
+ Raven::JavacTask.define_task(args, &block)
369
+ end
370
+
371
+ # Shortcut to jar. Only 3 letters, isn't that beautiful?
372
+ def jar(args, &block)
373
+ Raven::JarTask.define_task(args, &block)
374
+ end
375
+
376
+ # I think you've got it now.
377
+ def jar_source(args, &block)
378
+ Raven::JarSourceTask.define_task(args, &block)
379
+ end
380
+
381
+ def lib_dir(args, &block)
382
+ Raven::LibDirTask.define_task(args, &block)
383
+ end
384
+
385
+ def war(args, &block)
386
+ Raven::WarTask.define_task(args, &block)
387
+ end
388
+
389
+ def javadoc(args, &block)
390
+ Raven::JavaDocTask.define_task(args, &block)
391
+ end
392
+
393
+ def gem_wrap(args, &block)
394
+ Raven::GemWrapTask.define_task(args, &block)
395
+ end
396
+
397
+ def gem_wrap_inst(args, &block)
398
+ Raven::GemInstallTask.define_task(args, &block)
399
+ end