convox_installer 1.0.9 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/convox/client.rb CHANGED
@@ -1,23 +1,58 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "logger"
4
- require "json"
5
- require "fileutils"
3
+ require 'logger'
4
+ require 'json'
5
+ require 'fileutils'
6
+ require 'rubygems'
6
7
 
7
8
  module Convox
8
9
  class Client
9
- CONVOX_DIR = File.expand_path("~/.convox").freeze
10
- AUTH_FILE = File.join(CONVOX_DIR, "auth")
11
- HOST_FILE = File.join(CONVOX_DIR, "host")
10
+ CONVOX_DIR = File.expand_path('~/.convox').freeze
11
+ AUTH_FILE = File.join(CONVOX_DIR, 'auth')
12
+ HOST_FILE = File.join(CONVOX_DIR, 'host')
12
13
 
13
14
  attr_accessor :logger, :config
14
15
 
16
+ def cli_version_string
17
+ return @cli_version_string if @cli_version_string
18
+
19
+ cli_version_string ||= `convox --version`
20
+ return unless $CHILD_STATUS.success?
21
+
22
+ @cli_version_string = cli_version_string.chomp
23
+ end
24
+
25
+ def cli_version
26
+ return unless cli_version_string.is_a?(String)
27
+
28
+ if cli_version_string.match?(/^\d+\.\d+\.\d+/)
29
+ @cli_version ||= Gem::Version.new(version_string)
30
+ end
31
+ @cli_version
32
+ end
33
+
34
+ def convox_2_cli?
35
+ return false unless cli_version_string.is_a?(String)
36
+
37
+ cli_version_string.match?(/^20\d+$/)
38
+ end
39
+
40
+ def convox_3_cli?
41
+ return false if !cli_version_string.is_a?(String) ||
42
+ convox_2_cli? ||
43
+ !cli_version_string.match?(/^\d+\.\d+\.\d+/)
44
+
45
+ cli_version = Gem::Version.new(cli_version_string)
46
+ cli_version >= Gem::Version.new('3.0.0') &&
47
+ cli_version < Gem::Version.new('4.0.0')
48
+ end
49
+
15
50
  def auth
16
51
  load_auth_from_file
17
52
  end
18
53
 
19
54
  def initialize(options = {})
20
- @logger = Logger.new(STDOUT)
55
+ @logger = Logger.new($stdout)
21
56
  logger.level = options[:log_level] || Logger::INFO
22
57
  @config = options[:config] || {}
23
58
  end
@@ -27,16 +62,16 @@ module Convox
27
62
 
28
63
  %w[host rack].each do |f|
29
64
  path = File.join(CONVOX_DIR, f)
30
- if File.exist?(path)
31
- bak_file = "#{path}.bak"
32
- logger.info "Moving existing #{path} to #{bak_file}..."
33
- FileUtils.mv(path, bak_file)
34
- end
65
+ next unless File.exist?(path)
66
+
67
+ bak_file = "#{path}.bak"
68
+ logger.info "Moving existing #{path} to #{bak_file}..."
69
+ FileUtils.mv(path, bak_file)
35
70
  end
36
71
  end
37
72
 
38
73
  def install_convox
39
- require_config(%i[ aws_region stack_name ])
74
+ require_config(%i[aws_region stack_name])
40
75
  region = config.fetch(:aws_region)
41
76
  stack_name = config.fetch(:stack_name)
42
77
 
@@ -47,37 +82,37 @@ module Convox
47
82
  end
48
83
 
49
84
  require_config(%i[
50
- aws_region
51
- aws_access_key_id
52
- aws_secret_access_key
53
- stack_name
54
- instance_type
55
- ])
85
+ aws_region
86
+ aws_access_key_id
87
+ aws_secret_access_key
88
+ stack_name
89
+ instance_type
90
+ ])
56
91
 
57
92
  logger.info "Installing Convox (#{stack_name})..."
58
93
 
59
94
  env = {
60
- "AWS_REGION" => region,
61
- "AWS_ACCESS_KEY_ID" => config.fetch(:aws_access_key_id),
62
- "AWS_SECRET_ACCESS_KEY" => config.fetch(:aws_secret_access_key),
95
+ 'AWS_REGION' => region,
96
+ 'AWS_ACCESS_KEY_ID' => config.fetch(:aws_access_key_id),
97
+ 'AWS_SECRET_ACCESS_KEY' => config.fetch(:aws_secret_access_key)
63
98
  }
64
- command = %Q{rack install aws \
99
+ command = %(rack install aws \
65
100
  --name "#{config.fetch(:stack_name)}" \
66
101
  "InstanceType=#{config.fetch(:instance_type)}" \
67
- "BuildInstance="}
102
+ "BuildInstance=")
68
103
 
69
104
  run_convox_command!(command, env)
70
105
  end
71
106
 
72
107
  def rack_already_installed?
73
- require_config(%i[ aws_region stack_name ])
108
+ require_config(%i[aws_region stack_name])
74
109
 
75
110
  return unless File.exist?(AUTH_FILE)
76
111
 
77
112
  region = config.fetch(:aws_region)
78
113
  stack_name = config.fetch(:stack_name)
79
114
 
80
- auth.each do |host, password|
115
+ auth.each do |host, _password|
81
116
  if host.match?(/^#{stack_name}-\d+\.#{region}\.elb\.amazonaws\.com$/)
82
117
  return true
83
118
  end
@@ -85,8 +120,8 @@ module Convox
85
120
  false
86
121
  end
87
122
 
88
- def validate_convox_auth_and_set_host!
89
- require_config(%i[ aws_region stack_name ])
123
+ def validate_convox_auth_and_write_host!
124
+ require_config(%i[aws_region stack_name])
90
125
 
91
126
  unless File.exist?(AUTH_FILE)
92
127
  raise "Could not find auth file at #{AUTH_FILE}!"
@@ -97,7 +132,7 @@ module Convox
97
132
 
98
133
  match_count = 0
99
134
  matching_host = nil
100
- auth.each do |host, password|
135
+ auth.each do |host, _password|
101
136
  if host.match?(/^#{stack}-\d+\.#{region}\.elb\.amazonaws\.com$/)
102
137
  matching_host = host
103
138
  match_count += 1
@@ -105,36 +140,36 @@ module Convox
105
140
  end
106
141
 
107
142
  if match_count == 1
108
- set_host(matching_host)
143
+ write_host(matching_host)
109
144
  return matching_host
110
145
  end
111
146
 
112
- if match_count > 1
113
- error_message = "Found multiple matching hosts for "
114
- else
115
- error_message = "Could not find matching authentication for "
116
- end
147
+ error_message = if match_count > 1
148
+ 'Found multiple matching hosts for '
149
+ else
150
+ 'Could not find matching authentication for '
151
+ end
117
152
  error_message += "region: #{region}, stack: #{stack}"
118
153
  raise error_message
119
154
  end
120
155
 
121
- def set_host(host)
156
+ def write_host(host)
122
157
  logger.debug "Setting convox host to #{host} (in #{HOST_FILE})..."
123
- File.open(HOST_FILE, "w") { |f| f.puts host }
158
+ File.open(HOST_FILE, 'w') { |f| f.puts host }
124
159
  end
125
160
 
126
161
  def validate_convox_rack!
127
162
  require_config(%i[
128
- aws_region
129
- stack_name
130
- instance_type
131
- ])
132
- logger.debug "Validating that convox rack has the correct attributes..."
163
+ aws_region
164
+ stack_name
165
+ instance_type
166
+ ])
167
+ logger.debug 'Validating that convox rack has the correct attributes...'
133
168
  {
134
- provider: "aws",
169
+ provider: 'aws',
135
170
  region: config.fetch(:aws_region),
136
171
  type: config.fetch(:instance_type),
137
- name: config.fetch(:stack_name),
172
+ name: config.fetch(:stack_name)
138
173
  }.each do |k, v|
139
174
  convox_value = convox_rack_data[k.to_s]
140
175
  if convox_value != v
@@ -142,15 +177,16 @@ module Convox
142
177
  "but was: '#{convox_value}'"
143
178
  end
144
179
  end
145
- logger.debug "=> Convox rack has the correct attributes."
180
+ logger.debug '=> Convox rack has the correct attributes.'
146
181
  true
147
182
  end
148
183
 
149
184
  def convox_rack_data
150
185
  @convox_rack_data ||= begin
151
- logger.debug "Fetching convox rack attributes..."
186
+ logger.debug 'Fetching convox rack attributes...'
152
187
  convox_output = `convox api get /system`
153
- raise "convox command failed!" unless $?.success?
188
+ raise 'convox command failed!' unless $CHILD_STATUS.success?
189
+
154
190
  JSON.parse(convox_output)
155
191
  end
156
192
  end
@@ -162,17 +198,18 @@ module Convox
162
198
  app_name = config.fetch(:convox_app_name)
163
199
 
164
200
  logger.info "Creating app: #{app_name}..."
165
- logger.info "=> Documentation: " \
166
- "https://docs.convox.com/deployment/creating-an-application"
201
+ logger.info '=> Documentation: ' \
202
+ 'https://docs.convox.com/deployment/creating-an-application'
167
203
 
168
204
  run_convox_command! "apps create #{app_name} --wait"
169
205
 
170
206
  retries = 0
171
207
  loop do
172
208
  break if convox_app_exists?
209
+
173
210
  if retries > 5
174
211
  raise "Something went wrong while creating the #{app_name} app! " \
175
- "(Please wait a few moments and then restart the installation script.)"
212
+ '(Please wait a few moments and then restart the installation script.)'
176
213
  end
177
214
  logger.info "Waiting for #{app_name} to be ready..."
178
215
  sleep 3
@@ -183,9 +220,9 @@ module Convox
183
220
  end
184
221
 
185
222
  def set_default_app_for_directory!
186
- logger.info "Setting default app in ./.convox/app..."
187
- FileUtils.mkdir_p File.expand_path("./.convox")
188
- File.open(File.expand_path("./.convox/app"), "w") do |f|
223
+ logger.info 'Setting default app in ./.convox/app...'
224
+ FileUtils.mkdir_p File.expand_path('./.convox')
225
+ File.open(File.expand_path('./.convox/app'), 'w') do |f|
189
226
  f.puts config.fetch(:convox_app_name)
190
227
  end
191
228
  end
@@ -196,11 +233,11 @@ module Convox
196
233
 
197
234
  logger.debug "Looking for existing #{app_name} app..."
198
235
  convox_output = `convox api get /apps`
199
- raise "convox command failed!" unless $?.success?
236
+ raise 'convox command failed!' unless $CHILD_STATUS.success?
200
237
 
201
238
  apps = JSON.parse(convox_output)
202
239
  apps.each do |app|
203
- if app["name"] == app_name
240
+ if app['name'] == app_name
204
241
  logger.debug "=> Found #{app_name} app."
205
242
  return true
206
243
  end
@@ -217,9 +254,9 @@ module Convox
217
254
  logger.info "#{bucket_name} S3 bucket already exists!"
218
255
  else
219
256
  logger.info "Creating S3 bucket resource (#{bucket_name})..."
220
- run_convox_command! "rack resources create s3 " \
257
+ run_convox_command! 'rack resources create s3 ' \
221
258
  "--name \"#{bucket_name}\" " \
222
- "--wait"
259
+ '--wait'
223
260
 
224
261
  retries = 0
225
262
  loop do
@@ -227,14 +264,14 @@ module Convox
227
264
 
228
265
  if retries > 10
229
266
  raise "Something went wrong while creating the #{bucket_name} S3 bucket! " \
230
- "(Please wait a few moments and then restart the installation script.)"
267
+ '(Please wait a few moments and then restart the installation script.)'
231
268
  end
232
- logger.debug "Waiting for S3 bucket to be ready..."
269
+ logger.debug 'Waiting for S3 bucket to be ready...'
233
270
  sleep 3
234
271
  retries += 1
235
272
  end
236
273
 
237
- logger.debug "=> S3 bucket created!"
274
+ logger.debug '=> S3 bucket created!'
238
275
  end
239
276
 
240
277
  set_s3_bucket_cors_policy
@@ -245,7 +282,7 @@ module Convox
245
282
  bucket_name = config.fetch(:s3_bucket_name)
246
283
  logger.debug "Looking up S3 bucket resource: #{bucket_name}"
247
284
  `convox api get /resources/#{bucket_name} 2>/dev/null`
248
- $?.success?
285
+ $CHILD_STATUS.success?
249
286
  end
250
287
 
251
288
  def s3_bucket_details
@@ -255,12 +292,12 @@ module Convox
255
292
  logger.debug "Fetching S3 bucket resource details for #{bucket_name}..."
256
293
 
257
294
  response = `convox api get /resources/#{bucket_name}`
258
- raise "convox command failed!" unless $?.success?
295
+ raise 'convox command failed!' unless $CHILD_STATUS.success?
259
296
 
260
297
  bucket_data = JSON.parse(response)
261
- s3_url = bucket_data["url"]
298
+ s3_url = bucket_data['url']
262
299
  matches = s3_url.match(
263
- /^s3:\/\/(?<access_key_id>[^:]*):(?<secret_access_key>[^@]*)@(?<bucket_name>.*)$/
300
+ %r{^s3://(?<access_key_id>[^:]*):(?<secret_access_key>[^@]*)@(?<bucket_name>.*)$}
264
301
  )
265
302
 
266
303
  match_keys = %i[access_key_id secret_access_key bucket_name]
@@ -271,7 +308,7 @@ module Convox
271
308
  {
272
309
  access_key_id: matches[:access_key_id],
273
310
  secret_access_key: matches[:secret_access_key],
274
- name: matches[:bucket_name],
311
+ name: matches[:bucket_name]
275
312
  }
276
313
  end
277
314
  end
@@ -282,7 +319,7 @@ module Convox
282
319
  secret_access_key = config.fetch(:aws_secret_access_key)
283
320
 
284
321
  unless config.key? :s3_bucket_cors_policy
285
- logger.debug "No CORS policy provided in config: s3_bucket_cors_policy"
322
+ logger.debug 'No CORS policy provided in config: s3_bucket_cors_policy'
286
323
  return
287
324
  end
288
325
  cors_policy_string = config.fetch(:s3_bucket_cors_policy)
@@ -294,17 +331,17 @@ module Convox
294
331
  `AWS_ACCESS_KEY_ID=#{access_key_id} \
295
332
  AWS_SECRET_ACCESS_KEY=#{secret_access_key} \
296
333
  aws s3api get-bucket-cors --bucket #{bucket_name} 2>/dev/null`
297
- if $?.success? && existing_cors_policy_string.present?
334
+ if $CHILD_STATUS.success? && existing_cors_policy_string.present?
298
335
  # Sort all the nested arrays so that the equality operator works
299
336
  existing_cors_policy = JSON.parse(existing_cors_policy_string)
300
337
  cors_policy_json = JSON.parse(cors_policy_string)
301
338
  [existing_cors_policy, cors_policy_json].each do |policy_json|
302
- if policy_json.is_a?(Hash) && policy_json["CORSRules"]
303
- policy_json["CORSRules"].each do |rule|
304
- rule["AllowedHeaders"].sort! if rule["AllowedHeaders"]
305
- rule["AllowedMethods"].sort! if rule["AllowedMethods"]
306
- rule["AllowedOrigins"].sort! if rule["AllowedOrigins"]
307
- end
339
+ next unless policy_json.is_a?(Hash) && policy_json['CORSRules']
340
+
341
+ policy_json['CORSRules'].each do |rule|
342
+ rule['AllowedHeaders']&.sort!
343
+ rule['AllowedMethods']&.sort!
344
+ rule['AllowedOrigins']&.sort!
308
345
  end
309
346
  end
310
347
 
@@ -317,19 +354,20 @@ module Convox
317
354
  begin
318
355
  logger.info "Setting CORS policy for #{bucket_name}..."
319
356
 
320
- File.open("cors-policy.json", "w") { |f| f.puts cors_policy_string }
357
+ File.open('cors-policy.json', 'w') { |f| f.puts cors_policy_string }
321
358
 
322
359
  `AWS_ACCESS_KEY_ID=#{access_key_id} \
323
360
  AWS_SECRET_ACCESS_KEY=#{secret_access_key} \
324
361
  aws s3api put-bucket-cors \
325
362
  --bucket #{bucket_name} \
326
363
  --cors-configuration "file://cors-policy.json"`
327
- unless $?.success?
328
- raise "Something went wrong while setting the S3 bucket CORS policy!"
364
+ unless $CHILD_STATUS.success?
365
+ raise 'Something went wrong while setting the S3 bucket CORS policy!'
329
366
  end
367
+
330
368
  logger.info "=> Successfully set CORS policy for #{bucket_name}."
331
369
  ensure
332
- FileUtils.rm_f "cors-policy.json"
370
+ FileUtils.rm_f 'cors-policy.json'
333
371
  end
334
372
  end
335
373
 
@@ -338,38 +376,39 @@ module Convox
338
376
 
339
377
  registry_url = config.fetch(:docker_registry_url)
340
378
 
341
- logger.debug "Looking up existing Docker registries..."
379
+ logger.debug 'Looking up existing Docker registries...'
342
380
  registries_response = `convox api get /registries`
343
- unless $?.success?
344
- raise "Something went wrong while fetching the list of registries!"
381
+ unless $CHILD_STATUS.success?
382
+ raise 'Something went wrong while fetching the list of registries!'
345
383
  end
384
+
346
385
  registries = JSON.parse(registries_response)
347
386
 
348
- if registries.any? { |r| r["server"] == registry_url }
387
+ if registries.any? { |r| r['server'] == registry_url }
349
388
  logger.debug "=> Docker Registry already exists: #{registry_url}"
350
389
  return true
351
390
  end
352
391
 
353
392
  logger.info "Adding Docker Registry: #{registry_url}..."
354
- logger.info "=> Documentation: " \
355
- "https://docs.convox.com/deployment/private-registries"
393
+ logger.info '=> Documentation: ' \
394
+ 'https://docs.convox.com/deployment/private-registries'
356
395
 
357
396
  `convox registries add "#{registry_url}" \
358
397
  "#{config.fetch(:docker_registry_username)}" \
359
398
  "#{config.fetch(:docker_registry_password)}"`
360
- unless $?.success?
361
- raise "Something went wrong while adding the #{registry_url} registry!"
362
- end
399
+ return if $CHILD_STATUS.success?
400
+
401
+ raise "Something went wrong while adding the #{registry_url} registry!"
363
402
  end
364
403
 
365
404
  def default_service_domain_name
366
405
  require_config(%i[convox_app_name default_service])
367
406
 
368
407
  @default_service_domain_name ||= begin
369
- convox_domain = convox_rack_data["domain"]
370
- elb_name_and_region = convox_domain[/([^\.]*\.[^\.]*)\..*/, 1]
408
+ convox_domain = convox_rack_data['domain']
409
+ elb_name_and_region = convox_domain[/([^.]*\.[^.]*)\..*/, 1]
371
410
  unless elb_name_and_region.present?
372
- raise "Something went wrong while parsing the ELB name and region! " \
411
+ raise 'Something went wrong while parsing the ELB name and region! ' \
373
412
  "(#{elb_name_and_region})"
374
413
  end
375
414
  app = config.fetch(:convox_app_name)
@@ -383,7 +422,7 @@ module Convox
383
422
  def run_convox_command!(cmd, env = {})
384
423
  command = "convox #{cmd}"
385
424
  system env, command
386
- raise "Error running: #{command}" unless $?.success?
425
+ raise "Error running: #{command}" unless $CHILD_STATUS.success?
387
426
  end
388
427
 
389
428
  private
@@ -393,7 +432,7 @@ module Convox
393
432
 
394
433
  begin
395
434
  JSON.parse(File.read(AUTH_FILE))
396
- rescue
435
+ rescue StandardError
397
436
  {}
398
437
  end
399
438
  end
data/lib/convox.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "convox/client"
3
+ require 'convox/client'
@@ -1,48 +1,48 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "highline"
4
- require "fileutils"
5
- require "json"
6
- require "securerandom"
3
+ require 'highline'
4
+ require 'fileutils'
5
+ require 'json'
6
+ require 'securerandom'
7
7
 
8
8
  module ConvoxInstaller
9
9
  class Config
10
- CONFIG_FILE = File.expand_path("./.installer_config.json").freeze
10
+ CONFIG_FILE = File.expand_path('./.installer_config.json').freeze
11
11
 
12
12
  attr_accessor :logger, :config, :prompts, :highline
13
13
 
14
14
  DEFAULT_PROMPTS = [
15
15
  {
16
16
  key: :stack_name,
17
- title: "Convox Stack Name",
18
- prompt: "Please enter a name for your Convox installation",
19
- default: "convox",
17
+ title: 'Convox Stack Name',
18
+ prompt: 'Please enter a name for your Convox installation',
19
+ default: 'convox'
20
20
  },
21
21
  {
22
22
  key: :aws_region,
23
- title: "AWS Region",
24
- default: "us-east-1",
23
+ title: 'AWS Region',
24
+ default: 'us-east-1'
25
25
  },
26
26
  {
27
27
  key: :instance_type,
28
- title: "EC2 Instance Type",
29
- default: "t3.medium",
28
+ title: 'EC2 Instance Type',
29
+ default: 't3.medium'
30
30
  },
31
31
  {
32
- section: "Admin AWS Credentials",
32
+ section: 'Admin AWS Credentials'
33
33
  },
34
34
  {
35
35
  key: :aws_access_key_id,
36
- title: "AWS Access Key ID",
36
+ title: 'AWS Access Key ID'
37
37
  },
38
38
  {
39
39
  key: :aws_secret_access_key,
40
- title: "AWS Secret Access Key",
41
- },
40
+ title: 'AWS Secret Access Key'
41
+ }
42
42
  ].freeze
43
43
 
44
44
  def initialize(options = {})
45
- @logger = Logger.new(STDOUT)
45
+ @logger = Logger.new($stdout)
46
46
  logger.level = options[:log_level] || Logger::INFO
47
47
 
48
48
  self.prompts = options[:prompts] || DEFAULT_PROMPTS
@@ -74,13 +74,14 @@ module ConvoxInstaller
74
74
 
75
75
  @completed_prompt = true
76
76
 
77
- highline.say "Please double check all of these configuration details."
77
+ highline.say 'Please double check all of these configuration details.'
78
78
 
79
79
  agree = highline.agree(
80
- "Would you like to start the Convox installation?" \
80
+ 'Would you like to start the Convox installation?' \
81
81
  " (press 'n' to correct any settings)"
82
82
  )
83
83
  break if agree
84
+
84
85
  highline.say "\n"
85
86
  end
86
87
 
@@ -89,7 +90,7 @@ module ConvoxInstaller
89
90
 
90
91
  def show_config_summary
91
92
  highline.say "\n============================================"
92
- highline.say " SUMMARY"
93
+ highline.say ' SUMMARY'
93
94
  highline.say "============================================\n\n"
94
95
 
95
96
  config_titles = prompts.map do |prompt|
@@ -106,10 +107,18 @@ module ConvoxInstaller
106
107
  highline.say " #{padded_key} #{value}"
107
108
  end
108
109
  highline.say "\nWe've saved your configuration to: #{CONFIG_FILE}"
109
- highline.say "If anything goes wrong during the installation, " \
110
+ highline.say 'If anything goes wrong during the installation, ' \
110
111
  "you can restart the script to reload the config and continue.\n\n"
111
112
  end
112
113
 
114
+ def self.config_file_exists?
115
+ File.exist?(CONFIG_FILE)
116
+ end
117
+
118
+ def self.read_config_file
119
+ File.read(CONFIG_FILE)
120
+ end
121
+
113
122
  private
114
123
 
115
124
  def ask_prompt(prompt)
@@ -130,10 +139,10 @@ module ConvoxInstaller
130
139
 
131
140
  default = prompt[:value]
132
141
  config[key] = if default.is_a?(Proc)
133
- default.arity == 0 ? default.call : default.call(config)
134
- else
135
- default
136
- end
142
+ default.arity.zero? ? default.call : default.call(config)
143
+ else
144
+ default
145
+ end
137
146
  save_config_to_file
138
147
  return
139
148
  end
@@ -157,7 +166,7 @@ module ConvoxInstaller
157
166
 
158
167
  logger.debug "Loading saved config from #{CONFIG_FILE}..."
159
168
 
160
- loaded_config = JSON.parse(Config.read_config_file)["config"].symbolize_keys
169
+ loaded_config = JSON.parse(Config.read_config_file)['config'].symbolize_keys
161
170
  self.config = config.merge(loaded_config)
162
171
  end
163
172
 
@@ -178,13 +187,5 @@ module ConvoxInstaller
178
187
  f.puts(JSON.pretty_generate(config: config))
179
188
  end
180
189
  end
181
-
182
- def self.config_file_exists?
183
- File.exist?(CONFIG_FILE)
184
- end
185
-
186
- def self.read_config_file
187
- File.read(CONFIG_FILE)
188
- end
189
190
  end
190
191
  end