diff options
| -rw-r--r-- | data/doc/sisu/CHANGELOG_v4 | 4 | ||||
| -rw-r--r-- | data/doc/sisu/CHANGELOG_v5 | 4 | ||||
| -rw-r--r-- | rbuild | 34 | ||||
| -rwxr-xr-x | sisu-install | 3088 | 
4 files changed, 22 insertions, 3108 deletions
| diff --git a/data/doc/sisu/CHANGELOG_v4 b/data/doc/sisu/CHANGELOG_v4 index f20d4b83..e1ca2f64 100644 --- a/data/doc/sisu/CHANGELOG_v4 +++ b/data/doc/sisu/CHANGELOG_v4 @@ -30,6 +30,10 @@ http://www.jus.uio.no/sisu/pkg/src/sisu_4.2.12.orig.tar.xz    sisu_4.2.12.orig.tar.xz    sisu_4.2.12-1.dsc +* rake (& rant) sisu installer +  * do less by default +  * removed rant generated sisu-install +  * sisu_manual, minor info addition  %% 4.2.11.orig.tar.xz (2013-11-05:44/2) diff --git a/data/doc/sisu/CHANGELOG_v5 b/data/doc/sisu/CHANGELOG_v5 index 5cb6573d..35f82417 100644 --- a/data/doc/sisu/CHANGELOG_v5 +++ b/data/doc/sisu/CHANGELOG_v5 @@ -30,6 +30,10 @@ http://www.jus.uio.no/sisu/pkg/src/sisu_5.0.25.orig.tar.xz    sisu_5.0.25.orig.tar.xz    sisu_5.0.25-1.dsc +* rake (& rant) sisu installer +  * do less by default +  * removed rant generated sisu-install +  * sisu_manual, minor info addition  %% 5.0.24.orig.tar.xz (2013-11-05:44/2) @@ -29,8 +29,6 @@ raise 'Please, use ruby1.9.3 or later.' if RUBY_VERSION < '1.9.3'       rake -T     [if rant is preferred and installed]       rant -T -   [else [if sisu-install is present]] -     ruby sisu-install -T   SiSU can also be Setup/Installation using:   * Minero Aoki's setup.rb, provided along with SiSU, or @@ -106,7 +104,7 @@ class Project_details    def version      stamp={}      v="#{dir.pwd}/conf/sisu/version.yml" -    version=if File.exist?(v) +    if File.exist?(v)        stamp=YAML::load(File::open(v))        stamp[:version]      else '' @@ -119,7 +117,7 @@ def answer?(ask)    print ask + " ['yes', 'no' or 'quit']: "    resp=File.new('/dev/tty').gets.strip    #resp=gets.strip -  ans=if resp == 'yes'; true +  if resp == 'yes'; true    elsif resp == 'no'; false    elsif resp =~/^quit|exit$/; exit    else puts "[please type: 'yes', 'no' or 'quit']" @@ -129,13 +127,9 @@ end  def default_notice    ans= %{#{@p.rake_rant}    Information on alternative actions is available using: -  [if rake is installed:] -    "rake help" or "rake -T" -  [if rant is installed:] -    "rant help" or "rant -T" -  [else [if sisu-install is present]:] -    "sisu-install help" or "sisu-install -T" -  Default action selected - "install and to setup #{@p.name}" proceed? } +  [if rake (or rant) is installed:] +    "rake help" or "rake -T" (or "rant help" or "rant -T") +  Default action selected - "install #{@p.name}" proceed? }    resp=answer?(ans)    exit unless resp  end @@ -217,23 +211,23 @@ def project_help  Commands quick start list -  #{@p.name} Rake/Rant Help: (This Rakefile or Rantfile uses the same directory structure as setup.rb) +  #{@p.name} Rake/Rant Help: (Rakefile or Rantfile)      rake -T or rant -T          # a task list, (generated by Rake or Rant) for more complete and up to date help      rake system or rant system  # system info used    Quick start install and remove project #{@p.name}     as root:      rake or rant                                # install #{@p.name} +    rake base -    rake setup or rant setup                    # install #{@p.name} (without additonal configuration and generating of test file) +    rake setup                                  # install #{@p.name} (larger install) -    rake install or rant reinstall              # reinstall #{@p.name} +    rake install                                # reinstall #{@p.name} -    rake remove or rant remove                  # clobber/remove #{@p.name}, current version: #{@p.version} -    rake remove_package or rant remove_package  # clobber/remove #{@p.name}, all versions - -For a more detailed and up to date list of command options use +    rake remove                                 # clobber/remove #{@p.name}, current version: #{@p.version} +    rake remove_package                         # clobber/remove #{@p.name}, all versions +For a more detailed and up to date list of command options use:    rake -T    rant -T @@ -242,9 +236,9 @@ end  def tasks    sys('rant -T')  end -                                                           #%% tasks +                                                           #% tasks  desc "rake/rant (as root type 'rake' or 'rant' for default action)" -task :default => [:default_notice,:project] +task :default => [:default_notice,:setup_base]  #task :default => [:help,:notice,:project]  desc "Setup/Install #{@p.name} and try generate a file"  task :project=> [:setup_bin,:setup_lib,:setup_conf,:setup_share,:setup_data,:setup_man,:setup_vim,:post_install_note] diff --git a/sisu-install b/sisu-install deleted file mode 100755 index 206867fd..00000000 --- a/sisu-install +++ /dev/null @@ -1,3088 +0,0 @@ -#!/usr/bin/env ruby - -# sisu-install - Monolithic rant script, autogenerated by rant-import 0.5.8. -# -# Copyright (C) 2005 Stefan Lang <langstefan@gmx.at> -# -# This program is free software. -# You can distribute/modify this program under the terms of -# the GNU LGPL, Lesser General Public License version 2.1. - - -require 'getoptlong' - - -require 'rbconfig' - -unless Process::Status.method_defined?(:success?) # new in 1.8.2 -    class Process::Status -        def success?; exitstatus == 0; end -    end -end -unless Regexp.respond_to? :union # new in 1.8.1 -    def Regexp.union(*patterns) -        return /(?!)/ if patterns.empty? -        Regexp.new(patterns.join("|")) -    end -end -if RUBY_VERSION < "1.8.2" -    class Array -        undef_method :flatten, :flatten! -        def flatten -            cp = self.dup -            cp.flatten! -            cp -        end -        def flatten! -            res = [] -            flattened = false -            self.each { |e| -                if e.respond_to? :to_ary -                    res.concat(e.to_ary) -                    flattened = true -                else -                    res << e -                end -            } -            if flattened -                replace(res) -                flatten! -                self -            end -        end -    end -end - -class String -    def _rant_sub_ext(ext, new_ext = nil) -        if new_ext -            self.sub(/#{Regexp.escape ext}$/, new_ext) -        else -            self.sub(/(\.[^.]*$)|$/, ".#{ext}") -        end -    end -end - -module Rant -    VERSION = '0.5.8' - -    @__rant_no_value__ = Object.new.freeze -    def self.__rant_no_value__ -	@__rant_no_value__ -    end - -    module Env -        OS = ::Config::CONFIG['target'] -        RUBY = ::Config::CONFIG['ruby_install_name'] -        RUBY_BINDIR = ::Config::CONFIG['bindir'] -        RUBY_EXE = File.join(RUBY_BINDIR, RUBY + ::Config::CONFIG["EXEEXT"]) - -        @@zip_bin = false -        @@tar_bin = false - -        if OS =~ /mswin/i -            def on_windows?; true; end -        else -            def on_windows?; false; end -        end - -        def have_zip? -            if @@zip_bin == false -                @@zip_bin = find_bin "zip" -            end -            !@@zip_bin.nil? -        end -        def have_tar? -            if @@tar_bin == false -                @@tar_bin = find_bin "tar" -            end -            !@@tar_bin.nil? -        end -        def pathes -            path = ENV[on_windows? ? "Path" : "PATH"] -            return [] unless path -            path.split(on_windows? ? ";" : ":") -        end -        def find_bin bin_name -            if on_windows? -                bin_name_exe = nil -                if bin_name !~ /\.[^\.]{1,3}$/i -                    bin_name_exe = bin_name + ".exe" -                end -                pathes.each { |dir| -                    file = File.join(dir, bin_name) -                    return file if test(?f, file) -                    if bin_name_exe -                        file = File.join(dir, bin_name_exe) -                        return file if test(?f, file) -                    end -                } -            else -                pathes.each { |dir| -                    file = File.join(dir, bin_name) -                    return file if test(?x, file) -                } -            end -            nil -        end -        def shell_path path -            if on_windows? -                path = path.tr("/", "\\") -                if path.include? ' ' -                    '"' + path + '"' -                else -                    path -                end -            else -                if path.include? ' ' -                    "'" + path + "'" -                else -                    path -                end -            end -        end -        extend self -    end # module Env - -    module Sys -	def sp(arg) -            if arg.respond_to? :to_ary -                arg.to_ary.map{ |e| sp e }.join(' ') -            else -                _escaped_path arg -            end -	end -        def escape(arg) -            if arg.respond_to? :to_ary -                arg.to_ary.map{ |e| escape e }.join(' ') -            else -                _escaped arg -            end -        end -        if Env.on_windows? -            def _escaped_path(path) -		_escaped(path.to_s.tr("/", "\\")) -            end -            def _escaped(arg) -		sarg = arg.to_s -		return sarg unless sarg.include?(" ") -		sarg << "\\" if sarg[-1].chr == "\\" -                "\"#{sarg}\"" -            end -            def regular_filename(fn) -                fn.to_str.tr("\\", "/").gsub(%r{/{2,}}, "/") -            end -        else -            def _escaped_path(path) -                path.to_s.gsub(/(?=\s)/, "\\") -            end -            alias _escaped _escaped_path -            def regular_filename(fn) -                fn.to_str.gsub(%r{/{2,}}, "/") -            end -        end -        private :_escaped_path -        private :_escaped -	def split_all(path) -            names = regular_filename(path).split(%r{/}) -            names[0] = "/" if names[0] && names[0].empty? -            names -	end -        extend self -    end # module Sys - - -    ROOT_RANTFILE = "root.rant" -    SUB_RANTFILE = "sub.rant" -    RANTFILES = [ "Rantfile", "rantfile", ROOT_RANTFILE ] - -    CODE_IMPORTS = [] - -    class RantAbortException < StandardError -    end - -    class RantDoneException < StandardError -    end - -    class Error < StandardError -    end - -    module Generators -    end - -    module RantVar - -	class Error < Rant::Error -	end - -	class ConstraintError < Error - -	    attr_reader :constraint, :val - -	    def initialize(constraint, val, msg = nil) -		@msg = msg -		@constraint = constraint -		@val = val -	    end - -	    def message -		val_desc = @val.inspect -		val_desc[7..-1] = "..." if val_desc.length > 10 -		"#{val_desc} doesn't match constraint: #@constraint" -	    end -	end - -	class NotAConstraintFactoryError < Error -	    attr_reader :obj -	    def initialize(obj, msg = nil) -		@msg = msg -		@obj = obj -	    end -	    def message -		obj_desc = @obj.inspect -		obj_desc[7..-1] = "..." if obj_desc.length > 10 -		"#{obj_desc} is not a valid constraint factory" -	    end -	end - -	class InvalidVidError < Error -	    def initialize(vid, msg = nil) -		@msg = msg -		@vid = vid -	    end -	    def message -		vid_desc = @vid.inspect -		vid_desc[7..-1] = "..." if vid_desc.length > 10 -		"#{vid_desc} is not a valid var identifier" -	    end -	end - -	class InvalidConstraintError < Error -	end - -	class QueryError < Error -	end - -	class Space - -	    @@env_ref = Object.new - -	    def initialize -		@store = {} -		@constraints = {} -	    end - -	    def query(*args, &block) -		case args.size -		when 0 -		    raise QueryError, "no arguments", caller -		when 1 -		    arg = args.first -		    if Hash === arg -			if arg.size == 1 -			    arg.each { |k,v| -				self[k] = v if self[k].nil? -			    } -			    self -			else -			    init_all arg -			end -		    else -			self[arg] -		    end -		when 2, 3 -		    vid, cf, val = *args -                    constrain vid, -                        get_factory(cf).rant_constraint -		    self[vid] = val if val -		else -		    raise QueryError, "too many arguments" -		end -	    end - -	    def restrict vid, ct, *ct_args -		if vid.respond_to? :to_ary -		    vid.to_ary.each { |v| restrict(v, ct, *ct_args) } -		else -		    constrain vid, -			get_factory(ct).rant_constraint(*ct_args) -		end -		self -	    end - -	    def get_factory id -		if String === id || Symbol === id -                    id = Constraints.const_get(id) rescue nil -		end -		unless id.respond_to? :rant_constraint -                    raise NotAConstraintFactoryError.new(id), caller -		end -		id -	    end -	    private :get_factory - -	    def [](vid) -		vid = RantVar.valid_vid vid -		val = @store[vid] -		val.equal?(@@env_ref) ? ENV[vid] : val -	    end - -	    def []=(vid, val) -		vid = RantVar.valid_vid(vid) -		c = @constraints[vid] -		if @store[vid] == @@env_ref -		    ENV[vid] = c ? c.filter(val) : val -		else -		    @store[vid] = c ? c.filter(val) : val -		end -	    end - -	    def env(*vars) -		vars.flatten.each { |var| -		    vid = RantVar.valid_vid(var) -		    cur_val = @store[vid] -		    next if cur_val == @@env_ref -		    ENV[vid] = cur_val unless cur_val.nil? -		    @store[vid] = @@env_ref -		} -		nil -	    end - -	    def set_all hash -		unless Hash === hash -		    raise QueryError, -			"set_all argument has to be a hash" -		end -		hash.each_pair { |k, v| -		    self[k] = v -		} -	    end - -	    def init_all hash -		unless Hash === hash -		    raise QueryError, -			"init_all argument has to be a hash" -		end -		hash.each_pair { |k, v| -		    self[k] = v if self[k].nil? -		} -	    end - -	    def constrain vid, constraint -		vid = RantVar.valid_vid(vid) -		unless RantVar.valid_constraint? constraint -		    raise InvalidConstraintError, constraint -		end -		@constraints[vid] = constraint -		if @store.member? vid -		    begin -			val = @store[vid] -			@store[vid] = constraint.filter(@store[vid]) -		    rescue -			@store[vid] = constraint.default -			raise ConstraintError.new(constraint, val) -		    end -		else -		    @store[vid] = constraint.default -		end -	    end - -	    def has_var?(vid) -		!self[vid].nil? -	    end - -            def _set(vid, val) #:nodoc: -                @store[vid] = val -            end - -            def _get(vid) #:nodoc: -                @store[vid] -            end - -            def _init(vid, val) #:nodoc: -                @store[vid] ||= val -            end - -	end	# class Space - -	module Constraint -	    def matches? val -		filter val -		true -	    rescue -		return false -	    end -	end - -	def valid_vid(obj) -	    case obj -	    when String; obj -	    when Symbol; obj.to_s -	    else -		if obj.respond_to? :to_str -		    obj.to_str -		else -		    raise InvalidVidError.new(obj) -		end -	    end -	end - -	def valid_constraint?(obj) -	    obj.respond_to?(:filter) && -		obj.respond_to?(:matches?) && -		obj.respond_to?(:default) -	end - -	module_function :valid_constraint?, :valid_vid - -	module Constraints -	    class AutoList -		include Constraint -		class << self -		    alias rant_constraint new -		end -		def filter(val) -		    if val.respond_to? :to_ary -			val.to_ary -		    elsif val.nil? -			raise ConstraintError.new(self, val) -		    else -			[val] -		    end -		end -		def default -		    [] -		end -		def to_s -		    "list or single, non-nil value" -		end -	    end -        end # module Constraints -    end # module RantVar -end # module Rant - - -require 'fileutils' - - -module Rant -    def FileList(arg) -        if arg.respond_to?(:to_rant_filelist) -            arg.to_rant_filelist -        elsif arg.respond_to?(:to_ary) -            FileList.new(arg.to_ary) -        else -            raise TypeError, -                "cannot convert #{arg.class} into Rant::FileList" -        end -    end -    module_function :FileList -    class FileList -        include Enumerable - -        ESC_SEPARATOR = Regexp.escape(File::SEPARATOR) -        ESC_ALT_SEPARATOR = File::ALT_SEPARATOR ? -            Regexp.escape(File::ALT_SEPARATOR) : nil - -        class << self -            def [](*patterns) -                new.hide_dotfiles.include(*patterns) -            end -            def glob(*patterns) -                fl = new.hide_dotfiles.ignore(".", "..").include(*patterns) -                if block_given? then yield fl else fl end -            end -            def glob_all(*patterns) -                fl = new.ignore(".", "..").include(*patterns) -                if block_given? then yield fl else fl end -            end -        end - -        def initialize(store = []) -            @pending = false -            @def_glob_dotfiles = true -            @items = store -            @ignore_rx = nil -            @keep = {} -            @actions = [] -        end -        alias _object_dup dup -        private :_object_dup -        def dup -            c = _object_dup -            c.items = @items.dup -            c.actions = @actions.dup -            c.ignore_rx = @ignore_rx.dup if @ignore_rx -            c.instance_variable_set(:@keep, @keep.dup) -            c -        end -        def copy -            c = _object_dup -            c.items = @items.map { |entry| entry.dup } -            c.actions = @actions.dup -            c.ignore_rx = @ignore_rx.dup if @ignore_rx -            h_keep = {} -            @keep.each_key { |entry| h_keep[entry] = true } -            c.instance_variable_set(:@keep, h_keep) -            c -        end -        def glob_dotfiles? -            @def_glob_dotfiles -        end -        def glob_dotfiles=(flag) -            @def_glob_dotfiles = flag ? true : false -        end -        def hide_dotfiles -            @def_glob_dotfiles = false -            self -        end -        def glob_dotfiles -            @def_glob_dotfiles = true -            self -        end - -        protected -        attr_accessor :actions, :items -        attr_accessor :pending -        attr_accessor :ignore_rx - -        public -        def each(&block) -            resolve if @pending -            @items.each(&block) -            self -        end -        def to_ary -            resolve if @pending -            @items -        end -        alias to_a to_ary -        alias entries to_ary    # entries: defined in Enumerable -        def to_rant_filelist -            self -        end -        def +(other) -            if other.respond_to? :to_rant_filelist -                c = other.to_rant_filelist.dup -                c.actions.concat(@actions) -                c.items.concat(@items) -                c.pending = !c.actions.empty? -                c -            elsif other.respond_to? :to_ary -                c = dup -                c.actions << -                    [:apply_ary_method_1, :concat, other.to_ary.dup] -                c.pending = true -                c -            else -                raise TypeError, -                    "cannot add #{other.class} to Rant::FileList" -            end -        end -        def <<(file) -            @actions << [:apply_ary_method_1, :push, file] -            @keep[file] = true -            @pending = true -            self -        end -        def keep(entry) -            @keep[entry] = true -            @items << entry -            self -        end -        def concat(ary) -            if @pending -                ary = ary.to_ary.dup -                @actions << [:apply_ary_method_1, :concat, ary] -            else -                ix = ignore_rx and ary = ary.to_ary.reject { |f| f =~ ix } -                @items.concat(ary) -            end -            self -        end -        def size -            resolve if @pending -            @items.size -        end -        alias length size -        def empty? -            resolve if @pending -            @items.empty? -        end -        def join(sep = ' ') -            resolve if @pending -            @items.join(sep) -        end -        def pop -            resolve if @pending -            @items.pop -        end -        def push(entry) -            resolve if @pending -            @items.push(entry) if entry !~ ignore_rx -            self -        end -        def shift -            resolve if @pending -            @items.shift -        end -        def unshift(entry) -            resolve if @pending -            @items.unshift(entry) if entry !~ ignore_rx -            self -        end -        if Object.method_defined?(:fcall) || Object.method_defined?(:funcall) # in Ruby 1.9 like __send__ -          @@__send_private__ = Object.method_defined?(:fcall) ? :fcall : :funcall -          def resolve -              @pending = false -              @actions.each{ |action| self.__send__(@@__send_private__, *action) }.clear -              ix = ignore_rx -              if ix -                  @items.reject! { |f| f =~ ix && !@keep[f] } -              end -              self -          end -        else -          def resolve -              @pending = false -              @actions.each{ |action| self.__send__(*action) }.clear -              ix = ignore_rx -              if ix -                  @items.reject! { |f| f =~ ix && !@keep[f] } -              end -              self -          end -        end -        def include(*pats) -            @def_glob_dotfiles ? glob_all(*pats) : glob_unix(*pats) -        end -        alias glob include -        def glob_unix(*patterns) -            patterns.flatten.each { |pat| -                @actions << [:apply_glob_unix, pat] -            } -            @pending = true -            self -        end -        def glob_all(*patterns) -            patterns.flatten.each { |pat| -                @actions << [:apply_glob_all, pat] -            } -            @pending = true -            self -        end -        if RUBY_VERSION < "1.8.2" -            FN_DOTFILE_RX_ = ESC_ALT_SEPARATOR ? -                /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)\..* -                    ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x : -                /(^|#{ESC_SEPARATOR}+)\..* (#{ESC_SEPARATOR}+|$)/x -            def apply_glob_unix(pattern) -                inc_files = Dir.glob(pattern) -                unless pattern =~ /(^|\/)\./ -                    inc_files.reject! { |fn| fn =~ FN_DOTFILE_RX_ } -                end -                @items.concat(inc_files) -            end -        else -            def apply_glob_unix(pattern) -                @items.concat(Dir.glob(pattern)) -            end -        end -        private :apply_glob_unix -        def apply_glob_all(pattern) -            @items.concat(Dir.glob(pattern, File::FNM_DOTMATCH)) -        end -        private :apply_glob_all -        def exclude(*patterns) -            patterns.each { |pat| -                if Regexp === pat -                    @actions << [:apply_exclude_rx, pat] -                else -                    @actions << [:apply_exclude, pat] -                end -            } -            @pending = true -            self -        end -        def ignore(*patterns) -            patterns.each { |pat| -                add_ignore_rx(Regexp === pat ? pat : mk_all_rx(pat)) -            } -            @pending = true -            self -        end -        def add_ignore_rx(rx) -            @ignore_rx = -            if @ignore_rx -                Regexp.union(@ignore_rx, rx) -            else -                rx -            end -        end -        private :add_ignore_rx -        def apply_exclude(pattern) -            @items.reject! { |elem| -                File.fnmatch?(pattern, elem, File::FNM_DOTMATCH) && !@keep[elem] -            } -        end -        private :apply_exclude -        def apply_exclude_rx(rx) -            @items.reject! { |elem| -                elem =~ rx && !@keep[elem] -            } -        end -        private :apply_exclude_rx -        def exclude_name(*names) -            names.each { |name| -                @actions << [:apply_exclude_rx, mk_all_rx(name)] -            } -            @pending = true -            self -        end -        alias shun exclude_name -        if File::ALT_SEPARATOR -            def mk_all_rx(file) -                /(^|(#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+)#{Regexp.escape(file)} -                    ((#{ESC_SEPARATOR}|#{ESC_ALT_SEPARATOR})+|$)/x -            end -        else -            def mk_all_rx(file) -                /(^|#{ESC_SEPARATOR}+)#{Regexp.escape(file)} -                    (#{ESC_SEPARATOR}+|$)/x -            end -        end -        private :mk_all_rx -        def exclude_path(*patterns) -            patterns.each { |pat| -                @actions << [:apply_exclude_path, pat] -            } -            @pending = true -            self -        end -        def apply_exclude_path(pattern) -            flags = File::FNM_DOTMATCH|File::FNM_PATHNAME -            @items.reject! { |elem| -                File.fnmatch?(pattern, elem, flags) && !@keep[elem] -            } -        end -        private :apply_exclude -        def select(&block) -            d = dup -            d.actions << [:apply_select, block] -            d.pending = true -            d -        end -        alias find_all select -        def apply_select blk -            @items = @items.select(&blk) -        end -        private :apply_select -        def map(&block) -            d = dup -            d.actions << [:apply_ary_method, :map!, block] -            d.pending = true -            d -        end -        alias collect map -        def sub_ext(ext, new_ext=nil) -            map { |f| f._rant_sub_ext ext, new_ext } -        end -        def ext(ext_str) -            sub_ext(ext_str) -        end -        def arglist -            Rant::Sys.sp to_ary -        end -        alias to_s arglist -        alias object_inspect inspect -        def uniq! -            @actions << [:apply_ary_method, :uniq!] -            @pending = true -            self -        end -        def sort! -            @actions << [:apply_ary_method, :sort!] -            @pending = true -            self -        end -        def map!(&block) -            @actions << [:apply_ary_method, :map!, block] -            @pending = true -            self -        end -        def reject!(&block) -            @actions << [:apply_ary_method, :reject!, block] -            @pending = true -            self -        end -        private -        def apply_ary_method(meth, block=nil) -            @items.send meth, &block -        end -        def apply_ary_method_1(meth, arg1, block=nil) -            @items.send meth, arg1, &block -        end -    end # class FileList -end # module Rant - -if RUBY_VERSION == "1.8.3" -    module FileUtils -        METHODS = singleton_methods - %w(private_module_function -            commands options have_option? options_of collect_method) -        module Verbose -            class << self -                public(*::FileUtils::METHODS) -            end -            public(*::FileUtils::METHODS) -        end -    end -end - -if RUBY_VERSION < "1.8.1" -    module FileUtils -        undef_method :fu_list -        def fu_list(arg) -            arg.respond_to?(:to_ary) ? arg.to_ary : [arg] -        end -    end -end - -module Rant -    class RacFileList < FileList - -	attr_reader :subdir -	attr_reader :basedir - -	def initialize(rac, store = []) -	    super(store) -	    @rac = rac -	    @subdir = @rac.current_subdir -	    @basedir = Dir.pwd -	    @ignore_hash = nil -            @add_ignore_args = [] -	    update_ignore_rx -	end -        def dup -            c = super -            c.instance_variable_set( -                :@add_ignore_args, @add_ignore_args.dup) -            c -        end -        def copy -            c = super -            c.instance_variable_set( -                :@add_ignore_args, @add_ignore_args.map { |e| e.dup }) -            c -        end -        alias filelist_ignore ignore -        def ignore(*patterns) -            @add_ignore_args.concat patterns -            self -        end -	def ignore_rx -	    update_ignore_rx -	    @ignore_rx -	end -	alias filelist_resolve resolve -	def resolve -	    Sys.cd(@basedir) { filelist_resolve } -	end -	def each_cd(&block) -	    old_pwd = Dir.pwd -	    Sys.cd(@basedir) -	    filelist_resolve if @pending -	    @items.each(&block) -	ensure -	    Sys.cd(old_pwd) -	end -	private -	def update_ignore_rx -	    ri = @rac.var[:ignore] -            ri = ri ? (ri + @add_ignore_args) : @add_ignore_args -	    rh = ri.hash -	    unless rh == @ignore_hash -		@ignore_rx = nil -		filelist_ignore(*ri) -		@ignore_hash = rh -	    end -	end -    end	# class RacFileList - -    class MultiFileList - -	attr_reader :cur_list - -	def initialize(rac) -	    @rac = rac -	    @cur_list = RacFileList.new(@rac) -	    @lists = [@cur_list] -	end - -	def each_entry(&block) -	    @lists.each { |list| -		list.each_cd(&block) -	    } -	end - -	def add(filelist) -	    @cur_list = filelist -	    @lists << filelist -	    self -	end - -	def method_missing(sym, *args, &block) -	    if @cur_list && @cur_list.respond_to?(sym) -		if @cur_list.subdir == @rac.current_subdir -		    @cur_list.send(sym, *args, &block) -		else -		    add(RacFileList.new(@rac)) -		    @cur_list.send(sym, *args, &block) -		end -	    else -		super -	    end -	end -    end	# class MultiFileList - -    class CommandError < StandardError -	attr_reader :cmd -	attr_reader :status -	def initialize(cmd, status=nil, msg=nil) -	    @msg = msg -	    @cmd = cmd -	    @status = status -	end -	def message -	    if !@msg && cmd -		if status -		    "Command failed with status #{status.exitstatus}:\n" + -		    "[#{cmd}]" -		else -		    "Command failed:\n[#{cmd}]" -		end -	    else -		@msg -	    end -	end -    end - -    module Sys -	include ::FileUtils::Verbose - -	@symlink_supported = true -	class << self -	    attr_accessor :symlink_supported -	end - -	def fu_output_message(msg)	#:nodoc: -	end -        private :fu_output_message - -        def fu_each_src_dest(src, *rest) -            src = src.to_ary if src.respond_to? :to_ary -            super(src, *rest) -        end -        private :fu_each_src_dest - -	def sh(*cmd_args, &block) -	    cmd_args.flatten! -	    cmd = cmd_args.join(" ") -	    fu_output_message cmd -            success = system(*cmd_args) -	    if block_given? -                block[$?] -            elsif !success -		raise CommandError.new(cmd, $?) -	    end -	end - -	def ruby(*args, &block) -            if args.empty? -                sh(Env::RUBY_EXE, '', &block) -            else -                sh(args.unshift(Env::RUBY_EXE), &block) -            end -	end -        def cd(dir, &block) -            fu_output_message "cd #{dir}" -            orig_pwd = Dir.pwd -            Dir.chdir dir -            if block -                begin -                    block.arity == 0 ? block.call : block.call(Dir.pwd) -                ensure -                    fu_output_message "cd -" -                    Dir.chdir orig_pwd -                end -            else -                self -            end -        end - -	def safe_ln(src, dest) -            dest = dest.to_str -            src = src.respond_to?(:to_ary) ? src.to_ary : src.to_str -	    unless Sys.symlink_supported -		cp(src, dest) -	    else -		begin -		    ln(src, dest) -		rescue Exception # SystemCallError # Errno::EOPNOTSUPP -		    Sys.symlink_supported = false -		    cp(src, dest) -		end -	    end -	end - -        def ln_f(src, dest) -            ln(src, dest, :force => true) -        end - -        def split_path(str) -            str.split(Env.on_windows? ? ";" : ":") -        end - -        if Env.on_windows? -            def root_dir?(path) -                path == "/" || path == "\\" || -                    path =~ %r{\A[a-zA-Z]+:(\\|/)\Z} -            end -            def absolute_path?(path) -                path =~ %r{\A([a-zA-Z]+:)?(/|\\)} -            end -        else -            def root_dir?(path) -                path == "/" -            end -            def absolute_path?(path) -                path =~ %r{\A/} -            end -        end - -        extend self - -        if RUBY_VERSION >= "1.8.4"  # needed by 1.9.0, too -            class << self -                public(*::FileUtils::METHODS) -            end -            public(*::FileUtils::METHODS) -        end - -    end	# module Sys - -    class SysObject -	include Sys -	def initialize(rant) -	    @rant = rant or -		raise ArgumentError, "rant application required" -	end -        def ignore(*patterns) -            @rant.var[:ignore].concat(patterns) -            nil -        end -        def filelist(arg = Rant.__rant_no_value__) -            if Rant.__rant_no_value__.equal?(arg) -                RacFileList.new(@rant) -            elsif arg.respond_to?(:to_rant_filelist) -                arg.to_rant_filelist -            elsif arg.respond_to?(:to_ary) -                RacFileList.new(@rant, arg.to_ary) -            else -                raise TypeError, -                    "cannot convert #{arg.class} into Rant::FileList" -            end -        end -	def [](*patterns) -	    RacFileList.new(@rant).hide_dotfiles.include(*patterns) -	end -	def glob(*patterns, &block) -	    fl = RacFileList.new(@rant).hide_dotfiles.include(*patterns) -            fl.ignore(".", "..") -            if block_given? then yield fl else fl end -	end -        def glob_all(*patterns, &block) -	    fl = RacFileList.new(@rant).include(*patterns) -            fl.ignore(".", "..") # use case: "*.*" as pattern -            if block_given? then yield fl else fl end -        end -        def expand_path(path) -            File.expand_path(@rant.project_to_fs_path(path)) -        end -	private -	def fu_output_message(cmd) -	    @rant.cmd_msg cmd -	end -    end - - -    class TaskFail < StandardError -	def initialize(task, orig, msg) -	    @task = task -	    @orig = orig -            @msg = msg -	end -        def exception -            self -        end -	def task -	    @task -	end -	def tname -	    @task ? @task.name : nil -	end -	def orig -	    @orig -	end -        def msg -            @msg -        end -    end - -    class Rantfile -	attr_reader :tasks, :path -	attr_accessor :project_subdir -	def initialize(path) -	    @path = path or raise ArgumentError, "path required" -	    @tasks = [] -	    @project_subdir = nil -	end -        alias to_s path -        alias to_str path -    end	# class Rantfile - -    module Node - -	INVOKE_OPT = {}.freeze - -	T0 = Time.at(0).freeze - -	attr_reader :name -	attr_reader :rac -	attr_accessor :description -	attr_accessor :rantfile -	attr_accessor :line_number -        attr_accessor :project_subdir - -	def initialize -	    @description = nil -	    @rantfile = nil -	    @line_number = nil -	    @run = false -            @project_subdir = "" -	    @success = nil -	end - -        def reference_name -            sd = rac.current_subdir -            case sd -            when ""; full_name -            when project_subdir; name -            else "@#{full_name}".sub(/^@#{Regexp.escape sd}\//, '') -            end -        end - -        alias to_s reference_name -        alias to_rant_target name - -	def full_name -	    sd = project_subdir -	    sd.empty? ? name : File.join(sd, name) -	end - -        def ch -            {:file => rantfile.to_str, :ln => line_number} -        end - -	def goto_task_home -	    @rac.goto_project_dir project_subdir -	end - -        def file_target? -            false -        end - -	def done? -	    @success -	end - -	def needed? -            invoke(:needed? => true) -	end - -	def run? -	    @run -	end - -	def invoke(opt = INVOKE_OPT) -	    return circular_dep if run? -	    @run = true -	    begin -		return !done? if opt[:needed?] -		self.run if !done? -                @success = true -	    ensure -		@run = false -	    end -	end - -	def fail msg = nil, orig = nil -            raise TaskFail.new(self, orig, msg) -	end - -	def each_target -	end - -        def has_actions? -            defined? @block and @block -        end - -        def dry_run -            text = "Executing #{name.dump}" -            text << " [NOOP]" unless has_actions? -            @rac.cmd_msg text -            action_descs.each { |ad| -                @rac.cmd_print "  - " -                @rac.cmd_msg ad.sub(/\n$/, '').gsub(/\n/, "\n    ") -            } -        end - -        private -	def run -	    goto_task_home -            return if @rac.running_task(self) -	    return unless has_actions? -            @receiver.pre_run(self) if defined? @receiver and @receiver -	    @block.arity == 0 ? @block.call : @block[self] if @block -	end - -        def action_descs -            descs = [] -            if defined? @receiver and @receiver -                descs.concat(@receiver.pre_action_descs) -            end -            @block ? descs << action_block_desc : descs -        end - -        def action_block_desc -            @block.inspect =~ /^#<Proc:[\da-z]+@(.+):(\d+)>$/i -            fn, ln = $1, $2 -            "Ruby Proc at #{fn.sub(/^#{Regexp.escape @rac.rootdir}\//, '')}:#{ln}" -        end - -	def circular_dep -	    rac.warn_msg "Circular dependency on task `#{full_name}'." -	    false -	end -    end	# module Node - - -    def self.init_import_nodes__default(rac, *rest) -        rac.node_factory = DefaultNodeFactory.new -    end - -    class DefaultNodeFactory -        def new_task(rac, name, pre, blk) -            Task.new(rac, name, pre, &blk) -        end -        def new_file(rac, name, pre, blk) -            FileTask.new(rac, name, pre, &blk) -        end -        def new_dir(rac, name, pre, blk) -            DirTask.new(rac, name, pre, &blk) -        end -        def new_source(rac, name, pre, blk) -            SourceNode.new(rac, name, pre, &blk) -        end -        def new_custom(rac, name, pre, blk) -            UserTask.new(rac, name, pre, &blk) -        end -        def new_auto_subfile(rac, name, pre, blk) -            AutoSubFileTask.new(rac, name, pre, &blk) -        end -    end - -    class Task -	include Node - -        attr_accessor :receiver - -	def initialize(rac, name, prerequisites = [], &block) -	    super() -	    @rac = rac or raise ArgumentError, "rac not given" -            @name = name or raise ArgumentError, "name not given" -	    @pre = prerequisites || [] -	    @pre_resolved = false -	    @block = block -	    @run = false -            @receiver = nil -	end - -	def prerequisites -	    @pre.collect { |pre| pre.to_s } -	end -	alias deps prerequisites - -	def source -	    @pre.first.to_s -	end - -	def has_actions? -            @block or @receiver && @receiver.has_pre_action? -	end - -	def <<(pre) -	    @pre_resolved = false -	    @pre << pre -	end - -	def invoked? -	    !@success.nil? -	end - -	def fail? -	    @success == false -	end - -	def enhance(deps = nil, &blk) -	    if deps -		@pre_resolved = false -		@pre.concat deps -	    end -	    if @block -		if blk -		    first_block = @block -		    @block = lambda { |t| -			first_block[t] -			blk[t] -		    } -		end -	    else -		@block = blk -	    end -	end - -	def invoke(opt = INVOKE_OPT) -	    return circular_dep if @run -	    @run = true -	    begin -		return if done? -		internal_invoke opt -	    ensure -		@run = false -	    end -	end - -	def internal_invoke(opt, ud_init = true) -	    goto_task_home -	    update = ud_init || opt[:force] -	    dep = nil -	    uf = false -	    each_dep { |dep| -		if dep.respond_to? :timestamp -		    handle_timestamped(dep, opt) && update = true -		elsif Node === dep -		    handle_node(dep, opt) && update = true -		else -		    dep, uf = handle_non_node(dep, opt) -		    uf && update = true -		    dep -		end -	    } -            if @receiver -                goto_task_home -                update = true if @receiver.update?(self) -            end -	    return update if opt[:needed?] -            run if update -	    @success = true -	    update -	rescue StandardError => e -	    @success = false -	    self.fail(nil, e) -	end -	private :internal_invoke - -	def handle_node(dep, opt) -	    dep.invoke opt -	end - -	def handle_timestamped(dep, opt) -	    dep.invoke opt -	end - -	def handle_non_node(dep, opt) -	    @rac.err_msg "Unknown task `#{dep}',", -		"referenced in `#{rantfile.path}', line #{@line_number}!" -	    self.fail -	end - -	def each_dep -	    t = nil -	    if @pre_resolved -		return @pre.each { |t| yield(t) } -	    end -	    my_full_name = full_name -	    my_project_subdir = project_subdir -	    @pre.map! { |t| -		if Node === t -		    if t.full_name == my_full_name -			nil -		    else -			yield(t) -			t -		    end -		else -		    t = t.to_s if Symbol === t -		    if t == my_full_name #TODO -			nil -		    else -			selection = @rac.resolve t, -					my_project_subdir -			if selection.empty? -			    yield(t) -			else -			    selection.each { |st| yield(st) } -			    selection -			end -		    end -		end -	    } -            if @pre.kind_of? Rant::FileList -                @pre.resolve -            else -                @pre.flatten! -                @pre.compact! -            end -	    @pre_resolved = true -	end -    end	# class Task - -    class UserTask < Task - -	def initialize(*args) -	    super -	    @block = nil -	    @needed = nil -            @target_files = nil -	    yield self if block_given? -	end - -	def act(&block) -	    @block = block -	end - -	def needed(&block) -	    @needed = block -	end - -        def file_target? -            @target_files and @target_files.include? @name -        end - -        def each_target(&block) -            goto_task_home -            @target_files.each(&block) if @target_files -        end - -        def file_target(*args) -            args.flatten! -            args << @name if args.empty? -            if @target_files -                @target_files.concat(args) -            else -                @target_files = args -            end -        end - -	def invoke(opt = INVOKE_OPT) -	    return circular_dep if @run -	    @run = true -	    begin -		return if done? -		internal_invoke(opt, ud_init_by_needed) -	    ensure -		@run = false -	    end -	end - -	private -	def ud_init_by_needed -	    if @needed -		goto_task_home -		@needed.arity == 0 ? @needed.call : @needed[self] -	    end -	end -    end	# class UserTask - -    class FileTask < Task - -	def initialize(*args) -	    super -	    @ts = T0 -	end - -        def file_target? -            true -        end - -	def invoke(opt = INVOKE_OPT) -	    return circular_dep if @run -	    @run = true -	    begin -		return if done? -		goto_task_home -		if File.exist? @name -		    @ts = File.mtime @name -		    internal_invoke opt, false -		else -		    @ts = T0 -		    internal_invoke opt, true -		end -	    ensure -		@run = false -	    end -	end - -	def timestamp(opt = INVOKE_OPT) -	    File.exist?(@name) ? File.mtime(@name) : T0 -	end - -        def handle_node(dep, opt) -            return true if dep.file_target? && dep.invoke(opt) -	    if File.exist? dep.name -                File.mtime(dep.name) > @ts -            elsif !dep.file_target? -		@rac.err_msg @rac.pos_text(rantfile.path, line_number), -		    "in prerequisites: no such file: `#{dep.full_name}'" -		self.fail -	    end -        end - -	def handle_timestamped(dep, opt) -	    return true if dep.invoke opt -	    dep.timestamp(opt) > @ts -	end - -	def handle_non_node(dep, opt) -            goto_task_home # !!?? -	    unless File.exist? dep -		@rac.err_msg @rac.pos_text(rantfile.path, line_number), -		    "in prerequisites: no such file or task: `#{dep}'" -		self.fail -	    end -	    [dep, File.mtime(dep) > @ts] -	end - -	def each_target -	    goto_task_home -	    yield name -	end -    end	# class FileTask - -    module AutoInvokeDirNode -	private -	def run -            goto_task_home -            return if @rac.running_task(self) -	    dir = File.dirname(name) -            @rac.build dir unless dir == "." || dir == "/" -            return unless @block -            @block.arity == 0 ? @block.call : @block[self] -	end -    end - -    class AutoSubFileTask < FileTask -        include AutoInvokeDirNode -    end - -    class DirTask < Task - -	def initialize(*args) -	    super -	    @ts = T0 -	    @isdir = nil -	end - -	def invoke(opt = INVOKE_OPT) -	    return circular_dep if @run -	    @run = true -	    begin -		return if done? -		goto_task_home -		@isdir = test(?d, @name) -		if @isdir -		    @ts = @block ? test(?M, @name) : Time.now -		    internal_invoke opt, false -		else -		    @ts = T0 -		    internal_invoke opt, true -		end -	    ensure -		@run = false -	    end -	end - -        def file_target? -            true -        end - -        def handle_node(dep, opt) -            return true if dep.file_target? && dep.invoke(opt) -	    if File.exist? dep.name -                File.mtime(dep.name) > @ts -            elsif !dep.file_target? -		@rac.err_msg @rac.pos_text(rantfile.path, line_number), -		    "in prerequisites: no such file: `#{dep.full_name}'" -		self.fail -	    end -        end - -	def handle_timestamped(dep, opt) -	    return @block if dep.invoke opt -	    @block && dep.timestamp(opt) > @ts -	end - -	def handle_non_node(dep, opt) -            goto_task_home -	    unless File.exist? dep -		@rac.err_msg @rac.pos_text(rantfile.path, line_number), -		    "in prerequisites: no such file or task: `#{dep}'" -		self.fail -	    end -	    [dep, @block && File.mtime(dep) > @ts] -	end - -	def run -            return if @rac.running_task(self) -	    @rac.sys.mkdir @name unless @isdir -	    if @block -		@block.arity == 0 ? @block.call : @block[self] -		goto_task_home -		@rac.sys.touch @name -	    end -	end - -	def each_target -	    goto_task_home -	    yield name -	end -    end	# class DirTask - -    class SourceNode -	include Node -	def initialize(rac, name, prerequisites = []) -	    super() -	    @rac = rac -	    @name = name or raise ArgumentError, "name not given" -	    @pre = prerequisites -	    @run = false -	    @ts = nil -	end -	def prerequisites -	    @pre -	end -	def timestamp(opt = INVOKE_OPT) -	    return @ts if @ts -	    goto_task_home -	    if File.exist?(@name) -		@ts = File.mtime @name -	    else -		rac.abort_at(ch, "SourceNode: no such file -- #@name") -	    end -	    sd = project_subdir -	    @pre.each { |f| -		nodes = rac.resolve f, sd -		if nodes.empty? -		    if File.exist? f -			mtime = File.mtime f -			@ts = mtime if mtime > @ts -		    else -			rac.abort_at(ch, -			    "SourceNode: no such file -- #{f}") -		    end -		else -		    nodes.each { |node| -                        node.invoke(opt) -			if node.respond_to? :timestamp -			    node_ts = node.timestamp(opt) -                            goto_task_home -			    @ts = node_ts if node_ts > @ts -			else -			    rac.abort_at(ch, -				"SourceNode can't depend on #{node.name}") -			end -		    } -		end -	    } -	    @ts -	end -	def invoke(opt = INVOKE_OPT) -	    false -	end -        def related_sources -            @pre -        end -    end # class SourceNode - -    module Generators -        class Task -	    def self.rant_gen(rac, ch, args, &block) -		unless args.size == 1 -		    rac.abort("Task takes only one argument " + -			"which has to be like one given to the " + -			"`task' function") -		end -		rac.prepare_task(args.first, nil, ch) { |name,pre,blk| -		    rac.node_factory.new_custom(rac, name, pre, block) -		} -	    end -        end -        class Directory -	    def self.rant_gen(rac, ch, args, &block) -		case args.size -		when 1 -		    name, pre = rac.normalize_task_arg(args.first, ch) -		    self.task(rac, ch, name, pre, &block) -		when 2 -		    basedir = args.shift -		    if basedir.respond_to? :to_str -			basedir = basedir.to_str -		    else -			rac.abort_at(ch, -			    "Directory: basedir argument has to be a string.") -		    end -		    name, pre = rac.normalize_task_arg(args.first, ch) -		    self.task(rac, ch, name, pre, basedir, &block) -		else -		    rac.abort_at(ch, "Directory takes one argument, " + -			"which should be like one given to the `task' command.") -		end -	    end - -	    def self.task(rac, ch, name, prerequisites=[], basedir=nil, &block) -		dirs = ::Rant::Sys.split_all(name) -		if dirs.empty? -		    rac.abort_at(ch, -			"Not a valid directory name: `#{name}'") -		end -		path = basedir -		last_task = nil -		task_block = nil -		desc_for_last = rac.pop_desc -		dirs.each { |dir| -                    pre = [path] -                    pre.compact! -		    if dir.equal?(dirs.last) -			rac.cx.desc desc_for_last - -                        dp = prerequisites.dup -                        pre.each { |elem| dp << elem } -                        pre = dp - -			task_block = block -		    end -		    path = path.nil? ? dir : File.join(path, dir) -		    last_task = rac.prepare_task({:__caller__ => ch, -			    path => pre}, task_block) { |name,pre,blk| -			rac.node_factory.new_dir(rac, name, pre, blk) -		    } -		} -		last_task -	    end -        end # class Directory -        class SourceNode -            def self.rant_gen(rac, ch, args) -                unless args.size == 1 -                    rac.abort_at(ch, "SourceNode takes one argument.") -                end -                if block_given? -                    rac.abort_at(ch, "SourceNode doesn't take a block.") -                end -                rac.prepare_task(args.first, nil, ch) { |name, pre, blk| -                    rac.node_factory.new_source(rac, name, pre, blk) -                } -            end -        end -	class Rule -	    def self.rant_gen(rac, ch, args, &block) -		unless args.size == 1 -		    rac.abort_at(ch, "Rule takes only one argument.") -		end -                rac.abort_at(ch, "Rule: block required.") unless block -		arg = args.first -		target = nil -		src_arg = nil -		if Symbol === arg -		    target = ".#{arg}" -		elsif arg.respond_to? :to_str -		    target = arg.to_str -		elsif Regexp === arg -		    target = arg -		elsif Hash === arg && arg.size == 1 -		    arg.each_pair { |target, src_arg| } -		    src_arg = src_arg.to_str if src_arg.respond_to? :to_str -		    target = target.to_str if target.respond_to? :to_str -		    src_arg = ".#{src_arg}" if Symbol === src_arg -		    target = ".#{target}" if Symbol === target -		else -		    rac.abort_at(ch, "Rule argument " + -			"has to be a hash with one key-value pair.") -		end -		esc_target = nil -		target_rx = case target -                    when String -                        esc_target = Regexp.escape(target) -                        /#{esc_target}$/ -                    when Regexp -                        target -                    else -		    rac.abort_at(ch, "rule target has " + -			"to be a string or regular expression") -		end -		src_proc = case src_arg -                    when String, Array -                        unless String === target -                            rac.abort(ch, "rule target has to be " + -                                  "a string if source is a string") -                        end -                        if src_arg.kind_of? String -                            lambda { |name| -                                name.sub(/#{esc_target}$/, src_arg) -                            } -                        else -                            lambda { |name| -                                src_arg.collect { |s_src| -                                    s_src = ".#{s_src}" if Symbol === s_src -                                    name.sub(/#{esc_target}$/, s_src) -                                } -                            } -                        end -                    when Proc; src_arg -                    when nil; lambda { |name| [] } -                    else -                        rac.abort_at(ch, "rule source has to be a " + -                            "String, Array or Proc") -                    end -                rac.resolve_hooks << -                    (block.arity == 2 ? Hook : FileHook).new( -                           rac, ch, target_rx, src_proc, block) -		nil -	    end -            class Hook -                attr_accessor :target_rx -                def initialize(rant, ch, target_rx, src_proc, block) -                    @rant = rant -                    @ch = ch -                    @target_rx = target_rx -                    @src_proc = src_proc -                    @block = block -                end -                def call(target, rel_project_dir) -		    if @target_rx =~ target -                        have_src = true -                        src = @src_proc[target] -                        if src.respond_to? :to_ary -                            have_src = src.to_ary.all? { |s| -                                have_src?(rel_project_dir, s) -                            } -                        else -                            have_src = have_src?(rel_project_dir, src) -                        end -                        if have_src -                            create_nodes(rel_project_dir, target, src) -                        end -                    end -                end -                alias [] call -                private -                def have_src?(rel_project_dir, name) -                    return true unless -                        @rant.rec_save_resolve(name, self, rel_project_dir).empty? -                    test(?e, @rant.abs_path(rel_project_dir, name)) -                end -                def create_nodes(rel_project_dir, target, deps) -                    @rant.goto_project_dir rel_project_dir -                    case nodes = @block[target, deps] -                    when Array; nodes -                    when Node; [nodes] -                    else -                        @rant.abort_at(@ch, "Block has to " + -                            "return Node or array of Nodes.") -                    end -                end -            end -            class FileHook < Hook -                private -                def have_src?(rel_project_dir, name) -                    test(?e, @rant.abs_path(rel_project_dir, name)) or -                        @rant.rec_save_resolve(name, self, rel_project_dir -                            ).any? { |t| t.file_target? } -                end -                def create_nodes(rel_project_dir, target, deps) -                    @rant.goto_project_dir rel_project_dir -                    t = @rant.file(:__caller__ => @ch, -                            target => deps, &@block) -                    [t] -                end -            end -	end # class Rule -	class Action -	    def self.rant_gen(rac, ch, args, &block) -                case args.size -                when 0 -                    unless (rac[:tasks] || rac[:stop_after_load]) -                        yield -                    end -                when 1 -                    rx = args.first -                    unless rx.kind_of? Regexp -                        rac.abort_at(ch, "Action: argument has " + -                            "to be a regular expression.") -                    end -                    rac.resolve_hooks << self.new(rac, block, rx) -                    nil -                else -                    rac.abort_at(ch, "Action: too many arguments.") -                end -	    end -            def initialize(rant, block, rx) -                @rant = rant -                @subdir = @rant.current_subdir -                @block = block -                @rx = rx -            end -            def call(target, rel_project_dir) -                if target =~ @rx -                    @rant.resolve_hooks.delete(self) -                    @rant.goto_project_dir @subdir -                    @block.call -                    @rant.resolve(target, rel_project_dir) -                end -            end -            alias [] call -	end -    end	# module Generators -end # module Rant - -Rant::MAIN_OBJECT = self - -class String -    alias sub_ext _rant_sub_ext -    def to_rant_target -        self -    end -end - -module Rant::Lib -    def parse_caller_elem(elem) -        return { :file => "", :ln => 0 } unless elem -        if elem =~ /^(.+):(\d+)(?::|$)/ -            { :file => $1, :ln => $2.to_i } -        else -            $stderr.puts "parse_caller_elem: #{elem.inspect}" -            { :file => elem, :ln => 0 } -        end - -    end -    module_function :parse_caller_elem -end # module Lib - -module Rant::Console -    RANT_PREFIX		= "rant: " -    ERROR_PREFIX	= "[ERROR] " -    WARN_PREFIX		= "[WARNING] " -    def msg_prefix -	if defined? @msg_prefix and @msg_prefix -	    @msg_prefix -	else -	    RANT_PREFIX -	end -    end -    def msg(*text) -        pre = msg_prefix -        $stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}" -    end -    def vmsg(importance, *text) -        msg(*text) if verbose >= importance -    end -    def err_msg(*text) -        pre = msg_prefix + ERROR_PREFIX -        $stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}" -    end -    def warn_msg(*text) -        pre = msg_prefix + WARN_PREFIX -        $stderr.puts "#{pre}#{text.join("\n" + ' ' * pre.length)}" -    end -    def ask_yes_no text -        $stderr.print msg_prefix + text + " [y|n] " -        case $stdin.readline -        when /y|yes/i; true -        when /n|no/i; false -        else -            $stderr.puts(' ' * msg_prefix.length + -                "Please answer with `yes' or `no'") -            ask_yes_no text -        end -    end -    def prompt text -        $stderr.print msg_prefix + text -        input = $stdin.readline -	input ? input.chomp : input -    end -    def option_listing opts -	rs = "" -	opts.each { |lopt, *opt_a| -	    if opt_a.size == 2 -		mode, desc = opt_a -	    else -		sopt, mode, desc = opt_a -	    end -	    next unless desc	# "private" option -	    optstr = "" -	    arg = nil -	    if mode != GetoptLong::NO_ARGUMENT -		if desc =~ /(\b[A-Z_]{2,}\b)/ -		    arg = $1 -		end -	    end -	    if lopt -		optstr << lopt -		if arg -		    optstr << " " << arg -		end -		optstr = optstr.ljust(30) -	    end -	    if sopt -		optstr << "   " unless optstr.empty? -		optstr << sopt -		if arg -		    optstr << " " << arg -		end -	    end -	    rs << "  #{optstr}\n" -	    rs << "      #{desc.split("\n").join("\n      ")}\n" -	} -	rs -    end -    extend self -end # module Rant::Console - -module RantContext -    include Rant::Generators - -    Env = Rant::Env -    FileList = Rant::FileList - -    def task(targ, &block) -	rant.task(targ, &block) -    end - -    def file(targ, &block) -	rant.file(targ, &block) -    end - -    def enhance(targ, &block) -	rant.enhance(targ, &block) -    end - -    def desc(*args) -	rant.desc(*args) -    end - -    def gen(*args, &block) -	rant.gen(*args, &block) -    end - -    def import(*args, &block) -	rant.import(*args, &block) -    end - -    def plugin(*args, &block) -	rant.plugin(*args, &block) -    end - -    def subdirs(*args) -	rant.subdirs(*args) -    end - -    def source(opt, rantfile = nil) -	rant.source(opt, rantfile) -    end - -    def sys(*args, &block) -	rant.sys(*args, &block) -    end - -    def var(*args, &block) -	rant.var(*args, &block) -    end - -    def make(*args, &block) -        rant.make(*args, &block) -    end - -end	# module RantContext - -class RantAppContext -    include RantContext - -    def initialize(app) -	@__rant__ = app -    end - -    def rant -        @__rant__ -    end - -    def method_missing(sym, *args) -	Rant::MAIN_OBJECT.send(sym, *args) -    rescue NoMethodError -	raise NameError, "NameError: undefined local " + -	    "variable or method `#{sym}' for main:Object", caller -    end -end - -module Rant - -    @__rant__ = nil -    class << self - -	def run(first_arg=nil, *other_args) -	    other_args = other_args.flatten -	    args = first_arg.nil? ? ARGV.dup : ([first_arg] + other_args) -	    if rant && !rant.run? -		rant.run(args.flatten) -	    else -                @__rant__ = Rant::RantApp.new -		rant.run(args) -	    end -	end - -	def rant -	    @__rant__ -	end -    end - -end # module Rant - -class Rant::RantApp -    include Rant::Console - -    class AutoLoadNodeFactory -        def initialize(rant) -            @rant = rant -        end -        def method_missing(sym, *args, &block) -            @rant.import "nodes/default" -            @rant.node_factory.send(sym, *args, &block) -        end -    end - - - -    OPTIONS	= [ -	[ "--help",	"-h",	GetoptLong::NO_ARGUMENT, -	    "Print this help and exit."				], -	[ "--version",	"-V",	GetoptLong::NO_ARGUMENT, -	    "Print version of Rant and exit."			], -	[ "--verbose",	"-v",	GetoptLong::NO_ARGUMENT, -	    "Print more messages to stderr."			], -	[ "--quiet",	"-q",	GetoptLong::NO_ARGUMENT, -	    "Don't print commands."			        ], -	[ "--err-commands",	GetoptLong::NO_ARGUMENT, -	    "Print failed commands and their exit status."	], -	[ "--directory","-C",	GetoptLong::REQUIRED_ARGUMENT, -	    "Run rant in DIRECTORY."				], -        [ "--cd-parent","-c",   GetoptLong::NO_ARGUMENT, -            "Run rant in parent directory with Rantfile."       ], -        [ "--look-up",  "-u",   GetoptLong::NO_ARGUMENT, -            "Look in parent directories for root Rantfile."     ], -	[ "--rantfile",	"-f",	GetoptLong::REQUIRED_ARGUMENT, -	    "Process RANTFILE instead of standard rantfiles.\n" + -	    "Multiple files may be specified with this option." ], -	[ "--force-run","-a",	GetoptLong::REQUIRED_ARGUMENT, -	    "Force rebuild of TARGET and all dependencies."     ], -        [ "--dry-run",  "-n",   GetoptLong::NO_ARGUMENT, -            "Print info instead of actually executing actions."  ], -	[ "--tasks",	"-T",	GetoptLong::NO_ARGUMENT, -	    "Show a list of all described tasks and exit."	], - - -        [ "--import",   "-i",   GetoptLong::REQUIRED_ARGUMENT, nil ], -	[ "--stop-after-load",	GetoptLong::NO_ARGUMENT, nil	], -	[ "--trace-abort",	GetoptLong::NO_ARGUMENT, nil	], -    ] - -    ROOT_DIR_ID = "@" -    ESCAPE_ID = "\\" - -    attr_reader :args -    attr_reader :rantfiles -    attr_reader :force_targets -    attr_reader :plugins -    attr_reader :context -    alias cx context -    attr_reader :tasks -    attr_reader :imports -    attr_reader :current_subdir -    attr_reader :resolve_hooks -    attr_reader :rootdir - -    attr_accessor :node_factory - -    def initialize -	@args = [] -	@context = RantAppContext.new(self) -	@sys = ::Rant::SysObject.new(self) -	@rantfiles = [] -	@tasks = {} -	@opts = { -	    :verbose        => 0, -	    :quiet          => false, -	} -        @rootdir = Dir.pwd      # root directory of project -	@arg_rantfiles = []	# rantfiles given in args -	@arg_targets = []	# targets given in args -	@force_targets = []     # targets given with -a option -	@run = false            # run method was called at least once -	@done = false           # run method was successful -	@plugins = [] -	@var = Rant::RantVar::Space.new -	@var.query :ignore, :AutoList, [] -	@imports = [] - -	@task_desc = nil -        @last_build_subdir = "" - -	@current_subdir = "" -	@resolve_hooks = [] - -        @node_factory = AutoLoadNodeFactory.new(self) -    end - -    def [](opt) -	@opts[opt] -    end - -    def []=(opt, val) -        @opts[opt] = val -    end - -    def expand_path(subdir, path) -	case path -	when nil;	subdir.dup -	when "";	subdir.dup -	when /^@/;	path.sub(/^@/, '') -	else -            path = path.sub(/^\\(?=@)/, '') -	    if subdir.empty? -		path -	    else -		File.join(subdir, path) -	    end -	end -    end -    def resolve_root_ref(path) -        return File.join(@rootdir, path[1..-1]) if path =~ /^@/ -        path.sub(/^\\(?=@)/, '') -    end -    def project_to_fs_path(path) -	sub = expand_path(@current_subdir, path) -	sub.empty? ? @rootdir : File.join(@rootdir, sub) -    end -    def abs_path(subdir, fn) -        return fn if Rant::Sys.absolute_path?(fn) -        path = File.join(@rootdir, subdir, fn) -        path.gsub!(%r{/+}, "/") -        path.sub!(%r{/$}, "") if path.length > 1 -        path -    end -    def goto(dir) -        goto_project_dir(expand_path(@current_subdir, dir)) -    end -    def goto_project_dir(dir='') -        @current_subdir = dir -        abs_path = @current_subdir.empty? ? -            @rootdir : File.join(@rootdir, @current_subdir) -	unless Dir.pwd == abs_path -	    Dir.chdir abs_path -	    vmsg 1, "in #{abs_path}" -	end -    end - -    def run? -	@run -    end - -    def done? -	@done -    end - -    def run(*args) -	@run = true -	@args.concat(args.flatten) -	orig_pwd = @rootdir = Dir.pwd -	process_args -        Dir.chdir(@rootdir) rescue abort $!.message -	load_rantfiles - -	raise Rant::RantDoneException if @opts[:stop_after_load] - -	@plugins.each { |plugin| plugin.rant_start } -	if @opts[:tasks] -	    show_descriptions -	    raise Rant::RantDoneException -	end -	run_tasks -	raise Rant::RantDoneException -    rescue Rant::RantDoneException -	@done = true -	@plugins.each { |plugin| plugin.rant_done } -	return 0 -    rescue Rant::RantAbortException -	$stderr.puts "rant aborted!" -	return 1 -    rescue Exception => e -	ch = get_ch_from_backtrace(e.backtrace) -	if ch && !@opts[:trace_abort] -	    err_msg(pos_text(ch[:file], ch[:ln]), e.message) -	else -	    err_msg e.message, e.backtrace[0..4] -	end -	$stderr.puts "rant aborted!" -	return 1 -    ensure -        Dir.chdir @rootdir if test ?d, @rootdir -        hooks = var._get("__at_return__") -        hooks.each { |hook| hook.call } if hooks -	@plugins.each { |plugin| plugin.rant_plugin_stop } -	@plugins.each { |plugin| plugin.rant_quit } -        Dir.chdir orig_pwd -    end - - -    def desc(*args) -	if args.empty? || (args.size == 1 && args.first.nil?) -	    @task_desc = nil -	else -	    @task_desc = args.join("\n") -	end -    end - -    def task(targ, &block) -	prepare_task(targ, block) { |name,pre,blk| -            @node_factory.new_task(self, name, pre, blk) -	} -    end - -    def file(targ, &block) -	prepare_task(targ, block) { |name,pre,blk| -            @node_factory.new_file(self, name, pre, blk) -	} -    end - -    def gen(*args, &block) -	ch = Rant::Lib::parse_caller_elem(caller[1]) -	generator = args.shift -	unless generator.respond_to? :rant_gen -	    abort_at(ch, -		"gen: First argument has to be a task-generator.") -	end -	generator.rant_gen(self, ch, args, &block) -    end - -    def import(*args, &block) -	ch = Rant::Lib::parse_caller_elem(caller[1]) -	if block -	    warn_msg pos_text(ch[:file], ch[:ln]), -		"import: ignoring block" -	end -	args.flatten.each { |arg| -	    unless String === arg -                abort_at(ch, "import: only strings allowed as arguments") -	    end -	    unless @imports.include? arg -		unless Rant::CODE_IMPORTS.include? arg -		    begin -			vmsg 2, "import #{arg}" -			require "rant/import/#{arg}" -		    rescue LoadError => e -			abort_at(ch, "No such import - #{arg}") -		    end -		    Rant::CODE_IMPORTS << arg.dup -		end -                init_msg = "init_import_#{arg.gsub(/[^\w]/, '__')}" -                Rant.send init_msg, self if Rant.respond_to? init_msg -		@imports << arg.dup -	    end -	} -    end - -    def plugin(*args, &block) -	clr = caller[1] -	ch = Rant::Lib::parse_caller_elem(clr) -	name = nil -	pre = [] -	ln = ch[:ln] || 0 -	file = ch[:file] - -	pl_name = args.shift -	pl_name = pl_name.to_str if pl_name.respond_to? :to_str -	pl_name = pl_name.to_s if pl_name.is_a? Symbol -	unless pl_name.is_a? String -	    abort(pos_text(file, ln), -		"Plugin name has to be a string or symbol.") -	end -	lc_pl_name = pl_name.downcase -	import_name = "plugin/#{lc_pl_name}" -	unless Rant::CODE_IMPORTS.include? import_name -	    begin -		require "rant/plugin/#{lc_pl_name}" -		Rant::CODE_IMPORTS << import_name -	    rescue LoadError -		abort(pos_text(file, ln), -		    "no such plugin library -- #{lc_pl_name}") -	    end -	end -	pl_class = nil -	begin -	    pl_class = ::Rant::Plugin.const_get(pl_name) -	rescue NameError, ArgumentError -	    abort(pos_text(file, ln), -		"no such plugin -- #{pl_name}") -	end - -	plugin = pl_class.rant_plugin_new(self, ch, *args, &block) -	@plugins << plugin -	vmsg 2, "Plugin `#{plugin.rant_plugin_name}' registered." -	plugin.rant_plugin_init -	plugin -    end - -    def enhance(targ, &block) -	prepare_task(targ, block) { |name,pre,blk| -	    t = resolve(name).last -	    if t -		unless t.respond_to? :enhance -		    abort("Can't enhance task `#{name}'") -		end -		t.enhance(pre, &blk) -		return t -	    end -	    warn_msg "enhance \"#{name}\": no such task", -		"Generating a new file task with the given name." -            @node_factory.new_file(self, name, pre, blk) -	} -    end - -    def source(opt, rantfile = nil) -	unless rantfile -	    rantfile = opt -	    opt = nil -	end -	make_rf = opt != :n && opt != :now -	rf, is_new = rantfile_for_path(rantfile) -	return false unless is_new -	make rantfile if make_rf -	unless File.exist? rf.path -	    abort("source: No such file -- #{rantfile}") -	end - -	load_file rf -    end - -    def subdirs(*args) -	args.flatten! -	ch = Rant::Lib::parse_caller_elem(caller[1]) -	args.each { |arg| -	    if arg.respond_to? :to_str -		arg = arg.to_str -	    else -		abort_at(ch, "subdirs: arguments must be strings") -	    end -	    loaded = false -	    prev_subdir = @current_subdir -	    begin -		goto arg -                if test(?f, Rant::SUB_RANTFILE) -                    path = Rant::SUB_RANTFILE -                else -                    path = rantfile_in_dir -                end -                if path -                    if defined? @initial_subdir and -                            @initial_subdir == @current_subdir -                        rf, is_new = rantfile_for_path(path, false) -                        @rantfiles.unshift rf if is_new -                    else -                        rf, is_new = rantfile_for_path(path) -                    end -		    load_file rf if is_new -                elsif !@opts[:no_warn_subdir] -                    warn_msg(pos_text(ch[:file], ch[:ln]), -                        "subdirs: No Rantfile in subdir `#{arg}'.") -                end -	    ensure -		goto_project_dir prev_subdir -	    end -	} -    rescue SystemCallError => e -	abort_at(ch, "subdirs: " + e.message) -    end - -    def sys(*args, &block) -	args.empty? ? @sys : @sys.sh(*args, &block) -    end - -    def var(*args, &block) -	args.empty? ? @var : @var.query(*args, &block) -    end - -    def pop_desc -	td = @task_desc -	@task_desc = nil -	td -    end - -    def abort(*msg) -	err_msg(msg) unless msg.empty? -	$stderr.puts caller if @opts[:trace_abort] -	raise Rant::RantAbortException -    end - -    def abort_at(ch, *msg) -	err_msg(pos_text(ch[:file], ch[:ln]), msg) -	$stderr.puts caller if @opts[:trace_abort] -	raise Rant::RantAbortException -    end - -    def show_help -	puts "rant [-f Rantfile] [Options] [targets]" -	puts -	puts "Options are:" -	print option_listing(OPTIONS) -    end - -    def show_descriptions -	tlist = select_tasks { |t| t.description } -	def_target = target_list.first -	if tlist.empty? -	    puts "rant         # => " + list_task_names( -		resolve(def_target)).join(', ') -	    msg "No described tasks." -	    return -	end -	prefix = "rant " -	infix = "  # " -        name_length = (tlist.map{ |t| t.to_s.length } << 7).max -	cmd_length = prefix.length + name_length -	unless tlist.first.to_s == def_target -	    defaults = list_task_names( -		resolve(def_target)).join(', ') -	    puts "#{prefix}#{' ' * name_length}#{infix}=> #{defaults}" -	end -	tlist.each { |t| -	    print(prefix + t.to_s.ljust(name_length) + infix) -	    dt = t.description.sub(/\s+$/, "") -	    puts dt.gsub(/\n/, "\n" + ' ' * cmd_length + infix + "  ") -	} -	true -    end - -    def list_task_names(*tasks) -	rsl = [] -	tasks.flatten.each { |t| -	    if t.respond_to?(:has_actions?) && t.has_actions? -		rsl << t -	    elsif t.respond_to? :prerequisites -		if t.prerequisites.empty? -		    rsl << t -		else -                    t.prerequisites.each { |pre| -                        rsl.concat(list_task_names( -                            resolve(pre, t.project_subdir))) -                    } -		end -	    else -		rsl << t -	    end -	} -	rsl -    end -    private :list_task_names - -    def verbose -	@opts[:verbose] -    end - -    def quiet? -	@opts[:quiet] -    end - -    def pos_text(file, ln) -	t = "in file `#{file}'" -        t << ", line #{ln}" if ln && ln > 0 -	t << ": " -    end - -    def cmd_msg(cmd) -	puts cmd unless quiet? -    end - -    def cmd_print(text) -        print text unless quiet? -        $stdout.flush -    end - -    def cmd_targets -	@force_targets + @arg_targets -    end - -    def running_task(task) -        if @current_subdir != @last_build_subdir -            cmd_msg "(in #{@current_subdir.empty? ? -                @rootdir : @current_subdir})" -            @last_build_subdir = @current_subdir -        end -        if @opts[:dry_run] -            task.dry_run -            true -        end -    end - -    private -    def have_any_task? -        !@tasks.empty? -    end - -    def target_list -	if !have_any_task? && @resolve_hooks.empty? -	    abort("No tasks defined for this rant application!") -	end - -	target_list = @force_targets + @arg_targets -	if target_list.empty? -	    def_tasks = resolve "default" -	    unless def_tasks.empty? -		target_list << "default" -	    else -		@rantfiles.each { |f| -                    first = f.tasks.first -		    if first -                        target_list << first.reference_name -			break -		    end -		} -	    end -	end -	target_list -    end - -    def run_tasks -	target_list.each { |target| -	    if build(target) == 0 -		abort("Don't know how to make `#{target}'.") -	    end -        } -    end - -    def make(target, *args, &block) -        ch = nil -        if target.respond_to? :to_hash -            targ = target.to_hash -            ch = Rant::Lib.parse_caller_elem(caller[1]) -            abort_at(ch, "make: too many arguments") unless args.empty? -            tn = nil -            prepare_task(targ, block, ch) { |name,pre,blk| -                tn = name -                @node_factory.new_file(self, name, pre, blk) -            } -            build(tn) -        elsif target.respond_to? :to_rant_target -            rt = target.to_rant_target -            opt = args.shift -            unless args.empty? -                ch ||= Rant::Lib.parse_caller_elem(caller[1]) -                abort_at(ch, "make: too many arguments") -            end -            if block -                ch ||= Rant::Lib.parse_caller_elem(caller[1]) -                prepare_task(rt, block, ch) { |name,pre,blk| -                    @node_factory.new_file(self, name, pre, blk) -                } -                build(rt) -            else -                build(rt, opt||{}) -            end -        elsif target.respond_to? :rant_gen -            ch = Rant::Lib.parse_caller_elem(caller[1]) -            rv = target.rant_gen(self, ch, args, &block) -            unless rv.respond_to? :to_rant_target -                abort_at(ch, "make: invalid generator return value") -            end -            build(rv.to_rant_target) -            rv -        else -            ch = Rant::Lib.parse_caller_elem(caller[1]) -            abort_at(ch, -                "make: generator or target as first argument required.") -        end -    end -    public :make - -    def build(target, opt = {}) -	opt[:force] = true if @force_targets.delete(target) -        opt[:dry_run] = @opts[:dry_run] -	matching_tasks = 0 -	old_subdir = @current_subdir -	old_pwd = Dir.pwd -	resolve(target).each { |t| -            unless opt[:type] == :file && !t.file_target? -                matching_tasks += 1 -                begin -                    t.invoke(opt) -                rescue Rant::TaskFail => e -                    err_task_fail(e) -                    abort -                end -            end -	} -	@current_subdir = old_subdir -	Dir.chdir old_pwd -	matching_tasks -    end -    public :build - -    def resolve(task_name, rel_project_dir = @current_subdir) -	s = @tasks[expand_path(rel_project_dir, task_name)] -	case s -	when nil -	    @resolve_hooks.each { |s| -		s = s[task_name, rel_project_dir] -		return s if s -	    } -	    [] -	when Rant::Node; [s] -	else # assuming list of tasks -	    s -	end -    end -    public :resolve - -    def rec_save_resolve(task_name, excl_hook, rel_project_dir = @current_subdir) -	s = @tasks[expand_path(rel_project_dir, task_name)] -	case s -	when nil -	    @resolve_hooks.each { |s| -                next if s == excl_hook -		s = s[task_name, rel_project_dir] -		return s if s -	    } -	    [] -	when Rant::Node; [s] -	else -	    s -	end -    end -    public :rec_save_resolve - -    def at_resolve(&block) -	@resolve_hooks << block if block -    end -    public :at_resolve - -    def at_return(&block) -        hooks = var._get("__at_return__") -        if hooks -            hooks << block -        else -            var._set("__at_return__", [block]) -        end -    end -    public :at_return - -    def select_tasks -	selection = [] -	@rantfiles.each { |rf| -	    rf.tasks.each { |t| -		selection << t if yield t -	    } -	} -	selection -    end -    public :select_tasks - -    def load_rantfiles -        unless @arg_rantfiles.empty? -            @arg_rantfiles.each { |fn| -                if test(?f, fn) -                    rf, is_new = rantfile_for_path(fn) -                    load_file rf if is_new -                else -                    abort "No such file -- #{fn}" -                end -            } -            return -        end -        return if have_any_task? -        fn = rantfile_in_dir -        if @opts[:cd_parent] -            old_root = @rootdir -            until fn or @rootdir == "/" -                @rootdir = File.dirname(@rootdir) -                fn = rantfile_in_dir(@rootdir) -            end -            if @rootdir != old_root and fn -                Dir.chdir @rootdir -                cmd_msg "(in #@rootdir)" -            end -        end -        if fn -            rf, is_new = rantfile_for_path(fn) -            load_file rf if is_new -            return -        end -        have_sub_rantfile = test(?f, Rant::SUB_RANTFILE) -        if have_sub_rantfile || @opts[:look_up] -            cur_dir = Dir.pwd -            until cur_dir == "/" -                cur_dir = File.dirname(cur_dir) -                Dir.chdir cur_dir -                fn = rantfile_in_dir -                if fn -                    @initial_subdir = @rootdir.sub( -                        /^#{Regexp.escape cur_dir}\//, '') -                    @rootdir = cur_dir -                    cmd_msg "(root is #@rootdir, in #@initial_subdir)" -                    @last_build_subdir = @initial_subdir -                    rf, is_new = rantfile_for_path(fn) -                    load_file rf if is_new -                    goto_project_dir @initial_subdir -                    if have_sub_rantfile -                        rf, is_new = rantfile_for_path( -                                Rant::SUB_RANTFILE, false) -                        if is_new -                            @rantfiles.unshift rf -                            load_file rf -                        end -                    end -                    break -                end -            end -        end -        if @rantfiles.empty? -            abort("No Rantfile found, looking for:", -                Rant::RANTFILES.join(", ")) -        end -    end - -    def load_file(rantfile) -	vmsg 1, "source #{rantfile}" -	@context.instance_eval(File.read(rantfile), rantfile) -    end -    private :load_file - -    def rantfile_in_dir(dir=nil) -	::Rant::RANTFILES.each { |rfn| -	    path = dir ? File.join(dir, rfn) : rfn -            return path if test ?f, path -	} -        nil -    end - -    def process_args -	old_argv = ARGV.dup -	ARGV.replace(@args.dup) -	cmd_opts = GetoptLong.new(*OPTIONS.collect { |lst| lst[0..-2] }) -	cmd_opts.quiet = true -	cmd_opts.each { |opt, value| -	    case opt -	    when "--verbose"; @opts[:verbose] += 1 -	    when "--version" -		puts "rant #{Rant::VERSION}" -		raise Rant::RantDoneException -	    when "--help" -		show_help -		raise Rant::RantDoneException -	    when "--directory" -                @rootdir = File.expand_path(value) -	    when "--rantfile" -		@arg_rantfiles << value -	    when "--force-run" -		@force_targets << value -            when "--import" -                import value -	    else -		@opts[opt.sub(/^--/, '').tr('-', "_").to_sym] = true -	    end -	} -    rescue GetoptLong::Error => e -	abort(e.message) -    ensure -	rem_args = ARGV.dup -	ARGV.replace(old_argv) -	rem_args.each { |ra| -	    if ra =~ /(^[^=]+)=([^=]+)$/ -		vmsg 2, "var: #$1=#$2" -		@var[$1] = $2 -	    else -		@arg_targets << ra -	    end -	} -    end - -    def prepare_task(targ, block, clr = caller[2]) - -	if targ.is_a? Hash -	    targ.reject! { |k, v| clr = v if k == :__caller__ } -	end -	ch = Hash === clr ? clr : Rant::Lib::parse_caller_elem(clr) - -	name, pre = normalize_task_arg(targ, ch) - -	file, is_new = rantfile_for_path(ch[:file]) -	nt = yield(name, pre, block) -	nt.rantfile = file -        nt.project_subdir = @current_subdir -	nt.line_number = ch[:ln] -	nt.description = @task_desc -	@task_desc = nil -	file.tasks << nt -	hash_task nt -	nt -    end -    public :prepare_task - -    def hash_task(task) -	n = task.full_name -	et = @tasks[n] -	case et -	when nil -	    @tasks[n] = task -	when Rant::Node -	    mt = [et, task] -	    @tasks[n] = mt -	else # assuming list of tasks -	    et << task -	end -    end - -    def normalize_task_arg(targ, ch) -	name = nil -	pre = [] - -	if targ.is_a? Hash -	    if targ.empty? -		abort_at(ch, "Empty hash as task argument, " + -		    "task name required.") -	    end -	    if targ.size > 1 -		abort_at(ch, "Too many hash elements, " + -		    "should only be one.") -	    end -	    targ.each_pair { |k,v| -		name = normalize_task_name(k, ch) -		pre = v -	    } -	    unless ::Rant::FileList === pre -		if pre.respond_to? :to_ary -		    pre = pre.to_ary.dup -		    pre.map! { |elem| -			normalize_task_name(elem, ch) -		    } -		else -		    pre = [normalize_task_name(pre, ch)] -		end -	    end -	else -	    name = normalize_task_name(targ, ch) -	end - -	[name, pre] -    end -    public :normalize_task_arg - -    def normalize_task_name(arg, ch) -	return arg if arg.is_a? String -	if Symbol === arg -	    arg.to_s -	elsif arg.respond_to? :to_str -	    arg.to_str -	else -	    abort_at(ch, "Task name has to be a string or symbol.") -	end -    end - -    def rantfile_for_path(path, register=true) -	abs_path = File.expand_path(path) -        file = @rantfiles.find { |rf| rf.path == abs_path } -	if file -	    [file, false] -	else -	    file = Rant::Rantfile.new abs_path -	    file.project_subdir = @current_subdir -	    @rantfiles << file if register -	    [file, true] -	end -    end - -    def get_ch_from_backtrace(backtrace) -	backtrace.each { |clr| -	    ch = ::Rant::Lib.parse_caller_elem(clr) -	    if ::Rant::Env.on_windows? -		return ch if @rantfiles.any? { |rf| -		    rf.path.tr("\\", "/").sub(/^\w\:/, '') == -			ch[:file].tr("\\", "/").sub(/^\w\:/, '') -		} -	    else -		return ch if @rantfiles.any? { |rf| -		    rf.path == ch[:file] -		} -	    end -	} -	nil -    end - -    def err_task_fail(e) -	msg = [] -	t_msg = ["Task `#{e.tname}' fail."] -	orig = e -	loop { orig = orig.orig; break unless Rant::TaskFail === orig } -	if orig && orig != e && !(Rant::RantAbortException === orig) -            ch = get_ch_from_backtrace(orig.backtrace) -            msg << pos_text(ch[:file], ch[:ln]) if ch -            unless Rant::CommandError === orig && !@opts[:err_commands] -                msg << orig.message -                msg << orig.backtrace[0..4] unless ch -            end -	end -        if e.msg && !e.msg.empty? -            ch = get_ch_from_backtrace(e.backtrace) -            t_msg.unshift(e.msg) -            t_msg.unshift(pos_text(ch[:file], ch[:ln])) if ch -        end -	err_msg msg unless msg.empty? -	err_msg t_msg -    end -end	# class Rant::RantApp - -$".concat(['rant/rantlib.rb', 'rant/init.rb', 'rant/rantvar.rb', 'rant/rantsys.rb', 'rant/import/filelist/core.rb', 'rant/node.rb', 'rant/import/nodes/default.rb', 'rant/coregen.rb']) -Rant::CODE_IMPORTS.concat %w(nodes/default -    ) - -# Catch a `require "rant"', sad... -alias require_backup_by_rant require -def require libf -    if libf == "rant" -        # TODO: needs rework! look at lib/rant.rb -	self.class.instance_eval { include Rant } -    else -	begin -	    require_backup_by_rant libf -	rescue -	    raise $!, caller -	end -    end -end - -exit Rant.run | 
