fastlane-plugin-try_scan 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 871975db0faec46bf64db099bd0d14829460ff8e542bfa8dffcdd39c6d491854
4
- data.tar.gz: d518a6bcb11b1b4833d06bad970b8ba5764301be2f7ff9f8d0c3f92621f8c8b5
3
+ metadata.gz: 9a2ac62b11641f4b9eedad2e76438debeec8e6e85ce255c1d556f8bed37df3bf
4
+ data.tar.gz: f131bd125d5dddb9b2ee61858e1d089a73ed1883d761db1ba8202305330ef70d
5
5
  SHA512:
6
- metadata.gz: 913b1a9891ea9a4fcd066daa4d36c3fd96d0d18e05a0923691c82b32ad320766337a615615bd2bfa6894cc01657b67bb0224732fcfb8d6063c3b3eee92a3ac64
7
- data.tar.gz: e299cfc1124d6ce7545289eb8620d95b2eaf2da62062ce377c5ef3b86ed9ee613ce244ea5880298a4357f8758f0592a0da7fdf4feed5c55cc79facc4105f9ab2
6
+ metadata.gz: 1cd2f40bdd31874c7a531a411e4fa0524fcb9d21950eaade21cca1db6e73424ccf59cfdc5f8ff8ada9a452eacc28710313657ee0ac3a356245a093b7d696d505
7
+ data.tar.gz: 89333c0f2af0d2f258e3596268da05e44ead692bba3f80eab9e1cf86bcdc034c7b3dc9ee3b2da08aa4644bfee04361fa19a4816e89e80f96872bb1b296db4b69
data/README.md CHANGED
@@ -2,36 +2,38 @@
2
2
 
3
3
  [![fastlane Plugin Badge](https://rawcdn.githack.com/fastlane/fastlane/master/fastlane/assets/plugin-badge.svg)](https://rubygems.org/gems/fastlane-plugin-try_scan)
4
4
 
5
+ ## About try_scan
6
+
7
+ The easiest way to rerun tests of your iOS and Mac app 🚀
8
+
9
+ Under the hood `try_scan` uses official [`fastlane scan action`](https://docs.fastlane.tools/actions/scan/), it means that you are able to provide any `scan` options and use `Scanfile` as before — everything will work like a charm, `try_scan` just brings couple of new amazing options:
10
+
11
+ | Option | Description | Default |
12
+ | ------- |------------ | ------- |
13
+ | try_count | Number of times to try to get your tests green | 1 |
14
+ | try_parallel | Should first run be executed in parallel? Equivalent to `-parallel-testing-enabled` | true |
15
+ | retry_parallel | Should subsequent runs be executed in parallel? Required `try_parallel: true` | true |
16
+ | parallel_workers | Specify the exact number of test runners that will be spawned during parallel testing. Equivalent to `-parallel-testing-worker-count` and `concurrent_workers` | |
17
+ | retry_strategy | What would you like to retry after failure: test, class or suite? | test |
18
+
19
+ ## Requirements
20
+
21
+ * Xcode 11.x or greater. Download it at the [Apple Developer - Downloads](https://developer.apple.com/downloads) or the [Mac App Store](https://apps.apple.com/us/app/xcode/id497799835?mt=12).
22
+
5
23
  ## Getting Started
6
24
 
7
- This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To get started with `try_scan`, add it to your project by running:
25
+ To get started with `try_scan`, add it to your project by running:
8
26
 
9
27
  ```bash
10
- fastlane add_plugin try_scan
28
+ $ fastlane add_plugin try_scan
11
29
  ```
12
30
 
13
- ## About try_scan
14
-
15
- Simple way to retry your scan action 🚀
16
-
17
31
  ## Usage
18
32
 
19
33
  ```ruby
20
34
  try_scan(
21
35
  workspace: "Example.xcworkspace",
22
- devices: ["iPhone 6s", "iPad Air"],
36
+ devices: ["iPhone 7", "iPad Air"],
23
37
  try_count: 3
24
38
  )
25
39
  ```
26
-
27
- ## Issues and Feedback
28
-
29
- For any other issues and feedback about this plugin, please submit it to this repository.
30
-
31
- ## Troubleshooting
32
-
33
- If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
34
-
35
- ## About _fastlane_
36
-
37
- _fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
@@ -2,7 +2,6 @@ module Fastlane
2
2
  module Actions
3
3
 
4
4
  require 'json'
5
- require 'nokogiri'
6
5
  require 'fastlane/actions/scan'
7
6
  require_relative '../helper/scan_helper'
8
7
  require_relative '../helper/try_scan_runner'
@@ -11,61 +10,16 @@ module Fastlane
11
10
 
12
11
  class TryScanAction < Action
13
12
  def self.run(params)
14
- prepare_for_testing(params)
15
- success = TryScanManager::Runner.new(params.values).run
13
+ if Helper.xcode_at_least?('11.0.0')
14
+ params[:destination] = [params[:destination]] if params[:destination] && !params[:destination].kind_of?(Array)
15
+ success = TryScanManager::Runner.new(params.values).run
16
16
 
17
- raise FastlaneCore::UI.test_failure!('Tests have failed') if params[:fail_build] && !success
18
- end
19
-
20
- def self.prepare_for_testing(params)
21
- warn_of_xcode11_result_bundle_incompatability(params)
22
- use_scanfile_to_override_settings(params.values)
23
- turn_off_concurrent_workers(params.values)
24
- prepare_scan_config(params.values)
25
- coerce_destination_to_array(params)
26
- end
27
-
28
- def self.warn_of_xcode11_result_bundle_incompatability(params)
29
- if FastlaneCore::Helper.xcode_at_least?('11.0.0')
30
- if params[:result_bundle]
31
- FastlaneCore::UI.important('As of Xcode 11, test_result bundles created in the output directory are actually symbolic links to an xcresult bundle')
32
- end
33
- elsif params[:output_types]&.include?('xcresult')
34
- FastlaneCore::UI.important("The 'xcresult' :output_type is only supported for Xcode 11 and greater. You are using #{FastlaneCore::Helper.xcode_version}.")
35
- end
36
- end
37
-
38
- def self.coerce_destination_to_array(params)
39
- destination = params[:destination] || Scan.config[:destination] || []
40
- unless destination.kind_of?(Array)
41
- params[:destination] = Scan.config[:destination] = [destination]
42
- end
43
- end
44
-
45
- def self.turn_off_concurrent_workers(scan_options)
46
- if Gem::Version.new(Fastlane::VERSION) >= Gem::Version.new('2.142.0')
47
- scan_options.delete(:concurrent_workers) if scan_options[:concurrent_workers].to_i > 0
48
- end
49
- end
50
-
51
- def self.use_scanfile_to_override_settings(scan_options)
52
- overridden_options = FastlaneScanHelper.options_from_configuration_file(
53
- FastlaneScanHelper.scan_options_from_try_scan_options(scan_options)
54
- )
55
-
56
- unless overridden_options.empty?
57
- FastlaneCore::UI.important("Scanfile found: overriding try_scan options with it's values.")
58
- overridden_options.each { |key, val| scan_options[key] = val }
17
+ raise FastlaneCore::UI.test_failure!('Tests have failed') if params[:fail_build] && !success
18
+ else
19
+ raise FastlaneCore::UI.user_error!("Minimum supported Xcode: `v11.0.0` (used: `v#{Helper.xcode_version}`)")
59
20
  end
60
21
  end
61
22
 
62
- def self.prepare_scan_config(scan_options)
63
- Scan.config ||= FastlaneCore::Configuration.create(
64
- Fastlane::Actions::ScanAction.available_options,
65
- FastlaneScanHelper.scan_options_from_try_scan_options(scan_options)
66
- )
67
- end
68
-
69
23
  #####################################################
70
24
  # Documentation #
71
25
  #####################################################
@@ -78,20 +32,52 @@ module Fastlane
78
32
  ["Alexey Alter-Pesotskiy"]
79
33
  end
80
34
 
81
- def self.scan_options
82
- ScanAction.available_options.reject { |config| %i[output_types].include?(config.key) }
83
- end
84
-
85
35
  def self.available_options
86
- scan_options = ScanAction.available_options.reject { |config| %i[output_types].include?(config.key) }
87
- scan_options + [
36
+ ScanAction.available_options + [
88
37
  FastlaneCore::ConfigItem.new(
89
38
  key: :try_count,
90
39
  env_name: "FL_TRY_SCAN_TRY_COUNT",
91
- description: "The number of times to retry running tests via scan",
40
+ description: "Number of times to try to get your tests green",
92
41
  type: Integer,
93
42
  is_string: false,
43
+ optional: true,
94
44
  default_value: 1
45
+ ),
46
+ FastlaneCore::ConfigItem.new(
47
+ key: :try_parallel,
48
+ env_name: "FL_TRY_SCAN_TRY_PARALLEL",
49
+ description: "Should first run be executed in parallel? Equivalent to -parallel-testing-enabled",
50
+ is_string: false,
51
+ optional: true,
52
+ default_value: true
53
+ ),
54
+ FastlaneCore::ConfigItem.new(
55
+ key: :retry_parallel,
56
+ env_name: "FL_TRY_SCAN_RETRY_PARALLEL",
57
+ description: "Should subsequent runs be executed in parallel? Required :try_parallel: true",
58
+ is_string: false,
59
+ optional: true,
60
+ default_value: true
61
+ ),
62
+ FastlaneCore::ConfigItem.new(
63
+ key: :parallel_workers,
64
+ env_name: "FL_TRY_SCAN_PARALLEL_WORKERS",
65
+ description: "Specify the exact number of test runners that will be spawned during parallel testing. Equivalent to -parallel-testing-worker-count and :concurrent_workers",
66
+ type: Integer,
67
+ is_string: false,
68
+ optional: true
69
+ ),
70
+ FastlaneCore::ConfigItem.new(
71
+ key: :retry_strategy,
72
+ env_name: "FL_TRY_SCAN_RETRY_STRATEGY",
73
+ description: "What would you like to retry after failure: test, class or suite?",
74
+ is_string: true,
75
+ optional: true,
76
+ default_value: 'test',
77
+ verify_block: proc do |strategy|
78
+ possible_strategies = ['test', 'class', 'suite']
79
+ UI.user_error!("Error: :retry_strategy must equal to one of the following values: #{possible_strategies}") unless possible_strategies.include?(strategy)
80
+ end
95
81
  )
96
82
  ]
97
83
  end
@@ -101,7 +87,7 @@ module Fastlane
101
87
  end
102
88
 
103
89
  def self.is_supported?(platform)
104
- [:ios].include?(platform)
90
+ [:ios, :mac].include?(platform)
105
91
  end
106
92
  end
107
93
  end
@@ -19,31 +19,9 @@ module TryScanManager
19
19
  end
20
20
 
21
21
  def self.scan_options_from_try_scan_options(params)
22
- valid_scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
23
22
  params.select { |key, _| valid_scan_keys.include?(key) }
24
23
  end
25
24
 
26
- def self.options_from_configuration_file(params)
27
- config = FastlaneCore::Configuration.create(
28
- Fastlane::Actions::ScanAction.available_options,
29
- params
30
- )
31
- config_file = config.load_configuration_file(Scan.scanfile_name, nil, true)
32
- overridden_options = config_file ? config_file.options : {}
33
-
34
- FastlaneCore::Project.detect_projects(config)
35
- project = FastlaneCore::Project.new(config)
36
-
37
- imported_path = File.expand_path(Scan.scanfile_name)
38
- Dir.chdir(File.expand_path("..", project.path)) do
39
- if File.expand_path(Scan.scanfile_name) != imported_path
40
- config_file = config.load_configuration_file(Scan.scanfile_name, nil, true)
41
- end
42
- overridden_options.merge!(config_file.options) if config_file
43
- end
44
- overridden_options
45
- end
46
-
47
25
  def self.remove_preexisting_simulator_logs(params)
48
26
  return unless params[:include_simulator_logs]
49
27
 
@@ -90,4 +68,4 @@ module TryScanManager
90
68
  end
91
69
  end
92
70
  end
93
- end
71
+ end
@@ -5,42 +5,39 @@ module TryScanManager
5
5
 
6
6
  def initialize(options = {})
7
7
  @options = options
8
+ @options[:try_count] = 1 if @options[:try_count] < 1
9
+ @options[:result_bundle] = true
8
10
  end
9
11
 
10
12
  def run
11
- update_scan_config
13
+ configure_xcargs
14
+ prepare_scan_config(@options)
12
15
  print_summary
13
16
  @attempt = 1
14
17
  begin
15
18
  warn_of_performing_attempts
16
19
  clear_preexisting_data
17
20
  Scan::Runner.new.run
18
- print_parallel_scan_result
21
+ print_try_scan_result
19
22
  return true
20
23
  rescue FastlaneCore::Interface::FastlaneTestFailure => _
21
- failed_tests = extract_failed_tests
22
- print_parallel_scan_result(failed_tests_count: failed_tests.size)
23
- update_scan_junit_report
24
- return false if @attempt >= @options[:try_count]
24
+ failed_tests = failed_tests_from_xcresult_report
25
+ print_try_scan_result(failed_tests_count: failed_tests.size)
26
+ return false if finish?
25
27
 
26
28
  @attempt += 1
27
29
  update_scan_options(failed_tests)
28
30
  retry
29
31
  rescue FastlaneCore::Interface::FastlaneBuildFailure => _
30
- return false if @attempt >= @options[:try_count]
32
+ return false if finish?
31
33
 
32
34
  @attempt += 1
33
35
  retry
34
36
  end
35
37
  end
36
38
 
37
- def update_scan_config
38
- if !Scan.config[:output_types].include?('junit') && !parallel_running?
39
- output_types = Scan.config[:output_types].split(',')
40
- output_types << 'junit'
41
- Scan.config[:output_types] = output_types.join(',')
42
- end
43
- @options[:try_count] = 1 if @options[:try_count] < 1
39
+ def finish?
40
+ @attempt >= @options[:try_count]
44
41
  end
45
42
 
46
43
  def print_summary
@@ -70,9 +67,7 @@ module TryScanManager
70
67
  FastlaneScanHelper.remove_report_files
71
68
  end
72
69
 
73
- def print_parallel_scan_result(failed_tests_count: 0)
74
- return unless parallel_running?
75
-
70
+ def print_try_scan_result(failed_tests_count: 0)
76
71
  FastlaneCore::UI.important("TryScan: result after #{ordinalized_attempt} shot 👇")
77
72
  FastlaneCore::PrintTable.print_values(
78
73
  config: {"Number of tests" => tests_count_from_xcresult_report, "Number of failures" => failed_tests_count},
@@ -93,98 +88,73 @@ module TryScanManager
93
88
  end
94
89
  end
95
90
 
96
- def update_scan_options(failed_tests)
97
- scan_options = @options.select { |key, _|
98
- FastlaneScanHelper.valid_scan_keys.include?(key)
99
- }.merge(plugin_scan_options)
100
- scan_options[:only_testing] = failed_tests
101
- scan_options[:skip_build] = true
102
- scan_options[:test_without_building] = true
103
- scan_options[:build_for_testing] = false
104
- scan_options.delete(:skip_testing)
105
- Scan.cache.clear
106
- scan_options.each do |key, val|
107
- next if val.nil?
91
+ def prepare_scan_config(scan_options)
92
+ Scan.config = FastlaneCore::Configuration.create(
93
+ Fastlane::Actions::ScanAction.available_options,
94
+ FastlaneScanHelper.scan_options_from_try_scan_options(scan_options)
95
+ )
96
+ end
108
97
 
109
- Scan.config.set(key, val) unless val.nil?
110
- FastlaneCore::UI.verbose("\tSetting #{key.to_s} to #{val}")
98
+ def configure_xcargs
99
+ if @options[:xcargs]&.include?('-parallel-testing-enabled')
100
+ FastlaneCore::UI.important("TryScan overwrites `-parallel-testing-enabled` in :xcargs, use :try_parallel option instead")
101
+ @options[:xcargs].gsub!(/-parallel-testing-enabled(=|\s+)(YES|NO)/, '')
111
102
  end
112
- end
113
103
 
114
- def plugin_scan_options
115
- xcargs = @options[:xcargs] || ''
116
- if xcargs&.include?('build-for-testing')
117
- FastlaneCore::UI.important(":xcargs, #{xcargs}, contained 'build-for-testing', removing it")
118
- xcargs.slice!('build-for-testing')
104
+ if @options[:xcargs]&.include?('-parallel-testing-worker-count')
105
+ FastlaneCore::UI.important("TryScan overwrites `-parallel-testing-worker-count` in :xcargs, use :concurrent_workers option instead")
106
+ @options[:xcargs].gsub!(/-parallel-testing-worker-count(=|\s+)(\d+)/, '')
119
107
  end
120
- if xcargs.include?('-quiet')
121
- FastlaneCore::UI.important('Disabling -quiet as failing tests cannot be found with it enabled.')
122
- xcargs.gsub!('-quiet', '')
108
+
109
+ if @options[:xcargs]&.include?('build-for-testing') || @options[:build_for_testing]
110
+ FastlaneCore::UI.important("TryScan rejects `build-for-testing` request, use it in a separate scan lane")
111
+ @options[:xcargs].slice!('build-for-testing')
112
+ @options[:build_for_testing] = nil
123
113
  end
124
- @options.select { |key, _| FastlaneScanHelper.valid_scan_keys.include?(key) }.merge({ xcargs: xcargs })
125
- end
126
114
 
127
- def extract_failed_tests
128
- if parallel_running?
129
- failed_tests_from_xcresult_report
115
+ xcargs = []
116
+ if @options[:try_parallel]
117
+ xcargs << '-parallel-testing-enabled YES'
118
+ if @options[:parallel_workers] || @options[:concurrent_workers]
119
+ workers_count = [@options[:parallel_workers].to_i, @options[:concurrent_workers].to_i].max
120
+ xcargs << "-parallel-testing-worker-count #{workers_count}"
121
+ @options[:concurrent_workers] = nil
122
+ end
130
123
  else
131
- failed_tests_from_junit_report
124
+ xcargs << '-parallel-testing-enabled NO'
132
125
  end
126
+ @options[:xcargs] = "#{@options[:xcargs].to_s} #{xcargs.join(' ')}"
133
127
  end
134
128
 
135
- def parallel_running?
136
- return @options[:concurrent_workers].to_i > 0 ||
137
- (@options[:devices] && @options[:devices].size > 1) ||
138
- (@options[:xcargs] && (@options[:xcargs] =~ /-parallel-testing-enabled(=|\s+)YES/ || @options[:xcargs].split('-destination').size > 2))
139
- end
129
+ def update_scan_options(failed_tests)
130
+ scan_options = FastlaneScanHelper.scan_options_from_try_scan_options(@options)
131
+ scan_options[:only_testing] = failed_tests
132
+ scan_options[:skip_build] = true
133
+ scan_options.delete(:skip_testing)
134
+ if @options[:try_parallel] && !@options[:retry_parallel]
135
+ scan_options[:xcargs].gsub!(/-parallel-testing-enabled(=|\s+)(YES|NO)/, '-parallel-testing-enabled NO')
136
+ scan_options[:xcargs].gsub!(/-parallel-testing-worker-count(=|\s+)(\d+)/, '')
137
+ end
140
138
 
141
- def failed_tests_from_junit_report
142
- report = junit_report
143
- suite_name = report.xpath('testsuites/@name').to_s.split('.')[0]
144
- test_cases = report.xpath('//testcase')
145
- only_testing = []
146
- test_cases.each do |test_case|
147
- next if test_case.xpath('failure').empty?
139
+ Scan.cache.clear
140
+ scan_options.each do |key, val|
141
+ next if val.nil?
148
142
 
149
- test_class = test_case.xpath('@classname').to_s.split('.')[1]
150
- test_name = test_case.xpath('@name')
151
- only_testing << "#{suite_name}/#{test_class}/#{test_name}"
143
+ Scan.config.set(key, val)
144
+ FastlaneCore::UI.verbose("\tSetting #{key.to_s} to #{val}")
152
145
  end
153
- only_testing
154
146
  end
155
147
 
156
- def junit_report(cached: false)
157
- unless cached
158
- report_options = FastlaneScanHelper.report_options
159
- output_files = report_options.instance_variable_get(:@output_files)
160
- output_directory = report_options.instance_variable_get(:@output_directory)
161
- file_name = output_files.select { |name| name.include?('.xml') }.first
162
- @junit_report_path = "#{output_directory}/#{file_name}"
163
- @cached_junit_report = File.open(@junit_report_path) { |f| Nokogiri::XML(f) }
164
- end
165
- @cached_junit_report
148
+ def retry_failed_test?
149
+ @options[:retry_strategy] == 'test'
166
150
  end
167
151
 
168
- def update_scan_junit_report
169
- return if @attempt == 1 || parallel_running?
170
-
171
- old_junit_report = junit_report(cached: true)
172
- new_junit_report = junit_report(cached: false)
173
-
174
- new_junit_report.css("testsuites").zip(old_junit_report.css("testsuites")).each do |new_suites, old_suites|
175
- old_suites.attributes["failures"].value = new_suites.attributes["failures"].value
176
- new_suites.css("testsuite").zip(old_suites.css("testsuite")).each do |new_suite, old_suite|
177
- old_suite.attributes["failures"].value = new_suite.attributes["failures"].value
178
- end
179
- end
180
-
181
- new_junit_report.css('testcase').each do |node1|
182
- old_junit_report.css('testcase').each do |node2|
183
- node2.children = node1.children if node1['name'] == node2['name']
184
- end
185
- end
152
+ def retry_failed_class?
153
+ @options[:retry_strategy] == 'class'
154
+ end
186
155
 
187
- File.open(@junit_report_path, "w+") { |f| f.write(old_junit_report.to_xml) }
156
+ def retry_failed_suite?
157
+ @options[:retry_strategy] == 'suite'
188
158
  end
189
159
 
190
160
  def parse_xcresult_report
@@ -200,18 +170,24 @@ module TryScanManager
200
170
  def failed_tests_from_xcresult_report
201
171
  only_testing = []
202
172
  parse_xcresult_report['issues']['testFailureSummaries']['_values'].each do |failed_test|
203
- is_a_swift_file = failed_test['documentLocationInCreatingWorkspace']['url']['_value'].include?('.swift')
204
173
  suite_name = failed_test['producingTarget']['_value']
205
- if is_a_swift_file
206
- test_class = failed_test['testCaseName']['_value'].split('.').first
207
- test_name = failed_test['testCaseName']['_value'].split('.')[1].split('(').first
208
- else
209
- test_class = failed_test['testCaseName']['_value'].split('[')[1].split(' ').first
210
- test_name = failed_test['testCaseName']['_value'].split(' ')[1].split(']').first
174
+ test_path = failed_test['testCaseName']['_value']
175
+ begin
176
+ test_class = test_path.split('.').first
177
+ test_name = test_path.split('.')[1].split('(').first
178
+ rescue NoMethodError => _
179
+ test_class = test_path.split('[')[1].split(' ').first
180
+ test_name = test_path.split(' ')[1].split(']').first
181
+ end
182
+ only_testing << if retry_failed_test?
183
+ "#{suite_name}/#{test_class}/#{test_name}"
184
+ elsif retry_failed_class?
185
+ "#{suite_name}/#{test_class}"
186
+ elsif retry_failed_suite?
187
+ suite_name
211
188
  end
212
- only_testing << "#{suite_name}/#{test_class}/#{test_name}"
213
189
  end
214
- only_testing
190
+ only_testing.uniq
215
191
  end
216
192
 
217
193
  def tests_count_from_xcresult_report
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TryScan
3
- VERSION = "0.2.1"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,43 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-try_scan
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexey Alter-Pesotskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-15 00:00:00.000000000 Z
11
+ date: 2020-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: nokogiri
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: json
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
13
  - !ruby/object:Gem::Dependency
42
14
  name: pry
43
15
  requirement: !ruby/object:Gem::Requirement
@@ -165,7 +137,7 @@ dependencies:
165
137
  - !ruby/object:Gem::Version
166
138
  version: 2.144.0
167
139
  description:
168
- email: 33gri@bk.ru
140
+ email: a.alterpesotskiy@mail.ru
169
141
  executables: []
170
142
  extensions: []
171
143
  extra_rdoc_files: []
@@ -200,5 +172,5 @@ requirements: []
200
172
  rubygems_version: 3.0.3
201
173
  signing_key:
202
174
  specification_version: 4
203
- summary: Simple way to retry your scan action
175
+ summary: The easiest way to retry your fastlane scan action
204
176
  test_files: []