require 'yaml' module BuildTool # # # class Recipe attr_accessor :name attr_accessor :global_path attr_reader :settings def initialize( name ) raise StandardError if name.nil? @name = name @metainfo_loaded = false @short_description = "no description" @long_description = "no description" @global_path = Recipe.find_recipe( @name ) end def browse_repository return @browse_repository if @metainfo_loaded load_metainfo @browse_repository end # We look in # local_config_file_path()/ # global_config_file_path()/ # for the file name @name. Name is allowed to be a path def find_first_config_file( name ) if (pn = local_config_file_path( name )).exist? return pn end if (pn = global_config_file_path( name )).exist? return pn end return nil end def long_description return @long_description if @metainfo_loaded load_metainfo @long_description end def load_metainfo begin file = YAML.load_file( metainfo_file_path ) @long_description = file['LONG'] @short_description = file['SHORT'] @website = file['WEBSITE'] @repository = file['REPOSITORY'] @browse_repository = file['BROWSE_REPOSITORY'] rescue Errno::ENOENT => e logger.verbose "No description file found for recipe #{name}." @short_description = "No description file provided!" rescue ArgumentError => e logger.verbose "Invalid description file found for for recipe #{name}." @short_description = "Description File invalid!" end @metainfo_loaded = true end def load( local_config_name, settings ) @local_config_name = local_config_name raise StandardError, "Usage: recipe.load( settings )" if settings.nil? @settings = settings configuration = Configuration.new( self ) # Load the recipe logger.debug "Loading #{global_config_file_path( "recipe" )}" configuration = load_from_file( global_config_file_path( "recipe" ), configuration ) # Load the local modifications to the recipe if any local_config_file = local_config_file_path( "recipe" ) if local_config_file.exist? logger.debug "Loading #{local_config_file}" load_from_file( local_config_file, configuration ) end configuration end def load_from_file( file, configuration ) # Get the file content recipe = File.read( file ) # Create the parser parser = Cfg::Parser.new( configuration ) # Create the ERB erb = ERB.new( recipe, nil, "%<>" ) # Fill the env for ERB b = binding settings = @settings # Call the parser with the ERBed file content and return the # result conf = parser.parse_string( erb.result(b), file ) end def local_config_file_path(name) Pathname.new( BuildTool::Application::instance.local_configuration_dir ). join( @local_config_name, name) end def global_config_file_path( name ) return @global_path.join(name) end def repository return @repository if @metainfo_loaded load_metainfo @repository end def short_description return @short_description if @metainfo_loaded load_metainfo @short_description end def metainfo_file_path return @global_path.join('info.yaml') end def files_path return @global_path.join('files') end def website return @website if @metainfo_loaded load_metainfo @website end ################# # CLASS METHODS # ################# def self.config_directories return [ Pathname.new( BuildTool::Application::instance.local_configuration_dir ).join( "recipes" ), Pathname.new( BuildTool::Application::instance.application_root ).join( "recipes" ) ] end def self.all_recipes recipes = {} self.config_directories.each do |dir| # Skip directories that don't exist next if !dir.exist? Dir.foreach( dir ) { |name| next if name == '..' next if name == '.' pn = Pathname.new(dir).join(name) next if !pn.directory? next if recipes.has_key?(name) recipes[name] = Recipe.new(name) } end recipes end # Find recipe name. We look in # 1. /recipes/ # 2. /recipes/ # # The first one found is returned def self.find_recipe( name ) self.config_directories.each do |dir| recipe = dir.join( name ) return recipe if recipe.join('recipe').exist? end raise ConfigurationError, "Recipe #{name} not found!"; end end # class Recipe end # module BuildTool