climatic 0.2.26

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/CODE_OF_CONDUCT.md +74 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +52 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/climatic.gemspec +28 -0
  13. data/example/simple_app/.gitignore +12 -0
  14. data/example/simple_app/.rspec +2 -0
  15. data/example/simple_app/.ruby-version +1 -0
  16. data/example/simple_app/.travis.yml +5 -0
  17. data/example/simple_app/CODE_OF_CONDUCT.md +74 -0
  18. data/example/simple_app/Gemfile +6 -0
  19. data/example/simple_app/LICENSE.txt +21 -0
  20. data/example/simple_app/README.md +43 -0
  21. data/example/simple_app/Rakefile +6 -0
  22. data/example/simple_app/bin/console +14 -0
  23. data/example/simple_app/bin/setup +8 -0
  24. data/example/simple_app/etc/command_line.yml +52 -0
  25. data/example/simple_app/exe/user +57 -0
  26. data/example/simple_app/lib/tst_climatic/version.rb +3 -0
  27. data/example/simple_app/lib/tst_climatic.rb +5 -0
  28. data/example/simple_app/spec/spec_helper.rb +14 -0
  29. data/example/simple_app/spec/tst_climatic_spec.rb +11 -0
  30. data/example/simple_app/tst_climatic.gemspec +39 -0
  31. data/lib/climatic/config_layers/command_line_layer.rb +46 -0
  32. data/lib/climatic/config_layers/command_line_manager_binder.rb +84 -0
  33. data/lib/climatic/config_layers/env_layer.rb +41 -0
  34. data/lib/climatic/config_layers/executable_gem_layer.rb +45 -0
  35. data/lib/climatic/config_layers/gem_layer.rb +50 -0
  36. data/lib/climatic/config_layers/generic_layer.rb +62 -0
  37. data/lib/climatic/config_layers/global_layer.rb +28 -0
  38. data/lib/climatic/config_layers/program_description_helper.rb +94 -0
  39. data/lib/climatic/config_layers/project_layer.rb +61 -0
  40. data/lib/climatic/config_layers/provided_config_file_layer.rb +26 -0
  41. data/lib/climatic/config_layers/source_helper.rb +48 -0
  42. data/lib/climatic/config_layers/system_layer.rb +37 -0
  43. data/lib/climatic/config_layers/user_layer.rb +40 -0
  44. data/lib/climatic/initializer.rb +87 -0
  45. data/lib/climatic/layers_manager.rb +81 -0
  46. data/lib/climatic/logger/accumulator.rb +49 -0
  47. data/lib/climatic/logger/manager.rb +50 -0
  48. data/lib/climatic/logger/wrapper.rb +12 -0
  49. data/lib/climatic/processes/base.rb +51 -0
  50. data/lib/climatic/processes/command.rb +15 -0
  51. data/lib/climatic/processes/synchronous.rb +51 -0
  52. data/lib/climatic/processes/time_management.rb +21 -0
  53. data/lib/climatic/proxy.rb +27 -0
  54. data/lib/climatic/script/base.rb +65 -0
  55. data/lib/climatic/script/simple.rb +31 -0
  56. data/lib/climatic/script/unimplemented_processor.rb +19 -0
  57. data/lib/climatic/script.rb +4 -0
  58. data/lib/climatic/utils/error.rb +5 -0
  59. data/lib/climatic/utils/input.rb +65 -0
  60. data/lib/climatic/utils/safe_exec.rb +28 -0
  61. data/lib/climatic/utils/script_helper.rb +18 -0
  62. data/lib/climatic/version.rb +3 -0
  63. data/lib/climatic.rb +45 -0
  64. metadata +162 -0
@@ -0,0 +1,46 @@
1
+ require 'climatic/config_layers/command_line_manager_binder'
2
+
3
+ module Climatic
4
+ module ConfigLayers
5
+
6
+ class CommandLineLayer < SuperStack::Layer
7
+
8
+ include Climatic::ConfigLayers::CommandLineManagerBinder
9
+
10
+ CONFIG_ROOT_DIR = %w(etc config).freeze
11
+ DEFAULT_COMMAND_LINE_DEFINITION_FILE = 'command_line.yml'.freeze
12
+ COMMAND_LINE_MANAGER_CLASS = UltraCommandLine::Manager::Base
13
+
14
+ def initialize(command_line_manager = self.class.default_command_line_manager)
15
+ # raise UltraCommandLine::Error, 'Invalid command line manager !' unless command_line_manager.is_a? MANAGER_CLASS
16
+ @command_line_manager = command_line_manager
17
+ end
18
+
19
+ private
20
+
21
+ def self.default_command_line_manager
22
+ begin
23
+ CONFIG_ROOT_DIR.each do |sub_dir|
24
+ default_definition_file = File.join Climatic::ConfigLayers::ExecutableGemLayer.executable_gem_config_root, sub_dir, DEFAULT_COMMAND_LINE_DEFINITION_FILE
25
+ if File.readable? default_definition_file
26
+ return build_command_line_manager default_definition_file
27
+ end
28
+ end
29
+ rescue => e
30
+ Climatic.logger.debug "#{e.message}\nBacktrace:\n#{e.backtrace.join("\n\t")}"
31
+ end
32
+ UltraCommandLine::Manager::Base.new
33
+ end
34
+
35
+
36
+ def self.build_command_line_manager(definition_file)
37
+ mngr = COMMAND_LINE_MANAGER_CLASS.from_yaml_file definition_file
38
+ mngr.definition_hash_to_commands
39
+ mngr
40
+ end
41
+
42
+
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,84 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ module CommandLineManagerBinder
5
+
6
+ SUB_COMMANDS_HELP_HEADER = [
7
+ '',
8
+ '-' * 80,
9
+ ' Following subcommands exist too:',
10
+ ' For more information you can always issue sub_command_name --help...',
11
+ '-' * 80
12
+ ]
13
+
14
+ attr_accessor :command_line_manager
15
+
16
+ def cmd_line_args
17
+ command_line_manager.cmd_line_args
18
+ end
19
+
20
+ def cmd_line_args=(args)
21
+ command_line_manager.cmd_line_args = args
22
+ reload
23
+ end
24
+
25
+ def extra_parameters
26
+ with_selected_command {|c| c.extra_arguments }
27
+ end
28
+
29
+ def load
30
+ with_selected_command do |c|
31
+ replace c.params_hash
32
+ @file_name = :none
33
+ end
34
+ self
35
+ end
36
+ alias reload load
37
+
38
+ def help
39
+ with_selected_command do |c|
40
+ if c.root_command?
41
+ res = c.help
42
+ sub_commands = command_line_manager.commands.select {|command| not command.root_command?}
43
+ unless sub_commands.empty?
44
+ res.concat SUB_COMMANDS_HELP_HEADER
45
+ sub_commands.each do |command|
46
+ # command_summary = "#{command.help[0][0,60].tr("\n", ' ')}..."
47
+ res << " * #{command.name}: #{command_summary command}"
48
+ end
49
+
50
+ end
51
+ res
52
+ else
53
+ c.help
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+
60
+ def command_summary(command)
61
+ text = command.help[0][0,60].tr("\n", ' ')
62
+ text.match(/^\s*(?<sentence>[^\s][^\.]+)\./) do |md|
63
+ return "#{md['sentence']} ..."
64
+ end
65
+ text
66
+ end
67
+
68
+ def with_selected_command(&block)
69
+ selected_command = nil
70
+ begin
71
+ selected_command = command_line_manager.command
72
+ rescue UltraCommandLine::Error => e
73
+ UltraCommandLine.logger.debug 'No valid command found !'
74
+ end
75
+ unless selected_command.nil?
76
+ block.call selected_command
77
+ end
78
+ end
79
+
80
+
81
+ end
82
+
83
+ end
84
+ end
@@ -0,0 +1,41 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class EnvLayer < SuperStack::Layer
5
+
6
+ attr_reader :filter
7
+
8
+ def initialize(filter=nil)
9
+ self.filter = filter
10
+ end
11
+
12
+ def filter=(filter)
13
+ raise 'Invalid filter' unless [NilClass, String, Array, Regexp].include? filter.class
14
+ @filter = filter
15
+ load
16
+ end
17
+
18
+ def load(*args)
19
+ self.replace read_filtered_environment
20
+ @file_name = :none
21
+ self
22
+ end
23
+
24
+ private
25
+
26
+ def read_filtered_environment
27
+ return ENV.to_hash if filter.nil?
28
+
29
+ if filter.is_a? Array
30
+ ENV.to_hash.select {|k, v| filter.include?(k) }
31
+ elsif filter.is_a? Regexp
32
+ ENV.to_hash.select {|k, v| k =~ filter }
33
+ elsif filter.is_a? String
34
+ ENV.to_hash.select {|k, v| k == filter }
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,45 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class ExecutableGemLayer < Climatic::ConfigLayers::GenericLayer
5
+
6
+
7
+ def self.executable_gem_config_root
8
+ return nil unless $PROGRAM_NAME
9
+
10
+ Gem.loaded_specs.each_pair do |name, spec|
11
+ executable_basename = File.basename($PROGRAM_NAME)
12
+ return spec.full_gem_path if spec.executables.include? executable_basename
13
+ end
14
+ nil
15
+ end
16
+
17
+ def executable_gem_config_root
18
+ self.class.executable_gem_config_root
19
+ end
20
+
21
+ def possible_sources
22
+ [
23
+ %w(##EXECUTABLE_GEM_CONFIG_ROOT## etc ##PROGRAM_NAME##.##EXTENSION##),
24
+ %w(##EXECUTABLE_GEM_CONFIG_ROOT## etc ##PROGRAM_NAME## config.##EXTENSION##),
25
+ %w(##EXECUTABLE_GEM_CONFIG_ROOT## etc ##PROGRAM_NAME## ##PROGRAM_NAME##.##EXTENSION##),
26
+ %w(##EXECUTABLE_GEM_CONFIG_ROOT## config ##PROGRAM_NAME##.##EXTENSION##),
27
+ %w(##EXECUTABLE_GEM_CONFIG_ROOT## config ##PROGRAM_NAME## config.##EXTENSION##),
28
+ %w(##EXECUTABLE_GEM_CONFIG_ROOT## config ##PROGRAM_NAME## ##PROGRAM_NAME##.##EXTENSION##)
29
+ ]
30
+ end
31
+
32
+ def perform_substitutions path_part
33
+ return nil unless executable_gem_config_root
34
+ res = path_part.dup
35
+ res.gsub! '##EXECUTABLE_GEM_CONFIG_ROOT##', executable_gem_config_root
36
+ exec_name = manager.nil? ? Climatic::LayersManager.default_config_file_base_name : manager.config_file_base_name
37
+ res.gsub! '##PROGRAM_NAME##', exec_name
38
+ res
39
+ end
40
+
41
+
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,50 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class GemLayer < Climatic::ConfigLayers::GenericLayer
5
+
6
+ attr_reader :gem_name
7
+
8
+ def self.gem_config_root(gem_name)
9
+ return nil unless gem_name
10
+ Gem.loaded_specs.each_pair do |name, spec|
11
+ return spec.full_gem_path if name == gem_name
12
+ end
13
+ nil
14
+ end
15
+
16
+ def gem_config_root
17
+ self.class.gem_config_root gem_name
18
+ end
19
+
20
+
21
+ def gem_name=(gem_name)
22
+ @gem_name = gem_name.to_s
23
+ rescan
24
+ reload
25
+ end
26
+
27
+ def possible_sources
28
+ [
29
+ %w(##GEM_CONFIG_ROOT## etc ##GEM_NAME##.##EXTENSION##),
30
+ %w(##GEM_CONFIG_ROOT## etc ##GEM_NAME## config.##EXTENSION##),
31
+ %w(##GEM_CONFIG_ROOT## etc ##GEM_NAME## ##GEM_NAME##.##EXTENSION##),
32
+ %w(##GEM_CONFIG_ROOT## config ##GEM_NAME##.##EXTENSION##),
33
+ %w(##GEM_CONFIG_ROOT## config ##GEM_NAME## config.##EXTENSION##),
34
+ %w(##GEM_CONFIG_ROOT## config ##GEM_NAME## ##GEM_NAME##.##EXTENSION##)
35
+ ]
36
+ end
37
+
38
+ def perform_substitutions path_part
39
+ return nil unless gem_config_root
40
+ res = path_part.dup
41
+ res.gsub! '##GEM_CONFIG_ROOT##', gem_config_root
42
+ res.gsub! '##GEM_NAME##', gem_name if self.respond_to? :gem_name
43
+ res
44
+ end
45
+
46
+
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,62 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class GenericLayer < SuperStack::Layer
5
+
6
+ include Climatic::ConfigLayers::SourceHelper
7
+
8
+ def rescan
9
+ set_config_file possible_sources
10
+ end
11
+
12
+ def initialize
13
+ rescan
14
+ end
15
+
16
+ def possible_config_files(places=possible_sources)
17
+ result = {}
18
+ already_found = false
19
+ browse_files(places) do |file|
20
+ exists = File.readable?(file)
21
+ used = false
22
+ already_found = used = true if exists and not already_found
23
+ result[file] = {
24
+ exists: exists,
25
+ used: used,
26
+ layer: [name]
27
+ }
28
+ end
29
+ result
30
+ end
31
+
32
+ private
33
+
34
+ def set_config_file(places)
35
+ @file_name = nil
36
+ browse_files(places) do |file|
37
+ if File.readable? file
38
+ @file_name = file
39
+ return @file_name
40
+ end
41
+ end
42
+ end
43
+
44
+ def browse_files(places, &block)
45
+ places.each do |path_array|
46
+ begin
47
+ potential_config_file = File.join(path_array.map { |path_part| perform_substitutions path_part })
48
+ rescue
49
+ # do nothing
50
+ end
51
+ return unless potential_config_file
52
+ EXTENSIONS.each do |extension|
53
+ file = potential_config_file.gsub '##EXTENSION##', extension
54
+ yield file
55
+ end
56
+ end
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+ end
@@ -0,0 +1,28 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class GlobalLayer < Climatic::ConfigLayers::SystemLayer
5
+ def possible_sources
6
+ [
7
+ ['##SYSTEM_CONFIG_ROOT##', '##PROGRAM_NAME##.##EXTENSION##' ],
8
+ ['##SYSTEM_CONFIG_ROOT##', '##PROGRAM_NAME##', 'config.##EXTENSION##' ],
9
+ ['##SYSTEM_CONFIG_ROOT##', '##PROGRAM_NAME##', '##PROGRAM_NAME##.##EXTENSION##' ]
10
+ ]
11
+ end
12
+
13
+ def perform_substitutions(path_part)
14
+ res = path_part.dup
15
+ res.gsub! '##SYSTEM_CONFIG_ROOT##', system_config_root
16
+
17
+ exec_name = manager.nil? ? Climatic::LayersManager.default_config_file_base_name : manager.config_file_base_name
18
+ res.gsub! '##PROGRAM_NAME##', exec_name
19
+
20
+ res
21
+ end
22
+
23
+ end
24
+
25
+
26
+
27
+ end
28
+ end
@@ -0,0 +1,94 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ module ProgramDescriptionHelper
5
+
6
+ attr_reader :config_file_base_name, :app_name, :app_version, :app_description
7
+
8
+ def add_command_line_section(title='Script specific', &block)
9
+ command_line_layer.add_command_line_section title, &block
10
+ end
11
+
12
+ def config_file_base_name=(config_file_base_name)
13
+ return if config_file_base_name.nil?
14
+ @config_file_base_name = config_file_base_name
15
+ rescan_layers
16
+ reload_layers
17
+ end
18
+
19
+ def app_name=(app_name)
20
+ return if app_name.nil?
21
+ @app_name = app_name
22
+ command_line_layer.reload
23
+ end
24
+
25
+ def app_version=(app_version)
26
+ return if app_version.nil?
27
+ @app_version = app_version
28
+ command_line_layer.reload
29
+ end
30
+
31
+ def app_description=(app_description)
32
+ return if app_description.nil?
33
+ @app_description = app_description
34
+ command_line_layer.reload
35
+ end
36
+
37
+ def rescan_layers
38
+ layers.values.each do |layer|
39
+ if layer.respond_to? :rescan
40
+ layer.clear
41
+ layer.rescan
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+
48
+ def detailed_layers_info
49
+ info, sep = [], '-' * 80
50
+ info << sep
51
+ layers.values.sort {|a, b| a.priority <=> b.priority}.each do |layer|
52
+ info << layer.name
53
+ if layer.file_name.nil?
54
+ info << 'There is no file attached to this level.'
55
+ else
56
+ info << "Using '#{layer.file_name}' as config file for this layer."
57
+ end
58
+ if layer.empty?
59
+ info << 'There is no data in this layer'
60
+ else
61
+ info << 'This layer contains the following data:'
62
+ info << layer.to_yaml
63
+ end
64
+ info << sep
65
+ end
66
+ info.join "\n"
67
+ end
68
+
69
+ def detailed_config_files_info
70
+ merger = SuperStack::Manager.new
71
+ merger.merge_policy = SuperStack::MergePolicies::FullMergePolicy
72
+ layers.values.each do |layer|
73
+ merger << layer.possible_config_files if layer.respond_to? :possible_config_files
74
+ end
75
+ merger[]
76
+ end
77
+
78
+
79
+ def command_line_help
80
+ command_line_layer.help
81
+ end
82
+
83
+ def describes_application(options = {})
84
+ self.app_name = options.fetch(:app_name, nil)
85
+ self.app_version = options.fetch(:app_version, nil)
86
+ self.app_description = options.fetch(:app_description, nil)
87
+ self.config_file_base_name = options.fetch(:config_file_base_name, nil)
88
+ end
89
+
90
+ end
91
+
92
+ end
93
+ end
94
+
@@ -0,0 +1,61 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class ProjectLayer < SuperStack::Layer
5
+
6
+ attr_reader :started_from_directory, :project_file_basename
7
+
8
+ def initialize(file_or_directory, project_file_basename=nil)
9
+ if Dir.exists? file_or_directory
10
+ raise 'You have to provide the basename of the project file !' if project_file_basename.nil?
11
+ @started_from_directory = File.expand_path file_or_directory
12
+ self.project_file_basename = project_file_basename
13
+ else
14
+ raise "Invalid project file '#{file_or_directory}' !" unless File.readable? file_or_directory
15
+ normalized = File.expand_path file_or_directory
16
+ @started_from_directory = File.dirname normalized
17
+ self.project_file_basename = File.basename normalized
18
+ end
19
+ end
20
+
21
+ def file_name
22
+ @file_name ||= find_root_file project_file_basename, started_from_directory
23
+ end
24
+
25
+ def project_root
26
+ File.dirname file_name
27
+ end
28
+
29
+ def project_file_basename=(file)
30
+ @file_name = nil
31
+ @project_file_basename = file
32
+ end
33
+
34
+ private
35
+
36
+ def find_root_file(file_basename, initial_directory)
37
+ prev_dir = nil
38
+ cur_dir = initial_directory
39
+ found_file = nil
40
+ file_basename = file_basename.to_s
41
+
42
+ raise Climatic::Error, "Invalid directory '#{initial_directory}'" unless File.readable? initial_directory
43
+
44
+ while found_file.nil? and cur_dir != prev_dir
45
+ candidate_file = File.join cur_dir, file_basename
46
+ if File.readable? candidate_file
47
+ found_file = candidate_file
48
+ end
49
+ prev_dir = cur_dir
50
+ cur_dir = File.expand_path '..', cur_dir
51
+ end
52
+
53
+ raise Climatic::Error, "Cannot find any root file named '#{file_basename}' starting from '#{initial_directory}'." if found_file.nil?
54
+
55
+ found_file
56
+ end
57
+
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,26 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class ProvidedConfigFileLayer < SuperStack::Layer
5
+
6
+
7
+ def managed
8
+ if manager[:'config-file']
9
+ if File.readable? manager[:'config-file']
10
+ @file_name = manager[:'config-file']
11
+ self.merge_policy = SuperStack::MergePolicies::OverridePolicy if manager[:'config-override']
12
+ end
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def config_filepath
19
+ File.expand_path File.join('..', '..', '..', '..', 'etc', 'default_cmd_line_options.yml'), __FILE__
20
+ end
21
+
22
+
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,48 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ module SourceHelper
5
+
6
+ OS_FLAVOURS = {
7
+ mingw32: :windows,
8
+ linux: :unix
9
+ }
10
+ DEFAULT_OS_FLAVOUR = :unix
11
+
12
+
13
+ EXTENSIONS = %w(conf CONF cfg CFG yml YML yaml YAML)
14
+
15
+ def self.included(base)
16
+ base.extend ClassMethods
17
+ end
18
+
19
+ module ClassMethods
20
+ def os_flavour
21
+ Climatic::ConfigLayers::SourceHelper.os_flavour
22
+ end
23
+
24
+ def supported_oses
25
+ Climatic::ConfigLayers::SourceHelper.supported_oses
26
+ end
27
+ end
28
+
29
+ def self.os_flavour
30
+ OS_FLAVOURS[RbConfig::CONFIG['target_os'].to_sym] || DEFAULT_OS_FLAVOUR
31
+ end
32
+
33
+ def self.supported_oses
34
+ OS_FLAVOURS.values.sort.uniq
35
+ end
36
+
37
+ def os_flavour
38
+ @os_flavour ||= self.class.os_flavour
39
+ end
40
+
41
+ def supported_oses
42
+ self.class.supported_oses
43
+ end
44
+
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,37 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class SystemLayer < Climatic::ConfigLayers::GenericLayer
5
+
6
+ SYSTEM_CONFIG_ROOT = {
7
+ windows: [File.join(ENV['systemRoot'] || '', 'Config')],
8
+ unix: '/etc'
9
+ }
10
+
11
+ def self.system_config_root
12
+ SYSTEM_CONFIG_ROOT[os_flavour]
13
+ end
14
+
15
+ def system_config_root
16
+ self.class.system_config_root
17
+ end
18
+
19
+
20
+ def possible_sources
21
+ [
22
+ ['##SYSTEM_CONFIG_ROOT##', 'stacked_config.##EXTENSION##' ],
23
+ ['##SYSTEM_CONFIG_ROOT##', 'stacked_config', 'config.##EXTENSION##' ]
24
+ ]
25
+ end
26
+
27
+ def perform_substitutions path_part
28
+ res = path_part.dup
29
+ res.gsub! '##SYSTEM_CONFIG_ROOT##', system_config_root
30
+ res
31
+ end
32
+
33
+
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,40 @@
1
+ module Climatic
2
+ module ConfigLayers
3
+
4
+ class UserLayer < Climatic::ConfigLayers::GenericLayer
5
+
6
+
7
+ def self.user_config_root
8
+ Dir.home
9
+ end
10
+
11
+ def user_config_root
12
+ self.class.user_config_root
13
+ end
14
+
15
+
16
+ def possible_sources
17
+ [
18
+ ['##USER_CONFIG_ROOT##', '.##PROGRAM_NAME##.##EXTENSION##' ],
19
+ ['##USER_CONFIG_ROOT##', '.config', '##PROGRAM_NAME##.##EXTENSION##' ],
20
+ ['##USER_CONFIG_ROOT##', '.config', '##PROGRAM_NAME##', 'config.##EXTENSION##' ],
21
+ ['##USER_CONFIG_ROOT##', '.config', '##PROGRAM_NAME##', '##PROGRAM_NAME##.##EXTENSION##' ],
22
+ ['##USER_CONFIG_ROOT##', '.##PROGRAM_NAME##', 'config.##EXTENSION##' ],
23
+ ['##USER_CONFIG_ROOT##', '.##PROGRAM_NAME##', '##PROGRAM_NAME##.##EXTENSION##' ]
24
+ ]
25
+ end
26
+
27
+ def perform_substitutions path_part
28
+ res = path_part.dup
29
+ res.gsub! '##USER_CONFIG_ROOT##', user_config_root
30
+
31
+ exec_name = manager.nil? ? Climatic::LayersManager.default_config_file_base_name : manager.config_file_base_name
32
+ res.gsub! '##PROGRAM_NAME##', exec_name
33
+
34
+ res
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+ end