<commit_before># Encoding: utf-8

require 'thor'
require 'rspec'
require 'rspec/retry'
require 'chemistrykit/cli/new'
require 'chemistrykit/cli/formula'
require 'chemistrykit/cli/beaker'
require 'chemistrykit/cli/helpers/formula_loader'
require 'chemistrykit/catalyst'
require 'chemistrykit/formula/base'
require 'chemistrykit/formula/formula_lab'
require 'chemistrykit/chemist/repository/csv_chemist_repository'
require 'selenium_connect'
require 'chemistrykit/configuration'
require 'chemistrykit/rspec/j_unit_formatter'
require 'chemistrykit/rspec/retry_formatter'

require 'rspec/core/formatters/html_formatter'
require 'chemistrykit/rspec/html_formatter'

require 'chemistrykit/reporting/html_report_assembler'
require 'chemistrykit/split_testing/provider_factory'

require 'allure-rspec'

require 'rubygems'
require 'logging'
require 'rspec/logging_helper'

require 'fileutils'

module ChemistryKit
  module CLI
    # Main Chemistry Kit CLI Class
    class CKitCLI < Thor

      register(ChemistryKit::CLI::New, 'new', 'new [NAME]', 'Creates a new ChemistryKit project')

      check_unknown_options!
      default_task :help

      desc 'brew', 'Run ChemistryKit'
      method_option :params, type: :hash
      method_option :tag, type: :array
      method_option :config, default: 'config.yaml', aliases: '-c', desc: 'Supply alternative config file.'
      method_option :beakers, aliases: '-b', type: :array
      method_option :retry, default: false, aliases: '-x', desc: 'How many times should a failing test be retried.'
      method_option :all, default: false, aliases: '-a', desc: 'Run every beaker.', type: :boolean

      def brew
        config = load_config options['config']
        # TODO: perhaps the params should be rolled into the available
        # config object injected into the system?
        pass_params if options['params']

        # TODO: expand this to allow for more overrides as needed
        config.retries_on_failure = options['retry'].to_i if options['retry']

        load_page_objects

        # get those beakers that should be executed
        beakers = options['beakers'] ? options['beakers'] : Dir.glob(File.join(Dir.getwd, 'beakers/**/*')).select { |file| !File.directory?(file) }

        # if tags are explicity defined, apply them to all beakers
        setup_tags(options['tag'])

        # configure rspec
        rspec_config(config)

        # based on concurrency parameter run tests
        if config.concurrency > 1
          exit_code = run_parallel beakers, config.concurrency
        else
          exit_code = run_rspec beakers
        end

        process_html
        exit_code
      end

      protected

      def process_html
        results_folder = File.join(Dir.getwd, 'evidence')
        output_file    = File.join(Dir.getwd, 'evidence', 'final_results.html')
        assembler      = ChemistryKit::Reporting::HtmlReportAssembler.new(results_folder, output_file)
        assembler.assemble
      end

      def pass_params
        options['params'].each_pair do |key, value|
          ENV[key] = value
        end
      end

      def load_page_objects
        loader = ChemistryKit::CLI::Helpers::FormulaLoader.new
        loader.get_formulas(File.join(Dir.getwd, 'formulas')).each { |file| require file }
      end

      def load_config(file_name)
        config_file = File.join(Dir.getwd, file_name)
        ChemistryKit::Configuration.initialize_with_yaml config_file
      end

      def setup_tags(selected_tags)
        @tags = {}
        selected_tags.each do |tag|
          filter_type = tag.start_with?('~') ? :exclusion_filter : :filter

          name, value = tag.gsub(/^(~@|~|@)/, '').split(':')
          name        = name.to_sym

          value       = true if value.nil?

          @tags[filter_type]       ||= {}
          @tags[filter_type][name] = value
        end unless selected_tags.nil?
      end

      # rubocop:disable MethodLength
      def rspec_config(config)
        ::AllureRSpec.configure do |c|
          c.output_dir = "results"
        end

        ::RSpec.configure do |c|
          c.capture_log_messages

          c.include AllureRSpec::Adaptor
          c.treat_symbols_as_metadata_keys_with_true_values = true
          unless options[:all]
            c.filter_run @tags[:filter] unless @tags[:filter].nil?
            c.filter_run_excluding @tags[:exclusion_filter] unless @tags[:exclusion_filter].nil?
          end
          c.before(:all) do
            @config         = config
            ENV['BASE_URL'] = @config.base_url # assign base url to env variable for formulas
          end

          c.around(:each) do |example|
            # create the beaker name from the example data
            beaker_name     = example.metadata[:example_group][:description_args].first.downcase.strip.gsub(' ', '_').gsub(/[^\w-]/, '')
            test_name       = example.metadata[:full_description].downcase.strip.gsub(' ', '_').gsub(/[^\w-]/, '')

            # override log path with be beaker sub path
            sc_config       = @config.selenium_connect.dup
            sc_config[:log] += "/#{beaker_name}"
            beaker_path     = File.join(Dir.getwd, sc_config[:log])
            unless File.exists?(beaker_path)
              Dir.mkdir beaker_path
            end
            sc_config[:log] += "/#{test_name}"
            @test_path      = File.join(Dir.getwd, sc_config[:log])
            FileUtils.rm_rf(@test_path) if File.exists?(@test_path)
            Dir.mkdir @test_path

            # set the tags and permissions if sauce
            if sc_config[:host] == 'saucelabs' || sc_config[:host] == 'appium'
              tags       = example.metadata.reject do |key, value|
                [:example_group, :example_group_block, :description_args, :caller, :execution_result, :full_description].include? key
              end
              sauce_opts = {}
              sauce_opts.merge!(public: tags.delete(:public)) if tags.key?(:public)
              sauce_opts.merge!(tags: tags.map { |key, value| "#{key}:#{value}" }) unless tags.empty?

              if sc_config[:sauce_opts]
                sc_config[:sauce_opts].merge!(sauce_opts) unless sauce_opts.empty?
              else
                sc_config[:sauce_opts] = sauce_opts unless sauce_opts.empty?
              end

            end

            # configure and start sc
            configuration      = SeleniumConnect::Configuration.new sc_config<commit_msg>cli make beaker directory only if the directory doesn't exist (change File.exists? to Dir.exist?)<commit_after># Encoding: utf-8

require 'thor'
require 'rspec'
require 'rspec/retry'
require 'chemistrykit/cli/new'
require 'chemistrykit/cli/formula'
require 'chemistrykit/cli/beaker'
require 'chemistrykit/cli/helpers/formula_loader'
require 'chemistrykit/catalyst'
require 'chemistrykit/formula/base'
require 'chemistrykit/formula/formula_lab'
require 'chemistrykit/chemist/repository/csv_chemist_repository'
require 'selenium_connect'
require 'chemistrykit/configuration'
require 'chemistrykit/rspec/j_unit_formatter'
require 'chemistrykit/rspec/retry_formatter'

require 'rspec/core/formatters/html_formatter'
require 'chemistrykit/rspec/html_formatter'

require 'chemistrykit/reporting/html_report_assembler'
require 'chemistrykit/split_testing/provider_factory'

require 'allure-rspec'

require 'rubygems'
require 'logging'
require 'rspec/logging_helper'

require 'fileutils'

module ChemistryKit
  module CLI
    # Main Chemistry Kit CLI Class
    class CKitCLI < Thor

      register(ChemistryKit::CLI::New, 'new', 'new [NAME]', 'Creates a new ChemistryKit project')

      check_unknown_options!
      default_task :help

      desc 'brew', 'Run ChemistryKit'
      method_option :params, type: :hash
      method_option :tag, type: :array
      method_option :config, default: 'config.yaml', aliases: '-c', desc: 'Supply alternative config file.'
      method_option :beakers, aliases: '-b', type: :array
      method_option :retry, default: false, aliases: '-x', desc: 'How many times should a failing test be retried.'
      method_option :all, default: false, aliases: '-a', desc: 'Run every beaker.', type: :boolean

      def brew
        config = load_config options['config']
        # TODO: perhaps the params should be rolled into the available
        # config object injected into the system?
        pass_params if options['params']

        # TODO: expand this to allow for more overrides as needed
        config.retries_on_failure = options['retry'].to_i if options['retry']

        load_page_objects

        # get those beakers that should be executed
        beakers = options['beakers'] ? options['beakers'] : Dir.glob(File.join(Dir.getwd, 'beakers/**/*')).select { |file| !File.directory?(file) }
        
        # if tags are explicity defined, apply them to all beakers
        setup_tags(options['tag'])

        # configure rspec
        rspec_config(config)

        # based on concurrency parameter run tests
        if config.concurrency > 1
          exit_code = run_parallel beakers, config.concurrency
        else
          exit_code = run_rspec beakers
        end

        process_html
        exit_code
      end

      protected

      def process_html
        results_folder = File.join(Dir.getwd, 'evidence')
        output_file    = File.join(Dir.getwd, 'evidence', 'final_results.html')
        assembler      = ChemistryKit::Reporting::HtmlReportAssembler.new(results_folder, output_file)
        assembler.assemble
      end

      def pass_params
        options['params'].each_pair do |key, value|
          ENV[key] = value
        end
      end

      def load_page_objects
        loader = ChemistryKit::CLI::Helpers::FormulaLoader.new
        loader.get_formulas(File.join(Dir.getwd, 'formulas')).each { |file| require file }
      end

      def load_config(file_name)
        config_file = File.join(Dir.getwd, file_name)
        ChemistryKit::Configuration.initialize_with_yaml config_file
      end

      def setup_tags(selected_tags)
        @tags = {}
        selected_tags.each do |tag|
          filter_type = tag.start_with?('~') ? :exclusion_filter : :filter

          name, value = tag.gsub(/^(~@|~|@)/, '').split(':')
          name        = name.to_sym

          value       = true if value.nil?

          @tags[filter_type]       ||= {}
          @tags[filter_type][name] = value
        end unless selected_tags.nil?
      end

      # rubocop:disable MethodLength
      def rspec_config(config)
        ::AllureRSpec.configure do |c|
          c.output_dir = "results"
        end

        ::RSpec.configure do |c|
          c.capture_log_messages

          c.include AllureRSpec::Adaptor
          c.treat_symbols_as_metadata_keys_with_true_values = true
          unless options[:all]
            c.filter_run @tags[:filter] unless @tags[:filter].nil?
            c.filter_run_excluding @tags[:exclusion_filter] unless @tags[:exclusion_filter].nil?
          end
          c.before(:all) do
            @config         = config
            ENV['BASE_URL'] = @config.base_url # assign base url to env variable for formulas
          end

          c.around(:each) do |example|
            # create the beaker name from the example data
            beaker_name     = example.metadata[:example_group][:description_args].first.downcase.strip.gsub(' ', '_').gsub(/[^\w-]/, '')
            test_name       = example.metadata[:full_description].downcase.strip.gsub(' ', '_').gsub(/[^\w-]/, '')

            # override log path with be beaker sub path
            sc_config       = @config.selenium_connect.dup
            sc_config[:log] += "/#{beaker_name}"
            beaker_path     = File.join(Dir.getwd, sc_config[:log])
            Dir.mkdir beaker_path unless Dir.exist?(beaker_path)
            sc_config[:log] += "/#{test_name}"
            @test_path      = File.join(Dir.getwd, sc_config[:log])
            FileUtils.rm_rf(@test_path) if File.exists?(@test_path)
            Dir.mkdir @test_path

            # set the tags and permissions if sauce
            if sc_config[:host] == 'saucelabs' || sc_config[:host] == 'appium'
              tags       = example.metadata.reject do |key, value|
                [:example_group, :example_group_block, :description_args, :caller, :execution_result, :full_description].include? key
              end
              sauce_opts = {}
              sauce_opts.merge!(public: tags.delete(:public)) if tags.key?(:public)
              sauce_opts.merge!(tags: tags.map { |key, value| "#{key}:#{value}" }) unless tags.empty?

              if sc_config[:sauce_opts]
                sc_config[:sauce_opts].merge!(sauce_opts) unless sauce_opts.empty?
              else
                sc_config[:sauce_opts] = sauce_opts unless sauce_opts.empty?
              end

            end

            # configure and start sc
            configuration      = SeleniumConnect::Configuration.new sc_config
{'fraction_non_alphanumeric': 0.10704377311960543, 'fraction_numerical': 0.00030826140567200987, 'mean_word_length': 2.5937413458875658, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, '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': '1332370', 'n_tokens_mistral': 3874, 'n_tokens_neox': 3775, 'n_words': 885}