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
+