<commit_before>require 'optparse'

module Spinach
  # The cli is a class responsible of handling all the command line interface
  # logic.
  #
  class Cli
    # @param [Array<String>] arguments
    #   The command line arguments
    #
    # @api public
    def initialize(args = ARGV)
      @args = args
    end

    # Runs all the features.
    #
    # @return [true, false]
    #   The exit status - true for success, false for failure.
    #
    # @api public
    def run
      Spinach::Runner.new(feature_files).run
    end

    # Inits the reporter with a default one.
    #
    # @api public
    def init_reporter
      reporter = Spinach::Reporter::Stdout.new(options[:reporter])
      reporter.bind
    end

    # @return [Hash]
    #   A hash of options separated by its type.
    #
    # @example
    #   Cli.new.options
    #   # => { reporter: { backtrace: true } }
    #
    # @api public
    def options
      @options ||= parse_options
    end

    private

    # Parses the arguments into options.
    #
    # @return [Hash]
    #   A hash of options separated by its type.
    #
    # @api private
    def parse_options
      reporter_options = {}
      reporter_options[:backtrace] = false
      config = {}
      config[:tags] = []

      begin
        OptionParser.new do |opts|
          opts.on('-c', '--config_path PATH',
                  'Parse options from file (will get overriden by flags)') do |file|
            Spinach.config[:config_path] = file
          end

          opts.on('-b', '--backtrace',
                  'Show backtrace of errors') do |show_backtrace|
            reporter_options[:backtrace] = show_backtrace
          end

          opts.on('-t', '--tags TAG',
                  'Run all scenarios for given tags.') do |tag|
            tags = tag.delete('@').split(',')

            references_wip = lambda { |tag_groups|
              tag_groups.any? { |tag_group|
                tag_group.any? { |tag| tag =~ /wip$/ }
              }
            }

            unless references_wip.(config[:tags]) || references_wip.([tags])
              tags.unshift '~wip'
            end

            config[:tags] << tags
          end

          opts.on('-g', '--generate',
                  'Auto-generate the feature steps files') do
            Spinach::Generators.bind
          end<commit_msg>Refactor internals of --tag option parsing<commit_after>require 'optparse'

module Spinach
  # The cli is a class responsible of handling all the command line interface
  # logic.
  #
  class Cli
    # @param [Array<String>] arguments
    #   The command line arguments
    #
    # @api public
    def initialize(args = ARGV)
      @args = args
    end

    # Runs all the features.
    #
    # @return [true, false]
    #   The exit status - true for success, false for failure.
    #
    # @api public
    def run
      Spinach::Runner.new(feature_files).run
    end

    # Inits the reporter with a default one.
    #
    # @api public
    def init_reporter
      reporter = Spinach::Reporter::Stdout.new(options[:reporter])
      reporter.bind
    end

    # @return [Hash]
    #   A hash of options separated by its type.
    #
    # @example
    #   Cli.new.options
    #   # => { reporter: { backtrace: true } }
    #
    # @api public
    def options
      @options ||= parse_options
    end

    private

    # Parses the arguments into options.
    #
    # @return [Hash]
    #   A hash of options separated by its type.
    #
    # @api private
    def parse_options
      reporter_options = {}
      reporter_options[:backtrace] = false
      config = {}
      config[:tags] = []

      begin
        OptionParser.new do |opts|
          opts.on('-c', '--config_path PATH',
                  'Parse options from file (will get overriden by flags)') do |file|
            Spinach.config[:config_path] = file
          end

          opts.on('-b', '--backtrace',
                  'Show backtrace of errors') do |show_backtrace|
            reporter_options[:backtrace] = show_backtrace
          end

          opts.on('-t', '--tags TAG',
                  'Run all scenarios for given tags.') do |tag|
            tags = tag.delete('@').split(',')

            if (config[:tags] + tags).flatten.none? { |t| t =~ /wip$/ }
              tags.unshift '~wip'
            end

            config[:tags] << tags
          end

          opts.on('-g', '--generate',
                  'Auto-generate the feature steps files') do
            Spinach::Generators.bind
          end
{'fraction_non_alphanumeric': 0.11032500552730488, 'fraction_numerical': 0.0, 'mean_word_length': 1.738498789346247, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 7, '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': '2926107', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1318, 'n_words': 382}