class Fastlane::Actions::CodeStaticAnalyzerAction
Constants
- RESULT_FILE
- SUPPORTED_ANALYZER
Attributes
checked_pmd[R]
checked_pmd[RW]
checked_xcode_param[RW]
run_main[RW]
xml_content[RW]
Public Class Methods
add_root_path(root, file_list, is_inspected)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 191 def self.add_root_path(root, file_list, is_inspected) file_list_str = '' if file_list.nil? || file_list.empty? file_list_str = "'#{root}'" if is_inspected else file_list.each do |file| file_path = "#{root}#{file}" file_path = file_path.sub("//", '/') file_path = file_path.sub("/./", '/') file_list_str += "'#{file_path}' " end end file_list_str end
add_xml_content(root, analyzer_name, temp_result_file, info)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 130 def self.add_xml_content(root, analyzer_name, temp_result_file, info) UI.error "#{analyzer_name} analyzer failed to create temporary result file. More info in #{root}#{RESULT_FILE}" new_line = JunitParser.xml_level(3) if info.empty? info = "Don't see #{temp_result_file} file.#{new_line}Try to run command with --verbose" \ " to see warnings made by used analyzers" end failures = JunitParser.add_failure('', 'unexisted result file', "#{new_line}#{info}") @xml_content += JunitParser.add_failed_testcase("#{analyzer_name} analyzer crash", failures) end
analyzers_xml()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 118 def self.analyzers_xml @xml_content end
available_options()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 269 def self.available_options [ FastlaneCore::ConfigItem.new(key: :analyzers, env_name: "FL_CSA_RUN_ANALYZERS", description: "List of analysers you want to run. Supported analyzers: #{SUPPORTED_ANALYZER}", optional: false, type: Array, verify_block: proc do |value| UI.message '[!] Will be run all analyzers'.blue if (value and value.empty?) or value[0] == 'all' value.each do |run_analyzer| UI.user_error!("The analyzer '#{run_analyzer}' is not supported. Supported analyzers: #{SUPPORTED_ANALYZER}, 'all'") unless SUPPORTED_ANALYZER.map(&:downcase).include? run_analyzer.downcase or run_analyzer == 'all' end end), FastlaneCore::ConfigItem.new(key: :disable_junit, env_name: "FL_CSA_DISABLED_JUNIT_RESULTS", description: "List of analysers for which you want to disable results in JUnit format. Supported analyzers: #{SUPPORTED_ANALYZER}, 'all'", optional: true, type: Array), FastlaneCore::ConfigItem.new(key: :result_dir, env_name: "CSA_RESULT_DIR_NAME", description: "Directory's name for storing analysis results", optional: true, type: String, default_value: 'artifacts'), # parameters for CPD analyzer FastlaneCore::ConfigItem.new(key: :cpd_tokens, description: "The min number of words in code that is detected as copy paste", optional: true, type: String, default_value: '100'), FastlaneCore::ConfigItem.new(key: :cpd_files_to_inspect, description: "List of files and directories (relative to work directory) to inspect on copy paste", optional: true, type: Array), FastlaneCore::ConfigItem.new(key: :cpd_files_to_exclude, description: "List of files and directories (relative to work directory) not to inspect on copy paste", optional: true, type: Array), FastlaneCore::ConfigItem.new(key: :cpd_language, description: "Language used in files that will be inspected on copy paste.\nSupported analyzers: #{Actions::CpdAnalyzerAction::SUPPORTED_LAN} or don't set if you need any other language", optional: true, type: String, verify_block: proc do |value| UI.user_error!("Language '#{value}' is not supported.\nSupported languages: #{Actions::CpdAnalyzerAction::SUPPORTED_LAN}") unless Actions::CpdAnalyzerAction::SUPPORTED_LAN.map(&:downcase).include? value.downcase or value.empty? or !value end), # parameters for Ruby analyzer FastlaneCore::ConfigItem.new(key: :ruby_files, description: "List of path (relative to work directory) to ruby files to be inspected on warnings & syntax", optional: true, type: Array), # parameters for Warnings analyzer FastlaneCore::ConfigItem.new(key: :xcode_project_name, # required in analyzer description: "Xcode project name in work directory", optional: true, type: String), FastlaneCore::ConfigItem.new(key: :xcode_workspace_name, description: "Xcode workspace name in work directory", optional: true, type: String), FastlaneCore::ConfigItem.new(key: :xcode_targets, description: "List of Xcode targets to inspect", optional: true, type: Array), # parameters for Clang analyzer-formatter FastlaneCore::ConfigItem.new(key: :clang_basic_style, description: "Style ... ? ... .\nSupported styles: #{Actions::ClangAnalyzerAction::SUPPORTED_STYLE}", optional: true, type: String, verify_block: proc do |value| UI.user_error!("This style is not supported. Supported languages: #{Actions::ClangAnalyzerAction::SUPPORTED_STYLE}") unless Actions::ClangAnalyzerAction::SUPPORTED_STYLE.map(&:downcase).include? value.downcase or value.empty? or !value end, default_value:'custom'), FastlaneCore::ConfigItem.new(key: :clang_dir_to_inspect, description: "List of directories (relative to work directory) to inspect on clang styling", optional: true, type: Array), FastlaneCore::ConfigItem.new(key: :clang_dir_to_exclude, description: "List of directories (relative to work directory) not to inspect on clang styling", optional: true, type: Array), FastlaneCore::ConfigItem.new(key: :files_extention, description: "List of extentions of inspected files", optional: true, type: Array), FastlaneCore::ConfigItem.new(key: :clang_autocorrect, description: "--?", optional: true, is_string: false) ] end
check_file_exist(work_dir, file, parameter_name)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 181 def self.check_file_exist(work_dir, file, parameter_name) if file.kind_of?(Array) file.each do |file_path| UI.user_error!("Unexisted path '#{work_dir}#{file_path}'. Check '#{parameter_name}' parameter. Files should be relative to work directory '#{work_dir}'") if Dir.glob("#{work_dir}#{file_path}").empty? end else UI.user_error!("Unexisted path '#{work_dir}#{file}'. Check '#{parameter_name}' parameter. Files should be relative to work directory '#{work_dir}'") if Dir.glob("#{work_dir}#{file}").empty? end end
checked_xcode()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 126 def self.checked_xcode @checked_xcode_param end
create_analyzers_run_result(result_dir)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 141 def self.create_analyzers_run_result(result_dir) unless @xml_content.empty? junit_xml = JunitParser.add_testsuite('static anlyzers', @xml_content) JunitParser.create_junit_xml(junit_xml, "#{result_dir}/#{RESULT_FILE}") end end
description()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 250 def self.description "Runs different Static Analyzers and generate report" end
details()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 262 def self.details # Optional: "This plugins is the helper for checking code on warnings, copypaste, syntax, etc.\n" \ "Each analyzer in this plugin save result status in shared values <NAME>_ANALYZER_STATUS: 0 - code is clear, any other value - code include warnings/errors.\n" \ "Also each analyzer save results in separate file: codeAnalysResult_<name of analyzer>.xml" end
is_include(list, value)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 156 def self.is_include(list, value) if list list = list.map(&:downcase) value = value.downcase return (list.include? value) ? true : false else return false end end
is_installed(command_name, for_analyzer)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 166 def self.is_installed(command_name, for_analyzer) @checked_pmd = false begin Actions.sh("which #{command_name}") #pmd rescue UI.user_error! "#{command_name} not installed. Please, install #{command_name} for using #{for_analyzer}." end @checked_pmd = true end
is_supported?(platform)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 367 def self.is_supported?(platform) # Adjust this if your plugin only works for a particular platform (iOS vs. Android, for example) # See: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Platforms.md # # [:ios, :mac, :android].include?(platform) true end
output()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 360 def self.output # Define the shared values you are going to provide [ ['ANALYZER_STATUS', 'Code analysis result (0 - code is clear, any other value - code include warnings/errors/etc.)'] ] end
return_value()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 258 def self.return_value # If your method provides a return value, you can describe here what it does end
run(params)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 16 def self.run(params) @run_main = true Actions::CodeStaticAnalyzerAction.is_installed('pmd','copy paste analyzer') platform = Actions.lane_context[SharedValues::PLATFORM_NAME].to_s @xml_content = '' root_dir = work_dir analyzers = params[:analyzers] analyzers = SUPPORTED_ANALYZER if (analyzers and analyzers.empty?) or analyzers[0] == 'all' xcode_project = params[:xcode_project_name] xcode_workspace = params[:xcode_workspace_name] xcode_targets = params[:xcode_targets] # use additional checks for optional parameters, but required in specific analyzer exclude_junit = params[:disable_junit] if exclude_junit exclude_junit.each do |exclude_from| UI.error "disable_junit parameter is partly skipped: the analyzer '#{exclude_from}' is not supported. Supported analyzers: #{SUPPORTED_ANALYZER}, 'all'" unless SUPPORTED_ANALYZER.map(&:downcase).include? exclude_from.downcase or exclude_from == 'all' end exclude_junit = SUPPORTED_ANALYZER if exclude_junit[0] == 'all' end analyzers.each do |analyzer| case analyzer.downcase when 'xcodewar' UI.user_error!("No project name for Warnings Analyzer given. Pass using `xcode_project` or configure analyzers to run using `analyzers`") if !xcode_project or (xcode_project and xcode_project.empty?) and platform != 'android' checked_params = xcode_check_parameters(root_dir, xcode_project, xcode_workspace, xcode_targets) xcode_project = checked_params[0] xcode_workspace = checked_params[1] xcode_targets = checked_params[2] end end status_rubocop = 0 status_static = 0 status_clang = 0 clear_all_files = "#{root_dir}#{params[:result_dir]}/*.*" # clear_temp_files = "#{root_dir}#{params[:result_dir]}/*temp*.*" sh "rm -rf #{clear_all_files}" # Run alyzers use_junit = is_include(exclude_junit, "cpd") ? false : true status_cpd = Actions::CpdAnalyzerAction.run( result_dir: params[:result_dir], use_junit_format: use_junit, tokens: params[:cpd_tokens], language: params[:cpd_language], cpd_files_to_inspect: params[:cpd_files_to_inspect], cpd_files_to_exclude: params[:cpd_files_to_exclude] ) analyzers.each do |analyzer| case analyzer.downcase when 'xcodewar' use_junit = is_include(exclude_junit, "xcodewar") ? false : true if platform != "android" status_static = Actions::WarningAnalyzerAction.run( result_dir: params[:result_dir], xcode_project_name: xcode_project, xcode_workspace_name: xcode_workspace, xcode_targets: xcode_targets, use_junit_format: use_junit ) end when 'rubocop' use_junit = is_include(exclude_junit, "rubocop") ? false : true status_rubocop = Actions::RubyAnalyzerAction.run( result_dir: params[:result_dir], ruby_files: params[:ruby_files], use_junit_format: use_junit ) when 'clang' autofix = params[:clang_autocorrect]==nil ? false : params[:clang_autocorrect] status_clang = Actions::ClangAnalyzerAction.run( basic_style: params[:clang_basic_style], files_extention: params[:files_extention], clang_dir_to_inspect: params[:clang_dir_to_inspect], clang_dir_to_exclude: params[:clang_dir_to_exclude], result_dir: params[:result_dir], autocorrect: autofix ) end end # sh "rm -rf #{clear_temp_files}" create_analyzers_run_result("#{root_dir}#{params[:result_dir]}/") if Actions::CodeStaticAnalyzerAction.status_to_boolean(status_cpd) && Actions::CodeStaticAnalyzerAction.status_to_boolean(status_static) && Actions::CodeStaticAnalyzerAction.status_to_boolean(status_rubocop) && Actions::CodeStaticAnalyzerAction.status_to_boolean(status_clang) Actions.lane_context[SharedValues::ANALYZER_STATUS] = true else Actions.lane_context[SharedValues::ANALYZER_STATUS] = false end end
run_from_main_action()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 114 def self.run_from_main_action @run_main end
start_xml_content()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 110 def self.start_xml_content @xml_content = "" end
status_to_boolean(var)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 148 def self.status_to_boolean(var) if var == 0 or var == '0' or var == true or var == 'true' return true else return false end end
work_dir()
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 176 def self.work_dir directory = Dir.pwd directory + "/" unless directory.end_with? "/" end
xcode_check_parameters(root_dir, project, workspace, targets)
click to toggle source
# File lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb, line 206 def self.xcode_check_parameters(root_dir, project, workspace, targets) @checked_xcode_param = false if Actions.lane_context[SharedValues::PLATFORM_NAME] == 'android' UI.user_error! 'This warning_analyzer not supported for ios platform' else unless project.empty? project += '.xcodeproj' unless project.end_with? '.xcodeproj' wrong_path = Dir.glob(root_dir + project).empty? UI.user_error! "Wrong project name '#{project}'. Check extension if you use it." if wrong_path end if workspace and !workspace.empty? workspace += '.xcworkspace' unless workspace.end_with? '.xcworkspace' else workspace = project.gsub(".xcodeproj", '') + '.xcworkspace' end wrong_path = Dir.glob(root_dir + workspace).empty? UI.user_error! "Wrong workspace name '#{workspace}'" if wrong_path # check targets available_targets = [] new_targets = [] project_info = Xcodeproj::Project.open(project.to_s) project_info.targets.each do |target| available_targets.push(target.name) end if targets and targets.count > 0 error = [] targets.each do |currect_target| next if currect_target.tr(' ', '').empty? if available_targets.include? currect_target new_targets.push(currect_target) else error.push(currect_target) end end UI.user_error!("The #{error} targets don't exist in project.") unless error.count == 0 end new_targets = available_targets if new_targets.count == 0 @checked_xcode_param = true [project, workspace, new_targets] end end