stacked_config 0.4.2 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 62606ce3e0ef2d847602164f729b0054c3c9efe4
4
- data.tar.gz: b8cf48ecbe204b5dc0506992f26c1436132f8693
3
+ metadata.gz: 4b40875c352b97a4a48b2265e2952978785af039
4
+ data.tar.gz: 88c153c71f5795df1d1342f03e19a1d9adf45be0
5
5
  SHA512:
6
- metadata.gz: e07a261e6013213c74b124340128308c081fec41fed187a7249706a0a8f63ec3402e304f59b4a1a750635347dceb6c213a2ebd02706b471fc95937fcf7dbeabf
7
- data.tar.gz: b7456c412b5c158dac0fc295976b5d2ebe89a0883ee0f67e7376fdf4a8a73b7dc0038d83c52f76533bd45a509925cc2d5c042406b26930a9281c019a5c152600
6
+ metadata.gz: 8ef28bf029e4b335bbf6a024ff61939c7dca489cb7602b53dbc48d57b4f7668233d2dd625e1d8cdfda734a6bf6519625f160326498c0d7a2d042cc3aacbdfe92
7
+ data.tar.gz: e6360ba692bb4beb230a87bc067afff6063882a5448b917a6697c20b20d210e2582b28eaa34dc658b3ad45c7a6fcb6e3379cd4377bfe6e7a36d85fdafc5dc4b4
data/README.md CHANGED
@@ -10,13 +10,17 @@ The purpose of this gem is to provide a __simple__ way to handle the __inheritan
10
10
  script. By default, it will handle already few config layers:
11
11
 
12
12
  * The __system layer__, which is a layer common to all applications using this gem.
13
- * The __gem layer__, which is the layer that will enable a gem to embed its own config. __You may consider this level
14
- as the layer where you will set the default values for your properties__.
13
+ * The __executable gem layer__, which is the layer that will enable a script provided by a gem to embed its own default
14
+ config. __You may consider this level as the layer where you will set the default values for the properties of your
15
+ executable__. This layer will get the config from the Gem that hosts the current __executable__ running.
16
+ * The __gem layer__, which is the layer that will enable a gem to embed its own default config. Nevertheless as it is
17
+ not really possible to guess automatically the name of the gem, it has to be created manually.
15
18
  * The __global layer__, which is the layer to declare options for all users that use the ruby script using this gem.
16
19
  * The __user layer__, which is the layer, where a user can set options for the ruby script using this gem.
17
20
  * The __extra layer__, which provides the possibility to specify another config file from the config itself.
18
21
  * The __enviroment variables layer__, which provides the possibility to include in the config variables coming from
19
- the shell variables. See [below](#environment-variables) for more info.
22
+ the shell variables. See [below](#environment-variables) for more info. This level is optional and not created by
23
+ default.
20
24
  * The __command-line layer__, which provides the ability to specify options from the command line.
21
25
  * The __override layer__, which will contain all modifications done to the config at run time.
22
26
 
@@ -28,6 +32,8 @@ All the config files are following the [YAML] syntax.
28
32
  __If you're looking for a complete solution for your command line scripts, including some logging features, then you
29
33
  are probably looking for the [easy_app_helper Gem][EAH], which is itself internally relying on [stacked_config][SC].__
30
34
 
35
+ Version 1.x introduces some minor non compatibilities with previous versions. Check [below]() for more info.
36
+
31
37
  ## Installation
32
38
 
33
39
  Add this line to your application's Gemfile:
@@ -79,7 +85,7 @@ clears the override layer.
79
85
  Every layer is accessible through the following orchestrator properties:
80
86
 
81
87
  * `system_layer`
82
- * `gem_layer`
88
+ * `executable_gem_layer`
83
89
  * `global_layer`
84
90
  * `user_layer`
85
91
  * `provided_config_file_layer`
@@ -87,31 +93,25 @@ Every layer is accessible through the following orchestrator properties:
87
93
  * `command_line_layer`
88
94
  * `write_layer`
89
95
 
96
+ The 'gem_layer' has no direct accessor as there could be more than one.
97
+
98
+
90
99
  ### Where are my config files ?
91
100
 
92
101
  `stacked_config` will look for config files in different places depending on the layer we are talking about. Have a look
93
102
  at the source to understand where exactly your config files can be, but basically it is following the Unix way of
94
103
  doing things...
95
104
 
105
+ All file based layers are inheriting from `StackedConfig::Layers::GenericLayer`
106
+
96
107
  * Sources for the [system layer][SystemLayer]
108
+ * Sources for the [executable gem layer][ExecutableGemLayer]
97
109
  * Sources for the [gem layer][GemLayer]
98
110
  * Sources for the [global layer][GlobalLayer]
99
111
  * Sources for the [user layer][UserLayer]
100
112
 
101
- As you can see in the sources, paths are expressed using kind of 'templates', which meaning should be obvious
102
-
103
- * `##SYSTEM_CONFIG_ROOT##` is where the system config is stored. On Unix systems, it should be `/etc`.
104
- * `##USER_CONFIG_ROOT##` is where the user config is stored. On Unix systems, it should be your `$HOME` directory.
105
- * `##GEM_CONFIG_ROOT##` is the path to the "current" Gem root. The current gem being the one containing the
106
- currently executing script.
107
- * `##PROGRAM_NAME##` is by default the name of the script you are running (with no extension). You can if you want
108
- change this name at runtime. __Changing it (using the `config_file_base_name` orchestrator property ) will trigger a
109
- re-search and reload of all the config files__. `config_file_base_name` defines the base name to search for config
110
- files accross the system. by default the name of the gem will be used.
111
- * `##EXTENSION##` is one of the following extensions : `conf CONF cfg CFG yml YML yaml YAML`.
112
-
113
- The search of the config files for a layer is done according to the order defined in sources just above and then
114
- extensions are tried according to the extensions just above in that exact order.
113
+ The search of the config files for a layer is done according to the order defined in `possible_sources` just above
114
+ and then extensions are tried according to the extensions just above in that exact order.
115
115
 
116
116
  __The first file matching for a particular level is used ! And there can be only one per level.__
117
117
 
@@ -121,6 +121,10 @@ user config level, only the first is taken in account:
121
121
  * `~/.my_script.yml`
122
122
  * `~/.config/my_script.conf`
123
123
 
124
+ you can get information about all files that are checked by the layers inheriting from
125
+ `StackedConfig::Layers::GenericLayer` by using the orchestrator convenience method `detailed_config_files_info` that
126
+ returns a hash which keys are the file names and values are hashes of information stating if the file is valid or used.
127
+
124
128
 
125
129
  ### Environment variables
126
130
 
@@ -298,10 +302,11 @@ The way layers are processed is done according to their priority. By default the
298
302
  priorities:
299
303
 
300
304
  * The system layer has a priority of __10__
301
- * The gem layer has a priority of __20__
302
- * The global layer has a priority of __30__
303
- * The user layer has a priority of __40__
304
- * The extra layer has a priority of __50__
305
+ * The executable gem layer has a priority of __20__
306
+ * The gem layer has a priority of __30__ (if exists)
307
+ * The global layer has a priority of __40__
308
+ * The user layer has a priority of __50__
309
+ * The extra layer has a priority of __60__
305
310
  * The command-line layer has a priority of __100__
306
311
  * The override layer has a priority of __1000__
307
312
 
@@ -485,6 +490,13 @@ This layer contains the following data:
485
490
  ## Bye...
486
491
  ```
487
492
 
493
+
494
+ ## Non nackward compatible changes
495
+
496
+ ### Between version 0.x and 1.x
497
+
498
+ TODO
499
+
488
500
  ## Contributing
489
501
 
490
502
  1. [Fork it] ( https://github.com/lbriais/stacked_config/fork ), clone your fork.
@@ -493,12 +505,13 @@ This layer contains the following data:
493
505
  4. Push to the branch (`git push origin my-new-feature`).
494
506
  5. Create a Pull Request.
495
507
 
496
- [SS]: https://github.com/lbriais/super_stack "Super Stack gem"
497
- [SC]: https://github.com/lbriais/stacked_config "The stacked_config Gem"
498
- [SystemLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/system_layer.rb "the system layer places where config files are searched"
499
- [GemLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/gem_layer.rb "the gem layer places where config files are searched"
500
- [GlobalLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/global_layer.rb "the global layer places where config files are searched"
501
- [UserLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/user_layer.rb "the user layer places where config files are searched"
502
- [YAML]: http://www.yaml.org/ "The Yaml official site"
503
- [Slop]: https://rubygems.org/gems/slop "The Slop gem"
504
- [EAH]: https://github.com/lbriais/easy_app_helper "The EasyAppHelper gem"
508
+ [SS]: https://github.com/lbriais/super_stack "Super Stack gem"
509
+ [SC]: https://github.com/lbriais/stacked_config "The stacked_config Gem"
510
+ [SystemLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/system_layer.rb "the system layer places where config files are searched"
511
+ [ExecutableGemLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/executable_gem_layer.rb "the executable gem layer places where config files are searched"
512
+ [GemLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/gem_layer.rb "the gem layer places where config files are searched"
513
+ [GlobalLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/global_layer.rb "the global layer places where config files are searched"
514
+ [UserLayer]: https://github.com/lbriais/stacked_config/blob/master/lib/stacked_config/layers/user_layer.rb "the user layer places where config files are searched"
515
+ [YAML]: http://www.yaml.org/ "The Yaml official site"
516
+ [Slop]: https://rubygems.org/gems/slop "The Slop gem"
517
+ [EAH]: https://github.com/lbriais/easy_app_helper "The EasyAppHelper gem"
@@ -13,7 +13,10 @@ module StackedConfig
13
13
  def load(*args)
14
14
  slop_definition.parse
15
15
  slop_definition.banner = build_banner
16
- replace slop_definition.to_hash.delete_if {|k,v| v.nil?}
16
+ h = slop_definition.to_hash.delete_if {|k,v| v.nil?}
17
+ res = {}
18
+ h.each{|k,v| res[k.to_s] = v }
19
+ h
17
20
  end
18
21
 
19
22
  def possible_options
@@ -0,0 +1,45 @@
1
+ module StackedConfig
2
+ module Layers
3
+
4
+ class ExecutableGemLayer < StackedConfig::Layers::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? ? StackedConfig::Orchestrator.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
@@ -2,17 +2,48 @@ module StackedConfig
2
2
  module Layers
3
3
 
4
4
  class GemLayer < StackedConfig::Layers::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
+
5
27
  def possible_sources
6
28
  [
7
- ['##GEM_CONFIG_ROOT##', 'etc', '##PROGRAM_NAME##.##EXTENSION##' ],
8
- ['##GEM_CONFIG_ROOT##', 'etc', '##PROGRAM_NAME##', 'config.##EXTENSION##' ],
9
- ['##GEM_CONFIG_ROOT##', 'etc', '##PROGRAM_NAME##', '##PROGRAM_NAME##.##EXTENSION##' ],
10
- ['##GEM_CONFIG_ROOT##', 'config', '##PROGRAM_NAME##.##EXTENSION##' ],
11
- ['##GEM_CONFIG_ROOT##', 'config', '##PROGRAM_NAME##', 'config.##EXTENSION##' ],
12
- ['##GEM_CONFIG_ROOT##', 'config', '##PROGRAM_NAME##', '##PROGRAM_NAME##.##EXTENSION##' ]
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##)
13
35
  ]
14
36
  end
15
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
+
16
47
  end
17
48
 
18
49
  end
@@ -13,6 +13,49 @@ module StackedConfig
13
13
  rescan
14
14
  end
15
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
+
16
59
  end
17
60
 
18
61
  end
@@ -1,7 +1,7 @@
1
1
  module StackedConfig
2
2
  module Layers
3
3
 
4
- class GlobalLayer < StackedConfig::Layers::GenericLayer
4
+ class GlobalLayer < StackedConfig::Layers::SystemLayer
5
5
  def possible_sources
6
6
  [
7
7
  ['##SYSTEM_CONFIG_ROOT##', '##PROGRAM_NAME##.##EXTENSION##' ],
@@ -10,7 +10,19 @@ module StackedConfig
10
10
  ]
11
11
  end
12
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? ? StackedConfig::Orchestrator.default_config_file_base_name : manager.config_file_base_name
18
+ res.gsub! '##PROGRAM_NAME##', exec_name
19
+
20
+ res
21
+ end
22
+
13
23
  end
14
24
 
25
+
26
+
15
27
  end
16
28
  end
@@ -2,6 +2,21 @@ module StackedConfig
2
2
  module Layers
3
3
 
4
4
  class SystemLayer < StackedConfig::Layers::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
+
5
20
  def possible_sources
6
21
  [
7
22
  ['##SYSTEM_CONFIG_ROOT##', 'stacked_config.##EXTENSION##' ],
@@ -9,6 +24,13 @@ module StackedConfig
9
24
  ]
10
25
  end
11
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
+
12
34
  end
13
35
 
14
36
  end
@@ -3,6 +3,16 @@ module StackedConfig
3
3
 
4
4
  class UserLayer < StackedConfig::Layers::GenericLayer
5
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
+
6
16
  def possible_sources
7
17
  [
8
18
  ['##USER_CONFIG_ROOT##', '.##PROGRAM_NAME##.##EXTENSION##' ],
@@ -14,6 +24,16 @@ module StackedConfig
14
24
  ]
15
25
  end
16
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? ? StackedConfig::Orchestrator.default_config_file_base_name : manager.config_file_base_name
32
+ res.gsub! '##PROGRAM_NAME##', exec_name
33
+
34
+ res
35
+ end
36
+
17
37
  end
18
38
 
19
39
  end
@@ -3,7 +3,7 @@ module StackedConfig
3
3
 
4
4
  include StackedConfig::ProgramDescriptionHelper
5
5
 
6
- attr_reader :system_layer, :global_layer, :gem_layer, :user_layer, :env_layer,
6
+ attr_reader :system_layer, :global_layer, :executable_gem_layer, :user_layer, :env_layer,
7
7
  :command_line_layer, :provided_config_file_layer
8
8
 
9
9
  def initialize
@@ -19,13 +19,22 @@ module StackedConfig
19
19
  File.basename($PROGRAM_NAME).gsub /\.[^\.]+$/, ''
20
20
  end
21
21
 
22
- def include_env_layer(filter = nil, priority = 60)
22
+ def include_env_layer(filter = nil, priority = 70)
23
23
  @env_layer = StackedConfig::Layers::EnvLayer.new filter
24
24
  env_layer.name = 'Environment variables level'
25
25
  env_layer.priority = priority
26
26
  self << env_layer
27
27
  end
28
28
 
29
+ def include_gem_layer_for(gem_name, priority = 30)
30
+ gem_layer = StackedConfig::Layers::GemLayer.new
31
+ gem_layer.gem_name = gem_name
32
+ raise "No config found in gem #{gem_name}" if gem_layer.file_name.nil?
33
+ gem_layer.name = "#{gem_name} Gem configuration level"
34
+ gem_layer.priority = priority
35
+ self << gem_layer
36
+ end
37
+
29
38
  private
30
39
 
31
40
  def setup_layers
@@ -35,17 +44,17 @@ module StackedConfig
35
44
  # The system level
36
45
  @system_layer = setup_layer StackedConfig::Layers::SystemLayer, 'System-wide configuration level', 10
37
46
 
38
- # The gem level
39
- @gem_layer = setup_layer StackedConfig::Layers::GemLayer, 'Gem configuration level', 20
47
+ # The executable gem level
48
+ @executable_gem_layer = setup_layer StackedConfig::Layers::ExecutableGemLayer, 'Gem associated to the executable running configuration level', 20
40
49
 
41
50
  # The global level
42
- @global_layer = setup_layer StackedConfig::Layers::GlobalLayer, 'Global configuration level', 30
51
+ @global_layer = setup_layer StackedConfig::Layers::GlobalLayer, 'Global configuration level', 40
43
52
 
44
53
  # The user level
45
- @user_layer = setup_layer StackedConfig::Layers::UserLayer, 'User configuration level', 40
54
+ @user_layer = setup_layer StackedConfig::Layers::UserLayer, 'User configuration level', 50
46
55
 
47
56
  # The specifically provided config file level
48
- @provided_config_file_layer = setup_layer StackedConfig::Layers::ProvidedConfigFileLayer, 'Specific config file configuration level', 50
57
+ @provided_config_file_layer = setup_layer StackedConfig::Layers::ProvidedConfigFileLayer, 'Specific config file configuration level', 60
49
58
 
50
59
  # The layer to write something
51
60
  override_layer = setup_layer SuperStack::Layer, 'Overridden configuration level', 1000
@@ -64,6 +64,16 @@ module StackedConfig
64
64
  info.join "\n"
65
65
  end
66
66
 
67
+ def detailed_config_files_info
68
+ merger = SuperStack::Manager.new
69
+ merger.merge_policy = SuperStack::MergePolicies::FullMergePolicy
70
+ layers.values.each do |layer|
71
+ merger << layer.possible_config_files if layer.respond_to? :possible_config_files
72
+ end
73
+ merger[]
74
+ end
75
+
76
+
67
77
  def command_line_help
68
78
  command_line_layer.help
69
79
  end
@@ -7,97 +7,38 @@ module StackedConfig
7
7
  }
8
8
  DEFAULT_OS_FLAVOUR = :unix
9
9
 
10
- SYSTEM_CONFIG_ROOT = {
11
- windows: [File.join(ENV['systemRoot'] || '', 'Config')],
12
- unix: '/etc'
13
- }
14
10
 
15
11
  EXTENSIONS = %w(conf CONF cfg CFG yml YML yaml YAML)
16
12
 
17
- def self.os_flavour
18
- OS_FLAVOURS[RbConfig::CONFIG['target_os'].to_sym] || DEFAULT_OS_FLAVOUR
19
- end
20
-
21
- def self.supported_oses
22
- OS_FLAVOURS.values.sort.uniq
23
- end
24
-
25
- def self.system_config_root
26
- SYSTEM_CONFIG_ROOT[os_flavour]
27
- end
28
-
29
- def self.user_config_root
30
- Dir.home
13
+ def self.included(base)
14
+ base.extend ClassMethods
31
15
  end
32
16
 
33
- def self.gem_config_root
34
- return nil unless $PROGRAM_NAME
17
+ module ClassMethods
18
+ def os_flavour
19
+ StackedConfig::SourceHelper.os_flavour
20
+ end
35
21
 
36
- Gem.loaded_specs.each_pair do |name, spec|
37
- executable_basename = File.basename($PROGRAM_NAME)
38
- return spec.full_gem_path if spec.executables.include? executable_basename
22
+ def supported_oses
23
+ StackedConfig::SourceHelper.supported_oses
39
24
  end
40
- nil
41
25
  end
42
26
 
43
- def gem_config_root
44
- StackedConfig::SourceHelper.gem_config_root
27
+ def self.os_flavour
28
+ OS_FLAVOURS[RbConfig::CONFIG['target_os'].to_sym] || DEFAULT_OS_FLAVOUR
45
29
  end
46
30
 
47
- def supported_oses
48
- StackedConfig::SourceHelper.supported_oses
31
+ def self.supported_oses
32
+ OS_FLAVOURS.values.sort.uniq
49
33
  end
50
34
 
51
35
  def os_flavour
52
- @os_flavour ||= StackedConfig::SourceHelper.os_flavour
53
- end
54
-
55
- def system_config_root
56
- StackedConfig::SourceHelper.system_config_root
57
- end
58
-
59
- def user_config_root
60
- StackedConfig::SourceHelper.user_config_root
61
- end
62
-
63
- def set_config_file(places)
64
- @file_name = nil
65
- places.each do |path_array|
66
- # Perform path substitutions
67
- begin
68
- potential_config_file = File.join(path_array.map { |path_part| perform_substitutions path_part })
69
- rescue
70
- #do nothing
71
- end
72
- return unless potential_config_file
73
- # Try to find config file with extension
74
- EXTENSIONS.each do |extension|
75
- file = potential_config_file.gsub '##EXTENSION##', extension
76
- if File.readable? file
77
- @file_name = file
78
- return @file_name
79
- end
80
- end
81
- end
36
+ @os_flavour ||= self.class.os_flavour
82
37
  end
83
38
 
84
-
85
-
86
- def perform_substitutions path_part
87
- res = path_part.dup
88
- res.gsub! '##SYSTEM_CONFIG_ROOT##', system_config_root
89
- res.gsub! '##USER_CONFIG_ROOT##', user_config_root
90
-
91
- exec_name = manager.nil? ? StackedConfig::Orchestrator.default_config_file_base_name : manager.config_file_base_name
92
- res.gsub! '##PROGRAM_NAME##', exec_name
93
- if res =~ /##GEM_CONFIG_ROOT##/
94
- return nil unless gem_config_root
95
- res.gsub! '##GEM_CONFIG_ROOT##', gem_config_root
96
- end
97
-
98
- res
39
+ def supported_oses
40
+ self.class.supported_oses
99
41
  end
100
42
 
101
-
102
43
  end
103
44
  end
@@ -1,3 +1,3 @@
1
1
  module StackedConfig
2
- VERSION = '0.4.2'
2
+ VERSION = '1.0.2'
3
3
  end
@@ -6,6 +6,7 @@ require 'stacked_config/source_helper'
6
6
  require 'stacked_config/program_description_helper'
7
7
  require 'stacked_config/layers/generic_layer'
8
8
  require 'stacked_config/layers/system_layer'
9
+ require 'stacked_config/layers/executable_gem_layer'
9
10
  require 'stacked_config/layers/gem_layer'
10
11
  require 'stacked_config/layers/global_layer'
11
12
  require 'stacked_config/layers/user_layer'
@@ -46,6 +46,15 @@ describe StackedConfig::Layers::EnvLayer do
46
46
  expect(layer.keys.length == 1).to be_truthy
47
47
  end
48
48
 
49
+ [NIL_FILTER, STRING_FILTER, ARRAY_FILTER, REGEXP_FILTER].each do |filter|
50
+ it "should be the same to provide a #{filter.class} filter to the constructor or afterwards" do
51
+ layer1 = StackedConfig::Layers::EnvLayer.new(filter)
52
+ layer2 = StackedConfig::Layers::EnvLayer.new
53
+ layer2.filter = filter
54
+ expect(layer1).to eq layer2
55
+ end
56
+ end
57
+
49
58
  end
50
59
 
51
- end
60
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+
4
+ describe StackedConfig::Layers::ExecutableGemLayer do
5
+ # subject is a modified ExecutableGemLayer to redirect executable_gem_config_root to the test directory
6
+ subject {
7
+ s = StackedConfig::Layers::ExecutableGemLayer.new
8
+ gem_path = File.expand_path '../..', __FILE__
9
+ allow(s).to receive(:executable_gem_config_root) {File.join(gem_path, 'test', 'tstgem') }
10
+ s.rescan
11
+ s
12
+ }
13
+
14
+ it 'should provide an executable gem config root' do
15
+ expect(subject.executable_gem_config_root).to_not be_nil
16
+ end
17
+
18
+ it 'should return the path of the first matching config file it found' do
19
+ expect(subject.file_name).not_to be_nil
20
+ end
21
+
22
+
23
+ end
@@ -2,15 +2,19 @@ require 'spec_helper'
2
2
 
3
3
 
4
4
  describe StackedConfig::Layers::GemLayer do
5
- # subject is a modified SystemLayer to redirect gem_config_root to the test directory
5
+ # subject is a modified GemLayer to redirect gem_config_root to the test directory
6
6
  subject {
7
7
  s = StackedConfig::Layers::GemLayer.new
8
8
  gem_path = File.expand_path '../..', __FILE__
9
9
  allow(s).to receive(:gem_config_root) {File.join(gem_path, 'test', 'tstgem') }
10
- s.rescan
10
+ s.gem_name = 'tstgem'
11
11
  s
12
12
  }
13
13
 
14
+ it 'should provide a gem config root' do
15
+ expect(subject.gem_config_root).to_not be_nil
16
+ end
17
+
14
18
  it 'should return the path of the first matching config file it found' do
15
19
  expect(subject.file_name).not_to be_nil
16
20
  end
@@ -14,6 +14,10 @@ describe StackedConfig::Layers::GlobalLayer do
14
14
  s
15
15
  }
16
16
 
17
+ it 'should provide a system config root' do
18
+ expect(subject.system_config_root).to_not be_nil
19
+ end
20
+
17
21
  it 'should return the path of the first matching config file it found' do
18
22
  expect(subject.file_name).not_to be_nil
19
23
  end
@@ -25,9 +29,9 @@ describe StackedConfig::Layers::GlobalLayer do
25
29
  end
26
30
 
27
31
  it 'should enable to load the file' do
28
- expect(subject[:an_array]).to be_nil
32
+ expect(subject['an_array']).to be_nil
29
33
  subject.load
30
- expect(subject[:an_array]).to be_an Array
34
+ expect(subject['an_array']).to be_an Array
31
35
  end
32
36
 
33
37
 
@@ -7,13 +7,13 @@ describe StackedConfig::Orchestrator do
7
7
  # Patching SourceHelper to find test config files in this gem test directory instead of from the system.
8
8
  os = StackedConfig::SourceHelper.os_flavour
9
9
  gem_path = File.expand_path '../..', __FILE__
10
- altered_sys_conf_root = File.join gem_path, 'test', os.to_s, StackedConfig::SourceHelper::SYSTEM_CONFIG_ROOT[os]
10
+ altered_sys_conf_root = File.join gem_path, 'test', os.to_s, StackedConfig::Layers::SystemLayer::SYSTEM_CONFIG_ROOT[os]
11
11
  altered_user_conf_root = File.join gem_path, 'test', 'user'
12
12
  altered_gem_conf_root = File.join(gem_path, 'test', 'tstgem')
13
13
 
14
- allow(StackedConfig::SourceHelper).to receive(:system_config_root) { altered_sys_conf_root }
15
- allow(StackedConfig::SourceHelper).to receive(:user_config_root) { altered_user_conf_root }
16
- allow(StackedConfig::SourceHelper).to receive(:gem_config_root) { altered_gem_conf_root }
14
+ allow(StackedConfig::Layers::SystemLayer).to receive(:system_config_root) { altered_sys_conf_root }
15
+ allow(StackedConfig::Layers::UserLayer).to receive(:user_config_root) { altered_user_conf_root }
16
+ allow(StackedConfig::Layers::ExecutableGemLayer).to receive(:executable_gem_config_root) { altered_gem_conf_root }
17
17
 
18
18
  StackedConfig::Orchestrator.new
19
19
  }
@@ -53,8 +53,8 @@ describe StackedConfig::Orchestrator do
53
53
  expect(subject.system_layer).to be subject.to_a.first
54
54
  end
55
55
 
56
- it 'should have the gem layer evaluated in second' do
57
- expect(subject.gem_layer).to be subject.to_a[1]
56
+ it 'should have the executable gem layer evaluated in second' do
57
+ expect(subject.executable_gem_layer).to be subject.to_a[1]
58
58
  end
59
59
 
60
60
  it 'should have the global layer evaluated in third' do
@@ -130,5 +130,28 @@ describe StackedConfig::Orchestrator do
130
130
 
131
131
  end
132
132
 
133
+ context 'when adding a gem config in the config' do
134
+
135
+ it 'should insert the new layer with a default priority of 30' do
136
+ gem_path = File.expand_path '../..', __FILE__
137
+ allow(StackedConfig::Layers::GemLayer).to receive(:gem_config_root) do |gem_name|
138
+ File.join(gem_path, 'test', gem_name.to_s)
139
+ end
140
+ expect {subject.include_gem_layer_for :tstgem}.not_to raise_error
141
+ end
142
+
143
+ end
144
+
145
+ it 'should give info about where files are searched' do
146
+ info = subject.detailed_config_files_info
147
+ expect(info).to be_a Hash
148
+ found_files = info.keys.map { |file| File.readable?(file) ? file : nil}.compact
149
+ expect(found_files.length).to be 4
150
+ found_files.each do |file|
151
+ expect(info[file][:exists]).to be_truthy
152
+ expect(info[file][:used]).to be_truthy
153
+ end
154
+
155
+ end
133
156
 
134
157
  end
@@ -3,24 +3,14 @@ require 'spec_helper'
3
3
 
4
4
  describe StackedConfig::SourceHelper do
5
5
 
6
- subject {
7
- s = Object.new
8
- s.extend StackedConfig::SourceHelper
9
- s
10
- }
6
+ subject {StackedConfig::SourceHelper }
11
7
 
12
8
  it 'should provide an OS flavour' do
13
9
  expect(subject.os_flavour).to_not be_nil
10
+ # s = Object.new
11
+ # s.extend subject
12
+ # expect(s.os_flavour).to_not be_nil
14
13
  end
15
14
 
16
- it 'should provide a system config root' do
17
- expect(subject.system_config_root).to_not be_nil
18
- end
19
-
20
- it 'should provide a user config root' do
21
- expect(subject.user_config_root).to_not be_nil
22
- end
23
-
24
-
25
15
  end
26
16
 
@@ -14,6 +14,11 @@ describe StackedConfig::Layers::SystemLayer do
14
14
  s
15
15
  }
16
16
 
17
+ it 'should provide a system config root' do
18
+ expect(subject.system_config_root).to_not be_nil
19
+ end
20
+
21
+
17
22
  it 'should return the path of the first matching config file it found' do
18
23
  expect(subject.file_name).not_to be_nil
19
24
  end
@@ -25,11 +30,12 @@ describe StackedConfig::Layers::SystemLayer do
25
30
  end
26
31
 
27
32
  it 'should enable to load the file' do
28
- expect(subject[:stacked_config_copyright]).to be_nil
33
+ expect(subject['stacked_config_copyright']).to be_nil
29
34
  subject.load
30
- expect(subject[:stacked_config_copyright]).not_to be_nil
35
+ expect(subject['stacked_config_copyright']).not_to be_nil
31
36
  end
32
37
 
33
38
 
34
39
 
40
+
35
41
  end
@@ -13,6 +13,10 @@ describe StackedConfig::Layers::UserLayer do
13
13
  s
14
14
  }
15
15
 
16
+ it 'should provide a user config root' do
17
+ expect(subject.user_config_root).to_not be_nil
18
+ end
19
+
16
20
  it 'should return the path of the first matching config file it found' do
17
21
  expect(subject.file_name).not_to be_nil
18
22
  end
@@ -24,9 +28,9 @@ describe StackedConfig::Layers::UserLayer do
24
28
  end
25
29
 
26
30
  it 'should enable to load the file' do
27
- expect(subject[:an_array]).to be_nil
31
+ expect(subject['an_array']).to be_nil
28
32
  subject.load
29
- expect(subject[:an_array]).to be_an Array
33
+ expect(subject['an_array']).to be_an Array
30
34
  end
31
35
 
32
36
 
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'pry'
24
24
  spec.add_development_dependency 'rspec', '~> 3.0'
25
25
 
26
- spec.add_dependency 'super_stack', '~> 0.2', '>= 0.2.5', '< 0.4'
26
+ spec.add_dependency 'super_stack', '~> 0.4'
27
27
  spec.add_dependency 'slop', '~> 3.0'
28
28
 
29
29
  end
@@ -4,4 +4,4 @@
4
4
 
5
5
  gem_property: foo
6
6
  an_array:
7
- - something super weird (at gem level)
7
+ - something super weird (at executable gem level)
@@ -0,0 +1,7 @@
1
+ # This is supposed to be a file at "user" level.
2
+ # It is dedicated to configuration for this particular user running the program rspec.
3
+ # To be used at user level
4
+
5
+ gem_property: foo
6
+ an_array:
7
+ - something super weird (at gem level)
@@ -4,8 +4,8 @@ require 'spec_helper'
4
4
  describe 'Using stacked_config within a gem' do
5
5
 
6
6
  it 'should detect we are in a gem' do
7
- expect(StackedConfig::SourceHelper.gem_config_root).to_not be_nil
8
- expect(StackedConfig::SourceHelper.gem_config_root =~ /rspec-core/).to be_truthy
7
+ expect(StackedConfig::SourceHelper.executable_gem_config_root).to_not be_nil
8
+ expect(StackedConfig::SourceHelper.executable_gem_config_root =~ /rspec-core/).to be_truthy
9
9
  end
10
10
 
11
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stacked_config
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent B.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-27 00:00:00.000000000 Z
11
+ date: 2015-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -71,12 +71,6 @@ dependencies:
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ~>
74
- - !ruby/object:Gem::Version
75
- version: '0.2'
76
- - - '>='
77
- - !ruby/object:Gem::Version
78
- version: 0.2.5
79
- - - <
80
74
  - !ruby/object:Gem::Version
81
75
  version: '0.4'
82
76
  type: :runtime
@@ -84,12 +78,6 @@ dependencies:
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
80
  - - ~>
87
- - !ruby/object:Gem::Version
88
- version: '0.2'
89
- - - '>='
90
- - !ruby/object:Gem::Version
91
- version: 0.2.5
92
- - - <
93
81
  - !ruby/object:Gem::Version
94
82
  version: '0.4'
95
83
  - !ruby/object:Gem::Dependency
@@ -123,6 +111,7 @@ files:
123
111
  - lib/stacked_config.rb
124
112
  - lib/stacked_config/layers/command_line_layer.rb
125
113
  - lib/stacked_config/layers/env_layer.rb
114
+ - lib/stacked_config/layers/executable_gem_layer.rb
126
115
  - lib/stacked_config/layers/gem_layer.rb
127
116
  - lib/stacked_config/layers/generic_layer.rb
128
117
  - lib/stacked_config/layers/global_layer.rb
@@ -135,6 +124,7 @@ files:
135
124
  - lib/stacked_config/version.rb
136
125
  - spec/command_line_layer_spec.rb
137
126
  - spec/env_layer_spec.rb
127
+ - spec/executable_gem_layer_spec.rb
138
128
  - spec/gem_layer_spec.rb
139
129
  - spec/global_layer_spec.rb
140
130
  - spec/orchestrator_spec.rb
@@ -151,6 +141,7 @@ files:
151
141
  - test/tstgem/README.md
152
142
  - test/tstgem/Rakefile
153
143
  - test/tstgem/config/rspec.yml
144
+ - test/tstgem/config/tstgem.yml
154
145
  - test/tstgem/lib/tstgem.rb
155
146
  - test/tstgem/lib/tstgem/version.rb
156
147
  - test/tstgem/spec/global_spec.rb
@@ -180,13 +171,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
171
  version: '0'
181
172
  requirements: []
182
173
  rubyforge_project:
183
- rubygems_version: 2.0.14
174
+ rubygems_version: 2.0.0
184
175
  signing_key:
185
176
  specification_version: 4
186
177
  summary: Manages config files according to standard policy.
187
178
  test_files:
188
179
  - spec/command_line_layer_spec.rb
189
180
  - spec/env_layer_spec.rb
181
+ - spec/executable_gem_layer_spec.rb
190
182
  - spec/gem_layer_spec.rb
191
183
  - spec/global_layer_spec.rb
192
184
  - spec/orchestrator_spec.rb
@@ -202,6 +194,7 @@ test_files:
202
194
  - test/tstgem/README.md
203
195
  - test/tstgem/Rakefile
204
196
  - test/tstgem/config/rspec.yml
197
+ - test/tstgem/config/tstgem.yml
205
198
  - test/tstgem/lib/tstgem.rb
206
199
  - test/tstgem/lib/tstgem/version.rb
207
200
  - test/tstgem/spec/global_spec.rb