diff options
Diffstat (limited to 'tasks/gem.rake')
-rw-r--r-- | tasks/gem.rake | 196 |
1 files changed, 196 insertions, 0 deletions
diff --git a/tasks/gem.rake b/tasks/gem.rake new file mode 100644 index 0000000..e5e5d13 --- /dev/null +++ b/tasks/gem.rake @@ -0,0 +1,196 @@ +# -*- coding: UTF-8 -*- +# +require 'find' +require 'rake/packagetask' +require 'rubygems/user_interaction' +require 'rubygems/builder' + +module Bones +class GemPackageTask < Rake::PackageTask + # Ruby GEM spec containing the metadata for this package. The + # name, version and package_files are automatically determined + # from the GEM spec and don't need to be explicitly provided. + # + attr_accessor :gem_spec + + # Tasks from the Bones gem directory + attr_reader :bones_files + + # Create a GEM Package task library. Automatically define the gem + # if a block is given. If no block is supplied, then +define+ + # needs to be called to define the task. + # + def initialize(gem_spec) + init(gem_spec) + yield self if block_given? + define if block_given? + end + + # Initialization tasks without the "yield self" or define + # operations. + # + def init(gem) + super(gem.name, gem.version) + @gem_spec = gem + @package_files += gem_spec.files if gem_spec.files + @bones_files = [] + + local_setup = File.join(Dir.pwd, %w[tasks setup.rb]) + if !test(?e, local_setup) + Dir.glob(::Bones.path(%w[lib bones tasks *])).each {|fn| bones_files << fn} + end + end + + # Create the Rake tasks and actions specified by this + # GemPackageTask. (+define+ is automatically called if a block is + # given to +new+). + # + def define + super + task :prereqs + task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"] + file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do + when_writing("Creating GEM") { + chdir(package_dir_path) do + Gem::Builder.new(gem_spec).build + verbose(true) { mv gem_file, "../#{gem_file}" } + end + } + end + + file package_dir_path => bones_files do + mkdir_p package_dir rescue nil + + gem_spec.files = (gem_spec.files + bones_files.map {|fn| File.join('tasks', File.basename(fn))}).sort + + bones_files.each do |fn| + base_fn = File.join('tasks', File.basename(fn)) + f = File.join(package_dir_path, base_fn) + fdir = File.dirname(f) + mkdir_p(fdir) if !File.exist?(fdir) + if File.directory?(fn) + mkdir_p(f) + else + raise "file name conflict for '#{base_fn}' (conflicts with '#{fn}')" if test(?e, f) + safe_ln(fn, f) + end + end + end + end + + def gem_file + if @gem_spec.platform == Gem::Platform::RUBY + "#{package_name}.gem" + else + "#{package_name}-#{@gem_spec.platform}.gem" + end + end +end # class GemPackageTask +end # module Bones + +namespace :gem do + + PROJ.gem._spec = Gem::Specification.new do |s| + s.name = PROJ.name + s.version = PROJ.version + s.summary = PROJ.summary + s.authors = Array(PROJ.authors) + s.email = PROJ.email + s.homepage = Array(PROJ.url).first + s.rubyforge_project = PROJ.rubyforge.name + + s.description = PROJ.description + + PROJ.gem.dependencies.each do |dep| + s.add_dependency(*dep) + end + + PROJ.gem.development_dependencies.each do |dep| + s.add_development_dependency(*dep) + end + + s.files = PROJ.gem.files + s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)} + s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/ + + s.bindir = 'bin' + dirs = Dir["{#{PROJ.libs.join(',')}}"] + s.require_paths = dirs unless dirs.empty? + + incl = Regexp.new(PROJ.rdoc.include.join('|')) + excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext] + excl = Regexp.new(excl.join('|')) + rdoc_files = PROJ.gem.files.find_all do |fn| + case fn + when excl; false + when incl; true + else false end + end + s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main] + s.extra_rdoc_files = rdoc_files + + if test ?f, PROJ.test.file + s.test_file = PROJ.test.file + else + s.test_files = PROJ.test.files.to_a + end + + # Do any extra stuff the user wants + PROJ.gem.extras.each do |msg, val| + case val + when Proc + val.call(s.send(msg)) + else + s.send "#{msg}=", val + end + end + end # Gem::Specification.new + + Bones::GemPackageTask.new(PROJ.gem._spec) do |pkg| + pkg.need_tar = PROJ.gem.need_tar + pkg.need_zip = PROJ.gem.need_zip + end + + desc 'Show information about the gem' + task :debug => 'gem:prereqs' do + puts PROJ.gem._spec.to_ruby + end + + desc 'Write the gemspec ' + task :spec => 'gem:prereqs' do + File.open("#{PROJ.name}.gemspec", 'w') do |f| + f.write PROJ.gem._spec.to_ruby + end + end + + desc 'Install the gem' + task :install => [:clobber, 'gem:package'] do + sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}" + # use this version of the command for rubygems > 1.0.0 + #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}" + end + + desc 'Uninstall the gem' + task :uninstall do + installed_list = Gem.source_index.find_name(PROJ.name) + if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then + sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}" + end + end + + desc 'Reinstall the gem' + task :reinstall => [:uninstall, :install] + + desc 'Cleanup the gem' + task :cleanup do + sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}" + end +end # namespace :gem + +desc 'Alias to gem:package' +task :gem => 'gem:package' + +task :clobber => 'gem:clobber_package' +remove_desc_for_task 'gem:clobber_package' + +# EOF |