module Reap require 'yaml' require 'rbconfig' require 'reap/utilities' require 'reap/hosts' # = Project # # The Project class is the main class of Reap. It provides the tools for # working with a project. The CLI Application class delegates to this class, # for instance. class Project require 'reap/metadata' require 'reap/settings' require 'reap/defaults' require 'reap/runmodes' # Load up the tools require "reap/project/announce.rb" require "reap/project/check.rb" require "reap/project/clean.rb" require "reap/project/gem.rb" require "reap/project/html.rb" require "reap/project/log.rb" require "reap/project/make.rb" require "reap/project/package.rb" require "reap/project/publish.rb" require "reap/project/rdoc.rb" require "reap/project/release.rb" require "reap/project/scaffold.rb" require "reap/project/site.rb" require "reap/project/spec.rb" require "reap/project/stats.rb" require "reap/project/scm.rb" require "reap/project/test.rb" require "reap/project/version.rb" include Utilities # New Project. def initialize(options=nil) @options = options || {} @location = locate raise LoadError, "no .reap configuration file" unless @location @metadata = Metadata.read(location) @settings = Settings.read(location, @metadata) @defaults = Defaults.new(@metadata) @runmodes = RunModes.new(options) end # Location of project. def location ; @location ; end # Project metadata. def metadata ; @metadata ; end # Task defaults. def defaults ; @defaults ; end # Task user settings. def settings ; @settings ; end # Run modes. def runmodes ; @runmodes ; end # Common options. def options ; @options ; end #alias_method :init_options, :options # TODO: Improve me! (see stamp.rb) def dryrun? ; runmodes.dryrun? ; end def trace? ; runmodes.trace? ; end def force? ; runmodes.force? ; end def verbose? ; runmodes.verbose? ; end def debug? ; runmodes.debug? ; end def dryrun=(x) ; runmodes.dryrun = x ; end def trace=(x) ; runmodes.trace = x ; end def force=(x) ; runmodes.force = x ; end def verbose=(x) ; runmodes.verbose = x ; end def debug=(x) ; runmodes.debug = x ; end alias_method :noharm?, :dryrun? alias_method :noharm=, :dryrun= # Invoke a tool. def invoke(command, *args) begin #display_location meth = method(command) chdir_to_project do case meth.arity when 0 meth.call else meth.call(*args) end end rescue LoadError => e if trace? raise e else abort e.message.capitalize + '.' end end end # Display the project's root location. def display_location puts "[#{location}]" end # Change directory to project's root location, # and execute block if given. If a block is # provided, the current directory will revert # back to what it was prior to this call, otherwise # it will remain changed. def chdir_to_project(&block) if block Dir.chdir(location, &block) else Dir.chdir(location) end end # Return a list of all ruby script in the project loadpaths. #def scripts # @scripts ||= multiglob(*metadata.libpath.collect{ |l| File.join(l, '**', '*.rb') }) #end # Query infromation about reap settings and/or the current # project. # # NOTE: This would dhave been naed #inspect but for the # built-in method. def introspect(options) args = options['arguments'] if args args.each do |field| case field when 'defaults' y defaults when 'settings' y settings when 'metadata' y metadata else puts metadata.send(field) end end else puts puts "#{metadata.title} #{metadata.version}" puts metadata.brief puts metadata.homepage puts puts metadata.description puts puts metadata.copyright puts end end # Project manifest file. def manifest_file Dir.glob('Manifest{,.txt}', File::FNM_CASEFOLD).first end private # Locate the project root directory. This is determined # by ascending up the directory tree from the current position # until a .reap file is found. Returns +nil+ if not found. def locate loc = nil dir = Dir.pwd while dir != '/' glob = File.join(dir, Settings::REAP_FILE) #Project::PROJECT_FILE) file = Dir.glob(glob, File::FNM_CASEFOLD).first if file loc = File.dirname(file) break else dir = File.dirname(dir) end end return loc end # Tasks use this to automatically combine commandline options, # user settings, defualts. def configure_options(options, *entries) config = {} entries.each do |entry| config.update(defaults[entry] || {}) end entries.each do |entry| config.update(settings[entry] || {}) end options = (options || {}).rekey(&:to_s) config.update(options) return config end # Access to selected hosts. def hosts(select=nil) @hosts ||= {} select ||= metadata.hosts.keys result = [] metadata.hosts.each do |key, options| next unless select.include?(key) host_class = options['type'] ? Hosts.registry[options['type']] : Hosts.registry[key] next unless host_class # cache hosts @hosts[key] ||= host_class.from_project(self, options) result |= [@hosts[key]] end return result end # Access to project's scource control management system. def scm @scm ||= ( if system = Systems.current system.from_project(self, {}) #TODO: metadata.scm is a hash? end ) end end end