filegen 0.0.1 → 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.
Files changed (48) hide show
  1. data/.gitignore +1 -0
  2. data/.rdebugrc +7 -0
  3. data/.rspec +3 -0
  4. data/.rubocop.yml +10 -0
  5. data/.simplecov +9 -0
  6. data/.travis.yml +7 -0
  7. data/.yardopts +6 -0
  8. data/Gemfile +30 -0
  9. data/{LICENSE.txt → LICENSE.md} +1 -1
  10. data/README.DEVELOPER.md +28 -0
  11. data/README.md +106 -7
  12. data/Rakefile +60 -1
  13. data/bin/filegen +1 -1
  14. data/config/rubocop-disabled.yml +0 -0
  15. data/config/rubocop-enabled.yml +140 -0
  16. data/cucumber.yml +2 -0
  17. data/features/evaluate_template.feature +134 -0
  18. data/features/output_meta_data.feature +20 -0
  19. data/features/step_definitions.rb +9 -0
  20. data/features/support/env.rb +20 -0
  21. data/filegen.gemspec +8 -9
  22. data/lib/filegen.rb +11 -1
  23. data/lib/filegen/data.rb +48 -0
  24. data/lib/filegen/data_source_builder.rb +49 -0
  25. data/lib/filegen/data_sources.rb +5 -0
  26. data/lib/filegen/data_sources/environment.rb +21 -0
  27. data/lib/filegen/data_sources/yaml.rb +18 -0
  28. data/lib/filegen/erb_generator.rb +21 -6
  29. data/lib/filegen/exceptions.rb +8 -0
  30. data/lib/filegen/options.rb +77 -6
  31. data/lib/filegen/runner.rb +29 -9
  32. data/lib/filegen/version.rb +2 -1
  33. data/rubocop-todo.yml +144 -0
  34. data/scripts/terminal +12 -0
  35. data/spec/data_source_builder_spec.rb +53 -0
  36. data/spec/data_sources/environment_spec.rb +20 -0
  37. data/spec/data_sources/yaml_spec.rb +31 -0
  38. data/spec/data_spec.rb +60 -0
  39. data/spec/erb_generator_spec.rb +31 -0
  40. data/spec/options_spec.rb +32 -0
  41. data/spec/spec_helper.rb +10 -0
  42. data/spec/support/config.rb +6 -0
  43. data/spec/support/debugging.rb +5 -0
  44. data/spec/support/environment.rb +7 -0
  45. data/spec/support/filesystem.rb +11 -0
  46. data/spec/support/here_doc.rb +2 -0
  47. metadata +58 -25
  48. data/lib/filegen/env.rb +0 -14
@@ -0,0 +1,2 @@
1
+ default: -t @wip:3
2
+ all: -t ~@wip
@@ -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
@@ -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 = "filegen"
7
+ spec.name = 'filegen'
8
8
  spec.version = Filegen::VERSION
9
- spec.authors = ["Dennis Günnewig"]
10
- spec.email = ["dg1@vrnetze.de"]
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 = "MIT"
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 = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_development_dependency "bundler", "~> 1.3"
22
- spec.add_development_dependency "rake"
21
+ spec.add_runtime_dependency 'moneta'
23
22
  end
@@ -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/env'
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
@@ -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,5 @@
1
+ # encoding: utf-8
2
+ module Filegen
3
+ # Contains all data sources which can be used in template
4
+ module DataSources; end
5
+ 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
- attr_reader :template_binding
5
+ private
5
6
 
6
- def initialize(template_binding)
7
- @template_binding = template_binding
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
- def compile(source,destination)
11
- destination.puts ERB.new(source).result(template_binding)
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
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+ module Filegen
3
+ # Exceptions
4
+ module Exceptions
5
+ # raised if order arguments are invalid
6
+ class InvalidDataSources < Exception; end
7
+ end
8
+ end
@@ -1,24 +1,95 @@
1
1
  # encoding: utf-8
2
2
  module Filegen
3
+ # Commandline parser
3
4
  class Options
4
- attr_reader :template
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
- @template = argv.first.to_s
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
- return File.read(template) if valid_template?
24
+ validate_source
12
25
 
13
- fail "File does not exist or is not a erb file!"
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
- def valid_template?
21
- File.exists?(template) && /.erb$/ === File.basename(template)
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