stacked_config 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0cc8ac49474011f38a0cf1b6859849c9feb356b9
4
- data.tar.gz: 5b5076b0f63330df95152b0403619043807bee21
3
+ metadata.gz: 396a51271ebfbb2aee0f6a8d3d03674f46b7a398
4
+ data.tar.gz: d4215b4890198baf73cb42ea690ff46b000e9ea3
5
5
  SHA512:
6
- metadata.gz: f66b20e0469a6c5f3ce095c401ec1ba527ef9e9a0e1a15e597c02d6d4b4f7ddf7d90362548fe9b757b9e4b2822a94bb321f463181ecd375e92f2735fa0b2a16c
7
- data.tar.gz: 4f6b134a3dc729a0a03f67c70338eac58cae74780df30ee62d90a822bd5bb7026966cd1cec9fba06105b9f402c52d856f34d4f7f302a46c63bd1350734102359
6
+ metadata.gz: 35cc07767ab94e5891230097e9a83ecaac1202c4325af0d2e8e6fc82ff555d4b760e855bb8e41d8014e66135b52833608ff78e60a30df7e8750c67d48fb408e9
7
+ data.tar.gz: d114a476a6684535ffabc7a777fe4eff2175a11cd58cca4644ba9657b513e0fc4d3bad0850907425f12ce8c0074ad404d2c21c69da5f991cbc2c64410c5de3cd
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ script:
5
+ - bundle exec rake spec
data/README.md CHANGED
@@ -1,10 +1,21 @@
1
1
  # StackedConfig
2
+ [![Build Status](https://travis-ci.org/lbriais/stacked_config.svg)](https://travis-ci.org/lbriais/stacked_config)
3
+ [![Gem Version](https://badge.fury.io/rb/stacked_config.svg)](http://badge.fury.io/rb/stacked_config)
2
4
 
3
- Code should be ready for prod
5
+ The purpose of this gem is to provide a __simple__ way to handle the __inheritance__ of __config files__ for a ruby
6
+ script. By default, it will handle already few config layers:
4
7
 
5
- No doc written for the time being
8
+ * The __system layer__, which is a level common to all applications using this gem.
9
+ * The __global layer__, which is the level to declare options for all users that use the ruby script using this gem.
10
+ * The __user layer__, which is the level, where a user can set options for the ruby script using this gem.
11
+ * The __extra layer__, which provides the possibility to specify a config file from the command line.
12
+ * The __command-line layer__, which provides the ability to specify options from the command line.
13
+ * The __override layer__, which will contain all modifications done to the config at run time.
6
14
 
7
- Wait for version 0.1.x
15
+ The different layers are evaluated by default in that order using the [super_stack gem][SS] (Please read for more
16
+ detail).
17
+
18
+ All the config files are following the [YAML] syntax.
8
19
 
9
20
  ## Installation
10
21
 
@@ -22,12 +33,133 @@ Or install it yourself as:
22
33
 
23
34
  ## Usage
24
35
 
25
- TODO: Write usage instructions here
36
+ ### Basics
37
+
38
+ `stacked_config` is a very versatile configuration system for your scripts. The default behaviour may satisfy most of
39
+ the needs out of the box.
40
+
41
+ ```ruby
42
+ require 'stacked_config'
43
+
44
+ config = StackedConfig::Orchestrator.new
45
+
46
+ config[:runtime_property] = 'A runtime property'
47
+
48
+ # Displays all the internals of the config:
49
+ puts config.detailed_layers_info
50
+
51
+ # Normally you may probably only need to access some properties
52
+ if config[:help]
53
+ puts config.command_line_help
54
+ end
55
+ ```
56
+
57
+ Try this little script and then create some config files to test how it is handled (see next section to know where to
58
+ create the config files).
59
+
60
+
61
+ ### Where are my config files ?
62
+
63
+ `stacked_config` will look for config files in different places depending on the layer we are talking about. Have a look
64
+ at the source to understand where exactly your config files can be, but basically it is following the Unix way of
65
+ doing things...
66
+
67
+ * Sources for the [system layer][SystemLayer]
68
+ * Sources for the [global layer][GlobalLayer]
69
+ * Sources for the [user layer][UserLayer]
70
+
71
+ As you can see in the sources, paths are expressed using kind of 'templates', which meaning should be obvious
72
+
73
+ * `##SYSTEM_CONFIG_ROOT##` is where the system config is stored. On Unix systems, it should be `/etc`.
74
+ * `##PROGRAM_NAME##` is by default the name of the script you are running (with no extension). You can if you want
75
+ change this name at runtime. Changing it will trigger a re-search and reload of all the config files.
76
+ * `##USER_CONFIG_ROOT##` is where the user config is stored. On Unix systems, it should be your `$HOME` directory.
77
+ * `##EXTENSION##` is one of the following extensions : `conf CONF cfg CFG yml YML yaml YAML`.
78
+
79
+ The search of the config files is done according to the order defined in sources just above and then extensions
80
+ are tried according to the extensions just above in that exact order.
81
+
82
+ __The first file matching for a particular level is used !__ And there can be only one per level.
83
+
84
+ Thus according to the rules above, and assuming my script is named `my_script.rb` if the two following files exists at
85
+ user config level, only the first is taken in account:
86
+
87
+ * `~/.my_script.yml`
88
+ * `~/.config/my_script.conf`
89
+
90
+
91
+ ### Script command line options
92
+
93
+ `stacked_config` uses internally the fantastic [Slop] gem to manage options coming from
94
+ the command line.
95
+
96
+ To define your options the command-line layer exposes a `slop_definition` method that enables
97
+ to directly configure slop.
98
+
99
+ For most usages you can use the higher level method `add_command_line_section` from the orchestrator.
100
+
101
+ ```ruby
102
+ require 'stacked_config'
103
+
104
+ config = StackedConfig::Orchestrator.new
105
+ config.add_command_line_section do |slop|
106
+ slop.on :u, :useless, 'Stupid option', :argument => false
107
+ slop.on :an_int, 'Stupid option with integer argument', :argument => true, :as => Integer
108
+ end
109
+ ```
110
+
111
+ The `add_command_line_section` method supports a parameter to define the name of the section.
112
+
113
+
114
+ ### Advanced usage
115
+
116
+ #### Re-ordering layers
117
+
118
+ The way layers are processed is done according to their priority. By default the existing layers have the following
119
+ priorities:
120
+
121
+ * The system layer has a priority of 10
122
+ * The global layer has a priority of 20
123
+ * The user layer has a priority of 30
124
+ * The extra layer has a priority of 40
125
+ * The command-line layer has a priority of 100
126
+ * The override layer has a priority of 1000
127
+
128
+ But imagine you want to say that no-one could override properties defined at the system and global layer even from the
129
+ command-line, then you just have to change the priorities of those 2 layers.
130
+
131
+ ```ruby
132
+ require 'stacked_config'
133
+
134
+ config = StackedConfig::Orchestrator.new
135
+ config.system_layer.priority = 1500
136
+ config.global_layer.priority = 1600
137
+ ```
138
+
139
+ By doing such the system and global layers will be evaluated after the command line layer and therefore properties set
140
+ in those files cannot be overridden even at command line level.
141
+
142
+
143
+ #### Adding extra layers
144
+
145
+ Imagine you want to add a specific layer in your config, coming from let's say a web-service or a database, you may
146
+ create your own layers for this purpose. Have a look at [super_stack gem][SS] for further info about how to create
147
+ layers.
148
+
149
+ But basically just create your new layer, gives it a priority and add it to the orchestrator.
150
+
26
151
 
27
152
  ## Contributing
28
153
 
29
- 1. Fork it ( http://github.com/<my-github-username>/stacked_config/fork )
154
+ 1. [Fork it] ( https://github.com/lbriais/stacked_config/fork )
30
155
  2. Create your feature branch (`git checkout -b my-new-feature`)
31
156
  3. Commit your changes (`git commit -am 'Add some feature'`)
32
157
  4. Push to the branch (`git push origin my-new-feature`)
33
158
  5. Create new Pull Request
159
+
160
+ [SS]: https://github.com/lbriais/super_stack "Super Stack gem"
161
+ [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"
162
+ [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"
163
+ [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"
164
+ [YAML]: http://www.yaml.org/ "The Yaml official site"
165
+ [Slop]: https://rubygems.org/gems/slop "The Slop gem"
@@ -14,7 +14,11 @@ module StackedConfig
14
14
  slop_definition.parse
15
15
  slop_definition.banner = build_banner
16
16
  clear
17
- merge! slop_definition.to_hash
17
+ merge! slop_definition.to_hash.delete_if {|k,v| v.nil?}
18
+ end
19
+
20
+ def possible_options
21
+ slop_definition.to_hash.keys.sort
18
22
  end
19
23
 
20
24
  def reload
@@ -5,10 +5,7 @@ module StackedConfig
5
5
 
6
6
  include StackedConfig::SourceHelper
7
7
 
8
- attr_reader :orchestrator
9
-
10
8
  def rescan
11
-
12
9
  set_config_file possible_sources
13
10
  end
14
11
 
@@ -10,14 +10,42 @@ module StackedConfig
10
10
  super
11
11
  self.merge_policy = SuperStack::MergePolicies::FullMergePolicy
12
12
  setup_layers
13
- default_name = File.basename($PROGRAM_NAME)
13
+ default_name = self.class.default_executable_name
14
14
  describes_application executable_name: default_name, app_name: default_name
15
15
  end
16
16
 
17
+ def detailed_layers_info
18
+ info, sep = [], '-' * 80
19
+ info << sep
20
+ layers.values.sort {|a, b| a.priority <=> b.priority}.each do |layer|
21
+ info << layer.name
22
+ if layer.file_name.nil?
23
+ info << 'There is no file attached to this level.'
24
+ else
25
+ info << "Using '#{layer.file_name}' as config file for this layer."
26
+ end
27
+ if layer.empty?
28
+ info << 'There is no data in this layer'
29
+ else
30
+ info << 'This layer contains the following data:'
31
+ info << layer.to_yaml
32
+ end
33
+ info << sep
34
+ end
35
+ info.join "\n"
36
+ end
37
+
38
+ def command_line_help
39
+ command_line_layer.help
40
+ end
41
+
42
+ def self.default_executable_name
43
+ File.basename($PROGRAM_NAME).gsub /\.[^\.]+$/, ''
44
+ end
45
+
17
46
  private
18
47
 
19
48
  def setup_layers
20
-
21
49
  # The command line level.
22
50
  @command_line_layer = setup_layer StackedConfig::Layers::CommandLineLayer, 'Command line configuration level', 100
23
51
 
@@ -77,7 +77,7 @@ module StackedConfig
77
77
  res.gsub! '##SYSTEM_CONFIG_ROOT##', system_config_root
78
78
  res.gsub! '##USER_CONFIG_ROOT##', user_config_root
79
79
 
80
- exec_name = manager.nil? ? File.basename($PROGRAM_NAME) : manager.executable_name
80
+ exec_name = manager.nil? ? StackedConfig::Orchestrator.default_executable_name : manager.executable_name
81
81
  res.gsub! '##PROGRAM_NAME##', exec_name
82
82
  res
83
83
  end
@@ -1,3 +1,3 @@
1
1
  module StackedConfig
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.1'
3
3
  end
@@ -4,24 +4,24 @@ require 'spec_helper'
4
4
  describe StackedConfig::Layers::CommandLineLayer do
5
5
  subject { StackedConfig::Layers::CommandLineLayer.new }
6
6
 
7
- it 'should have some default command line options defined' do
8
- expect(subject.length > 0).to be_truthy
7
+ it 'should expose an empty layer by default' do
8
+ expect(subject.length == 0).to be_truthy
9
9
  end
10
10
 
11
11
  it 'should have a "help" command line options defined' do
12
- expect(subject.keys.include? :help).to be_truthy
12
+ expect(subject.possible_options.include? :help).to be_truthy
13
13
  end
14
14
 
15
15
  it 'should have a "auto" command line options defined' do
16
- expect(subject.keys.include? :auto).to be_truthy
16
+ expect(subject.possible_options.include? :auto).to be_truthy
17
17
  end
18
18
 
19
19
  it 'should have a "simulate" command line options defined' do
20
- expect(subject.keys.include? :simulate).to be_truthy
20
+ expect(subject.possible_options.include? :simulate).to be_truthy
21
21
  end
22
22
 
23
23
  it 'should have a "verbose" command line options defined' do
24
- expect(subject.keys.include? :verbose).to be_truthy
24
+ expect(subject.possible_options.include? :verbose).to be_truthy
25
25
  end
26
26
 
27
27
 
@@ -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.4'
26
+ spec.add_dependency 'super_stack', '~> 0.2', '>= 0.2.5'
27
27
  spec.add_dependency 'slop'
28
28
 
29
29
  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.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Laurent B.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-12-24 00:00:00.000000000 Z
11
+ date: 2014-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -75,7 +75,7 @@ dependencies:
75
75
  version: '0.2'
76
76
  - - '>='
77
77
  - !ruby/object:Gem::Version
78
- version: 0.2.4
78
+ version: 0.2.5
79
79
  type: :runtime
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
@@ -85,7 +85,7 @@ dependencies:
85
85
  version: '0.2'
86
86
  - - '>='
87
87
  - !ruby/object:Gem::Version
88
- version: 0.2.4
88
+ version: 0.2.5
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: slop
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -109,6 +109,7 @@ extra_rdoc_files: []
109
109
  files:
110
110
  - .gitignore
111
111
  - .rspec
112
+ - .travis.yml
112
113
  - Gemfile
113
114
  - LICENSE.txt
114
115
  - README.md