filegen 0.0.1 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rdebugrc +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +10 -0
- data/.simplecov +9 -0
- data/.travis.yml +7 -0
- data/.yardopts +6 -0
- data/Gemfile +30 -0
- data/{LICENSE.txt → LICENSE.md} +1 -1
- data/README.DEVELOPER.md +28 -0
- data/README.md +106 -7
- data/Rakefile +60 -1
- data/bin/filegen +1 -1
- data/config/rubocop-disabled.yml +0 -0
- data/config/rubocop-enabled.yml +140 -0
- data/cucumber.yml +2 -0
- data/features/evaluate_template.feature +134 -0
- data/features/output_meta_data.feature +20 -0
- data/features/step_definitions.rb +9 -0
- data/features/support/env.rb +20 -0
- data/filegen.gemspec +8 -9
- data/lib/filegen.rb +11 -1
- data/lib/filegen/data.rb +48 -0
- data/lib/filegen/data_source_builder.rb +49 -0
- data/lib/filegen/data_sources.rb +5 -0
- data/lib/filegen/data_sources/environment.rb +21 -0
- data/lib/filegen/data_sources/yaml.rb +18 -0
- data/lib/filegen/erb_generator.rb +21 -6
- data/lib/filegen/exceptions.rb +8 -0
- data/lib/filegen/options.rb +77 -6
- data/lib/filegen/runner.rb +29 -9
- data/lib/filegen/version.rb +2 -1
- data/rubocop-todo.yml +144 -0
- data/scripts/terminal +12 -0
- data/spec/data_source_builder_spec.rb +53 -0
- data/spec/data_sources/environment_spec.rb +20 -0
- data/spec/data_sources/yaml_spec.rb +31 -0
- data/spec/data_spec.rb +60 -0
- data/spec/erb_generator_spec.rb +31 -0
- data/spec/options_spec.rb +32 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/config.rb +6 -0
- data/spec/support/debugging.rb +5 -0
- data/spec/support/environment.rb +7 -0
- data/spec/support/filesystem.rb +11 -0
- data/spec/support/here_doc.rb +2 -0
- metadata +58 -25
- data/lib/filegen/env.rb +0 -14
data/cucumber.yml
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
Feature: Evaluate Template
|
2
|
+
|
3
|
+
As a user
|
4
|
+
I want to evaluate a template
|
5
|
+
In order to generate a file
|
6
|
+
|
7
|
+
Scenario: Existing file
|
8
|
+
Given a file named "template.erb" with:
|
9
|
+
"""
|
10
|
+
Hello World!
|
11
|
+
"""
|
12
|
+
When I successfully run `filegen template.erb`
|
13
|
+
Then the output should contain:
|
14
|
+
"""
|
15
|
+
Hello World!
|
16
|
+
"""
|
17
|
+
|
18
|
+
Scenario: Uses env variables in template
|
19
|
+
Given a file named "template.erb" with:
|
20
|
+
"""
|
21
|
+
Hello <%= lookup('NAME') %>!
|
22
|
+
"""
|
23
|
+
And I set the environment variables to:
|
24
|
+
| variable | value |
|
25
|
+
| NAME | Karl |
|
26
|
+
When I successfully run `filegen template.erb`
|
27
|
+
Then the output should contain:
|
28
|
+
"""
|
29
|
+
Hello Karl
|
30
|
+
"""
|
31
|
+
|
32
|
+
Scenario: Non existing file
|
33
|
+
When I run `filegen template1.erb`
|
34
|
+
Then the stderr should contain:
|
35
|
+
"""
|
36
|
+
File "template1.erb" does not exist
|
37
|
+
"""
|
38
|
+
|
39
|
+
Scenario: Non erb file
|
40
|
+
Given an empty file named "template1.abc"
|
41
|
+
When I run `filegen template1.abc`
|
42
|
+
Then the stderr should contain:
|
43
|
+
"""
|
44
|
+
File "template1.abc" is not a valid erb template: file ending erb
|
45
|
+
"""
|
46
|
+
|
47
|
+
Scenario: YAML file as input (short)
|
48
|
+
Given a file named "template.erb" with:
|
49
|
+
"""
|
50
|
+
Hello <%= lookup('name') %>!
|
51
|
+
"""
|
52
|
+
And a file named "input.yaml" with:
|
53
|
+
"""
|
54
|
+
---
|
55
|
+
name: Karl
|
56
|
+
"""
|
57
|
+
When I run `filegen -y input.yaml template.erb`
|
58
|
+
Then the output should contain:
|
59
|
+
"""
|
60
|
+
Hello Karl!
|
61
|
+
"""
|
62
|
+
|
63
|
+
Scenario: YAML file as input (long)
|
64
|
+
Given a file named "template.erb" with:
|
65
|
+
"""
|
66
|
+
Hello <%= lookup('name') %>!
|
67
|
+
"""
|
68
|
+
And a file named "input.yaml" with:
|
69
|
+
"""
|
70
|
+
---
|
71
|
+
name: Karl
|
72
|
+
"""
|
73
|
+
When I run `filegen --yaml-file input.yaml template.erb`
|
74
|
+
Then the output should contain:
|
75
|
+
"""
|
76
|
+
Hello Karl!
|
77
|
+
"""
|
78
|
+
|
79
|
+
Scenario: Define order of data sources for lookup (env first)
|
80
|
+
Given a file named "template.erb" with:
|
81
|
+
"""
|
82
|
+
Hello <%= lookup('NAME') %>!
|
83
|
+
"""
|
84
|
+
And a file named "input.yaml" with:
|
85
|
+
"""
|
86
|
+
---
|
87
|
+
NAME: Karl
|
88
|
+
"""
|
89
|
+
And I set the environment variables to:
|
90
|
+
| variable | value |
|
91
|
+
| NAME | Egon |
|
92
|
+
When I run `filegen --yaml-file input.yaml --data-sources env,yaml template.erb`
|
93
|
+
Then the output should contain:
|
94
|
+
"""
|
95
|
+
Hello Egon!
|
96
|
+
"""
|
97
|
+
|
98
|
+
Scenario: Define order of data sources for lookup (yaml first)
|
99
|
+
Given a file named "template.erb" with:
|
100
|
+
"""
|
101
|
+
Hello <%= lookup('NAME') %>!
|
102
|
+
"""
|
103
|
+
And a file named "input.yaml" with:
|
104
|
+
"""
|
105
|
+
---
|
106
|
+
NAME: Karl
|
107
|
+
"""
|
108
|
+
And I set the environment variables to:
|
109
|
+
| variable | value |
|
110
|
+
| NAME | Egon |
|
111
|
+
When I run `filegen --yaml-file input.yaml --data-sources yaml,env template.erb`
|
112
|
+
Then the output should contain:
|
113
|
+
"""
|
114
|
+
Hello Karl!
|
115
|
+
"""
|
116
|
+
|
117
|
+
Scenario: Leaving out a data source
|
118
|
+
Given a file named "template.erb" with:
|
119
|
+
"""
|
120
|
+
Hello <%= lookup('NAME') %>!
|
121
|
+
"""
|
122
|
+
And a file named "input.yaml" with:
|
123
|
+
"""
|
124
|
+
---
|
125
|
+
NAME: Karl
|
126
|
+
"""
|
127
|
+
And I set the environment variables to:
|
128
|
+
| variable | value |
|
129
|
+
| NAME | Egon |
|
130
|
+
When I run `filegen --yaml-file input.yaml --data-sources yaml template.erb`
|
131
|
+
Then the output should contain:
|
132
|
+
"""
|
133
|
+
Hello Karl!
|
134
|
+
"""
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: Output metadata
|
2
|
+
|
3
|
+
As a user
|
4
|
+
I want to get some meta data about the script
|
5
|
+
In order to use it better
|
6
|
+
|
7
|
+
# Scenario: Version (short)
|
8
|
+
# Given I successfully run `filegen -v`
|
9
|
+
# Then the output should contain:
|
10
|
+
# """
|
11
|
+
# Version:
|
12
|
+
# """
|
13
|
+
#
|
14
|
+
# Scenario: Version (long)
|
15
|
+
# Given I successfully run `filegen --version`
|
16
|
+
# Then the output should contain:
|
17
|
+
# """
|
18
|
+
# Version:
|
19
|
+
# """
|
20
|
+
#
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
Then /then environment contains the following variables/ do
|
3
|
+
$stderr.printf("%20s | %-20s\n", 'key', 'value')
|
4
|
+
$stderr.printf("%20s+%-20s\n", '-' * 21 , '-' * 21)
|
5
|
+
|
6
|
+
ENV.to_hash.sort_by { |key, value| key }.each do |key, value|
|
7
|
+
$stderr.printf("%20s | %-20s\n", key, value)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
$LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
|
3
|
+
|
4
|
+
unless ENV['CI'] == 'true'
|
5
|
+
require 'debugger'
|
6
|
+
require 'pry'
|
7
|
+
end
|
8
|
+
|
9
|
+
require 'simplecov'
|
10
|
+
SimpleCov.command_name 'cucumber'
|
11
|
+
|
12
|
+
require 'filegen'
|
13
|
+
include Filegen
|
14
|
+
|
15
|
+
require 'aruba'
|
16
|
+
require 'aruba/in_process'
|
17
|
+
require 'aruba/cucumber'
|
18
|
+
|
19
|
+
Aruba::InProcess.main_class = Filegen::Runner
|
20
|
+
Aruba.process = Aruba::InProcess
|
data/filegen.gemspec
CHANGED
@@ -4,20 +4,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'filegen/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'filegen'
|
8
8
|
spec.version = Filegen::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
9
|
+
spec.authors = ['Dennis Günnewig']
|
10
|
+
spec.email = ['dg1@vrnetze.de']
|
11
11
|
spec.description = %q{Evaluate erb templates}
|
12
|
-
spec.summary = %q{This helper takes an erb template and provides access to environment variables within that template}
|
13
|
-
spec.homepage =
|
14
|
-
spec.license =
|
12
|
+
spec.summary = %q{This helper takes an erb template and provides access to environment variables and a yaml file within that template}
|
13
|
+
spec.homepage = 'https://github.com/dg-vrnetze/filegen'
|
14
|
+
spec.license = 'MIT'
|
15
15
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = [
|
19
|
+
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.
|
22
|
-
spec.add_development_dependency "rake"
|
21
|
+
spec.add_runtime_dependency 'moneta'
|
23
22
|
end
|
data/lib/filegen.rb
CHANGED
@@ -1,9 +1,19 @@
|
|
1
|
+
# encoding: utf-8
|
1
2
|
require 'erb'
|
3
|
+
require 'moneta'
|
4
|
+
require 'optparse'
|
5
|
+
require 'forwardable'
|
6
|
+
require 'ostruct'
|
2
7
|
|
3
8
|
require 'filegen/version'
|
4
9
|
require 'filegen/runner'
|
5
10
|
require 'filegen/options'
|
6
|
-
require 'filegen/
|
11
|
+
require 'filegen/data'
|
7
12
|
require 'filegen/erb_generator'
|
13
|
+
require 'filegen/data_source_builder'
|
14
|
+
require 'filegen/data_sources/environment'
|
15
|
+
require 'filegen/data_sources/yaml'
|
16
|
+
require 'filegen/exceptions'
|
8
17
|
|
18
|
+
# Main class
|
9
19
|
module Filegen; end
|
data/lib/filegen/data.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# Main Class
|
3
|
+
module Filegen
|
4
|
+
# This class is used as context for the erb-template
|
5
|
+
class Data
|
6
|
+
private
|
7
|
+
|
8
|
+
attr_reader :data_sources
|
9
|
+
|
10
|
+
public
|
11
|
+
|
12
|
+
# Create context class
|
13
|
+
#
|
14
|
+
# @param [Array,DataSource] data_sources
|
15
|
+
# The data sources which should be available for variable lookup
|
16
|
+
def initialize(data_sources)
|
17
|
+
@data_sources = Array(data_sources)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Lookup a variable within the data sources
|
21
|
+
#
|
22
|
+
# @param [String] variable
|
23
|
+
# The variable to lookup
|
24
|
+
# @return [String]
|
25
|
+
# The value of the variable
|
26
|
+
def lookup(variable)
|
27
|
+
try_to_fetch_unless_found_or_end(variable)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Make the binding of the class available
|
31
|
+
# @return [Binding]
|
32
|
+
def instance_binding
|
33
|
+
binding
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def try_to_fetch_unless_found_or_end(variable)
|
39
|
+
result = nil
|
40
|
+
|
41
|
+
data_sources.each do |s|
|
42
|
+
(result = s.fetch(variable)) && (return result)
|
43
|
+
end
|
44
|
+
|
45
|
+
''
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Filegen
|
3
|
+
# Build data sources
|
4
|
+
class DataSourceBuilder
|
5
|
+
private
|
6
|
+
|
7
|
+
attr_reader :params
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
# @!attribute [r] sources
|
12
|
+
# Return the sources generated
|
13
|
+
attr_reader :sources
|
14
|
+
|
15
|
+
# Create the data source builder
|
16
|
+
#
|
17
|
+
# @param [OpenStruct] params
|
18
|
+
# the params instance which contains all parameter of the commandline utility
|
19
|
+
def initialize(params)
|
20
|
+
@params = params
|
21
|
+
|
22
|
+
validate_data_sources
|
23
|
+
|
24
|
+
@sources = []
|
25
|
+
chosen_data_sources.each do |o|
|
26
|
+
@sources << known_data_source_builders[o]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def chosen_data_sources
|
33
|
+
params.data_sources
|
34
|
+
end
|
35
|
+
|
36
|
+
def known_data_source_builders
|
37
|
+
params.data_source_builders
|
38
|
+
end
|
39
|
+
|
40
|
+
def allowed_data_sources
|
41
|
+
known_data_source_builders.keys
|
42
|
+
end
|
43
|
+
|
44
|
+
def validate_data_sources
|
45
|
+
invalid_data_sources = chosen_data_sources - allowed_data_sources
|
46
|
+
fail Exceptions::InvalidDataSources, "Unknown data source#{invalid_data_sources.size > 1 ? 's' : ''} \"#{invalid_data_sources.join(', ')}\" found." unless invalid_data_sources.empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Filegen
|
3
|
+
module DataSources
|
4
|
+
# Data source which makes environment variables available
|
5
|
+
class Environment
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
# @!method fetch(key, default_value=nil)
|
9
|
+
# Fetch value for key from data source
|
10
|
+
def_delegator :@source, :fetch, :fetch
|
11
|
+
|
12
|
+
# Create data source
|
13
|
+
def initialize
|
14
|
+
@source = Moneta.build do
|
15
|
+
use :Transformer, key: :to_s, value: []
|
16
|
+
adapter :Memory, backend: ENV
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Filegen
|
3
|
+
module DataSources
|
4
|
+
# Data source which makes yaml files available
|
5
|
+
class Yaml
|
6
|
+
extend Forwardable
|
7
|
+
|
8
|
+
# @!method fetch(key, default_value=nil)
|
9
|
+
# Fetch value for key from data source.
|
10
|
+
def_delegator :@source, :fetch, :fetch
|
11
|
+
|
12
|
+
# Create data source
|
13
|
+
def initialize(file)
|
14
|
+
@source = Moneta.new(:YAML, file: file)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -1,15 +1,30 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Filegen
|
3
|
+
# Used to generate the template
|
3
4
|
class ErbGenerator
|
4
|
-
|
5
|
+
private
|
5
6
|
|
6
|
-
|
7
|
-
|
7
|
+
attr_reader :data
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
# Create erb generator
|
12
|
+
#
|
13
|
+
# @param [Data] data
|
14
|
+
# The data class to be used within the template
|
15
|
+
def initialize(data)
|
16
|
+
@data = data
|
8
17
|
end
|
9
18
|
|
10
|
-
|
11
|
-
|
19
|
+
# Compile the template
|
20
|
+
#
|
21
|
+
# @param [IO] source
|
22
|
+
# The source template to be used
|
23
|
+
# @param [IO] destination
|
24
|
+
# The output io handle
|
25
|
+
def compile(source, destination)
|
26
|
+
erb = ERB.new(source.read)
|
27
|
+
destination.puts erb.result(data.instance_binding)
|
12
28
|
end
|
13
29
|
end
|
14
|
-
|
15
30
|
end
|
data/lib/filegen/options.rb
CHANGED
@@ -1,24 +1,95 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
module Filegen
|
3
|
+
# Commandline parser
|
3
4
|
class Options
|
4
|
-
|
5
|
+
private
|
5
6
|
|
7
|
+
attr_reader :params
|
8
|
+
|
9
|
+
public
|
10
|
+
|
11
|
+
# Create commandline parser
|
12
|
+
#
|
13
|
+
# @param [Array] argv
|
14
|
+
# The array which contains the commandline arguments
|
6
15
|
def initialize(argv)
|
7
|
-
@
|
16
|
+
@params = parse_options(argv)
|
8
17
|
end
|
9
18
|
|
19
|
+
# Source template
|
20
|
+
#
|
21
|
+
# @return [File]
|
22
|
+
# Returns a file handle for the template
|
10
23
|
def source
|
11
|
-
|
24
|
+
validate_source
|
12
25
|
|
13
|
-
|
26
|
+
File.new(params.template)
|
14
27
|
end
|
15
28
|
|
29
|
+
# Destination for output
|
30
|
+
#
|
31
|
+
# @return [IO]
|
32
|
+
# Returns a file handle for the output
|
16
33
|
def destination
|
17
34
|
$stdout
|
18
35
|
end
|
19
36
|
|
20
|
-
|
21
|
-
|
37
|
+
# The data sources which can be used
|
38
|
+
#
|
39
|
+
# @return [Array]
|
40
|
+
# An array of data sources which can be used
|
41
|
+
def data_sources
|
42
|
+
DataSourceBuilder.new(params).sources
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def parse_options(argv)
|
48
|
+
params = OpenStruct.new
|
49
|
+
parser = OptionParser.new
|
50
|
+
|
51
|
+
params.data_sources = [:env]
|
52
|
+
params.data_source_builders = {}
|
53
|
+
params.data_source_builders[:env] = DataSources::Environment.new
|
54
|
+
|
55
|
+
parser.on('-y', '--yaml-file FILE', 'YAML-file to look for variables') do |f|
|
56
|
+
params.yaml_file = f
|
57
|
+
params.data_sources << :yaml
|
58
|
+
params.data_source_builders[:yaml] = DataSources::Yaml.new(params.yaml_file)
|
59
|
+
end
|
60
|
+
|
61
|
+
parser.on('-d', '--data-sources a,b', Array, 'Order for variable lookup: yaml, env (default: env or env,yaml if yaml-file-option is given)') do |l|
|
62
|
+
params.data_sources = l.map(&:to_sym)
|
63
|
+
end
|
64
|
+
|
65
|
+
parser.on_tail('-h', '--help', 'Show this message') do
|
66
|
+
$stderr.puts parser
|
67
|
+
exit
|
68
|
+
end
|
69
|
+
|
70
|
+
parser.on_tail('-v', '--version', 'Show version') do
|
71
|
+
$stderr.puts Filegen::VERSION
|
72
|
+
exit
|
73
|
+
end
|
74
|
+
|
75
|
+
params.template = parser.parse(argv).first
|
76
|
+
|
77
|
+
params
|
78
|
+
end
|
79
|
+
|
80
|
+
def validate_source
|
81
|
+
fail "File \"#{params.template}\" does not exist" unless exists?
|
82
|
+
fail "File \"#{params.template}\" is not a valid erb template: file ending erb" unless erb_template?
|
83
|
+
end
|
84
|
+
|
85
|
+
def exists?
|
86
|
+
File.exists?(params.template)
|
87
|
+
end
|
88
|
+
|
89
|
+
def erb_template?
|
90
|
+
# rubocop:disable CaseEquality
|
91
|
+
/.erb$/ === File.basename(params.template)
|
92
|
+
# rubocop:enable CaseEquality
|
22
93
|
end
|
23
94
|
end
|
24
95
|
end
|