Class: Fastlane::Actions::OclintAction

Inherits:
Fastlane::Action show all
Defined in:
lib/fastlane/actions/oclint.rb

Constant Summary

Constants inherited from Fastlane::Action

Fastlane::Action::AVAILABLE_CATEGORIES

Documentation collapse

Class Method Summary collapse

Methods inherited from Fastlane::Action

action_name, authors, lane_context, method_missing, other_action, return_value, sample_return_value, sh, step_text

Class Method Details

.authorObject



201
202
203
# File 'lib/fastlane/actions/oclint.rb', line 201

def self.author
  'HeEAaD'
end

.available_optionsObject



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/fastlane/actions/oclint.rb', line 101

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, # select_reqex is deprecated, remove as soon as possible
                                 env_name: 'FL_OCLINT_SELECT_REQEX',
                                 description: 'Select all files matching this reqex',
                                 is_string: false,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :select_regex,
                                 env_name: 'FL_OCLINT_SELECT_REGEX',
                                 description: 'Select all files matching this regex',
                                 is_string: false,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :exclude_regex,
                                 env_name: 'FL_OCLINT_EXCLUDE_REGEX',
                                 description: 'Exclude all files matching this regex',
                                 is_string: false,
                                 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",
                                 is_string: false,
                                 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',
                                 is_string: false,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :enable_rules,
                                 env_name: 'FL_OCLINT_ENABLE_RULES',
                                 description: 'List of rules to pick explicitly',
                                 is_string: false,
                                 optional: true),
    FastlaneCore::ConfigItem.new(key: :disable_rules,
                                 env_name: 'FL_OCLINT_DISABLE_RULES',
                                 description: 'List of rules to disable',
                                 is_string: false,
                                 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',
                                 is_string: false,
                                 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',
                                 is_string: false,
                                 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',
                                 is_string: false,
                                 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",
                                 is_string: false,
                                 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)",
                                 is_string: false,
                                 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",
                                 is_string: false,
                                 default_value: false)
  ]
end

.categoryObject



240
241
242
# File 'lib/fastlane/actions/oclint.rb', line 240

def self.category
  :testing
end

.descriptionObject



97
98
99
# File 'lib/fastlane/actions/oclint.rb', line 97

def self.description
  "Lints implementation files with OCLint"
end

.detailsObject



209
210
211
# File 'lib/fastlane/actions/oclint.rb', line 209

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

.example_codeObject



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'lib/fastlane/actions/oclint.rb', line 213

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
    )'
  ]
end

.is_supported?(platform) ⇒ Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/fastlane/actions/oclint.rb', line 205

def self.is_supported?(platform)
  true
end

.outputObject

rubocop:enable Metrics/PerceivedComplexity



195
196
197
198
199
# File 'lib/fastlane/actions/oclint.rb', line 195

def self.output
  [
    ['FL_OCLINT_REPORT_PATH', 'The reports file path']
  ]
end

.run(params) ⇒ Object

rubocop:disable Metrics/PerceivedComplexity



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/fastlane/actions/oclint.rb', line 9

def self.run(params)
  oclint_path = params[:oclint_path]
  if `which #{oclint_path}`.to_s.empty? and !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' paramter 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
  exclude_regex = params[: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 << 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}"

  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