keepclean 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d53d71acf6dbc0ed3021281b4177a56208ea8024abb456fd8dcc777e9dac8a8b
4
+ data.tar.gz: 57851b8d5a96a49c13ba08cd2b7e26b151a7024dbd46fe31fced212645583efa
5
+ SHA512:
6
+ metadata.gz: d14ffe8aad2e92b58b571f279c997e57ffc1e0532ffdbdae2b3562ca259120e8003f817ef85743ceddd6e920d85a16134c47049aedf04d107b1ba0038af87c6f
7
+ data.tar.gz: 2ee0ea8861beb7ddc30022849c6226588c6c6bbbb4d588f67979d15e05ec4490d3dbdf1b59228b817b63064385a02f5c82131251ffcc64aa0f2127ec05e65ead
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'keepclean'
4
+ Keepclean.run(ARGV)
@@ -0,0 +1,37 @@
1
+ require 'pronto'
2
+ require 'pronto/cli'
3
+
4
+ module Integration
5
+ class Base
6
+ def initialize(pronto: false)
7
+ @pronto = pronto
8
+ end
9
+
10
+ def pronto_enabled?
11
+ @pronto
12
+ end
13
+
14
+ def pronto_name
15
+ self.class.name.demodulize.underscore
16
+ end
17
+
18
+ def run_with(config)
19
+ raise NotImplementedError
20
+ end
21
+
22
+ def run_with_config_handling_exit(config)
23
+ if pronto_enabled?
24
+ args = ['run', '.', '--exit-code', '--runner', pronto_name]
25
+ Keepclean.logger.debug "Running pronto with args: #{args.inspect}"
26
+ ::Pronto::CLI.start(args)
27
+ ::Pronto::Runner.remove_instance_variable(:@repository)
28
+ else
29
+ Keepclean.logger.debug "Running on all project"
30
+ run_with(config)
31
+ end
32
+ rescue SystemExit => e
33
+ Keepclean.logger.debug "Handling SystemExit: #{e.inspect} => status: #{e.status} / success?: #{e.success?}"
34
+ return e.success?
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'base'
2
+ require 'brakeman'
3
+ require 'brakeman/commandline'
4
+
5
+ module Integration
6
+ class Brakeman < Base
7
+ def run_with(config)
8
+ args = {
9
+ quiet: true,
10
+ summary_only: :no_summary,
11
+ }
12
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
13
+ ::Brakeman::Commandline.start(args)
14
+ true
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'base'
2
+ require 'bundler/audit/cli'
3
+
4
+ module Integration
5
+ class BundleAudit < Base
6
+ def run_with(config)
7
+ args = ['check']
8
+
9
+ ignored_cves = config.fetch('ignored_cve', [])
10
+
11
+ if !ignored_cves.empty?
12
+ args += ["--ignore"]
13
+ ignored_cves.each do |ignored_cve|
14
+ args << ignored_cve
15
+ end
16
+ end
17
+
18
+ Keepclean.logger.debug "Updating CVE database"
19
+ Bundler::Audit::CLI.start(['update', '--quiet'])
20
+
21
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
22
+ Bundler::Audit::CLI.start(args)
23
+ true
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'base'
2
+ require 'danger'
3
+
4
+ module Integration
5
+ class Danger < Base
6
+ def run_with(config)
7
+ args = ['staging']
8
+ Keepclean.logger.debug "Running with args: #{args}"
9
+ ::Danger::Runner.run args
10
+ end
11
+ end
12
+ end
@@ -0,0 +1 @@
1
+ warn "MR is classed as Work in Progress" if gitlab.mr_title.include? "WIP:"
@@ -0,0 +1,12 @@
1
+ require_relative 'base'
2
+ require 'erb_lint/cli'
3
+
4
+ module Integration
5
+ class ErbLint < Base
6
+ def run_with(config)
7
+ args = ['--lint-all']
8
+ Keepclean.logger.debug "Running with args: #{args}"
9
+ ERBLint::CLI.new.run(args)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,33 @@
1
+ require_relative 'base'
2
+ require 'flay'
3
+
4
+ module Integration
5
+ class Flay < Base
6
+ def run_with(config)
7
+ args = []
8
+
9
+ if mass_threshold = config['mass_threshold']
10
+ args += ['-m', mass_threshold.to_s]
11
+ end
12
+
13
+ should_delete_flayignore = false
14
+ if ignored = config['ignored']
15
+ if File.file?('.flayignore')
16
+ Keepclean.logger.warn('Using local .flayignore')
17
+ else
18
+ should_delete_flayignore = File.write('.flayignore', ignored.join("\n"), mode: 'a') != 0
19
+ end
20
+ end
21
+
22
+ args += ['-d', '-#']
23
+
24
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
25
+ flay = ::Flay.run(args)
26
+ flay.report
27
+
28
+ File.delete('.flayignore') if should_delete_flayignore
29
+
30
+ flay.total == 0
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require "flog_cli"
3
+
4
+ module Integration
5
+ class Flog < Base
6
+ def run_with(config)
7
+ args = ['-m']
8
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
9
+ FlogCLI.run(args)
10
+ true
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'base'
2
+ require 'license_finder'
3
+
4
+ module Integration
5
+ class LicenseFinder < Base
6
+ def run_with(config)
7
+ Tempfile.create(['dependency_decisions', '.yml']) do |f|
8
+ dependency_decisions = []
9
+
10
+ allowed_licenses = config.fetch('allowed_licenses', [])
11
+
12
+ allowed_licenses.each do |allowed_license|
13
+ dependency_decisions << [:permit, allowed_license, { who: 'Keepclean' }]
14
+ end
15
+
16
+ f.write dependency_decisions.to_yaml
17
+ f.close
18
+
19
+ args = ['--decisions_file', f.path]
20
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
21
+ ::LicenseFinder::CLI::Main.start(args)
22
+ end
23
+
24
+ true
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'base'
2
+ require 'rails_best_practices'
3
+
4
+ module Integration
5
+ class RailsBestPractices < Base
6
+ def run_with(config)
7
+ args = ['.', { 'silent' => true }]
8
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
9
+ analyzer = ::RailsBestPractices::Analyzer.new(*args)
10
+ analyzer.analyze
11
+ analyzer.output
12
+ analyzer.runner.errors.empty?
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'base'
2
+ require 'reek'
3
+ require 'reek/cli/application'
4
+
5
+ module Integration
6
+ class Reek < Base
7
+ def run_with(config)
8
+ args = ['.']
9
+ Keepclean.logger.debug "Running with args: #{args.inspect}"
10
+ ::Reek::CLI::Application.new(args).execute == 0
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require_relative 'base'
2
+ require 'rubocop'
3
+
4
+ module Integration
5
+ class Rubocop < Base
6
+ def run_with(config)
7
+ Keepclean.logger.debug "Running with args:"
8
+ RuboCop::CLI.new.run == 0
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,113 @@
1
+ require 'net/http'
2
+ require 'json'
3
+ require 'active_support/core_ext/string/inflections.rb'
4
+
5
+ require 'keepclean/version'
6
+ require 'keepclean/formatter'
7
+
8
+ module Keepclean
9
+ def self.project_name
10
+ ENV['KEEPCLEAN_PROJECT'] || ENV['DRONE_REPO']
11
+ end
12
+
13
+ def self.build_id
14
+ ENV['KEEPCLEAN_BUILD_ID'] || ENV['DRONE_BUILD_NUMBER']
15
+ end
16
+
17
+ def self.logger
18
+ return @logger if defined?(@logger)
19
+ @log_output = StringIO.new
20
+ @logger = ActiveSupport::TaggedLogging.new(Logger.new(@log_output)).tap do |l|
21
+ l.level = if ENV['KEEPCLEAN_DEBUG']
22
+ Logger::DEBUG
23
+ else
24
+ Logger::WARN
25
+ end
26
+ l.formatter = Formatter.new
27
+ end
28
+ end
29
+
30
+ def self.run(args)
31
+ at_exit do
32
+ logs = @log_output.string
33
+ unless logs.empty?
34
+ puts ""
35
+ puts "===== DEBUG ====="
36
+ puts ""
37
+ puts logs
38
+ end
39
+ end
40
+
41
+ puts "*** Keepclean v#{Keepclean::VERSION} ***"
42
+
43
+ token = ENV['KEEPCLEAN_TOKEN']
44
+ unless token
45
+ puts "Token no set, use KEEPCLEAN_TOKEN"
46
+ exit -1
47
+ end
48
+
49
+ unless project_name
50
+ puts "Project no set, use KEEPCLEAN_PROJECT"
51
+ exit -1
52
+ end
53
+
54
+ uri = URI('http://192.168.0.31:5000/manifest')
55
+ res = Net::HTTP.post_form(uri, {
56
+ version: Keepclean::VERSION,
57
+ token: token,
58
+ project: project_name
59
+ })
60
+
61
+ unless res['content-type'].start_with?('application/json')
62
+ puts res.body
63
+ exit -1
64
+ end
65
+
66
+ manifest = JSON.parse(res.body)
67
+ logger.debug "Manifest: #{manifest}"
68
+
69
+ puts "Configure at: #{manifest['configuration_url']}"
70
+
71
+ success = true
72
+
73
+ manifest.each do |key, metadata|
74
+ next unless metadata['enabled']
75
+
76
+ klass = case key
77
+ when 'custom'
78
+ class_name = metadata.dig('config', 'class_name')
79
+ unless class_name
80
+ puts "#{key} check skipped because the class_name is not configured"
81
+ next
82
+ end
83
+ class_name.gsub('Integration::', '')
84
+ else
85
+ key.camelize
86
+ end
87
+
88
+ logger.tagged(klass) do
89
+ begin
90
+ puts ""
91
+ puts "*** #{klass} ***"
92
+ puts ""
93
+
94
+ require "integrations/#{klass.underscore}"
95
+ success &= "Integration::#{klass}".constantize.new(pronto: metadata['on_branch']).run_with_config_handling_exit(metadata['config']) || metadata['allowed_to_fail']
96
+ logger.debug "Success: #{success}"
97
+ rescue LoadError => e
98
+ puts "#{klass} check skipped because of error: #{e.message}"
99
+ ensure
100
+ if klass
101
+ puts ""
102
+ puts "*** /#{klass}/ ***"
103
+ puts ""
104
+ end
105
+ end
106
+ end
107
+ end
108
+
109
+ exit success
110
+ rescue Errno::ECONNREFUSED => e
111
+ puts "We couldn't reach the keepclean server: #{e.message}"
112
+ end
113
+ end
@@ -0,0 +1,15 @@
1
+ require 'logger'
2
+ require 'active_support/tagged_logging.rb'
3
+
4
+ module Keepclean
5
+ class Formatter < Logger::Formatter
6
+ include ActiveSupport::TaggedLogging::Formatter
7
+
8
+ def call(severity, timestamp, progname, msg)
9
+ (String === msg ? msg : msg.inspect).split("\n").map do |line|
10
+ "%s %s[%s] %s%s: %s\n" % [Time.at(timestamp).strftime("%b %e %H:%M:%S"), Keepclean.project_name, Keepclean.build_id, tags_text, severity, line]
11
+ end.join
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,3 @@
1
+ module Keepclean
2
+ VERSION = '0.0.1'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,339 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: keepclean
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Yoann Lecuyer
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rubocop
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.85.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.85.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: brakeman
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 4.8.2
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 4.8.2
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler-audit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.7'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: danger
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 8.0.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 8.0.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: danger-gitlab
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 8.0.0
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 8.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rails_best_practices
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 1.20.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 1.20.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: reek
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 5.6.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 5.6.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: flay
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 2.12.1
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 2.12.1
125
+ - !ruby/object:Gem::Dependency
126
+ name: flog
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 4.6.4
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 4.6.4
139
+ - !ruby/object:Gem::Dependency
140
+ name: erb_lint
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: 0.0.10
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: 0.0.10
153
+ - !ruby/object:Gem::Dependency
154
+ name: license_finder
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '6'
160
+ type: :runtime
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '6'
167
+ - !ruby/object:Gem::Dependency
168
+ name: activesupport
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: 6.0.3.1
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: 6.0.3.1
181
+ - !ruby/object:Gem::Dependency
182
+ name: ruby2ruby
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: 2.4.4
188
+ type: :runtime
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: 2.4.4
195
+ - !ruby/object:Gem::Dependency
196
+ name: pronto
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: 0.10.0
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: 0.10.0
209
+ - !ruby/object:Gem::Dependency
210
+ name: pronto-reek
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: 0.10.0
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: 0.10.0
223
+ - !ruby/object:Gem::Dependency
224
+ name: pronto-flay
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: 0.10.0
230
+ type: :runtime
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: 0.10.0
237
+ - !ruby/object:Gem::Dependency
238
+ name: pronto-brakeman
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: 0.10.0
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: 0.10.0
251
+ - !ruby/object:Gem::Dependency
252
+ name: pronto-rails_best_practices
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - "~>"
256
+ - !ruby/object:Gem::Version
257
+ version: 0.10.0
258
+ type: :runtime
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - "~>"
263
+ - !ruby/object:Gem::Version
264
+ version: 0.10.0
265
+ - !ruby/object:Gem::Dependency
266
+ name: pronto-rubocop
267
+ requirement: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - "~>"
270
+ - !ruby/object:Gem::Version
271
+ version: 0.10.0
272
+ type: :runtime
273
+ prerelease: false
274
+ version_requirements: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - "~>"
277
+ - !ruby/object:Gem::Version
278
+ version: 0.10.0
279
+ - !ruby/object:Gem::Dependency
280
+ name: pronto-erb_lint
281
+ requirement: !ruby/object:Gem::Requirement
282
+ requirements:
283
+ - - "~>"
284
+ - !ruby/object:Gem::Version
285
+ version: 0.1.5
286
+ type: :runtime
287
+ prerelease: false
288
+ version_requirements: !ruby/object:Gem::Requirement
289
+ requirements:
290
+ - - "~>"
291
+ - !ruby/object:Gem::Version
292
+ version: 0.1.5
293
+ description: Keep your repo clean with simple CI rules
294
+ email: yoann.lecuyer@gmail.com
295
+ executables:
296
+ - keepclean
297
+ extensions: []
298
+ extra_rdoc_files: []
299
+ files:
300
+ - bin/keepclean
301
+ - lib/integrations/base.rb
302
+ - lib/integrations/brakeman.rb
303
+ - lib/integrations/bundle_audit.rb
304
+ - lib/integrations/danger.rb
305
+ - lib/integrations/danger/Dangerfile
306
+ - lib/integrations/erb_lint.rb
307
+ - lib/integrations/flay.rb
308
+ - lib/integrations/flog.rb
309
+ - lib/integrations/license_finder.rb
310
+ - lib/integrations/rails_best_practices.rb
311
+ - lib/integrations/reek.rb
312
+ - lib/integrations/rubocop.rb
313
+ - lib/keepclean.rb
314
+ - lib/keepclean/formatter.rb
315
+ - lib/keepclean/version.rb
316
+ homepage: https://rubygems.org/gems/keepclean
317
+ licenses:
318
+ - MIT
319
+ metadata: {}
320
+ post_install_message:
321
+ rdoc_options: []
322
+ require_paths:
323
+ - lib
324
+ required_ruby_version: !ruby/object:Gem::Requirement
325
+ requirements:
326
+ - - ">="
327
+ - !ruby/object:Gem::Version
328
+ version: '0'
329
+ required_rubygems_version: !ruby/object:Gem::Requirement
330
+ requirements:
331
+ - - ">="
332
+ - !ruby/object:Gem::Version
333
+ version: '0'
334
+ requirements: []
335
+ rubygems_version: 3.0.0
336
+ signing_key:
337
+ specification_version: 4
338
+ summary: Keep clean!
339
+ test_files: []