configulator 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0be977b2ac66bdc4eff6e156fc0b79d4f58a6f39
4
+ data.tar.gz: 666cb63c44ab7c9f7361ad415b68e751fe0fef83
5
+ SHA512:
6
+ metadata.gz: 633253c21f194e83c9e3163ac120ca75cce1ef39689693c0404e4ae64253631bb96fa29d8e60bf820b8a93b739ba86c97e522dd224a999b3f2e8a54aede2d194
7
+ data.tar.gz: 5b79fc953a1535c89bab8c616c5d968e5035c3dc8df97765eafb83cd3ef8081ff56ca367521d2c94cf0329862295ebc87452ae82f7d7c53e670fb7d1653c98a6
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ .ruby-gemset
2
+ .ruby-version
3
+ docs
4
+ *.gem
5
+ *.rbc
6
+ .bundle
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in configulator.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Brian Muller
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # Configulator : Generate Config Files
2
+
3
+ Configurator allows you to maintain a single file with configuration values that can be used to generate other config files based on templates.
4
+
5
+ For instance, if you need to generate all of the config files for a Hadoop cluster and the files vary in type (xml, json, yaml, etc) but all rely on the same few configuration values, you can use configulator to generate those files.
6
+
7
+ Configulator is a tool that takes a single master input config file and some number of template files as input and then outputs the template files with the correct configuration values substituted. Additionally, there is a way of specifying default values, and then configulator will override on the necessary ones per environment.
8
+
9
+ See [this blog post](http://findingscience.com/linux/sysadmin/ruby/2010/10/27/config-template-class.html) for the background on why this can be useful.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ gem 'configulator'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install configulator
24
+
25
+ ## Usage
26
+
27
+ Configulator can accept a master config file either in json or yaml. Here's an example config file:
28
+
29
+ mysql_host: 127.0.0.1
30
+ mysql_port: 5678
31
+ db_host: <%= mysql_host %>
32
+ db_port: <%= mysql_port %>
33
+ current_time: <%= Time.now %>
34
+
35
+ It specifies a mysql host and port, as well as a general db host and port that will simply use the values for mysql. Then, given an example config file that's nasty and written in XML:
36
+
37
+ <xml><config><host><%= db_host %></host></config></xml>
38
+
39
+ We can now convert the above file into one with db_host filled in either using code or the configulator command. Here's what the code looks like (assuming our master config is master.yml and our xml is xmlisbad.xml.tmpl):
40
+
41
+ require 'configulator'
42
+ converted = Configulator.from_yaml_file('master.yml').convert_file('xmlisbad.xml')
43
+ File.write 'xmlisbad.xml', converted
44
+
45
+ You can also access specific variables in the ruby code:
46
+
47
+ puts converted.db_host # => 127.0.0.1
48
+
49
+ Using the configulator command instead looks like this:
50
+
51
+ configulator master.yml xmlisbad.xml.tmpl > xmlisbad.xml
52
+
53
+ ## Environments
54
+
55
+ You have the option of setting default values in your master config file and then separate environment sections beneath that. For instance, here's a yaml config file with default values for some keys:
56
+
57
+ default:
58
+ debug: INFO
59
+ db_host: <%= mysql_host %>
60
+ db_port: <%= mysql_port %>
61
+ production:
62
+ mysql_host: 1.2.3.4
63
+ mysql_port: 5678
64
+ development:
65
+ mysql_host: 127.0.0.1
66
+ mysql_port: 5678
67
+
68
+ We can spit out the production values like this (just passing in an extra argument to from_yaml_file):
69
+
70
+ require 'configulator'
71
+ converted = Configulator.from_yaml_file('master.yml', 'production').convert_file('xmlisbad.xml')
72
+ File.write 'xmlisbad.xml', converted
73
+
74
+ When db_host is used in the xml file, configulator will look for it first in the production section and then in the default (where it is found, then repeats process for mysql_host).
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rdoc/task'
3
+ require 'rake/testtask'
4
+
5
+ task :default => [:test]
6
+
7
+ RDoc::Task.new("doc") { |rdoc|
8
+ rdoc.title = "Configulator - Generate config files"
9
+ rdoc.rdoc_dir = 'docs'
10
+ rdoc.rdoc_files.include('README.md')
11
+ rdoc.rdoc_files.include('lib/**/*.rb')
12
+ }
13
+
14
+ desc "Run all unit tests"
15
+ Rake::TestTask.new("test") { |t|
16
+ t.libs << "lib"
17
+ t.test_files = FileList['test/*.rb']
18
+ }
data/bin/configulator ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ begin
4
+ require 'configulator'
5
+ rescue LoadError
6
+ require 'rubygems'
7
+ require 'configulator'
8
+ end
9
+
10
+ if ARGV.length < 2
11
+ puts "Usage: configulator <master config file> <template file> [<environment>]"
12
+ exit 1
13
+ end
14
+
15
+ if ARGV[0].end_with? '.yml' or ARGV[0].end_with? '.yaml'
16
+ conf = Configulator.from_yaml_file(ARGV[0], ARGV[2])
17
+ else
18
+ conf = Configulator.from_json_file(ARGV[0], ARGV[2])
19
+ end
20
+
21
+ puts conf.convert_file ARGV[1]
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'configulator/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "configulator"
8
+ spec.version = Configulator::VERSION
9
+ spec.authors = ["Brian Muller"]
10
+ spec.email = ["bamuller@gmail.com"]
11
+ spec.summary = %q{Generate config files from a template}
12
+ spec.description = %q{Configurator allows you to maintain a single file with configuration values that can be used to generate other config files based on templates.}
13
+ spec.homepage = "https://github.com/bmuller/configulator"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rdoc"
24
+ end
@@ -0,0 +1,20 @@
1
+ require "configulator/version"
2
+ require "configulator/config_template"
3
+
4
+ module Configulator
5
+ def self.from_json(conf, environment = nil)
6
+ JSONConfigTemplate.new conf, environment
7
+ end
8
+
9
+ def self.from_json_file(fname, environment = nil)
10
+ from_json File.read(fname), environment
11
+ end
12
+
13
+ def self.from_yaml(fname, environment = nil)
14
+ YAMLConfigTemplate.new fname, environment
15
+ end
16
+
17
+ def self.from_yaml_file(fname, environment = nil)
18
+ from_yaml File.read(fname), environment
19
+ end
20
+ end
@@ -0,0 +1,63 @@
1
+ require 'yaml'
2
+ require 'json'
3
+ require 'erb'
4
+
5
+ module Configulator
6
+ class ConfStruct < Struct
7
+ def get_binding
8
+ binding
9
+ end
10
+ end
11
+
12
+ class ConfigTemplate
13
+ def initialize(conf, environment = nil)
14
+ if environment.nil?
15
+ @binding = make_binding conf
16
+ else
17
+ raise "No such environment: #{environment}" unless conf.has_key? environment
18
+ env = conf[environment]
19
+ env = conf['default'].merge(env) if conf.has_key? 'default'
20
+ env['environment_name'] = environment
21
+ @binding = make_binding env
22
+ end
23
+ end
24
+
25
+ def convert_file(infile)
26
+ ERB.new(File.read(infile)).result(@binding)
27
+ end
28
+
29
+ def get(name)
30
+ eval name.to_s, @binding
31
+ end
32
+
33
+ def method_missing(name, *args, &block)
34
+ get name
35
+ end
36
+
37
+ private
38
+ def make_binding(env)
39
+ klass = ConfStruct.new *env.keys.map(&:intern)
40
+ k = klass.new *env.values
41
+ # support up to 5 levels of embedding
42
+ 5.times do
43
+ values = env.values.map do |v|
44
+ v.is_a?(String) ? ERB.new(v).result(k.get_binding) : v
45
+ end
46
+ k = klass.new *values
47
+ end
48
+ k.get_binding
49
+ end
50
+ end
51
+
52
+ class JSONConfigTemplate < ConfigTemplate
53
+ def initialize(config, environment = nil)
54
+ super JSON.parse(config), environment
55
+ end
56
+ end
57
+
58
+ class YAMLConfigTemplate < ConfigTemplate
59
+ def initialize(config, environment = nil)
60
+ super YAML.load(config), environment
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,3 @@
1
+ module Configulator
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,77 @@
1
+ # -*- coding: utf-8 -*-
2
+ lib = File.expand_path('../../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'configulator'
5
+ require 'test/unit'
6
+
7
+ class ConfigulatorTest < Test::Unit::TestCase
8
+ def test_json_load_without_env
9
+ input = {
10
+ "one" => "something",
11
+ "two" => "<%= one %> one",
12
+ "three" => "<%= two %> two"
13
+ }
14
+ c = Configulator.from_json(JSON.dump(input))
15
+ assert_equal c.one, "something"
16
+ assert_equal c.two, "something one"
17
+ assert_equal c.three, "something one two"
18
+ end
19
+
20
+ def test_json_load_with_env
21
+ input = {
22
+ "default" => {
23
+ "one" => "something",
24
+ "two" => "<%= one %> one",
25
+ "three" => "<%= two %> two"
26
+ },
27
+ "test" => {
28
+ "three" => "<%= one %> as three",
29
+ "newone" => 3
30
+ }
31
+ }
32
+ c = Configulator.from_json(JSON.dump(input), "test")
33
+ assert_equal c.one, "something"
34
+ assert_equal c.two, "something one"
35
+ assert_equal c.three, "something as three"
36
+ assert_equal c.newone, 3
37
+
38
+ assert_raise RuntimeError do
39
+ Configulator.from_json(JSON.dump(input), "testfake")
40
+ end
41
+ end
42
+
43
+ def test_yaml_load_without_env
44
+ input = {
45
+ "one" => "something",
46
+ "two" => "<%= one %> one",
47
+ "three" => "<%= two %> two"
48
+ }
49
+ c = Configulator.from_yaml(YAML.dump(input))
50
+ assert_equal c.one, "something"
51
+ assert_equal c.two, "something one"
52
+ assert_equal c.three, "something one two"
53
+ end
54
+
55
+ def test_yaml_load_with_env
56
+ input = {
57
+ "default" => {
58
+ "one" => "something",
59
+ "two" => "<%= one %> one",
60
+ "three" => "<%= two %> two"
61
+ },
62
+ "test" => {
63
+ "three" => "<%= one %> as three",
64
+ "newone" => 3
65
+ }
66
+ }
67
+ c = Configulator.from_yaml(YAML.dump(input), "test")
68
+ assert_equal c.one, "something"
69
+ assert_equal c.two, "something one"
70
+ assert_equal c.three, "something as three"
71
+ assert_equal c.newone, 3
72
+
73
+ assert_raise RuntimeError do
74
+ Configulator.from_yaml(YAML.dump(input), "testfake")
75
+ end
76
+ end
77
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: configulator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brian Muller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rdoc
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Configurator allows you to maintain a single file with configuration
56
+ values that can be used to generate other config files based on templates.
57
+ email:
58
+ - bamuller@gmail.com
59
+ executables:
60
+ - configulator
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".travis.yml"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - bin/configulator
71
+ - configulator.gemspec
72
+ - lib/configulator.rb
73
+ - lib/configulator/config_template.rb
74
+ - lib/configulator/version.rb
75
+ - test/configulator_test.rb
76
+ homepage: https://github.com/bmuller/configulator
77
+ licenses:
78
+ - MIT
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.2.2
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Generate config files from a template
100
+ test_files:
101
+ - test/configulator_test.rb