lib/reap/projectinfo.rb in reap-4.3.4 vs lib/reap/projectinfo.rb in reap-4.4.0

- old
+ new

@@ -3,80 +3,137 @@ require 'facet/hash/traverse' require 'facet/string/tabto' require 'facet/dir/self/ascend' +require 'facet/basicobject' + +#-- +# NOTE At some point get past the use of the global variable perhaps? +#++ + class ProjectInfo INFO_FILES = [ 'ProjectInfo', 'ReapFile', 'projectinfo', 'reapfile' ] - def self.add_info_file( f ) - INFO_FILES.unshift( f ) + class << self + + # Load the project information from a file. Generally + # no file needs to be specified; the file will be found + # by ascending up the current path until a default + # file name is found (eg. ProjectInfo or Reapfile). + + def load( fpath=nil, report=false ) + if fpath + new.read( fpath, report ) + else + new.read( find, report ) + end + end + + # Find project information file. + + def find + info_dir, info_file = nil, nil + Dir.ascend(Dir.pwd) do |info_dir| + info_file = INFO_FILES.find{ |f| File.file?( File.join( info_dir, f ) ) } + break if info_file + end + return File.join( info_dir, info_file ) + end + + #def add_file( f ) + # INFO_FILES.unshift( f ) + #end + end - #def self.[](name) - # @self ||= self.new - # @self[name] - #end - attr_reader :info, :info_stream, :info_dir + attr_reader :info, :info_stream, :info_dir, :info_file - def initialize( alt_info_file=nil ) + def initialize( &block ) + @info = {} + @info_stream = nil - # Consider alternative info files? - # NOTE Should this work out of the current working dir only? - add_info_file( alt_info_file ) if alt_info_file + define( &block ) if block_given? - info_dir = nil - info_file = nil + $PROJECT_INFO = self + end - Dir.ascend(Dir.pwd) do |info_dir| - #Dir.chdir(info_dir) - info_file = INFO_FILES.find{ |f| File.file?( File.join( info_dir, f ) ) } - break if info_file - end + # Define project information programmatically. - return unless info_file + def define( &block ) + return unless block - info_file = File.basename( info_file ) - @info_dir = info_dir - @info_file = info_file - Dir.chdir(info_dir) + @info = HashBuilder.new( &block ).to_h + @info_stream = @info.to_yaml - puts "(in #{Dir.pwd})" #unless dir == Dir.pwd + validate + defaults - info_stream = File.read( info_file ).strip + self + end - begin - info = YAML::load( info_stream ) - rescue - #info_proc = lambda { instance_eval( info_stream ) } - info = HashBuilder.new( info_stream ).to_h + # Load project information from YAML file. + + def read( fpath, report=true ) + return unless fpath + + @info_dir = File.dirname( fpath ) + @info_file = fpath #File.basename( fpath ) + @info_stream = File.read( fpath ).strip + @info = YAML::load( info_stream ).traverse{ |k,v| [k.to_s.downcase, v] } + + Dir.chdir(@info_dir) + if report + puts "(in #{Dir.pwd})" #unless dir == Dir.pwd end - @info_stream = info_stream - @info = info.traverse{ |k,v| [k.to_s.downcase, v] } + validate + defaults + self + end + + # Update project information. + + def update( info=nil, &block ) + if info + @info.update( info.traverse{ |k,v| [k.to_s.downcase, v] } ) + end + if block_given? + @info.update( HashBuilder.new( &block ).to_h ) + end + @info_stream = @info.to_yaml + validate defaults + + self end + # Project information file exists? (may need to change to info exists?) + def exists? - @info_dir + @info_file end + # Validate project information. + def validate raise "NAME is a required piece of information" unless info['name'] raise "VERSION is a required piece of informatiomn" unless info['version'] end + # Project information defaults. + def defaults self['title'] ||= self['name'].capitalize self['series'] ||= '1' self['date'] ||= Time.now.strftime("%Y-%m-%d") self['author'] ||= "Anonymous" @@ -86,18 +143,24 @@ self['status'] ||= 'Beta' self['project'] ||= self['rubyforge'] ? self['rubyforge']['project'] : nil self['homepage'] ||= self['rubyforge'] ? self['rubyforge']['homepage'] : nil end + # Information fetch. + def [](name) info[name] end + # Information sore. + def []=(name, x) info[name] = x end + # Information to hash. + def to_h @info end end @@ -119,27 +182,29 @@ end def to_h ; @hash ; end def method_missing( sym, *args, &block ) + sym = sym.to_s.downcase if @hash.key?(sym) unless @flag[sym] @hash[sym] = [ @hash[sym] ] @flag[sym] = true end if block_given? - @hash[sym] << HashBuilder.new( &block ).to_h + @hash[sym] << self.__class__.new( &block ).to_h else @hash[sym] << args[0] end else if block_given? - @hash[sym] = HashBuilder.new( &block ).to_h + @hash[sym] = self.__class__.new( &block ).to_h else @hash[sym] = args[0] end end end end +