From f1033f460e3f77c1788c1a0775f920b8de1496e8 Mon Sep 17 00:00:00 2001 From: David Bailey Date: Fri, 14 Apr 2023 16:01:56 +0200 Subject: [PATCH] feat: :sparkles: add dedicated dependency generator artefact --- lib/comfpile/engines/parser_engine.rb | 63 ++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 6 deletions(-) diff --git a/lib/comfpile/engines/parser_engine.rb b/lib/comfpile/engines/parser_engine.rb index da66e2b..1ceee95 100644 --- a/lib/comfpile/engines/parser_engine.rb +++ b/lib/comfpile/engines/parser_engine.rb @@ -121,11 +121,54 @@ module Comfpile end end - included_artefacts.each { |a| include_artefact :parsed, a, wait_if_exists: false } - required_artefacts.each { |a| require_artefact :parsed, a, wait_if_exists: false } - referenced_artefacts.each { |a| reference_artefact :parsed, a, wait_if_exists: false, required: true } + class DependencyAnalysisArtefact < Artefact + attr_reader :dependencies - log "Generated dependencies. Included #{included_artefacts.size}, required #{required_artefacts.size} and referenced #{referenced_artefacts.size}." + def initialize(*args, traverse: nil, **opts) + super(*args, **opts) + + parent_artefact :parsed, @target + + @dependencies = [] + + @dependency_processed_artefacts = {} + @dependency_waiting_on = [ @parent_artefact ] + + @traverse = traverse || ['include', 'require', 'reference'] + + add_step do + recursive_dependency_wait_step + end + end + + def recursive_dependency_wait_step + dependency_unfurl = @dependency_waiting_on + @dependency_waiting_on = [] + + loop do + break if dependency_unfurl.empty? + + artefact = dependency_unfurl.pop + + next if @dependency_processed_artefacts[artefact.target] + + @dependencies << artefact + @dependency_processed_artefacts[artefact.target] = true + + artefact.parsed_dependencies.each do |key, dep_list| + next unless @traverse.nil? or @traverse.include? key + + dep_list.each do |dep_artefact| + if wait_on dep_artefact + @dependency_waiting_on << dep_artefact + else + dependency_unfurl << dep_artefact + end + end + end + end + + retry_step! unless @dependency_waiting_on.empty? end end @@ -159,12 +202,20 @@ module Comfpile search_regexes: @search_regexes) end + def generate_dependency_analysis_artefact(stage, target, **opts) + match = @input_file_regex.match target + return nil if match.nil? + + DependencyAnalysisArtefact.new(@core, self, stage, target, **opts) + end + def craft(stage, target) case stage when :parsed generate_parser_artefact(stage, target) - when :dependency_list - nil + when /^dependency_analysis(?:_(.+))?$/ + traverse = $1&.split('_') + generate_dependency_analysis_artefact(stage, target, traverse: traverse) else nil end