forked from jruby/activerecord-jdbc-adapter
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Rakefile
362 lines (312 loc) · 13.3 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
# Common usage
#
# rake build:adapters - to build all specific adapter gems and the base gem
# rake release:do - build:adapters + git tag + push gems
#
# Environment variables used by this Rakefile:
#
# INCLUDE_JAR_IN_GEM [default task - false, other taks - true]:
# Note: This is something you should not normally have to set.
# For local development we always will end up including the jar file
# in any task which generates our main gem. The wrinkle to this
# is when we do a custom github link in bundler:
#
# gem 'ar-jdbc', github: '...'
#
# Because we stopped committing a .jar file for every change and so when
# we include a gem like this it clones the repository and does a default
# build in rake. This in turn will end up forcing a compile to generate
# that jar (similar to how c-extensions compile at the time of install).
# For shipped gems we do include the jar so that people do not require
# this compile step.
#
# NOOP [release:do - false]
#
# No commands or gem pushing during a release.
require 'rake/clean'
CLEAN.include 'derby*', 'test.db.*', '*test.sqlite3', 'test/reports'
CLEAN.include 'lib/**/*.jar', 'MANIFEST.MF', '*.log', 'target/*'
task :default => :jar # RubyGems extention will do a bare `rake' e.g. :
# jruby" -rubygems /opt/local/rvm/gems/jruby-1.7.16@jdbc/gems/rake-10.3.2/bin/rake
# RUBYARCHDIR=/opt/local/rvm/gems/jruby-1.7.16@jdbc/gems/activerecord-jdbc-adapter-1.4.0.dev/lib
# RUBYLIBDIR=/opt/local/rvm/gems/jruby-1.7.16@jdbc/gems/activerecord-jdbc-adapter-1.4.0.dev/lib
#
# under Bundler it points those DIRs to an empty one where only built extensions are stored :
# jruby -rubygems /opt/local/rvm/gems/jruby-1.7.19@temp/gems/rake-10.4.2/bin/rake
# RUBYARCHDIR=/opt/local/rvm/gems/jruby-1.7.19@temp/bundler/gems/extensions/universal-java-1.7/1.9/activerecord-jdbc-adapter-472b5fddba43
# RUBYLIBDIR=/opt/local/rvm/gems/jruby-1.7.19@temp/bundler/gems/extensions/universal-java-1.7/1.9/activerecord-jdbc-adapter-472b5fddba43
#
# javac -target 1.6 -source 1.6 -Xlint:unchecked -g -cp
# "/opt/local/rvm/rubies/jruby-1.7.19/lib/jruby.jar:
# /opt/local/maven-repo/mysql/mysql-connector-java/5.1.33/mysql-connector-java-5.1.33.jar:
# /opt/local/maven-repo/org/postgresql/postgresql/9.4-1200-jdbc4/postgresql-9.4-1200-jdbc4.jar"
# -d /tmp/d20150417-32100-7mb1bk src/java/arjdbc/ArJdbcModule.java ...
base_dir = Dir.pwd
gem_name = 'activerecord-jdbc-adapter'
gemspec_path = File.expand_path('activerecord-jdbc-adapter.gemspec', File.dirname(__FILE__))
gemspec = lambda do
@_gemspec_ ||= Dir.chdir(File.dirname(__FILE__)) do
Gem::Specification.load(gemspec_path)
end
end
built_gem_path = lambda do
Dir[File.join(base_dir, "#{gem_name}-*.gem")].sort_by{ |f| File.mtime(f) }.last
end
current_version = lambda { gemspec.call.version }
rake = lambda { |task| ruby "-S", "rake", task }
# NOTE: avoid Bundler loading due native extension building!
desc "Build #{gem_name} gem into the pkg directory."
task :build => :jar do
include_jar = ENV['INCLUDE_JAR_IN_GEM'] || 'true'
sh("INCLUDE_JAR_IN_GEM=#{include_jar} gem build -V '#{gemspec_path}'") do
gem_path = built_gem_path.call
file_name = File.basename(gem_path)
FileUtils.mkdir_p(File.join(base_dir, 'pkg'))
FileUtils.mv(gem_path, 'pkg')
puts "\n#{gem_name} #{current_version.call} built to 'pkg/#{file_name}'"
end
end
desc "Build and install #{gem_name} gem into system gems."
task :install => :build do
gem_path = built_gem_path.call
sh("gem install '#{gem_path}' --local") do |ok|
raise "Couldn't install gem, run `gem install #{gem_path}' for more detailed output" unless ok
puts "\n#{gem_name} (#{current_version.call}) installed"
end
end
desc "Releasing AR-JDBC gems (use NOOP=true to disable gem pushing)"
task 'release:do' do
Rake::Task['build'].invoke
Rake::Task['build:adapters'].invoke
noop = ENV.key?('NOOP') && (ENV['NOOP'] != 'false' && ENV['NOOP'] != '')
version = current_version.call; version_tag = "v#{version}"
sh("git diff --no-patch --exit-code", :noop => noop) { |ok| fail "git working dir is not clean" unless ok }
sh("git diff-index --quiet --cached HEAD", :noop => noop) { |ok| fail "git index is not clean" unless ok }
sh "git tag -a -m \"AR-JDBC #{version}\" #{version_tag}", :noop => noop
branch = `git rev-parse --abbrev-ref HEAD`.strip
puts "releasing from (current) branch #{branch.inspect}"
sh "for gem in `ls pkg/*-#{version}-java.gem`; do gem push $gem; done", :noop => noop do |ok|
sh "git push origin #{branch} --tags", :noop => noop if ok
end
end
task 'release:push' do
sh "for gem in `ls pkg/*-#{current_version.call}-java.gem`; do gem push $gem; done"
end
ADAPTERS = %w[mysql postgresql sqlite3].map { |a| "activerecord-jdbc#{a}-adapter" }
DRIVERS = %w[mysql postgres sqlite3].map { |a| "jdbc-#{a}" }
TARGETS = ( ADAPTERS + DRIVERS )
ADAPTERS.each do |target|
namespace target do
task :build do
version = current_version.call
Dir.chdir(target) { rake.call "build" }
cp FileList["#{target}/pkg/#{target}-#{version}-java.gem"], "pkg"
end
end
end
DRIVERS.each do |target|
namespace target do
task :build do
Dir.chdir(target) { rake.call "build" }
cp FileList["#{target}/pkg/#{target}-*.gem"], "pkg"
end
end
end
TARGETS.each do |target|
namespace target do
task :install do
Dir.chdir(target) { rake.call "install" }
end
#task :release do
# Dir.chdir(target) { rake.call "release" }
#end
end
end
# DRIVERS
desc "Build drivers"
task "build:drivers" => DRIVERS.map { |name| "#{name}:build" }
task "drivers:build" => 'build:drivers'
desc "Install drivers"
task "install:drivers" => DRIVERS.map { |name| "#{name}:install" }
task "drivers:install" => 'install:drivers'
# ADAPTERS
desc "Build adapters"
task "build:adapters" => [ 'build' ] + ADAPTERS.map { |name| "#{name}:build" }
task "adapters:build" => 'build:adapters'
desc "Install adapters"
task "install:adapters" => [ 'install' ] + ADAPTERS.map { |name| "#{name}:install" }
task "adapters:install" => 'install:adapters'
# ALL
task "build:all" => [ 'build' ] + TARGETS.map { |name| "#{name}:build" }
task "all:build" => 'build:all'
task "install:all" => [ 'install' ] + TARGETS.map { |name| "#{name}:install" }
task "all:install" => 'install:all'
require 'rake/testtask'
# native JRuby extension (adapter_java.jar) compilation :
if defined? JRUBY_VERSION
jar_file = 'lib/arjdbc/jdbc/adapter_java.jar'; CLEAN << jar_file
desc "Compile the native (Java) extension."
task :jar => jar_file
namespace :jar do
task :force do
rm jar_file if File.exist?(jar_file)
Rake::Task['jar'].invoke
end
end
#directory classes = 'pkg/classes'; CLEAN << classes
file jar_file => FileList[ 'src/java/**/*.java' ] do
source = target = '1.8'; debug = true
get_driver_jars_local = lambda do |*args|
driver_deps = args.empty? ? [ :Postgres, :MySQL ] : args
driver_jars = []
driver_deps.each do |name|
driver_jars << Dir.glob("jdbc-#{name.to_s.downcase}/lib/*.jar").sort.last
end
if driver_jars.empty? # likely on a `gem install ...'
# NOTE: we're currently assuming jdbc-xxx (compile) dependencies are
# installed, they are declared as gemspec.development_dependencies !
# ... the other option is to simply `mvn prepare-package'
driver_deps.each do |name|
#require "jdbc/#{name.to_s.downcase}"
#driver_jars << Jdbc.const_get(name).driver_jar
# thanks Bundler for mocking RubyGems completely :
#spec = Gem::Specification.find_by_name("jdbc-#{name.to_s.downcase}")
#driver_jars << Dir.glob(File.join(spec.gem_dir, 'lib/*.jar')).sort.last
gem_name = "jdbc-#{name.to_s.downcase}"; matched_gem_paths = []
Gem.paths.path.each do |path|
base_path = File.join(path, "gems/")
Dir.glob(File.join(base_path, "*")).each do |gem_path|
if gem_path.sub(base_path, '').start_with?(gem_name)
matched_gem_paths << gem_path
end
end
end
if gem_path = matched_gem_paths.sort.last
driver_jars << Dir.glob(File.join(gem_path, 'lib/*.jar')).sort.last
end
end
end
driver_jars
end
get_driver_jars_maven = lambda do
require 'jar_dependencies'
requirements = gemspec.call.requirements
match_driver_jars = lambda do
matched_jars = []
gemspec.call.requirements.each do |requirement|
if match = requirement.match(/^jar\s+([\w\-\.]+):([\w\-]+),\s+?([\w\.\-]+)?/)
matched_jar = Jars.send :to_jar, match[1], match[2], match[3], nil
matched_jar = File.join( Jars.home, matched_jar )
matched_jars << matched_jar if File.exists?( matched_jar )
end
end
matched_jars
end
driver_jars = match_driver_jars.call
if driver_jars.size < requirements.size
if (ENV['JARS_SKIP'] || ENV_JAVA['jars.skip']) == 'true'
warn "jar resolving skipped, extension might not compile"
else
require 'jars/installer'
ENV['JARS_QUIET'] = 'true'
puts "resolving jar dependencies to build extension (should only happen once) ..."
installer = Jars::Installer.new( gemspec_path )
installer.install_jars( false )
driver_jars = match_driver_jars.call
end
end
driver_jars
end
# TODO not good but since jar-dependencies doesn't do the job, let's default to local (for now)
if ENV['BUILD_EXT_MAVEN'] == 'true' # || ENV['RUBYARCHDIR']
driver_jars = get_driver_jars_maven.call
else
driver_jars = get_driver_jars_local.call
end
classpath = []
[ 'java.class.path', 'sun.boot.class.path' ].map { |key| ENV_JAVA[key] }.each do |v|
classpath += v.split(File::PATH_SEPARATOR).find_all { |jar| jar =~ /jruby/i } if v
end
# Using Java 9+. Let's try and infer jruby.jar location from rbconfig
if classpath.empty?; require 'rbconfig'
libdir = RbConfig::CONFIG['libdir']
if libdir.start_with? 'classpath:'
error "Cannot build activerecord-jdbc with jruby-complete"
end
classpath << File.join(libdir, 'jruby.jar')
end
classpath += driver_jars
classpath = classpath.compact.join(File::PATH_SEPARATOR)
source_files = FileList[ 'src/java/**/*.java' ]
version = lambda do
begin
require 'arjdbc/version'
rescue LoadError
path = File.expand_path('lib', File.dirname(__FILE__))
unless $LOAD_PATH.include?(path)
$LOAD_PATH << path; retry
end
end
gem_version = Gem::Version.create(ArJdbc::VERSION)
if gem_version.segments.last == 'DEV'
gem_version.segments[0...-1] # 50.0.DEV -> 50.0
else
gem_version.segments.dup
end
end
require 'tmpdir'; Dir.mktmpdir do |classes_dir|
# Cross-platform way of finding an executable in the $PATH. Thanks to @mislav
which = lambda do |cmd|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
ENV['PATH'].split(File::PATH_SEPARATOR).map do |path|
exts.map { |ext| File.join(path, "#{cmd}#{ext}") }
end.flatten.select{|f| File.executable? f}.first
end
args = [ '-Xlint:unchecked' ]
unless javac = which.call('javac')
warn "could not find javac, please make sure it's on the PATH"
end
javac = "#{javac} -target #{target} -source #{source} #{args.join(' ')}"
javac << " #{debug ? '-g' : ''}"
javac << " -cp \"#{classpath}\" -d #{classes_dir} #{source_files.join(' ')}"
sh(javac) do |ok|
raise 'could not build .jar extension - compilation failure' unless ok
end
# class_files = FileList["#{classes_dir}/**/*.class"].gsub("#{classes_dir}/", '')
# avoid environment variable expansion using backslash
# class_files.gsub!('$', '\$') unless windows?
# args = class_files.map { |path| [ "-C #{classes_dir}", path ] }.flatten
if ENV['INCLUDE_JAR_IN_GEM'] == 'true'; require 'tempfile'
manifest = "Built-Time: #{Time.now.utc.strftime('%Y-%m-%d %H:%M:%S')}\n"
manifest += "Built-JRuby: #{JRUBY_VERSION}\n"
manifest += "Specification-Title: ActiveRecord-JDBC\n"
manifest += "Specification-Vendor: JRuby\n"
manifest += "Specification-Version: #{version.call[0].to_s.split('').join('.')}\n" # AR VERSION (52 -> 5.2)
manifest += "Implementation-Vendor: The JRuby Team\n"
manifest += "Implementation-Version: #{version.call.join('.')}\n"
manifest = Tempfile.new('MANIFEST').tap { |f| f << manifest; f.close }.path
end
args = []; opts = '-cf'
if manifest
opts = "#{opts}m"
args = [ "#{manifest}" ]
end
args += [ '-C', "#{classes_dir}/ ." ]
jar_path = jar_file
if ext_lib_dir = ENV['RUBYLIBDIR']
jar_path = File.join(ext_lib_dir, File.basename(jar_file))
end
unless jar = which.call('jar')
warn "could not find jar tool, please make sure it's on the PATH"
end
sh("#{jar} #{opts} #{jar_path} #{args.join(' ')}") do |ok|
raise 'could not build .jar extension - packaging failure' unless ok
end
cp jar_path, jar_file if ext_lib_dir # NOTE: hopefully RG won't mind?!
end
end
else
task :jar do
warn "please run `rake jar' under JRuby to re-compile the native (Java) extension"
end
end