From 71a3346906c1c3785ba536a4bb589790d2c068d8 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Mon, 17 Apr 2023 16:33:41 +0200 Subject: [PATCH] feat: :sparkles: add a YAML config load engine TODO: This needs to be replaced with a dynamic loader system --- lib/comfpile/engines/config_engine.rb | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 lib/comfpile/engines/config_engine.rb diff --git a/lib/comfpile/engines/config_engine.rb b/lib/comfpile/engines/config_engine.rb new file mode 100644 index 0000000..7c76013 --- /dev/null +++ b/lib/comfpile/engines/config_engine.rb @@ -0,0 +1,70 @@ + +require 'yaml' + +class ::Hash + def deep_merge(second) + merger = proc { |_, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 } + merge(second.to_h, &merger) + end +end + +module Comfpile + class ConfigArtefact < Artefact + attr_reader :loaded_config + attr_reader :config + + attr_reader :mtime + + def initialize(*args, **opts) + super(*args, **opts) + + @loaded_config = {} + + unless @target == '.' or @target == '' + parent_artefact :config_file, File.dirname(@target) + end + + @config_file_artefact = craft_artefact(:sourcefile, File.join(@target, "comf.yml")) + wait_on @config_file_artefact + + add_step do + unless @config_file_artefact.nil? + @loaded_config = YAML.load_file(@config_file_artefact.file) + + log "Config file found and loaded for directory #{@target}!" + end + + fail! "Config YAML file is not a hash!" unless @loaded_config.is_a? Hash + + if @parent_artefact.nil? + @config = @loaded_config + @mtime = @config_file_artefact.mtime + else + defaults = @loaded_config['defaults'] || {} + + @config = defaults.deep_merge(@parent_artefact.config.deep_merge(@loaded_config)) + @mtime = [@config_file_artefact.mtime, @parent_artefact.mtime].max + end + end + end + + def [](key) + @config[key] + end + + undef []= + end + + class ConfigLoaderEngine < ArtefactEngine + def initialize(core, **options) + super(core, **options) + + end + + def craft(stage, target) + return unless stage == :config_file + + ConfigArtefact.new(@core, self, stage, target) + end + end +end \ No newline at end of file