config_templates 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5de2246c3e82a63bc34895e45b8a985ff1150745
4
+ data.tar.gz: 8282e90119c9857e119e8a0d73c3134f46a0171c
5
+ SHA512:
6
+ metadata.gz: 9b4e153ab13492fe3a75954fab318987d91ce2f23ceffddac93eabc22e2d4bf76ae1eee43052ee5188e67f0e7dcefc172843298e01fe922b405f5a8e592f1c33
7
+ data.tar.gz: d973e1a75bdf5457420d68a0c5f6448e82709c1450d4d17c52b0a4f7e2a3a027ea141113158fecf3f00f924099013838d11c0907646bd0b4441de3020a5e97cf
data/lib/autoload.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'yaml'
2
+ require 'fileutils'
3
+
4
+ module ConfigTemplates
5
+ module Contexts; end
6
+ module Criteria; end
7
+ module Engines; end
8
+ module Models; end
9
+ module Outputs; end
10
+ module Repositories; end
11
+ module Validators; end
12
+ end
13
+
14
+ Dir[File.join(File.dirname(__FILE__), 'config_templates', '**', '*.rb')].each { |path| require path }
@@ -0,0 +1,38 @@
1
+ module ConfigTemplates
2
+ class Config
3
+ attr_accessor :templates_path, :destination_path
4
+ attr_accessor :settings_path, :settings_file_basename
5
+ attr_accessor :stage, :stages
6
+
7
+ def initialize
8
+ @stages = []
9
+ @outputs = ::ConfigTemplates::Repositories::Outputs.new
10
+ @engines = ::ConfigTemplates::Repositories::Engines.new
11
+ @validators = ::ConfigTemplates::Repositories::Validators.new
12
+ end
13
+
14
+ def output(name)
15
+ @outputs.find_by_name name
16
+ end
17
+
18
+ def outputs(outputs)
19
+ @outputs.add outputs
20
+ end
21
+
22
+ def engine(extension)
23
+ @engines.find_by_extension extension
24
+ end
25
+
26
+ def engines(engines)
27
+ @engines.add engines
28
+ end
29
+
30
+ def validator(file_name)
31
+ @validators.find_by_file_name file_name
32
+ end
33
+
34
+ def validators(validators)
35
+ @validators.add validators
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ module ConfigTemplates::Contexts
2
+ class Compilation
3
+ def initialize
4
+ @templates = ::ConfigTemplates::Repositories::Templates.new
5
+ @settings = ::ConfigTemplates::Repositories::Settings.new
6
+ @criteria = ::ConfigTemplates::Criteria::Composite.new
7
+ end
8
+
9
+ def criteria(criteria)
10
+ @criteria = ::ConfigTemplates::Criteria::Composite.new @criteria, criteria
11
+ end
12
+
13
+ def renderers
14
+ @templates.find_all_by(@criteria).map do |template|
15
+ ::ConfigTemplates::Models::Renderer.new template, renderer_context
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def renderer_context
22
+ ::ConfigTemplates::Contexts::Renderer.new @settings
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ module ConfigTemplates::Contexts
2
+ class Renderer
3
+ def initialize(settings)
4
+ @settings = settings
5
+ @config = ::ConfigTemplates.config
6
+ end
7
+
8
+ def param(path, default = nil)
9
+ path.split('.').inject(@settings.find_all) { |value, current| value[current] }
10
+ rescue
11
+ default
12
+ end
13
+
14
+ def method_missing(method_name)
15
+ stage_request = method_name[-1] == '?'
16
+ stage = method_name[0..-2] if stage_request
17
+ stage.nil? ? super : stage?(stage)
18
+ end
19
+
20
+ def respond_to_missing?(method_name)
21
+ method_name[-1] == '?' || super
22
+ end
23
+
24
+ private
25
+
26
+ def stage?(stage)
27
+ if @config.stages.include?(stage.to_sym)
28
+ @config.stage == stage.to_sym
29
+ else
30
+ raise ::ConfigTemplates::Errors::StageNotFound, stage
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ module ConfigTemplates::Criteria
2
+ class Composite
3
+ def initialize(*criteria)
4
+ @criteria = criteria
5
+ end
6
+
7
+ def matches?(target)
8
+ @criteria.inject(true) do |result, criteria|
9
+ result && criteria.matches?(target)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,12 @@
1
+ module ConfigTemplates::Criteria
2
+ class Name
3
+ def initialize(pattern, override = true)
4
+ @pattern = pattern
5
+ @override = override
6
+ end
7
+
8
+ def matches?(target)
9
+ @pattern.match?(target) && @override
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module ConfigTemplates::Engines
2
+ class ERB
3
+ def evaluate(template, context)
4
+ ::ERB.new(template).result(context.instance_eval { binding })
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module ConfigTemplates::Engines
2
+ class Text
3
+ def evaluate(template, _)
4
+ template
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ module ConfigTemplates::Errors
2
+ class EngineNotFound < RuntimeError; end
3
+ class StageNotFound < RuntimeError; end
4
+ class InvalidTemplate < RuntimeError; end
5
+ end
@@ -0,0 +1,18 @@
1
+ module ConfigTemplates
2
+ class FileLocator
3
+ def initialize
4
+ @config = ::ConfigTemplates.config
5
+ end
6
+
7
+ def templates
8
+ ::Dir[::File.join(@config.templates_path, '**', '*')].lazy.select { |path| ::File.file? path }
9
+ end
10
+
11
+ def settings
12
+ ::Dir[
13
+ ::File.join(@config.settings_path, "#{@config.settings_file_basename}.yml"),
14
+ ::File.join(@config.settings_path, "#{@config.settings_file_basename}.#{@config.stage}.yml")
15
+ ]
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,26 @@
1
+ module ConfigTemplates::Models
2
+ class Compilation
3
+ def initialize
4
+ @config = ::ConfigTemplates.config
5
+ @context = ::ConfigTemplates::Contexts::Compilation.new
6
+ end
7
+
8
+ def select(expression)
9
+ @context.criteria ::ConfigTemplates::Criteria::Name.new expression
10
+ self
11
+ end
12
+
13
+ def reject(expression)
14
+ @context.criteria ::ConfigTemplates::Criteria::Name.new expression, false
15
+ self
16
+ end
17
+
18
+ def send_to(output_name)
19
+ @context.renderers.each do |renderer|
20
+ renderer.validate!
21
+ output = @config.output output_name
22
+ output.print renderer
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ module ConfigTemplates::Models
2
+ class Renderer
3
+ attr_reader :template
4
+
5
+ def initialize(template, context)
6
+ @template = template
7
+ @context = context
8
+ end
9
+
10
+ def validate!
11
+ @template.validator.validate! render
12
+ end
13
+
14
+ def render
15
+ @render ||= @template.engine.evaluate @template.content, @context
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,32 @@
1
+ module ConfigTemplates::Models
2
+ class Template
3
+ def initialize(path)
4
+ @path = path
5
+ @config = ::ConfigTemplates.config
6
+ end
7
+
8
+ def content
9
+ @content ||= ::File.read @path
10
+ end
11
+
12
+ def extension
13
+ ::File.extname @path
14
+ end
15
+
16
+ def destination
17
+ ::File.join(
18
+ @config.destination_path,
19
+ @config.stage.to_s,
20
+ @path.sub(@config.templates_path, '').sub(extension, '')
21
+ )
22
+ end
23
+
24
+ def validator
25
+ @config.validator @path
26
+ end
27
+
28
+ def engine
29
+ @config.engine extension
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,9 @@
1
+ module ConfigTemplates::Outputs
2
+ class Filesystem
3
+ def print(renderer)
4
+ destination = renderer.template.destination
5
+ ::FileUtils.mkdir_p ::File.dirname destination
6
+ ::File.write destination, renderer.render
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ module ConfigTemplates::Outputs
2
+ class Stdout
3
+ def print(renderer)
4
+ ::Kernel.puts renderer.render
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ module ConfigTemplates::Repositories
2
+ class Engines
3
+ def initialize
4
+ @default = ::ConfigTemplates::Engines::Text.new
5
+ @engines = { /^.*\.erb$/ => ::ConfigTemplates::Engines::ERB.new }
6
+ end
7
+
8
+ def add(engines)
9
+ @engines.merge! engines
10
+ end
11
+
12
+ def find_by_extension(extension)
13
+ find_by ::ConfigTemplates::Criteria::Name.new extension
14
+ end
15
+
16
+ def find_by(criteria)
17
+ @engines.select { |(k, _)| criteria.matches?(k) }.first.last
18
+ rescue
19
+ @default
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,19 @@
1
+ module ConfigTemplates::Repositories
2
+ class Outputs
3
+ def initialize
4
+ @default = :stdout
5
+ @outputs = {
6
+ stdout: ::ConfigTemplates::Outputs::Stdout.new,
7
+ filesystem: ::ConfigTemplates::Outputs::Filesystem.new
8
+ }
9
+ end
10
+
11
+ def add(outputs)
12
+ @outputs.merge! outputs
13
+ end
14
+
15
+ def find_by_name(name)
16
+ @outputs.fetch(name) { @outputs[@default] }
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module ConfigTemplates::Repositories
2
+ class Settings
3
+ def initialize
4
+ @locator = ::ConfigTemplates::FileLocator.new
5
+ end
6
+
7
+ def find_all
8
+ @find_all ||= @locator.settings.reduce({}) {
9
+ |result, current| result.merge ::YAML.load_file current
10
+ }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module ConfigTemplates::Repositories
2
+ class Templates
3
+ def initialize
4
+ @locator = ::ConfigTemplates::FileLocator.new
5
+ end
6
+
7
+ def find_all_by(criteria)
8
+ @locator.templates
9
+ .select { |filename| criteria.matches? filename }
10
+ .map { |filename| ::ConfigTemplates::Models::Template.new filename }
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,22 @@
1
+ module ConfigTemplates::Repositories
2
+ class Validators
3
+ def initialize
4
+ @default = ::ConfigTemplates::Validators::Composite.new
5
+ @validators = {}
6
+ end
7
+
8
+ def add(validators)
9
+ @validators.merge! validators
10
+ end
11
+
12
+ def find_by_file_name(file_name)
13
+ ::ConfigTemplates::Validators::Composite.new(
14
+ *find_all_by(::ConfigTemplates::Criteria::Name.new(file_name))
15
+ )
16
+ end
17
+
18
+ def find_all_by(criteria)
19
+ @validators.select { |(k, _)| criteria.matches?(k) }.values
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,11 @@
1
+ module ConfigTemplates::Validators
2
+ class Composite
3
+ def initialize(*validators)
4
+ @validators = validators
5
+ end
6
+
7
+ def validate!(result)
8
+ @validators.each { |validator| validator.validate! result }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module ConfigTemplates
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'autoload'
2
+
3
+ module ConfigTemplates
4
+ class << self
5
+ def configure
6
+ yield config
7
+ end
8
+
9
+ def config
10
+ @config ||= Config.new
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,2 @@
1
+ test:
2
+ value: true
@@ -0,0 +1,2 @@
1
+ test:
2
+ value: false
@@ -0,0 +1,3 @@
1
+ <% if production? %>
2
+ <%= param('test.value') %>
3
+ <% end %>
@@ -0,0 +1,11 @@
1
+ module Mocks
2
+ module Outputs
3
+ class Test
4
+ attr_accessor :result
5
+
6
+ def print(renderer)
7
+ @result = renderer.render
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,14 @@
1
+ require_relative './mocks/outputs/test'
2
+
3
+ RSpec.configure do |spec|
4
+ spec.before(:all) do
5
+ ::ConfigTemplates.configure do |config|
6
+ config.templates_path = 'spec/fixtures/src'
7
+ config.destination_path = 'spec/fixtures/dest'
8
+ config.settings_path = 'spec/fixtures/settings'
9
+ config.settings_file_basename = 'settings'
10
+ config.stage = :production
11
+ config.stages = %i[production prerel staging]
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ require 'config_templates'
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe ::ConfigTemplates do
5
+ before(:all) { @output_mock = ::Mocks::Outputs::Test.new }
6
+ before(:all) do
7
+ ::ConfigTemplates.configure { |config| config.outputs test: @output_mock }
8
+ end
9
+
10
+ before(:each) { @output_mock.result = nil }
11
+
12
+ it 'renders selected template using configs and environment metadata' do
13
+ compilation = ::ConfigTemplates::Models::Compilation.new
14
+ compilation.select(/.*/).send_to(:test)
15
+ expect(@output_mock.result.strip).to eq('true')
16
+ end
17
+
18
+ it 'doesnt render not selected template' do
19
+ compilation = ::ConfigTemplates::Models::Compilation.new
20
+ compilation.reject(/.*/).send_to(:test)
21
+ expect(@output_mock.result).to be_nil
22
+ end
23
+
24
+ it 'renders without explicitly selected templates' do
25
+ compilation = ::ConfigTemplates::Models::Compilation.new
26
+ compilation.send_to(:test)
27
+ expect(@output_mock.result.strip).to eq('true')
28
+ end
29
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: config_templates
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - g.ivanov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-29 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: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
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: :runtime
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: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec_junit_formatter
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: config_templates
70
+ email:
71
+ - g.ivanov@fun-box.ru
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - lib/autoload.rb
77
+ - lib/config_templates.rb
78
+ - lib/config_templates/config.rb
79
+ - lib/config_templates/contexts/compilation.rb
80
+ - lib/config_templates/contexts/renderer.rb
81
+ - lib/config_templates/criteria/composite.rb
82
+ - lib/config_templates/criteria/name.rb
83
+ - lib/config_templates/engines/erb.rb
84
+ - lib/config_templates/engines/text.rb
85
+ - lib/config_templates/errors.rb
86
+ - lib/config_templates/file_locator.rb
87
+ - lib/config_templates/models/compilation.rb
88
+ - lib/config_templates/models/renderer.rb
89
+ - lib/config_templates/models/template.rb
90
+ - lib/config_templates/outputs/filesystem.rb
91
+ - lib/config_templates/outputs/stdout.rb
92
+ - lib/config_templates/repositories/engines.rb
93
+ - lib/config_templates/repositories/outputs.rb
94
+ - lib/config_templates/repositories/settings.rb
95
+ - lib/config_templates/repositories/templates.rb
96
+ - lib/config_templates/repositories/validators.rb
97
+ - lib/config_templates/validators/composite.rb
98
+ - lib/config_templates/version.rb
99
+ - spec/fixtures/settings/settings.production.yml
100
+ - spec/fixtures/settings/settings.yml
101
+ - spec/fixtures/src/kapacitor/config.erb
102
+ - spec/mocks/outputs/test.rb
103
+ - spec/spec_helper.rb
104
+ - spec/templates_spec.rb
105
+ homepage:
106
+ licenses: []
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.6.13
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: config_templates
128
+ test_files:
129
+ - spec/fixtures/src/kapacitor/config.erb
130
+ - spec/fixtures/settings/settings.yml
131
+ - spec/fixtures/settings/settings.production.yml
132
+ - spec/mocks/outputs/test.rb
133
+ - spec/templates_spec.rb
134
+ - spec/spec_helper.rb