kafo 0.6.12 → 0.7.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.
@@ -3,14 +3,17 @@
3
3
  # note current configuration is written to kafo.yaml every time kafo is run
4
4
 
5
5
  ## Installer configuration
6
- # Your project name
7
- # :name: Kafo
6
+ # Human readable scenario name
7
+ # :name: default
8
+ # Description of the installer scenario and its purpose
9
+ # :description:
8
10
  # Path to answer file, if the file does not exist a $pwd/config/answers.yaml is used as a fallback
9
11
  # :answer_file: /etc/kafo/answers.yaml
10
12
  # Custom installer path
11
13
  # :installer_dir: /usr/share/kafo/
12
- # Uncomment if you want to load puppet modules from a specific path, $pwd/modules is used by default
13
- # :modules_dir: /usr/share/kafo/modules
14
+ # Uncomment if you want to load puppet modules from a specific path, $pwd/modules is used by default,
15
+ # multiple dirs are allowed
16
+ # :module_dirs: /usr/share/kafo/modules
14
17
  # Similar as modules_dir but for kafo internal modules, leave nil if you don't need to change it
15
18
  # :kafo_modules_dir:
16
19
  # Enable colors? If you don't touch this, we'll autodetect terminal capabilities
@@ -44,6 +47,11 @@
44
47
  # :hook_dirs:
45
48
  # - /opt/hooks
46
49
 
50
+ ## Checks - system checks in these extra directories will be loaded
51
+ # by default $installer_dir/checks is used
52
+ # :check_dirs:
53
+ # - /opt/checks
54
+
47
55
  # custom storage is handy if you use hooks and you must store some configuration
48
56
  # which should persist among installer runs. It can be also used for passing
49
57
  # value from one hook to another.
@@ -2,12 +2,18 @@ require 'highline/import'
2
2
 
3
3
  module Kafo
4
4
  class ColorScheme
5
- def initialize(config)
6
- @config = config
5
+
6
+ def self.colors_possible?
7
+ ::ENV['TERM'] && !`which tput 2> /dev/null`.empty? && `tput colors`.to_i > 0
8
+ end
9
+
10
+ def initialize(options={})
11
+ @background = options[:background].nil? ? :dark : options[:background]
12
+ @colors = options[:colors].nil? ? self.class.colors_possible? : options[:colors]
7
13
  end
8
14
 
9
15
  def setup
10
- if @config.app[:colors]
16
+ if @colors
11
17
  HighLine.color_scheme = build_color_scheme
12
18
  HighLine.use_color = true
13
19
  else
@@ -28,6 +34,7 @@ module Kafo
28
34
  def color_hash
29
35
  @color_hash ||= {
30
36
  :headline => build_color(:yellow),
37
+ :title => build_color(:yellow),
31
38
  :horizontal_line => build_color(:white),
32
39
  :important => build_color(:white),
33
40
  :question => build_color(:green),
@@ -41,7 +48,7 @@ module Kafo
41
48
  end
42
49
 
43
50
  def build_color(color)
44
- bright = @config.app[:color_of_background].to_s == 'bright'
51
+ bright = @background.to_s == 'bright'
45
52
  color = convert_bright_to_dark(color) if bright
46
53
 
47
54
  attributes = [ color ]
@@ -3,16 +3,15 @@ require 'yaml'
3
3
  require 'tmpdir'
4
4
  require 'kafo/puppet_module'
5
5
  require 'kafo/password_manager'
6
+ require 'kafo/color_scheme'
6
7
 
7
8
  module Kafo
8
9
  class Configuration
9
10
  attr_reader :config_file, :answer_file
10
11
 
11
- def self.colors_possible?
12
- !`which tput 2> /dev/null`.empty? && `tput colors`.to_i > 0
13
- end
14
-
15
12
  DEFAULT = {
13
+ :name => '',
14
+ :description => '',
16
15
  :log_dir => '/var/log/kafo',
17
16
  :log_name => 'configuration.log',
18
17
  :log_level => 'info',
@@ -20,13 +19,14 @@ module Kafo
20
19
  :mapping => {},
21
20
  :answer_file => './config/answers.yaml',
22
21
  :installer_dir => '.',
23
- :modules_dir => './modules',
22
+ :module_dirs => ['./modules'],
24
23
  :default_values_dir => '/tmp',
25
- :colors => Configuration.colors_possible?,
24
+ :colors => Kafo::ColorScheme.colors_possible?,
26
25
  :color_of_background => :dark,
27
26
  :hook_dirs => [],
28
27
  :custom => {},
29
28
  :low_priority_modules => [],
29
+ :verbose_log_level => 'info'
30
30
  }
31
31
 
32
32
  def initialize(file, persist = true)
@@ -37,7 +37,7 @@ module Kafo
37
37
 
38
38
  @answer_file = app[:answer_file]
39
39
  begin
40
- @data = YAML.load_file(@answer_file)
40
+ @data = load_yaml_file(@answer_file)
41
41
  rescue Errno::ENOENT => e
42
42
  puts "No answer file at #{@answer_file} found, can not continue"
43
43
  KafoConfigure.exit(:no_answer_file)
@@ -62,13 +62,15 @@ module Kafo
62
62
  def app
63
63
  @app ||= begin
64
64
  begin
65
- configuration = YAML.load_file(@config_file)
65
+ configuration = load_yaml_file(@config_file)
66
66
  rescue => e
67
67
  configuration = {}
68
68
  end
69
69
 
70
70
  result = DEFAULT.merge(configuration || {})
71
71
  result[:password] ||= PasswordManager.new.password
72
+ result[:module_dirs] = result[:modules_dir] || result[:module_dirs]
73
+ result.delete(:modules_dir)
72
74
  result
73
75
  end
74
76
  end
@@ -82,11 +84,31 @@ module Kafo
82
84
  end
83
85
 
84
86
  def modules
85
- @modules ||= @data.keys.map { |mod| PuppetModule.new(mod).parse }.sort
87
+ @modules ||= @data.keys.map { |mod| PuppetModule.new(mod, KafoParsers::PuppetModuleParser, self).parse }.sort
88
+ end
89
+
90
+ def root_dir
91
+ File.expand_path(app[:installer_dir])
92
+ end
93
+
94
+ def check_dirs
95
+ [app[:check_dirs] || File.join(root_dir, 'checks')].flatten
96
+ end
97
+
98
+ def module_dirs
99
+ [app[:module_dirs] || (app[:installer_dir] + '/modules')].flatten.map { |dir| File.expand_path(dir) }
100
+ end
101
+
102
+ def gem_root
103
+ File.join(File.dirname(__FILE__), '../../')
104
+ end
105
+
106
+ def kafo_modules_dir
107
+ app[:kafo_modules_dir] || (gem_root + '/modules')
86
108
  end
87
109
 
88
110
  def add_module(name)
89
- mod = PuppetModule.new(name).parse
111
+ mod = PuppetModule.new(name, KafoParsers::PuppetModuleParser, self).parse
90
112
  unless modules.map(&:name).include?(mod.name)
91
113
  mod.enable
92
114
  @modules << mod
@@ -98,13 +120,25 @@ module Kafo
98
120
  save_configuration(app)
99
121
  end
100
122
 
123
+ def migrate_configuration(from_config, options={})
124
+ keys_to_skip = options.fetch(:skip, [])
125
+ keys = [:log_dir, :log_name, :log_level, :no_prefix, :default_values_dir,
126
+ :colors, :color_of_background, :custom, :password, :verbose_log_level]
127
+ keys += options.fetch(:with, [])
128
+ keys.each do |key|
129
+ next if keys_to_skip.include?(key)
130
+ app[key] = from_config.app[key]
131
+ end
132
+ save_configuration(app)
133
+ end
134
+
101
135
  def params_default_values
102
136
  @params_default_values ||= begin
103
137
  @logger.debug "Creating tmp dir within #{app[:default_values_dir]}..."
104
138
  temp_dir = Dir.mktmpdir(nil, app[:default_values_dir])
105
139
  KafoConfigure.exit_handler.register_cleanup_path temp_dir
106
140
  @logger.info 'Loading default values from puppet modules...'
107
- command = PuppetCommand.new("$temp_dir=\"#{temp_dir}\" #{includes} dump_values(#{params})").append('2>&1').command
141
+ command = PuppetCommand.new("$temp_dir=\"#{temp_dir}\" #{includes} dump_values(#{params_to_dump})", ['--noop'], self).append('2>&1').command
108
142
  result = `#{command}`
109
143
  @logger.debug result
110
144
  unless $?.exitstatus == 0
@@ -116,7 +150,7 @@ module Kafo
116
150
  KafoConfigure.exit(:defaults_error)
117
151
  end
118
152
  @logger.info "... finished"
119
- YAML.load_file(File.join(temp_dir, 'default_values.yaml'))
153
+ load_yaml_file(File.join(temp_dir, 'default_values.yaml'))
120
154
  end
121
155
  end
122
156
 
@@ -133,7 +167,7 @@ module Kafo
133
167
  end
134
168
 
135
169
  def config_header
136
- files = [app[:config_header_file], File.join(KafoConfigure.gem_root, '/config/config_header.txt')].compact
170
+ files = [app[:config_header_file], File.join(gem_root, '/config/config_header.txt')].compact
137
171
  file = files.select { |f| File.exists?(f) }.first
138
172
  @config_header ||= file.nil? ? '' : File.read(file)
139
173
  end
@@ -145,6 +179,83 @@ module Kafo
145
179
  File.open(filename, 'w') { |file| file.write(config_header + format(YAML.dump(data))) }
146
180
  end
147
181
 
182
+ def params
183
+ @params ||= modules.map(&:params).flatten
184
+ end
185
+
186
+ def param(mod, name)
187
+ params.detect { |p| p.name == name && p.module.name == mod }
188
+ end
189
+
190
+ def preset_defaults_from_puppet
191
+ # set values based on default_values
192
+ params.each do |param|
193
+ param.set_default(params_default_values)
194
+ end
195
+ end
196
+
197
+ def preset_defaults_from_yaml
198
+ # set values based on YAML
199
+ params.each do |param|
200
+ param.set_value_by_config(self)
201
+ end
202
+ end
203
+
204
+ def preset_defaults_from_other_config(other_config)
205
+ params_changed(other_config).each do |par|
206
+ param(par.module.class_name, par.name).value = other_config.param(par.module.class_name, par.name).value
207
+ end
208
+ end
209
+
210
+ def params_changed(old_config)
211
+ # finds params that had different value in the old config
212
+ params.select do |par|
213
+ next unless par.module.enabled?
214
+ old_param = old_config.param(par.module.class_name, par.name)
215
+ old_param && old_param.value != par.value
216
+ end
217
+ end
218
+
219
+ def params_missing(old_config)
220
+ # finds params that are present but will be missing in the new config
221
+ old_config.params.select do |par|
222
+ next if !par.module.enabled? || !module_enabled?(par.module.name)
223
+ param(par.module.class_name, par.name).nil?
224
+ end
225
+ end
226
+
227
+ def temp_config_file
228
+ @temp_config_file ||= "/tmp/kafo_answers_#{rand(1_000_000)}.yaml"
229
+ end
230
+
231
+ def log_file
232
+ File.join(app[:log_dir], app[:log_name])
233
+ end
234
+
235
+ def log_exists?
236
+ File.exists?(log_file) && File.size(log_file) > 0
237
+ end
238
+
239
+ def answers
240
+ @data
241
+ end
242
+
243
+ def run_migrations
244
+ migrations = Kafo::Migrations.new(migrations_dir)
245
+ @app, @data = migrations.run(app, answers)
246
+ if migrations.migrations.count > 0
247
+ @modules = nil # force the lazy loaded modules to reload next time they are used
248
+ save_configuration(app)
249
+ store(answers)
250
+ migrations.store_applied
251
+ @logger.info("#{migrations.migrations.count} migration/s were applied. Updated configuration was saved.")
252
+ end
253
+ end
254
+
255
+ def migrations_dir
256
+ @config_file.gsub(/\.yaml$/, '.migrations')
257
+ end
258
+
148
259
  private
149
260
 
150
261
  def custom_storage
@@ -153,20 +264,26 @@ module Kafo
153
264
 
154
265
  def includes
155
266
  modules.map do |mod|
156
- params_file = File.join(KafoConfigure.modules_dir, mod.params_path)
157
- @logger.debug "checking presence of #{params_file}"
158
- File.exist?(params_file) ? "include #{mod.dir_name}::#{mod.params_class_name}" : nil
267
+ module_dir = module_dirs.find do |dir|
268
+ params_file = File.join(dir, mod.params_path)
269
+ @logger.debug "checking presence of #{params_file}"
270
+ File.exist?(params_file)
271
+ end
272
+ module_dir ? "include #{mod.dir_name}::#{mod.params_class_name}" : nil
159
273
  end.uniq.compact.join(' ')
160
274
  end
161
275
 
162
- def params
163
- params = modules.map(&:params).flatten
164
- params = params.select { |p| p.default != 'UNSET' }
165
- params.map { |param| "#{param.dump_default}" }.join(',')
276
+ def params_to_dump
277
+ parameters = params.select { |p| p.default != 'UNSET' }
278
+ parameters.map { |param| "#{param.dump_default}" }.join(',')
166
279
  end
167
280
 
168
281
  def format(data)
169
282
  data.gsub('!ruby/sym ', ':')
170
283
  end
284
+
285
+ def load_yaml_file(filename)
286
+ YAML.load_file(filename)
287
+ end
171
288
  end
172
289
  end
@@ -15,7 +15,9 @@ module Kafo
15
15
  :manifest_error => 22,
16
16
  :no_answer_file => 23,
17
17
  :unknown_module => 24,
18
- :defaults_error => 25
18
+ :defaults_error => 25,
19
+ :unknown_scenario => 26,
20
+ :scenario_error => 27
19
21
  }
20
22
  end
21
23
 
@@ -23,7 +25,7 @@ module Kafo
23
25
  @exit_code = translate_exit_code(code)
24
26
  block.call if block
25
27
  KafoConfigure.logger.debug "Exit with status code: #{@exit_code} (signal was #{code})"
26
- KafoConfigure.logger.dump_errors
28
+ KafoConfigure.logger.dump_errors unless KafoConfigure.verbose
27
29
  cleanup
28
30
  Kernel.exit(@exit_code)
29
31
  end
@@ -2,6 +2,7 @@ require 'kafo/hook_context'
2
2
 
3
3
  module Kafo
4
4
  class Hooking
5
+ # pre_migrations - just after kafo reads its configuration - useful for config file updates. Only in this stage it is posible to request config reload (`Kafo.request_config_reload`) to get in our changes
5
6
  # boot - before kafo is ready to work, useful for adding new app arguments, logger won't work yet
6
7
  # init - just after hooking is initialized and kafo is configured, parameters have no values yet
7
8
  # pre_values - just before value from CLI is set to parameters (they already have default values)
@@ -9,7 +10,7 @@ module Kafo
9
10
  # pre_commit - after validations or interactive wizard have completed, all parameter values are set but not yet stored in the answer file
10
11
  # pre - just before puppet is executed to converge system
11
12
  # post - just after puppet is executed to converge system
12
- TYPES = [:boot, :init, :pre, :post, :pre_values, :pre_validations, :pre_commit]
13
+ TYPES = [:pre_migrations, :boot, :init, :pre, :post, :pre_values, :pre_validations, :pre_commit]
13
14
 
14
15
  attr_accessor :hooks, :kafo
15
16
 
@@ -53,6 +54,10 @@ module Kafo
53
54
  logger.info "All hooks in group #{group} finished"
54
55
  end
55
56
 
57
+ def register_pre_migrations(name, &block)
58
+ register(:pre_migrations, name, &block)
59
+ end
60
+
56
61
  def register_boot(name, &block)
57
62
  register(:boot, name, &block)
58
63
  end
@@ -9,8 +9,10 @@ end
9
9
 
10
10
  require 'pty'
11
11
  require 'clamp'
12
+ require 'kafo/color_scheme'
12
13
  require 'kafo_parsers/exceptions'
13
14
  require 'kafo/exceptions'
15
+ require 'kafo/migrations'
14
16
  require 'kafo/configuration'
15
17
  require 'kafo/logger'
16
18
  require 'kafo/string_helper'
@@ -21,6 +23,7 @@ require 'kafo/puppet_command'
21
23
  require 'kafo/progress_bar'
22
24
  require 'kafo/hooking'
23
25
  require 'kafo/exit_handler'
26
+ require 'kafo/scenario_manager'
24
27
 
25
28
  module Kafo
26
29
  class KafoConfigure < Clamp::Command
@@ -28,8 +31,8 @@ module Kafo
28
31
 
29
32
  class << self
30
33
  attr_accessor :config, :root_dir, :config_file, :gem_root, :temp_config_file,
31
- :modules_dir, :kafo_modules_dir, :verbose, :app_options, :logger,
32
- :exit_handler
34
+ :module_dirs, :kafo_modules_dir, :verbose, :app_options, :logger,
35
+ :check_dirs, :exit_handler, :scenario_manager
33
36
  attr_writer :hooking
34
37
 
35
38
  def hooking
@@ -38,29 +41,53 @@ module Kafo
38
41
  end
39
42
 
40
43
  def initialize(*args)
44
+ self.class.preset_color_scheme
41
45
  self.class.logger = Logger.new
42
46
  self.class.exit_handler = ExitHandler.new
43
- self.class.config_file = config_file
44
- self.class.config = Configuration.new(self.class.config_file)
45
- self.class.root_dir = File.expand_path(self.class.config.app[:installer_dir])
46
- modules_dir = self.class.config.app[:modules_dir] || (self.class.config.app[:installer_dir] + '/modules')
47
- self.class.modules_dir = File.expand_path(modules_dir)
48
- self.class.gem_root = File.join(File.dirname(__FILE__), '../../')
49
- self.class.kafo_modules_dir = self.class.config.app[:kafo_modules_dir] || (self.class.gem_root + '/modules')
50
47
  @progress_bar = nil
51
- self.class.hooking.load
52
- self.class.hooking.kafo = self
48
+ @config_reload_requested = false
49
+
50
+ scenario_manager = setup_scenario_manager
51
+ self.class.scenario_manager = scenario_manager
52
+
53
+ # Handle --list-scenarios before we need them
54
+ scenario_manager.list_available_scenarios if ARGV.include?('--list-scenarios')
55
+ setup_config(config_file)
56
+
57
+ self.class.hooking.execute(:pre_migrations)
58
+
59
+ # run migrations
60
+ self.class.config.run_migrations
61
+
62
+ # reload config
63
+ if @config_reload_requested
64
+ scenario_manager = setup_scenario_manager
65
+ self.class.scenario_manager = scenario_manager
66
+ setup_config(self.class.config_file)
67
+ self.class.logger.info('Installer configuration was reloaded')
68
+ end
69
+
70
+ if scenario_manager.configured?
71
+ scenario_manager.check_scenario_change(self.class.config_file)
72
+ if scenario_manager.scenario_changed?(self.class.config_file)
73
+ prev_config = scenario_manager.load_configuration(scenario_manager.previous_scenario)
74
+ prev_config.run_migrations
75
+ self.class.config.migrate_configuration(prev_config, :skip => [:log_name])
76
+ setup_config(self.class.config_file)
77
+ self.class.logger.info("Due to scenario change the configuration (#{self.class.config_file}) was updated with #{scenario_manager.previous_scenario} and reloaded.")
78
+ end
79
+ end
53
80
 
54
81
  super
55
82
 
56
83
  self.class.hooking.execute(:boot)
57
- set_app_options
84
+ set_app_options # define args for installer
58
85
  # we need to parse app config params using clamp even before run method does it
59
86
  # so we limit parsing only to app config options (because of --help and later defined params)
60
87
  parse clamp_app_arguments
61
- parse_app_arguments
88
+ parse_app_arguments # set values from ARGS to config.app
62
89
  Logger.setup
63
- ColorScheme.new(config).setup
90
+ self.class.set_color_scheme
64
91
 
65
92
  self.class.hooking.execute(:init)
66
93
  set_parameters # here the params gets parsed and we need app config populated
@@ -104,10 +131,11 @@ module Kafo
104
131
 
105
132
  self.class.hooking.execute(:pre_commit)
106
133
  if dont_save_answers? || noop?
107
- self.class.temp_config_file = temp_config_file
108
- store_params(temp_config_file)
134
+ self.class.temp_config_file = self.class.config.temp_config_file
135
+ store_params(self.class.config.temp_config_file)
109
136
  else
110
137
  store_params
138
+ self.class.scenario_manager.link_last_scenario(self.class.config_file) if self.class.scenario_manager.configured?
111
139
  end
112
140
  run_installation
113
141
  return self
@@ -178,21 +206,39 @@ module Kafo
178
206
  end
179
207
 
180
208
  def param(mod, name)
181
- params.detect { |p| p.name == name && p.module.name == mod }
209
+ config.param(mod, name)
182
210
  end
183
211
 
212
+ def request_config_reload
213
+ @config_reload_requested = true
214
+ end
215
+
216
+
184
217
  private
185
218
 
186
- def set_parameters
187
- # set values based on default_values
188
- params.each do |param|
189
- param.set_default(config.params_default_values)
190
- end
219
+ def setup_config(conf_file)
220
+ self.class.config_file = conf_file
221
+ self.class.config = Configuration.new(self.class.config_file)
222
+ self.class.root_dir = self.class.config.root_dir
223
+ self.class.check_dirs = self.class.config.check_dirs
224
+ self.class.module_dirs = self.class.config.module_dirs
225
+ self.class.gem_root = self.class.config.gem_root
226
+ self.class.kafo_modules_dir = self.class.config.kafo_modules_dir
227
+ self.class.hooking.load
228
+ self.class.hooking.kafo = self
229
+ end
230
+
231
+ def setup_scenario_manager
232
+ ScenarioManager.new((defined?(CONFIG_DIR) && CONFIG_DIR) || (defined?(CONFIG_FILE) && CONFIG_FILE))
233
+ end
191
234
 
235
+ def set_parameters
236
+ config.preset_defaults_from_puppet
192
237
  self.class.hooking.execute(:pre_values)
193
- # set values based on YAML
194
- params.each do |param|
195
- param.set_value_by_config(config)
238
+ config.preset_defaults_from_yaml
239
+ if self.class.scenario_manager.scenario_changed?(config.config_file)
240
+ prev_scenario = self.class.scenario_manager.load_and_setup_configuration(self.class.scenario_manager.previous_scenario)
241
+ config.preset_defaults_from_other_config(prev_scenario)
196
242
  end
197
243
  end
198
244
 
@@ -216,6 +262,10 @@ module Kafo
216
262
  self.class.app_option ['-v', '--verbose'], :flag, 'Display log on STDOUT instead of progressbar'
217
263
  self.class.app_option ['-l', '--verbose-log-level'], 'LEVEL', 'Log level for verbose mode output',
218
264
  :default => 'info'
265
+ self.class.app_option ['-S', '--scenario'], 'SCENARIO', 'Use installation scenario'
266
+ self.class.app_option ['--list-scenarios'], :flag, 'List available installation scenaraios'
267
+ self.class.app_option ['--force'], :flag, 'Force change of installation scenaraio'
268
+ self.class.app_option ['--compare-scenarios'], :flag, 'Show changes between last used scenario and the scenario specified with -S or --scenario argument'
219
269
  end
220
270
 
221
271
  def set_options
@@ -341,7 +391,7 @@ module Kafo
341
391
  end
342
392
  @progress_bar.close if @progress_bar
343
393
  logger.info "Puppet has finished, bye!"
344
- FileUtils.rm(temp_config_file, :force => true)
394
+ FileUtils.rm(self.class.config.temp_config_file, :force => true)
345
395
  self.class.exit(exit_code) do
346
396
  self.class.hooking.execute(:post)
347
397
  end
@@ -375,13 +425,32 @@ module Kafo
375
425
 
376
426
  def config_file
377
427
  return CONFIG_FILE if defined?(CONFIG_FILE) && File.exists?(CONFIG_FILE)
428
+ return self.class.scenario_manager.select_scenario if self.class.scenario_manager.configured?
378
429
  return '/etc/kafo/kafo.yaml' if File.exists?('/etc/kafo/kafo.yaml')
379
430
  return "#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml" if File.exists?("#{::RbConfig::CONFIG['sysconfdir']}/kafo/kafo.yaml")
380
431
  File.join(Dir.pwd, 'config', 'kafo.yaml')
381
432
  end
382
433
 
383
- def temp_config_file
384
- @temp_config_file ||= "/tmp/kafo_answers_#{rand(1_000_000)}.yaml"
434
+ def self.use_colors?
435
+ if config
436
+ colors = config.app[:colors]
437
+ else
438
+ colors = ARGV.include?('--no-colors') ? false : nil
439
+ colors = ARGV.include?('--colors') ? true : nil if colors.nil?
440
+ end
441
+ colors
442
+ end
443
+
444
+ def self.preset_color_scheme
445
+ match = ARGV.join(' ').match /--color-of-background[ =](\w+)/
446
+ background = match && match[1]
447
+ ColorScheme.new(:background => background, :colors => use_colors?).setup
448
+ end
449
+
450
+ def self.set_color_scheme
451
+ ColorScheme.new(
452
+ :background => config.app[:color_of_background],
453
+ :colors => use_colors?).setup
385
454
  end
386
455
  end
387
456
  end