mobile_metrics 0.0.3 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30ed2b68c154f8901ce362daf0dd744ce7b0d325fa88dc9294af55b4b0bfa7e1
4
- data.tar.gz: a2993af8b7d748b55d40a9478b37628e75126fdfdc4f1a082c50b43580f131ea
3
+ metadata.gz: 71fab7bc92efcbd6f73f826acb238b1f9a8176ce0a25abc5e8e7a0f80772ee7f
4
+ data.tar.gz: 43d17ec1681e016bcc0123d516497a6754f696d67964908a824f5a2bff71d532
5
5
  SHA512:
6
- metadata.gz: 0bed566a44e5080bb5b18a649c90c193dd785a54720c940e1a0ec3ce7e661523eadc7f1f4c6815bed24808d728f1b317597539d9b47bcaea1ff588bb94d6523d
7
- data.tar.gz: df938aec687c837a8b7ded3dfb193f6738b95083dc89a2f2e40890e2ed9a02ebaa337dab3e0812ad3951aec540148be68f55410d009f7eb0eb8a46d3a50bd1ce
6
+ metadata.gz: f0f94715c4f0039f8f96780b9c3b85f58806c57acdefb02c2e9b0dbdfab1545e4b4e58677a5763436dac765fbb7eda5ee4b78dda503fe3e0b27b93ccd29ca2e9
7
+ data.tar.gz: 9a85990eeda3eee10fe92a4b5660697c7b1385749b235a4d99e5af4da718cb94b7a1b5fbfccca1e4272e55d10e0cf307e309d8124d4d1d224cfbd8cf9911a30e
@@ -1,14 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mobile_metrics (0.0.2)
4
+ mobile_metrics (0.1.0)
5
5
  ox (~> 2.0)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
10
  diff-lcs (1.3)
11
- ox (2.5.0)
11
+ ox (2.13.4)
12
12
  rake (10.5.0)
13
13
  rspec (3.7.0)
14
14
  rspec-core (~> 3.7.0)
@@ -34,4 +34,4 @@ DEPENDENCIES
34
34
  rspec (~> 3.0)
35
35
 
36
36
  BUNDLED WITH
37
- 1.16.1
37
+ 1.17.3
@@ -1,5 +1,5 @@
1
- require "mobile_metrics/version"
2
- require "mobile_metrics/junit"
1
+ require 'mobile_metrics/version'
2
+ require 'mobile_metrics/junit'
3
3
 
4
4
  require 'time'
5
5
  require 'json'
@@ -8,18 +8,18 @@ require 'fileutils'
8
8
  require 'pathname'
9
9
 
10
10
  # Metric types
11
- METRIC_TIMER = 'x.mobile_metric.timer'
12
- METRIC_COUNTER = 'x.mobile_metric.counter'
13
- METRIC_RATIO = 'x.mobile_metric.ratio'
14
- METRIC_SIZE = 'x.mobile_metric.size'
11
+ METRIC_TIMER = 'x.mobile_metric.timer'.freeze
12
+ METRIC_COUNTER = 'x.mobile_metric.counter'.freeze
13
+ METRIC_RATIO = 'x.mobile_metric.ratio'.freeze
14
+ METRIC_SIZE = 'x.mobile_metric.size'.freeze
15
15
 
16
16
  # Misc Constants
17
- UNKNOWN = 'UNKNOWN'
18
- LOG_PREFIX = 'CI-METRICS:'
19
- LOGGING_DIR = '/tmp/cimetricslogs'
20
- UPLOAD_ENV_VAR = 'MOBILE_METRICS_UPLOAD_LOCATION'
17
+ UNKNOWN = 'UNKNOWN'.freeze
18
+ LOG_PREFIX = 'CI-METRICS:'.freeze
19
+ LOGGING_DIR = '/tmp/cimetricslogs'.freeze
20
+ UPLOAD_ENV_VAR = 'MOBILE_METRICS_UPLOAD_LOCATION'.freeze
21
21
 
22
- module MobileMetrics
22
+ module MobileMetrics
23
23
  class Log
24
24
 
25
25
  @@in_progress_timers = {}
@@ -27,63 +27,63 @@ module MobileMetrics
27
27
  @@env_values = nil
28
28
  @@verbose = false
29
29
  @@upload_location = nil
30
-
30
+
31
31
  #========================================
32
32
  # Configuration
33
33
  #=========================================
34
-
34
+
35
35
  # Named params, with ability to override / leave out stuff we don't care about.
36
36
  def self.set_default_values(
37
37
  # Required params
38
38
  project:,
39
39
  # These params either aren't required, or have sensible defaults.
40
- level: "info",
41
- platform: "iOS",
42
- buildUrl: ENV['BUILD_URL'],
43
- gitUrl: ENV['GIT_URL'],
44
- gitBranch: ENV['DOTCI_BRANCH'],
45
- gitSha: ENV['DOTCI_SHA'],
40
+ level: "info",
41
+ platform: "iOS",
42
+ buildUrl: ENV['BUILD_URL'],
43
+ gitUrl: ENV['GIT_URL'],
44
+ gitBranch: ENV['BRANCH'],
45
+ gitSha: ENV['SHA'],
46
46
  # no sensible defaults for these, we'll strip them later
47
- buildType: UNKNOWN,
47
+ buildType: UNKNOWN,
48
48
  brand: UNKNOWN,
49
49
  # Controls log levels within this class
50
50
  verbose: false,
51
51
  # Upload location for logs
52
52
  upload_location: nil
53
- )
54
-
53
+ )
54
+
55
55
  #TODO: May be able to support overridding these at some point in the future.
56
56
  # It won't be threadsafe, but our builds aren't parallelized at the build script level anyway.
57
57
  if @@env_values
58
58
  print 'Can only override default values once! Aborting!'
59
59
  return
60
60
  end
61
-
62
- if project.nil?
61
+
62
+ if project.nil?
63
63
  print 'Project value for logging MUST be non-nil, failing build.'
64
64
  exit 14
65
65
  return
66
66
  end
67
-
67
+
68
68
  @@verbose = verbose
69
-
69
+
70
70
  # Upload location
71
71
  @@upload_location = (upload_location || ENV[UPLOAD_ENV_VAR])
72
- if @@upload_location.nil?
72
+ if @@upload_location.nil?
73
73
  print 'Upload location value for logging MUST not be nil, exiting.'
74
74
  exit 15
75
75
  return
76
76
  end
77
-
77
+
78
78
  # Create the logging dir + filename
79
79
  FileUtils.mkdir_p(LOGGING_DIR)
80
80
  filename = "metrics_#{project}_#{build_number}.log"
81
81
  @@log_file = Pathname.new(LOGGING_DIR) + filename
82
82
  print @@log_file if @@verbose
83
-
83
+
84
84
  # Populate our env values
85
85
  @@env_values = {}
86
-
86
+
87
87
  # Required
88
88
  @@env_values[:project] = project
89
89
  # Optional
@@ -93,131 +93,155 @@ module MobileMetrics
93
93
  @@env_values[:gitBranch] = gitBranch
94
94
  @@env_values[:gitSha] = gitSha
95
95
  @@env_values[:buildUrl] = buildUrl
96
-
96
+
97
97
  #TODO: Should any of these be required?
98
98
  @@env_values[:buildType] = buildType if buildType != UNKNOWN
99
99
  @@env_values[:brand] = brand if brand != UNKNOWN
100
100
  end
101
-
102
- # =begin
103
- # # Sample timer metric
104
- # {
105
- # "time": "<yyyy-MM-ddThh:mm:ss[.sss]Z>",
106
- # "name": "x.mobile_metric.<metric_type>",
107
- # "level": "info",
108
- # "data": {
109
- # "name": "<metric_name>",
110
- # … // additional data per metric type
111
- # }
112
- # "context": {
113
- # "platform": "<ios_or_android>",
114
- # "project": "<project_name>",
115
- # "gitUrl": "<git_url>",
116
- # "gitBranch": "<git_branch>",
117
- # "gitSha": "<git_sha>",
118
- # "buildType": "<build_type>",
119
- # "brand": "<brand>",
120
- # "host": "<machine_dns_name_or_device_name>",
121
- # "processId": "<process_id_or_build_number>"
122
- # }
123
- # }
124
- # =end
101
+
102
+ # =begin
103
+ # # Sample timer metric
104
+ # {
105
+ # "time": "<yyyy-MM-ddThh:mm:ss[.sss]Z>",
106
+ # "name": "x.mobile_metric.<metric_type>",
107
+ # "level": "info",
108
+ # "data": {
109
+ # "name": "<metric_name>",
110
+ # … // additional data per metric type
111
+ # }
112
+ # "context": {
113
+ # "platform": "<ios_or_android>",
114
+ # "project": "<project_name>",
115
+ # "gitUrl": "<git_url>",
116
+ # "gitBranch": "<git_branch>",
117
+ # "gitSha": "<git_sha>",
118
+ # "buildType": "<build_type>",
119
+ # "brand": "<brand>",
120
+ # "host": "<machine_dns_name_or_device_name>",
121
+ # "processId": "<process_id_or_build_number>"
122
+ # }
123
+ # }
124
+ # =end
125
125
 
126
126
  #=========================================
127
127
  # Public Logging Methods
128
128
  #=========================================
129
-
129
+
130
130
  def self.log_ratio_metric(name:, ratio:)
131
- overrides = {name: METRIC_RATIO, data: {name: name, ratio: ratio.to_f }}
131
+ overrides = { name: METRIC_RATIO, data: { name: name, ratio: ratio.to_f } }
132
132
  log_partial_metric(overrides)
133
133
  end
134
-
134
+
135
135
  def self.log_counter_metric(name:, count:)
136
- overrides = {name: METRIC_COUNTER, data: {name: name, count: count.to_i }}
136
+ overrides = { name: METRIC_COUNTER, data: {name: name, count: count.to_i } }
137
137
  log_partial_metric(overrides)
138
138
  end
139
-
139
+
140
140
  def self.log_size_metric(name:, sizeInBytes:, filename:, artifactUrl:)
141
- overrides = {name: METRIC_SIZE, data: {name: name, filename: filename, sizeInBytes: sizeInBytes, artifactUrl: artifactUrl }}
141
+ overrides = { name: METRIC_SIZE, data: { name: name, filename: filename, size: sizeInBytes, artifactUrl: artifactUrl } }
142
142
  log_partial_metric(overrides)
143
143
  end
144
-
144
+
145
+ def self.log_timer(name:, delta_in_ms:)
146
+ overrides = {name: METRIC_TIMER, data: {name: name, duration: delta_in_ms }}
147
+ log_partial_metric(overrides)
148
+ end
149
+
145
150
  def self.start_timer_metric(name:)
146
- if @@in_progress_timers.has_key?(name)
151
+ if @@in_progress_timers.has_key?(name)
147
152
  print "WARNING: #{name} already has a running timer, refusing to start a new timer"
148
153
  return
149
154
  end
150
155
  @@in_progress_timers[name] = monotonic_timestamp
151
156
  end
152
-
157
+
153
158
  def self.end_timer_metric(name:)
154
159
  if !@@in_progress_timers.has_key?(name)
155
160
  print "WARNING: #{name} does not have a running timer, the end_timer_metric call has no effect"
156
161
  return
157
162
  end
158
-
163
+
159
164
  # Calculate delta
160
165
  start = @@in_progress_timers[name]
161
166
  now = monotonic_timestamp
162
167
  delta_in_ms = ((now - start) * 1000).to_i
163
-
168
+
164
169
  # remove existing timer
165
170
  @@in_progress_timers.delete(name)
166
-
171
+
167
172
  # log to file
168
173
  overrides = {name: METRIC_TIMER, data: {name: name, duration: delta_in_ms }}
169
174
  log_partial_metric(overrides)
170
175
  end
171
-
176
+
172
177
  # Block based timer. This is the recommended way to timer operations.
173
- def self.time(name:, &block)
178
+ def self.time(name:, &_block)
174
179
  self.start_timer_metric(name: name)
175
180
  yield
176
181
  self.end_timer_metric(name: name)
177
182
  end
178
-
179
- def self.upload_logs()
180
- # Already called upload logs before, second time is a no-op
181
- if @@log_file.nil? || !@@log_file.file?
182
- print "WARN: Log file is empty or doesn't exist. Was upload_logs called previously?"
183
- return
183
+
184
+ def self.log_unit_test_count_from_file(junit_file:, fail_build_on_file_not_found: false)
185
+ if !File.exist?(junit_file)
186
+ print "WARN: JUnit file #{junit_file} does not exist on disk"
187
+ exit 16 if fail_build_on_file_not_found
188
+ return if !fail_build_on_file_not_found
184
189
  end
185
-
190
+
191
+ parser = MobileMetrics::JunitParser.new
192
+ parser.parse(junit_file)
193
+ unit_test_count = parser.tests.count
194
+
195
+ # Only log values > 0 to avoid any parser issues.
196
+ if unit_test_count == 0
197
+ print 'WARN: Parsed unit test count is zero, avoiding logging.'
198
+ else
199
+ self.log_counter_metric(name: 'unit_tests_count', count: unit_test_count)
200
+ end
201
+ end
202
+
203
+ def self.upload_logs
204
+ # Already called upload logs before, second time is a no-op
205
+ if @@log_file.nil? || !@@log_file.file?
206
+ print 'WARN: Log file is empty or doesn\'t exist. Was upload_logs called previously?'
207
+ return
208
+ end
209
+
186
210
  # Skip uploads for local dev machines
187
- if !should_upload_logs()
211
+ if !should_upload_logs
188
212
  print 'Detected local machine, refusing to upload build metrics. Removing intermediate log file'
189
- remove_log_file()
213
+ remove_log_file
190
214
  return
191
215
  end
192
-
216
+
193
217
  # Warn for any open timers
194
- if @@in_progress_timers.size > 0
195
- @@in_progress_timers.each { |k,v|
218
+ if @@in_progress_timers.size > 0
219
+ @@in_progress_timers.each { |k, _v|
196
220
  print "WARN: Timer not closed when upload_logs was called: #{k}"
197
221
  }
198
222
  end
199
-
200
- # Upload
201
- upload_log_file()
202
-
223
+
224
+ # Upload
225
+ upload_log_file
226
+
203
227
  # Remove log file
204
- remove_log_file()
228
+ remove_log_file
205
229
  end
206
-
207
- def self.log_file()
230
+
231
+ def self.log_file
208
232
  @@log_file
209
233
  end
210
-
211
- def self.upload_location()
234
+
235
+ def self.upload_location
212
236
  @@upload_location
213
237
  end
214
-
238
+
215
239
  # Tears down logging instance, removes any intermediate log files.
216
240
  # Does not finalize or upload any in-progress logs.
217
241
  # To use the logger again, you'll have to call set_default_values before any other methods.
218
- def self.reset()
219
- if @@log_file
220
- remove_log_file()
242
+ def self.reset
243
+ if @@log_file
244
+ remove_log_file
221
245
  end
222
246
  @@log_file = nil
223
247
  @@env_values = nil
@@ -225,15 +249,15 @@ module MobileMetrics
225
249
  @@verbose = false
226
250
  @@upload_location = nil
227
251
  end
228
-
229
- def self.remove_all_log_files()
230
- FileUtils.rm_rf(LOGGING_DIR)
252
+
253
+ def self.remove_all_log_files
254
+ FileUtils.rm_rf(LOGGING_DIR)
231
255
  end
232
-
256
+
233
257
  private
234
258
 
235
259
  # Creates a stubbed metric with common fields
236
- def self.default_metric()
260
+ def self.default_metric
237
261
  if !@@env_values
238
262
  print 'default_metric called before env_values initialized, aborting!'
239
263
  exit 12
@@ -251,25 +275,26 @@ module MobileMetrics
251
275
  buildUrl: @@env_values[:buildUrl],
252
276
  host: hostname(),
253
277
  processId: build_number()
254
- }.select { |k,v| !v.nil? }
278
+ }.select { |k,v| !v.nil? }
255
279
  {time: timestamp(), level:@@env_values[:level], context: context}
256
280
  end
257
-
281
+
258
282
  def self.append_to_log(value)
259
283
  # Create the log file if it doesn't exist
260
284
  if !@@log_file.file?
261
- FileUtils.touch(@@log_file)
285
+ FileUtils.touch(@@log_file)
262
286
  end
263
287
  File.open(@@log_file, 'a+') { |f| f.puts(value + "\n") }
264
288
  end
265
-
266
- def self.remove_log_file()
289
+
290
+ def self.remove_log_file
267
291
  FileUtils.rm_rf(@@log_file)
268
292
  end
269
-
270
- def self.upload_log_file()
293
+
294
+ def self.upload_log_file
271
295
  destination = @@upload_location + "metrics_#{@@env_values[:project]}_#{build_number}.log"
272
- command = "scp -v -o StrictHostKeyChecking=no #{@@log_file} #{destination}"
296
+ verbose_flag = @@verbose ? '-v' : ''
297
+ command = "scp #{verbose_flag} -o StrictHostKeyChecking=no #{@@log_file} #{destination}"
273
298
  # This feels icky
274
299
  print `#{command}`
275
300
  end
@@ -278,17 +303,17 @@ module MobileMetrics
278
303
  # Note: This format doesn't currently add milliseconds.
279
304
  # Example: "2018-03-27T21:12:21Z"
280
305
  # Note: DO NOT use this for benchmarking / measuring timers, see monotonic_timestamp instead.
281
- def self.timestamp()
306
+ def self.timestamp
282
307
  Time.now.utc.iso8601.to_s
283
308
  end
284
-
309
+
285
310
  # Returns a floating point monotonic timestamp suitable for timers
286
311
  # Monotonic means we won't ever go back for things like leap seconds
287
312
  # Unit is a floating point in seconds.
288
- def self.monotonic_timestamp()
313
+ def self.monotonic_timestamp
289
314
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
290
315
  end
291
-
316
+
292
317
  # Each metric should call this method.
293
318
  # This method handles merging the metric hash with the default hash,
294
319
  # Generates the JSON with the keys in the right order, then appends to the log.
@@ -299,40 +324,39 @@ module MobileMetrics
299
324
  metric = ordered_hash.to_json
300
325
  append_to_log(metric)
301
326
  end
302
-
327
+
303
328
  # Util method for merging the default hash values and overrides recursively as we want them
304
329
  def self.merge_hashes(default, overrides)
305
- default.merge(overrides) { |key, oldval, newval|
306
- if key == :data || key == :contenxt
330
+ default.merge(overrides) { |key, oldval, newval|
331
+ if key == :data || key == :context
307
332
  oldval.merge(newval)
308
333
  else
309
334
  newval
310
335
  end
311
336
  }
312
337
  end
313
-
338
+
314
339
  # Returns the host name of the machine we are currently running on
315
- def self.hostname()
340
+ def self.hostname
316
341
  ENV['NODE_NAME'] || 'local-dev'
317
342
  end
318
-
319
- def self.build_number()
343
+
344
+ def self.build_number
320
345
  ENV['BUILD_NUMBER']
321
346
  end
322
-
347
+
323
348
  # This method checks against a bunch of default environment variables available through DOTCI
324
349
  # The intent is never to upload timing logs from a local machine, so we make it unlikely that these
325
350
  # env variables are present on a dev's local machine
326
- def self.should_upload_logs()
351
+ def self.should_upload_logs
327
352
  have_workspace = ENV['WORKSPACE'] && !ENV['WORKSPACE'].empty?
328
353
  have_build_number = ENV['BUILD_NUMBER'] && !ENV['BUILD_NUMBER'].empty?
329
354
  have_jenkins_url = ENV['JENKINS_URL'] && !ENV['JENKINS_URL'].empty?
330
- have_ci_var = ENV['CI'] && !ENV['CI'].empty?
331
- have_workspace && have_build_number && have_jenkins_url && have_ci_var
355
+ have_workspace && have_build_number && have_jenkins_url
332
356
  end
333
-
357
+
334
358
  def self.print(val)
335
359
  puts("#{LOG_PREFIX} #{val}")
336
360
  end
337
361
  end
338
- end
362
+ end
@@ -1,6 +1,5 @@
1
1
 
2
2
  module MobileMetrics
3
-
4
3
  # Adapted from: https://github.com/orta/danger-junit/blob/master/lib/junit/plugin.rb
5
4
  class JunitParser
6
5
  # All the tests for introspection
@@ -55,23 +54,23 @@ module MobileMetrics
55
54
  failed_suites = suite_root.nodes.select { |suite| suite[:failures].to_i > 0 || suite[:errors].to_i > 0 }
56
55
  failed_tests = failed_suites.map(&:nodes).flatten.select { |node| node.kind_of?(Ox::Element) && node.value == 'testcase' }
57
56
 
58
- @failures = failed_tests.select do |test|
57
+ @failures = failed_tests.select do |test|
59
58
  test.nodes.count > 0
60
59
  end.select do |test|
61
60
  node = test.nodes.first
62
61
  node.kind_of?(Ox::Element) && node.value == 'failure'
63
62
  end
64
63
 
65
- @errors = failed_tests.select do |test|
64
+ @errors = failed_tests.select do |test|
66
65
  test.nodes.count > 0
67
- end.select do |test|
66
+ end.select do |test|
68
67
  node = test.nodes.first
69
68
  node.kind_of?(Ox::Element) && node.value == 'error'
70
69
  end
71
70
 
72
- @skipped = tests.select do |test|
71
+ @skipped = tests.select do |test|
73
72
  test.nodes.count > 0
74
- end.select do |test|
73
+ end.select do |test|
75
74
  node = test.nodes.first
76
75
  node.kind_of?(Ox::Element) && node.value == 'skipped'
77
76
  end
@@ -79,4 +78,4 @@ module MobileMetrics
79
78
  @passes = tests - @failures - @errors - @skipped
80
79
  end
81
80
  end
82
- end
81
+ end
@@ -1,3 +1,3 @@
1
1
  module MobileMetrics
2
- VERSION = "0.0.3"
2
+ VERSION = '0.1.0'
3
3
  end
@@ -13,12 +13,12 @@ Gem::Specification.new do |spec|
13
13
  # spec.homepage = "TODO: Put your gem's website or public repo URL here."
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0").reject do |f|
16
- f.match(%r{^(test|spec|features|README|scripts)/}) || f.match(%r{^(.ci|README.md)})
16
+ f.match(%r{^(test|spec|features|README|scripts)/}) || f.match(%r{^(.ci|README.md)})
17
17
  end
18
18
  spec.bindir = "exe"
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
-
21
+
22
22
  spec.add_runtime_dependency 'ox', '~> 2.0'
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.16"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mobile_metrics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - dbeard
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-05 00:00:00.000000000 Z
11
+ date: 2020-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ox
@@ -66,7 +66,7 @@ dependencies:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '3.0'
69
- description:
69
+ description:
70
70
  email:
71
71
  - dbeard@groupon.com
72
72
  executables: []
@@ -75,7 +75,6 @@ extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
77
  - ".rspec"
78
- - ".travis.yml"
79
78
  - Gemfile
80
79
  - Gemfile.lock
81
80
  - Rakefile
@@ -85,10 +84,10 @@ files:
85
84
  - lib/mobile_metrics/junit.rb
86
85
  - lib/mobile_metrics/version.rb
87
86
  - mobile_metrics.gemspec
88
- homepage:
87
+ homepage:
89
88
  licenses: []
90
89
  metadata: {}
91
- post_install_message:
90
+ post_install_message:
92
91
  rdoc_options: []
93
92
  require_paths:
94
93
  - lib
@@ -103,9 +102,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
102
  - !ruby/object:Gem::Version
104
103
  version: '0'
105
104
  requirements: []
106
- rubyforge_project:
107
- rubygems_version: 2.7.7
108
- signing_key:
105
+ rubygems_version: 3.0.3
106
+ signing_key:
109
107
  specification_version: 4
110
108
  summary: Mobile logging format library
111
109
  test_files: []
@@ -1,5 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- rvm:
4
- - 2.4.0
5
- before_install: gem install bundler -v 1.16.1