fastlane-plugin-code_static_analyzer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +143 -0
- data/lib/assets/code_analys.sh +27 -0
- data/lib/assets/formatter.rb +31 -0
- data/lib/assets/junit_parser.rb +225 -0
- data/lib/assets/run_script.sh +13 -0
- data/lib/fastlane/plugin/code_static_analyzer.rb +17 -0
- data/lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb +310 -0
- data/lib/fastlane/plugin/code_static_analyzer/actions/cpd_analyzer.rb +134 -0
- data/lib/fastlane/plugin/code_static_analyzer/actions/ruby_analyzer.rb +112 -0
- data/lib/fastlane/plugin/code_static_analyzer/actions/warning_analyzer.rb +156 -0
- data/lib/fastlane/plugin/code_static_analyzer/helper/code_static_analyzer_helper.rb +12 -0
- data/lib/fastlane/plugin/code_static_analyzer/version.rb +5 -0
- metadata +168 -0
@@ -0,0 +1,112 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
RUBY_ANALYZER_STATUS = :RUBY_ANALYZER_STATUS
|
5
|
+
end
|
6
|
+
|
7
|
+
class RubyAnalyzerAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
UI.header 'Ruby analyzer' if Actions::CodeStaticAnalyzerAction.run_from_main_action
|
10
|
+
work_dir = Actions::CodeStaticAnalyzerAction.work_dir
|
11
|
+
|
12
|
+
# checking files for analysing
|
13
|
+
files_to_inspect = params[:ruby_files]
|
14
|
+
|
15
|
+
UI.message '[!] Ruby analyzer will be run for all ruby files in work directory'.blue if !files_to_inspect or files_to_inspect.empty?
|
16
|
+
Actions::CodeStaticAnalyzerAction.check_file_exist(work_dir, files_to_inspect, 'ruby_files')
|
17
|
+
|
18
|
+
# prepare script and metadata for saving results
|
19
|
+
result_dir_path = "#{work_dir}#{params[:result_dir]}"
|
20
|
+
FileUtils.mkdir_p(result_dir_path) unless File.exist?(result_dir_path)
|
21
|
+
temp_result_file = "#{result_dir_path}/temp_ruby.json"
|
22
|
+
result_file = "#{result_dir_path}/codeAnalysResults_ruby.xml"
|
23
|
+
files = Actions::CodeStaticAnalyzerAction.add_root_path(work_dir, files_to_inspect, true)
|
24
|
+
run_script = "bundle exec rubocop -f j -a #{files}"
|
25
|
+
run_script_path = File.join CodeStaticAnalyzer::ROOT, "assets/run_script.sh"
|
26
|
+
run_script = "#{run_script_path} \"#{run_script}\" '#{temp_result_file}'"
|
27
|
+
# use analyzer
|
28
|
+
FastlaneCore::CommandExecutor.execute(command: run_script.to_s,
|
29
|
+
print_all: false,
|
30
|
+
error: proc do |error_output|
|
31
|
+
# handle error here
|
32
|
+
end)
|
33
|
+
status = $?.exitstatus
|
34
|
+
# prepare results
|
35
|
+
if Dir.glob(temp_result_file).empty?
|
36
|
+
info = (status == 2) ? 'Rubocop return 2: terminates abnormally due to invalid configuration, invalid CLI options, or an internal error' : ''
|
37
|
+
Actions::CodeStaticAnalyzerAction.start_xml_content unless Actions::CodeStaticAnalyzerAction.run_from_main_action
|
38
|
+
Actions::CodeStaticAnalyzerAction.add_xml_content("#{result_dir_path}/", 'Ruby', temp_result_file, info)
|
39
|
+
Actions::CodeStaticAnalyzerAction.create_analyzers_run_result("#{result_dir_path}/") unless Actions::CodeStaticAnalyzerAction.run_from_main_action
|
40
|
+
status = 43
|
41
|
+
else
|
42
|
+
status = 0 if File.read(temp_result_file).empty?
|
43
|
+
xml_content = JunitParser.parse_json(temp_result_file)
|
44
|
+
junit_xml = JunitParser.add_testsuite('rubocop', xml_content)
|
45
|
+
JunitParser.create_junit_xml(junit_xml, result_file)
|
46
|
+
end
|
47
|
+
Actions.lane_context[SharedValues::RUBY_ANALYZER_STATUS] = status
|
48
|
+
end
|
49
|
+
|
50
|
+
#####################################################
|
51
|
+
# @!group Documentation
|
52
|
+
#####################################################
|
53
|
+
|
54
|
+
def self.description
|
55
|
+
"This analyzer detect warnings, errors and check syntax in ruby files. This is based on rubocop"
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.details
|
59
|
+
# Optional:
|
60
|
+
# this is your chance to provide a more detailed description of this action
|
61
|
+
# "You can use this action to do cool things..."
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.available_options
|
65
|
+
# Define all options your action supports.
|
66
|
+
|
67
|
+
# Below a few examples
|
68
|
+
[
|
69
|
+
FastlaneCore::ConfigItem.new(key: :result_dir,
|
70
|
+
env_name: "FL_RUBY_ANALYZER_RESULT_DIR",
|
71
|
+
description: "Directory's name for storing analysis results",
|
72
|
+
optional: true,
|
73
|
+
type: String,
|
74
|
+
default_value: 'artifacts'),
|
75
|
+
FastlaneCore::ConfigItem.new(key: :ruby_files,
|
76
|
+
env_name: "FL_RUBY_ANALYZER_FILES_TO_INSPECT",
|
77
|
+
description: "List of path (relative to work directory) to ruby files to be inspected",
|
78
|
+
optional: true,
|
79
|
+
type: Array)
|
80
|
+
]
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.output
|
84
|
+
# Define the shared values you are going to provide
|
85
|
+
[
|
86
|
+
['RUBY_ANALYZER_STATUS', 'Ruby analyzer result status (0 - success, any other value - failed)']
|
87
|
+
]
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.return_value
|
91
|
+
# If you method provides a return value, you can describe here what it does
|
92
|
+
end
|
93
|
+
|
94
|
+
def self.authors
|
95
|
+
# So no one will ever forget your contribution to fastlane :) You are awesome btw!
|
96
|
+
["olgakn"]
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.is_supported?(platform)
|
100
|
+
# you can do things like
|
101
|
+
#
|
102
|
+
# true
|
103
|
+
#
|
104
|
+
# platform == :ios
|
105
|
+
#
|
106
|
+
# [:ios, :mac].include?(platform)
|
107
|
+
#
|
108
|
+
true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
WARNING_ANALYZER_STATUS = :WARNING_ANALYZER_STATUS
|
5
|
+
end
|
6
|
+
|
7
|
+
class WarningAnalyzerAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
UI.header 'iOS warning analyzer' if Actions::CodeStaticAnalyzerAction.run_from_main_action
|
10
|
+
work_dir = Actions::CodeStaticAnalyzerAction.work_dir
|
11
|
+
|
12
|
+
# checking files for analysing
|
13
|
+
workspace = params[:xcode_workspace_name]
|
14
|
+
project = params[:xcode_project_name]
|
15
|
+
targets = params[:xcode_targets]
|
16
|
+
unless Actions::CodeStaticAnalyzerAction.run_from_main_action
|
17
|
+
checked_params = Actions::CodeStaticAnalyzerAction.xcode_check_parameters(work_dir, project, workspace, targets)
|
18
|
+
project = checked_params[0]
|
19
|
+
workspace = checked_params[1]
|
20
|
+
targets = checked_params[2]
|
21
|
+
end
|
22
|
+
is_workspace = false
|
23
|
+
is_workspace = true if workspace and !workspace.empty?
|
24
|
+
|
25
|
+
# prepare script and metadata for saving results
|
26
|
+
result_dir_path = "#{work_dir}#{params[:result_dir]}"
|
27
|
+
FileUtils.mkdir_p(result_dir_path) unless File.exist?(result_dir_path)
|
28
|
+
# lib_path = File.join(Helper.gem_path('fastlane-plugin-code_static_analyzer'), "lib")
|
29
|
+
# File.join(lib_path, "assets/code_analys.sh")
|
30
|
+
run_script_path = File.join CodeStaticAnalyzer::ROOT, "assets/code_analys.sh"
|
31
|
+
|
32
|
+
status_static_arr = []
|
33
|
+
xml_content = ''
|
34
|
+
temp_result_file = "#{result_dir_path}/temp_warnings.log"
|
35
|
+
result_file = "#{result_dir_path}/codeAnalysResults_warning.xml"
|
36
|
+
|
37
|
+
# use analyzer and collect results
|
38
|
+
project_workspace = project
|
39
|
+
project_workspace = workspace if is_workspace
|
40
|
+
Actions::CodeStaticAnalyzerAction.start_xml_content unless Actions::CodeStaticAnalyzerAction.run_from_main_action
|
41
|
+
targets.each do |target|
|
42
|
+
Formatter.xcode_format(target)
|
43
|
+
run_script = "#{run_script_path} #{project_workspace} #{target} '#{temp_result_file}' #{is_workspace}"
|
44
|
+
FastlaneCore::CommandExecutor.execute(command: run_script.to_s,
|
45
|
+
print_all: false,
|
46
|
+
print_command: false,
|
47
|
+
error: proc do |error_output|
|
48
|
+
# handle error here
|
49
|
+
end)
|
50
|
+
|
51
|
+
Actions::CodeStaticAnalyzerAction.start_xml_content unless Actions::CodeStaticAnalyzerAction.run_from_main_action
|
52
|
+
if Dir.glob(temp_result_file).empty?
|
53
|
+
Actions::CodeStaticAnalyzerAction.add_xml_content("#{result_dir_path}/", 'iOS Warning', temp_result_file, '')
|
54
|
+
Actions::CodeStaticAnalyzerAction.create_analyzers_run_result("#{result_dir_path}/") unless Actions::CodeStaticAnalyzerAction.run_from_main_action
|
55
|
+
status_static_arr.push(1)
|
56
|
+
else
|
57
|
+
file = File.read(temp_result_file)
|
58
|
+
UI.important "wrong profiles. Code isn't checked" if file =~ /BCEROR/
|
59
|
+
is_warnings = file =~ /warning:|error:|BCEROR/
|
60
|
+
if is_warnings
|
61
|
+
status_static_arr.push(1)
|
62
|
+
else
|
63
|
+
status_static_arr.push(0)
|
64
|
+
end
|
65
|
+
xml_content += JunitParser.parse_xcode_log(temp_result_file, target, is_warnings)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# prepare results
|
70
|
+
unless Dir.glob(temp_result_file).empty?
|
71
|
+
junit_xml = JunitParser.add_testsuite('xcode warnings', xml_content)
|
72
|
+
JunitParser.create_junit_xml(junit_xml, result_file)
|
73
|
+
end
|
74
|
+
status = if status_static_arr.any? { |x| x > 0 }
|
75
|
+
1
|
76
|
+
else
|
77
|
+
0
|
78
|
+
end
|
79
|
+
|
80
|
+
Actions.lane_context[SharedValues::WARNING_ANALYZER_STATUS] = status
|
81
|
+
end
|
82
|
+
|
83
|
+
#####################################################
|
84
|
+
# @!group Documentation
|
85
|
+
#####################################################
|
86
|
+
|
87
|
+
def self.description
|
88
|
+
"This analyzer detect warnings in Xcode projects."
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.details
|
92
|
+
# Optional:
|
93
|
+
# this is your chance to provide a more detailed description of this action
|
94
|
+
# "You can use this action to do cool things..."
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.available_options
|
98
|
+
# Define all options your action supports.
|
99
|
+
[
|
100
|
+
FastlaneCore::ConfigItem.new(key: :result_dir,
|
101
|
+
env_name: "FL_WARNING_ANALYZER_RESULT_DIR",
|
102
|
+
description: "Directory's name for storing analysis results",
|
103
|
+
optional: true,
|
104
|
+
type: String,
|
105
|
+
default_value: 'artifacts'),
|
106
|
+
FastlaneCore::ConfigItem.new(key: :xcode_project_name,
|
107
|
+
env_name: "FL_WARNING_ANALYZER_PROJECT_NAME",
|
108
|
+
description: "Xcode project name in work directory",
|
109
|
+
optional: false,
|
110
|
+
type: String,
|
111
|
+
verify_block: proc do |value|
|
112
|
+
UI.user_error!("No project name for WarningAnalyzerAction given, pass using `xcode_project_name` parameter") unless value and !value.empty?
|
113
|
+
end),
|
114
|
+
FastlaneCore::ConfigItem.new(key: :xcode_workspace_name,
|
115
|
+
env_name: "FL_WARNING_ANALYZER_WORKSPACE_NAME",
|
116
|
+
description: "Xcode workspace name in work directory. Set it if you use different project & workspace names",
|
117
|
+
optional: true,
|
118
|
+
type: String),
|
119
|
+
FastlaneCore::ConfigItem.new(key: :xcode_targets,
|
120
|
+
env_name: "FL_WARNING_ANALYZER_TARGETS",
|
121
|
+
description: "List of Xcode targets to inspect. By default used all project targets",
|
122
|
+
optional: true,
|
123
|
+
type: Array)
|
124
|
+
]
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.output
|
128
|
+
# Define the shared values you are going to provide
|
129
|
+
[
|
130
|
+
['WARNING_ANALYZER_STATUS', 'Warning analyzer result status (0 - success, any other value - failed)']
|
131
|
+
]
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.return_value
|
135
|
+
# If you method provides a return value, you can describe here what it does
|
136
|
+
end
|
137
|
+
|
138
|
+
def self.authors
|
139
|
+
# So no one will ever forget your contribution to fastlane :) You are awesome btw!
|
140
|
+
["olgakn"]
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.is_supported?(platform)
|
144
|
+
# you can do things like
|
145
|
+
#
|
146
|
+
# true
|
147
|
+
#
|
148
|
+
# platform == :ios
|
149
|
+
#
|
150
|
+
# [:ios, :mac].include?(platform)
|
151
|
+
#
|
152
|
+
[:ios, :mac].include?(platform)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Helper
|
3
|
+
class CodeStaticAnalyzerHelper
|
4
|
+
# class methods that you define here become available in your action
|
5
|
+
# as `Helper::CodeStaticAnalyzerHelper.your_method`
|
6
|
+
#
|
7
|
+
def self.show_message
|
8
|
+
UI.message("Hello from the code_static_analyzer plugin helper!")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,168 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fastlane-plugin-code_static_analyzer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Olga Kniazska
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-01-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: crack
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: xcpretty
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rspec
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: fastlane
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 2.1.1
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.1.1
|
125
|
+
description:
|
126
|
+
email: olgak.kiev@ukr.net
|
127
|
+
executables: []
|
128
|
+
extensions: []
|
129
|
+
extra_rdoc_files: []
|
130
|
+
files:
|
131
|
+
- LICENSE
|
132
|
+
- README.md
|
133
|
+
- lib/assets/code_analys.sh
|
134
|
+
- lib/assets/formatter.rb
|
135
|
+
- lib/assets/junit_parser.rb
|
136
|
+
- lib/assets/run_script.sh
|
137
|
+
- lib/fastlane/plugin/code_static_analyzer.rb
|
138
|
+
- lib/fastlane/plugin/code_static_analyzer/actions/code_static_analyzer_action.rb
|
139
|
+
- lib/fastlane/plugin/code_static_analyzer/actions/cpd_analyzer.rb
|
140
|
+
- lib/fastlane/plugin/code_static_analyzer/actions/ruby_analyzer.rb
|
141
|
+
- lib/fastlane/plugin/code_static_analyzer/actions/warning_analyzer.rb
|
142
|
+
- lib/fastlane/plugin/code_static_analyzer/helper/code_static_analyzer_helper.rb
|
143
|
+
- lib/fastlane/plugin/code_static_analyzer/version.rb
|
144
|
+
homepage: https://github.com/knolga/fastlane-plugin-code_static_analyzer
|
145
|
+
licenses:
|
146
|
+
- MIT
|
147
|
+
metadata: {}
|
148
|
+
post_install_message:
|
149
|
+
rdoc_options: []
|
150
|
+
require_paths:
|
151
|
+
- lib
|
152
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
version: '0'
|
157
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
requirements: []
|
163
|
+
rubyforge_project:
|
164
|
+
rubygems_version: 2.4.8
|
165
|
+
signing_key:
|
166
|
+
specification_version: 4
|
167
|
+
summary: Runs different Static Analyzers and generate report
|
168
|
+
test_files: []
|