<commit_before>module StackMaster
  module Commands
    class Apply
      include Command
      include Commander::UI
      include StackMaster::Prompter

      def initialize(config, stack_definition, options = {})
        @config = config
        @s3_config = stack_definition.s3
        @stack_definition = stack_definition
        @from_time = Time.now
        @updating = false
      end

      def perform
        diff_stacks
        unless ask?("Continue and apply the stack (y/n)? ")
          StackMaster.stdout.puts "Stack update aborted"
          return
        end
        begin
          return if stack_too_big
          upload_files if use_s3?
          create_or_update_stack
          tail_stack_events
        rescue StackMaster::CtrlC
          cancel
        end
      rescue Aws::CloudFormation::Errors::ServiceError => e
        StackMaster.stdout.puts "#{e.class} #{e.message}"
      end

      private

      def cf
        @cf ||= StackMaster.cloud_formation_driver
      end

      def s3
        @s3 ||= StackMaster.s3_driver
      end

      def stack
        @stack ||= Stack.find(@stack_definition.region, @stack_definition.stack_name)
      end

      def proposed_stack
        @proposed_stack ||= Stack.generate(@stack_definition, @config)
      end

      def stack_exists?
        !stack.nil?
      end

      def use_s3?
        !@s3_config.empty?
      end

      def diff_stacks
        StackDiffer.new(proposed_stack, stack).output_diff
      end

      def cancel
        if @updating
          if ask?("Cancel stack update?")
            StackMaster.stdout.puts "Attempting to cancel stack update"
            cf.cancel_update_stack({stack_name: @stack_definition.stack_name})
            tail_stack_events
          end
        end
      end

      def create_or_update_stack
        if stack_exists?
          update_stack
        else
          create_stack
        end
      end

      def stack_too_big
        if proposed_stack.too_big?(use_s3?)
          StackMaster.stdout.puts 'The (space compressed) stack is larger than the limit set by AWS. See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'
          true
        else
          false
        end
      end

      def update_stack
        @updating = true
        cf.update_stack(stack_options)
      end

      def create_stack
        cf.create_stack(stack_options.merge(tags: proposed_stack.aws_tags))
      end

      def upload_files
        s3.upload_files(s3_options)
      end

      def template_method
        return :template_body unless use_s3?
        :template_url
      end

      def template_value
        return proposed_stack.maybe_compressed_template_body unless use_s3?
        s3.url(bucket: @s3_config['bucket'], prefix: @s3_config['prefix'], region: @s3_config['region'], template: @stack_definition.template)
      end

      def files_to_upload
        return {} unless use_s3?
        {
          @stack_definition.template => {
            :path => @stack_definition.template_file_path,
            :body => proposed_stack.compiled_template_body
          }
        }
      end

      def stack_options
        {
          stack_name: @stack_definition.stack_name,<commit_msg>reverting to old name.<commit_after>module StackMaster
  module Commands
    class Apply
      include Command
      include Commander::UI
      include StackMaster::Prompter

      def initialize(config, stack_definition, options = {})
        @config = config
        @s3_config = stack_definition.s3
        @stack_definition = stack_definition
        @from_time = Time.now
        @updating = false
      end

      def perform
        diff_stacks
        unless ask?("Continue and apply the stack (y/n)? ")
          StackMaster.stdout.puts "Stack update aborted"
          return
        end
        begin
          return if stack_too_big
          upload_files if use_s3?
          create_or_update_stack
          tail_stack_events
        rescue StackMaster::CtrlC
          cancel
        end
      rescue Aws::CloudFormation::Errors::ServiceError => e
        StackMaster.stdout.puts "#{e.class} #{e.message}"
      end

      private

      def cf
        @cf ||= StackMaster.cloud_formation_driver
      end

      def s3
        @s3 ||= StackMaster.s3_driver
      end

      def stack
        @stack ||= Stack.find(@stack_definition.region, @stack_definition.stack_name)
      end

      def proposed_stack
        @proposed_stack ||= Stack.generate(@stack_definition, @config)
      end

      def stack_exists?
        !stack.nil?
      end

      def use_s3?
        !@s3_config.empty?
      end

      def diff_stacks
        StackDiffer.new(proposed_stack, stack).output_diff
      end

      def cancel
        if @updating
          if ask?("Cancel stack update?")
            StackMaster.stdout.puts "Attempting to cancel stack update"
            cf.cancel_update_stack({stack_name: @stack_definition.stack_name})
            tail_stack_events
          end
        end
      end

      def create_or_update_stack
        if stack_exists?
          update_stack
        else
          create_stack
        end
      end

      def stack_too_big
        if proposed_stack.too_big?(use_s3?)
          StackMaster.stdout.puts 'The (space compressed) stack is larger than the limit set by AWS. See http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html'
          true
        else
          false
        end
      end

      def update_stack
        @updating = true
        cf.update_stack(stack_options)
      end

      def create_stack
        cf.create_stack(stack_options.merge(tags: proposed_stack.aws_tags))
      end

      def upload_files
        s3.upload_files(s3_options)
      end

      def template_method
        return :template_body unless use_s3?
        :template_url
      end

      def template_value
        return proposed_stack.maybe_compressed_template_body unless use_s3?
        s3.url(bucket: @s3_config['bucket'], prefix: @s3_config['prefix'], region: @s3_config['region'], template: @stack_definition.template)
      end

      def files_to_upload
        return {} unless use_s3?
        {
          @stack_definition.template => {
            :path => @stack_definition.template_file_path,
            :body => proposed_stack.maybe_compressed_template_body
          }
        }
      end

      def stack_options
        {
          stack_name: @stack_definition.stack_name,
{'fraction_non_alphanumeric': 0.06946787302560957, 'fraction_numerical': 0.00552062567090937, 'mean_word_length': 1.965893587994543, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, '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': '7300767', 'n_tokens_mistral': 1868, 'n_tokens_neox': 1825, 'n_words': 412}