lib/reap/projectinfo.rb in reap-5.10.10 vs lib/reap/projectinfo.rb in reap-6.0.0

- old
+ new

@@ -1,51 +1,208 @@ require 'yaml' -require 'facet/hash/traverse' +#require 'facet/hash/traverse' +require 'facet/hash/graph' require 'facet/string/tabto' require 'facet/dir/self/ascend' -module ProjectInfo - extend self +#require 'facet/basicobject' +require 'facet/opencascade' - INFO_FILES = [ 'ProjectInfo', 'ReapFile', 'projectinfo', 'reapfile' ] +# Project information. +# +# ProjectInfo is a Singleton. Access it via the +# ProjectInfo.instance method. - def add_info_file( f ) - INFO_FILES.unshift( f ) - end +class ProjectInfo - def info_stream - dir = Dir.pwd - unless @info_stream - Dir.ascend(Dir.pwd) do |d| - Dir.chdir(d) - info_file = INFO_FILES.find{ |f| File.file?( f ) } - if info_file - @info_stream = File.read( info_file ) - puts "(in #{d})" unless dir == Dir.pwd - break + include Enumerable + + INFO_FILES = [ 'ProjectInfo','projectinfo' ] + + class << self + + # Singelton Pattern. + + private :new + + def instance( &block ) + @instance ||= block_given? ? new( &block ) : load + end + + # Move to file's location. + + def prime_location( fpath=nil ) + if fpath + Dir.chdir( File.dirname( fpath ) ) + else + fpath = find + if fpath + Dir.chdir( File.dirname( fpath ) ) end end end - @info_stream + + # 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 nil unless info_file + return File.join( info_dir, info_file ) + end + + # 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 ) + unless fpath + fpath = find + if fpath + Dir.chdir( File.dirname( fpath ) ) + end + end + new.read( fpath ) + end + + def exist? + @instance.info_file ? true : false + end + alias_method :exists?, :exist? + end - def info - if info_stream - @info ||= YAML::load(info_stream).traverse{ |k,v| [k.downcase, v] } - else - {} + + attr_reader :info, :info_stream, :info_dir, :info_file + + def initialize( &block ) + @info = {} + @info_stream = nil + +# define( &block ) if block_given? + end + + # Define project information programmatically. + +# def define( &block ) +# return unless block +# +# @info = HashBuilder.new( &block ).to_h +# @info_stream = @info.to_yaml +# @info_dir = Dir.pwd #? +# @info_file = nil +# +# #validate +# defaults +# +# self +# end + + # Load project information from YAML file. + + def read( fpath ) + return self unless fpath + + @info_dir = File.dirname( fpath ) + @info_file = fpath #File.basename( fpath ) + @info_stream = File.read( fpath ).strip + @info = YAML::load( info_stream ) + @info = @info.graph{ |k,v| [k.to_s.downcase, v] } + + #validate + defaults +=begin + # register the task entries + @info.each do |key, val| + #value = @info[key] = {} if value.nil? + if Reap::TaskDef === val + val.name = key.to_s + end end +=end + self end - # not using at the moment - def validate - # required main parameters - #raise "TITLE is a required configuration field" unless info['title'] - raise "NAME is a required piece of information" unless info['name'] - raise "VERSION is a required piece of informatiomn" unless info['version'] +# # 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_file end + alias_method :exist?, :exists? + # Validate project information. + + def validate #( *fields ) + val = true + (puts "NAME is required in project information file."; val=false) unless info['name'] + (puts "VERSION is required in project information file."; val=false) unless info['version'] + exit -1 unless val + 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" + self['maintainer'] ||= self['author'] + self['arch'] ||= 'Any' + self['license'] ||= 'Ruby/GPL' + self['status'] ||= 'Beta' + self['project'] ||= self['rubyforge'] ? self['rubyforge']['project'] : nil + self['homepage'] ||= self['rubyforge'] ? self['rubyforge']['homepage'] : nil + self['trunk'] ||= 'trunk' if File.directory?( File.join( @info_dir, 'trunk' )) + end + + # Convert to a CascadinOpenObject. + + def to_opencascade + OpenCascade.new( @info ) + end + + # Information fetch. + def [](name) - info[name] + @info[name] end + + # Information store. + + def []=(name, x) + @info[name] = x + end + + def each( &block ) + @info.each( &block ) + end + + # Information to hash. + + def to_h + @info.dup + end + end +