module Bozo::Hooks # Hook for creating files based upon configuration files and ERB-style # templates before any compilation occurs. # # == Overview # # This hook is primarily intended for generating config files with shared # values but it is capable of generating whatever files you want. Each # instance of the hook is isolated from the anothers so you could specify # multiple hooks to work with different configurations and templates if you # wished. # # By default the hook will load default.rb followed by # [environment].rb followed by [machine_name].rb from the # configured config_path if the file exists. It will then load any files # explicitly required through the config_file method. # # == Hook configuration # # pre_compile :file_templating do |t| # t.config_path 'somewhere' # defaults to 'config' if not specified # t.config_file 'my/specific/file.rb' # must be a specific file # t.source_files 'src/**/*.config.template' # can use glob format # end # # Source files are expected to have an additional extension compared to the # target file. For example, a source file of # src/csharp/Project/Project.config.template will generate the file # src/csharp/Project/Project.config. # # == Configuration files # # Configuration files specify a hash of hashes in a more readable format. # For example: # # group :example do # set :one, 'foo' # set :two, 'bar' # end # # Internally creates a hash like: # # {:example => {:one => 'foo', :two => 'bar'}} # # A configuration file can overwrite the values specified by a preceding one # without error. Groups can be opened and closed as desired and nesting # groups is possible. # # == Template files # # To use a value within an ERB template you specify the hash hierarchy as if # they were method names rather than having to use the full hash syntax. # # Therefore, this is valid: # # Foo is <%= example.one %> # # Whilst this is *not* valid: # # Foo is <%= self[:example][:one] %> # # If a template uses a value that is not specified within the configuration # then the hook will raise an error and halt the build. class FileTemplating # Creates a new instance. def initialize @config_path = 'config' @template_globs = [] @config_files = [] end # Sets the path of the directory within which the hook should look for the # default configuration files. # # @param [String] path # The path to the directory containing the default configuration # files. def config_path(path) @config_path = path end # Adds a specific file to load configuration from. # # @param [String] path # The path to a configuration file. def config_file(path) @config_files << path end # Adds a set of templates files from which to generate files. # # @param [String] glob # A glob that points to a set of files that should pass through the # templating engine. def template_files(glob) @template_globs << glob end # Generate all the files matching the configuration. def pre_compile log_info '' # formatting log_info 'Generating files' get_coordinator.generate_files do |template, target| log_debug "Generating #{target} from #{template}" end end private # Creates a new templating coordinator based upon the current # configuration. def get_coordinator coordinator = Bozo::ErubisTemplatingCoordinator.new add_config coordinator add_templates coordinator coordinator end # Adds the configuration to the templating coordinator. def add_config(coordinator) add_default_config_files coordinator @config_files.each {|f| coordinator.required_config_file f} end # Adds the default configuration from the configuration directory to the # templating coordinator. # # @param [ErubisTemplatingCoordinator] coordinator # The template coordinator to add the configuration to. def add_default_config_files(coordinator) default_files = ['default.rb', "#{environment}.rb"] default_files << "#{env['MACHINENAME']}.rb" if env['MACHINENAME'] default_files.each do |file| coordinator.config_file File.join(@config_path, file) end end # Adds the templates to the templating coordinator. def add_templates(coordinator) @template_globs.each do |glob| coordinator.template_files glob end end end end