class Fastlane::Actions::OclintAction

Public Class Methods

author() click to toggle source
# File fastlane/lib/fastlane/actions/oclint.rb, line 225
def self.author
  'HeEAaD'
end
available_options() click to toggle source
# File fastlane/lib/fastlane/actions/oclint.rb, line 120
def self.available_options
  [
    FastlaneCore::ConfigItem.new(key: :oclint_path,
                                 env_name: 'FL_OCLINT_PATH',
                                 description: 'The path to oclint binary',
                                 default_value: 'oclint',
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :compile_commands,
                                 env_name: 'FL_OCLINT_COMPILE_COMMANDS',
                                 description: 'The json compilation database, use xctool reporter \'json-compilation-database\'',
                                 default_value: 'compile_commands.json',
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :select_reqex,
                                 env_name: 'FL_OCLINT_SELECT_REQEX',
                                 description: 'Select all files matching this reqex',
                                 skip_type_validation: true, # allows Regex
                                 deprecated: "Use `:select_regex` instead",
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :select_regex,
                                 env_name: 'FL_OCLINT_SELECT_REGEX',
                                 description: 'Select all files matching this regex',
                                 skip_type_validation: true, # allows Regex
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :exclude_regex,
                                 env_name: 'FL_OCLINT_EXCLUDE_REGEX',
                                 description: 'Exclude all files matching this regex',
                                 skip_type_validation: true, # allows Regex
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :report_type,
                                 env_name: 'FL_OCLINT_REPORT_TYPE',
                                 description: 'The type of the report (default: html)',
                                 default_value: 'html',
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :report_path,
                                 env_name: 'FL_OCLINT_REPORT_PATH',
                                 description: 'The reports file path',
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :list_enabled_rules,
                                 env_name: "FL_OCLINT_LIST_ENABLED_RULES",
                                 description: "List enabled rules",
                                 type: Boolean,
                                 default_value: false),
    FastlaneCore::ConfigItem.new(key: :rc,
                                 env_name: 'FL_OCLINT_RC',
                                 description: 'Override the default behavior of rules',
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :thresholds,
                                 env_name: 'FL_OCLINT_THRESHOLDS',
                                 description: 'List of rule thresholds to override the default behavior of rules',
                                 type: Array,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :enable_rules,
                                 env_name: 'FL_OCLINT_ENABLE_RULES',
                                 description: 'List of rules to pick explicitly',
                                 type: Array,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :disable_rules,
                                 env_name: 'FL_OCLINT_DISABLE_RULES',
                                 description: 'List of rules to disable',
                                 type: Array,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :max_priority_1,
                                 env_name: 'FL_OCLINT_MAX_PRIOTITY_1',
                                 description: 'The max allowed number of priority 1 violations',
                                 type: Integer,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :max_priority_2,
                                 env_name: 'FL_OCLINT_MAX_PRIOTITY_2',
                                 description: 'The max allowed number of priority 2 violations',
                                 type: Integer,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :max_priority_3,
                                 env_name: 'FL_OCLINT_MAX_PRIOTITY_3',
                                 description: 'The max allowed number of priority 3 violations',
                                 type: Integer,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :enable_clang_static_analyzer,
                                 env_name: "FL_OCLINT_ENABLE_CLANG_STATIC_ANALYZER",
                                 description: "Enable Clang Static Analyzer, and integrate results into OCLint report",
                                 type: Boolean,
                                 default_value: false),
    FastlaneCore::ConfigItem.new(key: :enable_global_analysis,
                                 env_name: "FL_OCLINT_ENABLE_GLOBAL_ANALYSIS",
                                 description: "Compile every source, and analyze across global contexts (depends on number of source files, could results in high memory load)",
                                 type: Boolean,
                                 default_value: false),
    FastlaneCore::ConfigItem.new(key: :allow_duplicated_violations,
                                 env_name: "FL_OCLINT_ALLOW_DUPLICATED_VIOLATIONS",
                                 description: "Allow duplicated violations in the OCLint report",
                                 type: Boolean,
                                 default_value: false),
    FastlaneCore::ConfigItem.new(key: :extra_arg,
                                 env_name: 'FL_OCLINT_EXTRA_ARG',
                                 description: 'Additional argument to append to the compiler command line',
                                 optional: true)
  ]
end
category() click to toggle source
# File fastlane/lib/fastlane/actions/oclint.rb, line 265
def self.category
  :testing
end
description() click to toggle source

@!group Documentation

# File fastlane/lib/fastlane/actions/oclint.rb, line 116
def self.description
  "Lints implementation files with OCLint"
end
details() click to toggle source
# File fastlane/lib/fastlane/actions/oclint.rb, line 233
def self.details
  "Run the static analyzer tool [OCLint](http://oclint.org) for your project. You need to have a `compile_commands.json` file in your _fastlane_ directory or pass a path to your file."
end
ensure_array_is_not_string!(array) click to toggle source

return a proper array of strings if array string is single-quoted

# File fastlane/lib/fastlane/actions/oclint.rb, line 106
def self.ensure_array_is_not_string!(array)
  return array unless array.kind_of?(String)

  array.split(',')
end
ensure_regex_is_not_string!(regex) click to toggle source

return a proper regex object if regex string is single-quoted

# File fastlane/lib/fastlane/actions/oclint.rb, line 99
def self.ensure_regex_is_not_string!(regex)
  return regex unless regex.kind_of?(String)

  Regexp.new(regex)
end
example_code() click to toggle source
# File fastlane/lib/fastlane/actions/oclint.rb, line 237
def self.example_code
  [
    'oclint(
      compile_commands: "commands.json",    # The JSON compilation database, use xctool reporter "json-compilation-database"
      select_regex: /ViewController.m/,     # Select all files matching this regex
      exclude_regex: /Test.m/,              # Exclude all files matching this regex
      report_type: "pmd",                   # The type of the report (default: html)
      max_priority_1: 10,                   # The max allowed number of priority 1 violations
      max_priority_2: 100,                  # The max allowed number of priority 2 violations
      max_priority_3: 1000,                 # The max allowed number of priority 3 violations
      thresholds: [                         # Override the default behavior of rules
        "LONG_LINE=200",
        "LONG_METHOD=200"
      ],
      enable_rules: [                       # List of rules to pick explicitly
        "DoubleNegative",
        "SwitchStatementsDon\'TNeedDefaultWhenFullyCovered"
      ],
      disable_rules: ["GotoStatement"],     # List of rules to disable
      list_enabled_rules: true,             # List enabled rules
      enable_clang_static_analyzer: true,   # Enable Clang Static Analyzer, and integrate results into OCLint report
      enable_global_analysis: true,         # Compile every source, and analyze across global contexts (depends on number of source files, could results in high memory load)
      allow_duplicated_violations: true,    # Allow duplicated violations in the OCLint report
      extra_arg: "-Wno-everything"          # Additional argument to append to the compiler command line
    )'
  ]
end
is_supported?(platform) click to toggle source
# File fastlane/lib/fastlane/actions/oclint.rb, line 229
def self.is_supported?(platform)
  true
end
output() click to toggle source

rubocop:enable Metrics/PerceivedComplexity

# File fastlane/lib/fastlane/actions/oclint.rb, line 219
def self.output
  [
    ['FL_OCLINT_REPORT_PATH', 'The reports file path']
  ]
end
run(params) click to toggle source

rubocop:disable Metrics/PerceivedComplexity

# File fastlane/lib/fastlane/actions/oclint.rb, line 9
def self.run(params)
  oclint_path = params[:oclint_path]
  if `which #{oclint_path}`.to_s.empty? && !Helper.test?
    UI.user_error!("You have to install oclint or provide path to oclint binary. Fore more details: ") + "http://docs.oclint.org/en/stable/intro/installation.html".yellow
  end

  compile_commands = params[:compile_commands]
  compile_commands_dir = params[:compile_commands]
  UI.user_error!("Could not find json compilation database at path '#{compile_commands}'") unless File.exist?(compile_commands)

  # We'll attempt to sort things out so that we support receiving either a path to a
  # 'compile_commands.json' file (as our option asks for), or a path to a directory
  # *containing* a 'compile_commands.json' file (as oclint actually wants)
  if File.file?(compile_commands_dir)
    compile_commands_dir = File.dirname(compile_commands_dir)
  else
    compile_commands = File.join(compile_commands_dir, 'compile_commands.json')
  end

  if params[:select_reqex]
    UI.important("'select_reqex' parameter is deprecated. Please use 'select_regex' instead.")
    select_regex = params[:select_reqex]
  end

  select_regex = params[:select_regex] if params[:select_regex] # Overwrite deprecated select_reqex
  select_regex = ensure_regex_is_not_string!(select_regex)

  exclude_regex = params[:exclude_regex]
  exclude_regex = ensure_regex_is_not_string!(exclude_regex)

  files = JSON.parse(File.read(compile_commands)).map do |compile_command|
    file = compile_command['file']
    File.exist?(file) ? file : File.join(compile_command['directory'], file)
  end

  files.uniq!
  files.select! do |file|
    file_ruby = file.gsub('\ ', ' ')
    File.exist?(file_ruby) and
      (!select_regex or file_ruby =~ select_regex) and
      (!exclude_regex or file_ruby !~ exclude_regex)
  end

  command_prefix = [
    'cd',
    File.expand_path('.').shellescape,
    '&&'
  ].join(' ')

  report_type = params[:report_type]
  report_path = params[:report_path] ? params[:report_path] : 'oclint_report.' + report_type

  oclint_args = ["-report-type=#{report_type}", "-o=#{report_path}"]

  oclint_args << "-list-enabled-rules" if params[:list_enabled_rules]

  if params[:rc]
    UI.important("It's recommended to use 'thresholds' instead of deprecated 'rc' parameter")
    oclint_args << "-rc=#{params[:rc]}" if params[:rc] # Deprecated
  end

  oclint_args << ensure_array_is_not_string!(params[:thresholds]).map { |t| "-rc=#{t}" } if params[:thresholds]
  # Escape ' in rule names with \' when passing on to shell command
  oclint_args << params[:enable_rules].map { |r| "-rule #{r.shellescape}" } if params[:enable_rules]
  oclint_args << params[:disable_rules].map { |r| "-disable-rule #{r.shellescape}" } if params[:disable_rules]

  oclint_args << "-max-priority-1=#{params[:max_priority_1]}" if params[:max_priority_1]
  oclint_args << "-max-priority-2=#{params[:max_priority_2]}" if params[:max_priority_2]
  oclint_args << "-max-priority-3=#{params[:max_priority_3]}" if params[:max_priority_3]

  oclint_args << "-enable-clang-static-analyzer" if params[:enable_clang_static_analyzer]
  oclint_args << "-enable-global-analysis" if params[:enable_global_analysis]
  oclint_args << "-allow-duplicated-violations" if params[:allow_duplicated_violations]
  oclint_args << "-p #{compile_commands_dir.shellescape}"

  oclint_args << "-extra-arg=#{params[:extra_arg]}" if params[:extra_arg]

  command = [
    command_prefix,
    oclint_path,
    oclint_args,
    '"' + files.join('" "') + '"'
  ].join(' ')

  Actions.lane_context[SharedValues::FL_OCLINT_REPORT_PATH] = File.expand_path(report_path)

  return Action.sh(command)
end