filegen 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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