<commit_before>module Fastlane
  module Actions
    class SwiftlintAction < Action
      def self.run(params)
        if `which swiftlint`.to_s.length == 0 && params[:executable].nil? && !Helper.test?
          UI.user_error!("You have to install swiftlint using `brew install swiftlint` or specify the executable path with the `:executable` option.")
        end

        version = swiftlint_version(executable: params[:executable])
        if params[:mode] == :autocorrect && version < Gem::Version.new('0.5.0') && !Helper.test?
          UI.user_error!("Your version of swiftlint (#{version}) does not support autocorrect mode.\nUpdate swiftlint using `brew update && brew upgrade swiftlint`")
        end

        command = (params[:executable] || "swiftlint").dup
        command << " #{params[:mode]}"
        command << " --path #{params[:path].shellescape}" if params[:path]
        command << supported_option_switch(params, :strict, "0.9.2", true)
        command << " --config #{params[:config_file].shellescape}" if params[:config_file]
        command << " --reporter #{params[:reporter]}" if params[:reporter]
        command << supported_option_switch(params, :quiet, "0.9.0", true)
        command << supported_option_switch(params, :format, "0.11.0", true) if params[:mode] == :autocorrect
        command << " --compiler-log-path #{params[:compiler_log_path].shellescape}" if params[:compiler_log_path]

        if params[:files]
          if version < Gem::Version.new('0.5.1')
            UI.user_error!("Your version of swiftlint (#{version}) does not support list of files as input.\nUpdate swiftlint using `brew update && brew upgrade swiftlint`")
          end

          files = params[:files].map.with_index(0) { |f, i| "SCRIPT_INPUT_FILE_#{i}=#{f.shellescape}" }.join(" ")
          command = command.prepend("SCRIPT_INPUT_FILE_COUNT=#{params[:files].count} #{files} ")
          command << " --use-script-input-files"
        end

        command << " > #{params[:output_file].shellescape}" if params[:output_file]

        begin
          Actions.sh(command)
        rescue
          handle_swiftlint_error(params[:ignore_exit_status], $?.exitstatus)
        end
      end

      # Get current SwiftLint version
      def self.swiftlint_version(executable: nil)
        binary = executable || 'swiftlint'
        Gem::Version.new(`#{binary} version`.chomp)
      end

      # Return "--option" switch if option is on and current SwiftLint version is greater or equal than min version.
      # Return "" otherwise.
      def self.supported_option_switch(params, option, min_version, can_ignore = false)
        return "" unless params[option]
        version = swiftlint_version(executable: params[:executable])
        if version < Gem::Version.new(min_version)
          message = "Your version of swiftlint (#{version}) does not support '--#{option}' option.\nUpdate swiftlint to #{min_version} or above using `brew update && brew upgrade swiftlint`"
          message += "\nThe option will be ignored." if can_ignore
          can_ignore ? UI.important(message) : UI.user_error!(message)
          ""
        else
          " --#{option}"
        end
      end

      #####################################################
      # @!group Documentation
      #####################################################

      def self.description
        "Run swift code validation using SwiftLint"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(key: :mode,
                                       description: "SwiftLint mode: :lint, :autocorrect or :analyze",
                                       is_string: false,
                                       default_value: :lint,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :path,
                                       description: "Specify path to lint",
                                       is_string: true,
                                       optional: true,
                                       verify_block: proc do |value|
                                         UI.user_error!("Couldn't find path '#{File.expand_path(value)}'") unless File.exist?(value)
                                       end),
          FastlaneCore::ConfigItem.new(key: :output_file,
                                       description: 'Path to output SwiftLint result',
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :config_file,
                                       description: 'Custom configuration file of SwiftLint',
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :strict,
                                       description: 'Fail on warnings? (true/false)',
                                       default_value: false,
                                       is_string: false,
                                       type: Boolean,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :files,
                                       description: 'List of files to process',
                                       is_string: false,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :ignore_exit_status,
                                       description: "Ignore the exit status of the SwiftLint command, so that serious violations \
                                                    don't fail the build (true/false)",
                                       default_value: false,
                                       is_string: false,
                                       type: Boolean,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :reporter,
                                       description: 'Choose output reporter',
                                       is_string: true,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :quiet,
                                       description: "Don't print status logs like 'Linting <file>' & 'Done linting'",
                                       default_value: false,
                                       is_string: false,
                                       type: Boolean,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :executable,
                                       description: "Path to the `swiftlint` executable on your machine",
                                       is_string: true,<commit_msg>SwiftLint :reporter documented and validated (#15941)<commit_after>module Fastlane
  module Actions
    class SwiftlintAction < Action
      def self.run(params)
        if `which swiftlint`.to_s.length == 0 && params[:executable].nil? && !Helper.test?
          UI.user_error!("You have to install swiftlint using `brew install swiftlint` or specify the executable path with the `:executable` option.")
        end

        version = swiftlint_version(executable: params[:executable])
        if params[:mode] == :autocorrect && version < Gem::Version.new('0.5.0') && !Helper.test?
          UI.user_error!("Your version of swiftlint (#{version}) does not support autocorrect mode.\nUpdate swiftlint using `brew update && brew upgrade swiftlint`")
        end

        command = (params[:executable] || "swiftlint").dup
        command << " #{params[:mode]}"
        command << " --path #{params[:path].shellescape}" if params[:path]
        command << supported_option_switch(params, :strict, "0.9.2", true)
        command << " --config #{params[:config_file].shellescape}" if params[:config_file]
        command << " --reporter #{params[:reporter]}" if params[:reporter]
        command << supported_option_switch(params, :quiet, "0.9.0", true)
        command << supported_option_switch(params, :format, "0.11.0", true) if params[:mode] == :autocorrect
        command << " --compiler-log-path #{params[:compiler_log_path].shellescape}" if params[:compiler_log_path]

        if params[:files]
          if version < Gem::Version.new('0.5.1')
            UI.user_error!("Your version of swiftlint (#{version}) does not support list of files as input.\nUpdate swiftlint using `brew update && brew upgrade swiftlint`")
          end

          files = params[:files].map.with_index(0) { |f, i| "SCRIPT_INPUT_FILE_#{i}=#{f.shellescape}" }.join(" ")
          command = command.prepend("SCRIPT_INPUT_FILE_COUNT=#{params[:files].count} #{files} ")
          command << " --use-script-input-files"
        end

        command << " > #{params[:output_file].shellescape}" if params[:output_file]

        begin
          Actions.sh(command)
        rescue
          handle_swiftlint_error(params[:ignore_exit_status], $?.exitstatus)
        end
      end

      # Get current SwiftLint version
      def self.swiftlint_version(executable: nil)
        binary = executable || 'swiftlint'
        Gem::Version.new(`#{binary} version`.chomp)
      end

      # Return "--option" switch if option is on and current SwiftLint version is greater or equal than min version.
      # Return "" otherwise.
      def self.supported_option_switch(params, option, min_version, can_ignore = false)
        return "" unless params[option]
        version = swiftlint_version(executable: params[:executable])
        if version < Gem::Version.new(min_version)
          message = "Your version of swiftlint (#{version}) does not support '--#{option}' option.\nUpdate swiftlint to #{min_version} or above using `brew update && brew upgrade swiftlint`"
          message += "\nThe option will be ignored." if can_ignore
          can_ignore ? UI.important(message) : UI.user_error!(message)
          ""
        else
          " --#{option}"
        end
      end

      #####################################################
      # @!group Documentation
      #####################################################

      def self.description
        "Run swift code validation using SwiftLint"
      end

      def self.available_options
        [
          FastlaneCore::ConfigItem.new(key: :mode,
                                       description: "SwiftLint mode: :lint, :autocorrect or :analyze",
                                       is_string: false,
                                       default_value: :lint,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :path,
                                       description: "Specify path to lint",
                                       is_string: true,
                                       optional: true,
                                       verify_block: proc do |value|
                                         UI.user_error!("Couldn't find path '#{File.expand_path(value)}'") unless File.exist?(value)
                                       end),
          FastlaneCore::ConfigItem.new(key: :output_file,
                                       description: 'Path to output SwiftLint result',
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :config_file,
                                       description: 'Custom configuration file of SwiftLint',
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :strict,
                                       description: 'Fail on warnings? (true/false)',
                                       default_value: false,
                                       is_string: false,
                                       type: Boolean,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :files,
                                       description: 'List of files to process',
                                       is_string: false,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :ignore_exit_status,
                                       description: "Ignore the exit status of the SwiftLint command, so that serious violations \
                                                    don't fail the build (true/false)",
                                       default_value: false,
                                       is_string: false,
                                       type: Boolean,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :reporter,
                                       description: "Choose output reporter. Available: xcode, json, csv, checkstyle, junit, html, \
                                                     emoji, sonarqube, markdown, github-actions-logging",
                                       is_string: true,
                                       optional: true,
                                       verify_block: proc do |value|
                                         available = ['xcode', 'json', 'csv', 'checkstyle', 'junit', 'html', 'emoji', 'sonarqube', 'markdown', 'github-actions-logging']
                                         UI.user_error!("Available values are '#{available.join("', '")}'") unless available.include?(value)
                                       end),
          FastlaneCore::ConfigItem.new(key: :quiet,
                                       description: "Don't print status logs like 'Linting <file>' & 'Done linting'",
                                       default_value: false,
                                       is_string: false,
                                       type: Boolean,
                                       optional: true),
          FastlaneCore::ConfigItem.new(key: :executable,
                                       description: "Path to the `swiftlint` executable on your machine",
                                       is_string: true,
{'fraction_non_alphanumeric': 0.11349693251533742, 'fraction_numerical': 0.002924810957340562, 'mean_word_length': 1.5241267554915376, 'pattern_counts': {'":': 0, '<': 53, '<?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': 88, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4141308', 'n_tokens_mistral': 3346, 'n_tokens_neox': 3200, 'n_words': 849}