# Phusion Passenger - http://www.modrails.com/ # Copyright (C) 2008 Phusion # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. require 'pathname' # Provides useful extensions for Rake. module RakeExtensions # Allows one to define Rake rules in the context of the given # subdirectory. For example, # # subdir 'foo' do # file 'libfoo.so' => ['foo.c'] do # sh 'gcc foo.c -shared -fPIC -o libfoo.so' # end # end # # subdir 'bar' do # file 'bar' => ['bar.c', '../foo/libfoo.so'] do # sh 'gcc bar.c -o bar -L../foo -lfoo' # end # end # # is equivalent to: # # file 'foo/libfoo.so' => ['foo/foo.c'] do # Dir.chdir('foo') do # sh 'gcc foo.c -shared -fPIC -o libfoo.so' # end # end # # file 'bar/bar' => ['bar/bar.c', 'foo/libfoo.so'] do # Dir.chdir('bar') do # sh 'gcc bar.c -o bar -L../foo -lfoo' # end # end # # === String dependencies are assumed to be filenames # # But be careful with string dependencies. They are assumed to be filenames, # and will be automatically converted. For example: # # subdir 'foo' do # task 'super_app' => ['super_app:compile', 'super_app:unit_test'] # # task 'super_app:compile' do # ... # end # # task 'super_app:unit_test' do # ... # end # end # # will be treated like: # # subdir 'foo' do # # !!!!!!! # task 'super_app' => ['foo/super_app:compile', 'foo/super_app:unit_test'] # # task 'super_app:compile' do # ... # end # # task 'super_app:unit_test' do # ... # end # end # # To solve this, declare your dependencies as symbols: # # task 'super_app' => [:'super_app:compile', :'super_app:unit_test'] # # (note the leading ':' character) # # === Supported Rake commands # # Only the file and target Rake commands are supported. def subdir(dir, &block) subdir = Subdir.new(dir) Dir.chdir(dir) do subdir.instance_eval(&block) end end class Subdir # :nodoc: def initialize(dir) @dir = dir @toplevel_dir = Pathname.getwd end def file(args, &block) case args when String args = mangle_path(args) when Hash target = mangle_path(args.keys[0]) sources = mangle_path_or_path_array(args.values[0]) args = { target => sources } end Rake::FileTask.define_task(args) do puts "### In #{@dir}:" Dir.chdir(@dir) do Object.class_eval(&block) end puts "" end end def task(*args, &block) if !args.empty? && args[0].is_a?(Hash) target = args[0].keys[0] sources = mangle_path_or_path_array(args[0].values[0]) args[0] = { target => sources } end if block_given? Rake::Task.define_task(*args) do puts "### In #{@dir}:" Dir.chdir(@dir) do Object.class_eval(&block) end puts "" end else Rake::Task.define_task(*args) end end private def mangle_path(path) path = File.expand_path(path) return Pathname.new(path).relative_path_from(@toplevel_dir).to_s end def mangle_path_array(array) array = array.dup array.each_with_index do |item, i| if item.is_a?(String) array[i] = mangle_path(item) end end return array end def mangle_path_or_path_array(item) case item when String return mangle_path(item) when Array return mangle_path_array(item) else return item end end end end # module RakeExtensions Object.class_eval do include RakeExtensions end