<commit_before>require 'json'
require 'set'
require 'tsort'
require 'stackmate/logging'

module StackMate

class Stacker
    include TSort
    include Logging

    def initialize(stackstr, stackname, params)
        @stackname = stackname
        @resolved = params
        @templ = JSON.parse(stackstr) 
        @templ['StackName'] = @stackname
        @param_names = @templ['Parameters']
        @deps = {}
        @pdeps = {}
        validate_param_values
        resolve_dependencies()
        @templ['ResolvedNames'] = @resolved
    end

    
    def validate_param_values
        #TODO CloudFormation parameters have validity constraints specified
        #Use them to validate parameter values (e.g., email addresses)
    end

    def resolve_dependencies
        @templ['Resources'].each { |key,val| 
            deps = Set.new
            pdeps = Set.new
            find_refs(key, val, deps, pdeps)
            deps << val['DependsOn'] if val['DependsOn']
            #print key, " depends on ", deps.to_a, "\n"
            @deps[key] = deps.to_a
            @pdeps[key] = pdeps.to_a
        }
        @pdeps.keys.each do |k|
            unres = @pdeps[k] - @resolved.keys
            if ! unres.empty?
                unres.each do |u|
                    deflt = @param_names[u]['Default']
                    #print "Found default value ", deflt, " for ", u, "\n" if deflt
                    @resolved[u] = deflt if deflt
                end
                unres = @pdeps[k] - @resolved.keys
                throw :unresolved, (@pdeps[k] - @resolved.keys) if !unres.empty?
            end
        end
    end


    def find_refs (parent, jsn, deps, pdeps)
        case jsn
            when Array
                jsn.each {|x| find_refs(parent, x, deps, pdeps)}
                #print parent, ": ", jsn, "\n"
            when Hash
                jsn.keys.each do |k|
                    #TODO Fn::GetAtt
                    if k == "Ref"
                        #only resolve dependencies on other resources for now
                        if !@param_names.keys.index(jsn[k]) && jsn[k] != 'AWS::Region' && jsn[k] != 'AWS::StackId'
                            deps << jsn[k]
                            #print parent, ": ", deps.to_a, "\n"
                        else if @param_names.keys.index(jsn[k])
                            pdeps << jsn[k]
                        end
                        end
                    else
                        find_refs(parent, jsn[k], deps, pdeps)
                    end
                end
        end
        return deps
    end

    def tsort_each_node(&block)
        @deps.each_key(&block)
    end

    def tsort_each_child(name, &block)
        @deps[name].each(&block) if @deps.has_key?(name)
    end
    
end

end
<commit_msg>Don't add StackName to list of participants<commit_after>require 'json'
require 'set'
require 'tsort'
require 'stackmate/logging'

module StackMate

class Stacker
    include TSort
    include Logging

    def initialize(stackstr, stackname, params)
        @stackname = stackname
        @resolved = params
        @templ = JSON.parse(stackstr) 
        @templ['StackName'] = @stackname
        @param_names = @templ['Parameters']
        @deps = {}
        @pdeps = {}
        validate_param_values
        resolve_dependencies()
        @templ['ResolvedNames'] = @resolved
    end

    
    def validate_param_values
        #TODO CloudFormation parameters have validity constraints specified
        #Use them to validate parameter values (e.g., email addresses)
    end

    def resolve_dependencies
        @templ['Resources'].each { |key,val| 
            deps = Set.new
            pdeps = Set.new
            find_refs(key, val, deps, pdeps)
            deps << val['DependsOn'] if val['DependsOn']
            #print key, " depends on ", deps.to_a, "\n"
            @deps[key] = deps.to_a
            @pdeps[key] = pdeps.to_a
        }
        @pdeps.keys.each do |k|
            unres = @pdeps[k] - @resolved.keys
            if ! unres.empty?
                unres.each do |u|
                    deflt = @param_names[u]['Default']
                    #print "Found default value ", deflt, " for ", u, "\n" if deflt
                    @resolved[u] = deflt if deflt
                end
                unres = @pdeps[k] - @resolved.keys
                throw :unresolved, (@pdeps[k] - @resolved.keys) if !unres.empty?
            end
        end
    end


    def find_refs (parent, jsn, deps, pdeps)
        case jsn
            when Array
                jsn.each {|x| find_refs(parent, x, deps, pdeps)}
                #print parent, ": ", jsn, "\n"
            when Hash
                jsn.keys.each do |k|
                    #TODO Fn::GetAtt
                    if k == "Ref"
                        #only resolve dependencies on other resources for now
                        if !@param_names.keys.index(jsn[k]) && jsn[k] != 'AWS::Region' && jsn[k] != 'AWS::StackId' && jsn[k] != 'AWS::StackName'
                            deps << jsn[k]
                            #print parent, ": ", deps.to_a, "\n"
                        else if @param_names.keys.index(jsn[k])
                            pdeps << jsn[k]
                        end
                        end
                    else
                        find_refs(parent, jsn[k], deps, pdeps)
                    end
                end
        end
        return deps
    end

    def tsort_each_node(&block)
        @deps.each_key(&block)
    end

    def tsort_each_child(name, &block)
        @deps[name].each(&block) if @deps.has_key?(name)
    end
    
end

end

{'fraction_non_alphanumeric': 0.10715550832447751, 'fraction_numerical': 0.0, 'mean_word_length': 1.4101579172001708, 'pattern_counts': {'":': 4, '<': 15, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2094093', 'n_tokens_mistral': 1754, 'n_tokens_neox': 1656, 'n_words': 414}