stacked_config 0.1.0 → 0.1.1

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: 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