eac_templates 0.3.2 → 0.4.0

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/eac_templates/core_ext.rb +1 -1
  3. data/lib/eac_templates/interface_methods.rb +12 -0
  4. data/lib/eac_templates/modules/ancestor/directory.rb +15 -0
  5. data/lib/eac_templates/modules/ancestor/file.rb +15 -0
  6. data/lib/eac_templates/modules/ancestor/fs_object.rb +32 -0
  7. data/lib/eac_templates/modules/ancestor.rb +48 -0
  8. data/lib/eac_templates/modules/base.rb +35 -0
  9. data/lib/eac_templates/modules.rb +9 -0
  10. data/lib/eac_templates/patches/module/template.rb +2 -3
  11. data/lib/eac_templates/sources/directory.rb +24 -0
  12. data/lib/eac_templates/sources/file.rb +24 -0
  13. data/lib/eac_templates/sources/from_all_gems.rb +4 -0
  14. data/lib/eac_templates/sources/from_gem.rb +37 -0
  15. data/lib/eac_templates/sources/fs_object.rb +53 -0
  16. data/lib/eac_templates/sources/internal_set.rb +22 -0
  17. data/lib/eac_templates/sources/set.rb +54 -0
  18. data/lib/eac_templates/sources/single.rb +29 -0
  19. data/lib/eac_templates/sources.rb +9 -0
  20. data/lib/eac_templates/variables/directory.rb +47 -0
  21. data/lib/eac_templates/variables/file.rb +50 -0
  22. data/lib/eac_templates/variables/fs_object.rb +65 -0
  23. data/lib/eac_templates/variables/not_found_error.rb +7 -0
  24. data/lib/eac_templates/variables/providers/base.rb +23 -0
  25. data/lib/eac_templates/variables/providers/config_reader.rb +29 -0
  26. data/lib/eac_templates/variables/providers/entries_reader.rb +25 -0
  27. data/lib/eac_templates/variables/providers/generic.rb +25 -0
  28. data/lib/eac_templates/variables/providers/hash.rb +29 -0
  29. data/lib/eac_templates/variables/providers.rb +25 -0
  30. data/lib/eac_templates/variables.rb +9 -0
  31. data/lib/eac_templates/version.rb +1 -1
  32. metadata +33 -30
  33. data/lib/eac_templates/directory.rb +0 -108
  34. data/lib/eac_templates/file.rb +0 -48
  35. data/lib/eac_templates/from_all_gems.rb +0 -4
  36. data/lib/eac_templates/from_gem.rb +0 -35
  37. data/lib/eac_templates/searcher.rb +0 -53
  38. data/lib/eac_templates/variable_not_found_error.rb +0 -5
  39. data/lib/eac_templates/variable_providers/base.rb +0 -21
  40. data/lib/eac_templates/variable_providers/config_reader.rb +0 -27
  41. data/lib/eac_templates/variable_providers/entries_reader.rb +0 -23
  42. data/lib/eac_templates/variable_providers/generic.rb +0 -23
  43. data/lib/eac_templates/variable_providers/hash.rb +0 -27
  44. data/lib/eac_templates/variable_providers.rb +0 -23
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 63916b49b6fe5333356bcfa18ed5b3118fb784ffad1ba65d14312a2eafad7a54
4
- data.tar.gz: 0a5e61d751f1bf2194f24623c958134f36f27548bbe0b6e956fe1c80e0f0d024
3
+ metadata.gz: 4693c8bc468202051ac7c3ea070b1c3d11d29de84f009caa168a11a5dd85bb7a
4
+ data.tar.gz: b247d9ce2cb2b5959e9a3f18a7f9f6ddd62e2ce21c7d8a47001ecc1f67527d14
5
5
  SHA512:
6
- metadata.gz: df42a3b2ec8c86b5b71d0f9713c56e04efa9b8da6533c9858debb610bc1a2a4be6d15dd970ff2b52f10cfc2c18850cfaa1762951b69737a22f7befe0045b7e34
7
- data.tar.gz: 299b5c3aa4ac068d4c598990e41d367c8803cd47fed01a7efa8e49f8372fea4acd20d8b03a7dc4da9394949e87e204d839c39ce03de61b7e39cd7647c22092d3
6
+ metadata.gz: 8742d8c59890381772209cbbda1c7b5aa07145279c3eb37767c786be91b13a5a403b36f85b00e33157b63d4b39f8d6f5e2142ece147235da20546a4c83d3bfe5
7
+ data.tar.gz: 8d8269d321709f68bfa6adee7cda5969076cf26688b7f0265fac48f985e3efb16590aff6f0b80eee9ef38192ccc07986029ca67fbbae3d24250f8e9906814ca3
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_templates/patches'
4
- require 'eac_templates/from_all_gems'
4
+ require 'eac_templates/sources/from_all_gems'
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacTemplates
4
+ module InterfaceMethods
5
+ COMMON = %w[apply path].freeze
6
+ ONLY_DIRECTORY = %w[child children].freeze
7
+ DIRECTORY = COMMON + ONLY_DIRECTORY
8
+ ONLY_FILE = %w[apply_to_file content variables].freeze
9
+ FILE = COMMON + ONLY_FILE
10
+ ALL = COMMON + ONLY_DIRECTORY + ONLY_FILE
11
+ end
12
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/interface_methods'
5
+ require 'eac_templates/modules/ancestor/fs_object'
6
+
7
+ module EacTemplates
8
+ module Modules
9
+ class Ancestor
10
+ class Directory < ::EacTemplates::Modules::Ancestor::FsObject
11
+ delegate(*::EacTemplates::InterfaceMethods::ONLY_DIRECTORY, to: :source_object)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/interface_methods'
5
+ require 'eac_templates/modules/ancestor/fs_object'
6
+
7
+ module EacTemplates
8
+ module Modules
9
+ class Ancestor
10
+ class File < ::EacTemplates::Modules::Ancestor::FsObject
11
+ delegate(*::EacTemplates::InterfaceMethods::ONLY_FILE, to: :source_object)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/interface_methods'
5
+
6
+ module EacTemplates
7
+ module Modules
8
+ class Ancestor
9
+ class FsObject
10
+ enable_simple_cache
11
+ common_constructor :base
12
+ delegate(*::EacTemplates::InterfaceMethods::COMMON, :found?, to: :source_object)
13
+
14
+ # @return [Symbol]
15
+ def object_type
16
+ self.class.name.demodulize.underscore.to_sym
17
+ end
18
+
19
+ # @return [Pathname, nil]
20
+ def path
21
+ source_object.found? ? source_object.send(:real_paths).first : nil
22
+ end
23
+
24
+ private
25
+
26
+ def source_object_uncached
27
+ base.source_set.send(object_type, base.path_for_search)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/interface_methods'
5
+
6
+ module EacTemplates
7
+ module Modules
8
+ class Ancestor
9
+ class << self
10
+ # @param a_module [Module]
11
+ # @return [Pathname]
12
+ def path_for_search(a_module)
13
+ a_module.name.underscore.to_pathname
14
+ end
15
+ end
16
+
17
+ common_constructor :base, :ancestor
18
+ delegate :subpath, :source_set, to: :base
19
+ delegate(*::EacTemplates::InterfaceMethods::ALL, to: :source_object)
20
+
21
+ # @return [EacTemplates::Modules::Directory]
22
+ def directory
23
+ ::EacTemplates::Modules::Ancestor::Directory.new(self)
24
+ end
25
+
26
+ # @return [EacTemplates::Modules::File]
27
+ def file
28
+ @file ||= ::EacTemplates::Modules::Ancestor::File.new(self)
29
+ end
30
+
31
+ # @return [Pathname]
32
+ def path_for_search
33
+ r = self.class.path_for_search(ancestor)
34
+ subpath.if_present(r) { |v| r.join(v) }
35
+ end
36
+
37
+ # @return [EacTemplates::Modules::Ancestor::FsObject]
38
+ def source_object
39
+ return file if file.found?
40
+ return directory if directory.found?
41
+
42
+ raise "No template found: #{path_for_search}"
43
+ end
44
+
45
+ require_sub __FILE__
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/interface_methods'
5
+ require 'eac_templates/modules/ancestor'
6
+ require 'eac_templates/sources/set'
7
+
8
+ module EacTemplates
9
+ module Modules
10
+ class Base
11
+ enable_listable
12
+ lists.add_symbol :option, :source_set, :subpath
13
+ common_constructor :the_module, :options, default: [{}] do
14
+ self.options = self.class.lists.option.hash_keys_validate!(options)
15
+ end
16
+ delegate(*::EacTemplates::InterfaceMethods::ALL, :path_for_search, :source_object,
17
+ to: :self_ancestor)
18
+
19
+ # @return [EacTemplates::Modules::Ancestor]
20
+ def self_ancestor
21
+ @self_ancestor ||= ::EacTemplates::Modules::Ancestor.new(self, the_module)
22
+ end
23
+
24
+ # @return [EacTemplates::SourceSet]
25
+ def source_set
26
+ options[OPTION_SOURCE_SET] || ::EacTemplates::Sources::Set.default
27
+ end
28
+
29
+ # @return [Pathname, nil]
30
+ def subpath
31
+ options[OPTION_SUBPATH].if_present(&:to_pathname)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacTemplates
6
+ module Modules
7
+ require_sub __FILE__
8
+ end
9
+ end
@@ -1,10 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'active_support/core_ext/string/inflections'
4
- require 'eac_templates/searcher'
3
+ require 'eac_templates/modules/base'
5
4
 
6
5
  class Module
7
6
  def template
8
- @template ||= ::EacTemplates::Searcher.default.template(name.underscore)
7
+ @template ||= ::EacTemplates::Modules::Base.new(self)
9
8
  end
10
9
  end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/sources/fs_object'
5
+ require 'eac_templates/variables/directory'
6
+
7
+ module EacTemplates
8
+ module Sources
9
+ class Directory < ::EacTemplates::Sources::FsObject
10
+ delegate :apply, :child, :children, :path, to: :applier
11
+
12
+ # @return [Class]
13
+ def applier_class
14
+ ::EacTemplates::Variables::Directory
15
+ end
16
+
17
+ # @param path [Pathname]
18
+ # @return [Boolean]
19
+ def select_path?(path)
20
+ super && path.directory?
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/sources/fs_object'
5
+ require 'eac_templates/variables/file'
6
+
7
+ module EacTemplates
8
+ module Sources
9
+ class File < ::EacTemplates::Sources::FsObject
10
+ delegate :apply, :apply_to_file, :content, :path, :variables, to: :applier
11
+
12
+ # @return [Class]
13
+ def applier_class
14
+ ::EacTemplates::Variables::File
15
+ end
16
+
17
+ # @param path [Pathname]
18
+ # @return [Boolean]
19
+ def select_path?(path)
20
+ super && path.file?
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_templates/sources/from_gem'
4
+ ::EacTemplates::Sources::FromGem.include_all
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_templates/sources/set'
4
+
5
+ module EacTemplates
6
+ module Sources
7
+ class FromGem
8
+ class << self
9
+ def include_all(searcher = nil)
10
+ ::Gem::Specification.each { |gemspec| new(gemspec, searcher).include }
11
+ end
12
+ end
13
+
14
+ TEMPLATES_DIR_SUBPATH = 'template'
15
+
16
+ common_constructor :gemspec, :searcher, default: [nil] do
17
+ self.searcher ||= ::EacTemplates::Sources::Set.default
18
+ end
19
+
20
+ # @return [Boolean]
21
+ delegate :exist?, to: :path
22
+
23
+ # @return [Pathname]
24
+ def include
25
+ return nil unless exist?
26
+
27
+ searcher.included_paths << path
28
+ path
29
+ end
30
+
31
+ # @return [Pathname]
32
+ def path
33
+ gemspec.gem_dir.to_pathname.join(TEMPLATES_DIR_SUBPATH)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacTemplates
6
+ module Sources
7
+ class FsObject
8
+ enable_abstract_methods
9
+ enable_simple_cache
10
+ common_constructor :source_set, :subpath do
11
+ self.subpath = subpath.to_pathname
12
+ end
13
+
14
+ # @return [Boolean]
15
+ def found?
16
+ real_paths.any?
17
+ end
18
+
19
+ protected
20
+
21
+ # @return [Class]
22
+ def applier_class
23
+ raise_abstract_method __method__
24
+ end
25
+
26
+ # @return [EacTemplates::Variables::SourceFile]
27
+ def applier_uncached
28
+ raise "No #{self.class.name.downcase} found for \"#{subpath}\"" unless found?
29
+
30
+ applier_class.new(real_paths.first)
31
+ end
32
+
33
+ # @return [Array<Pathname>]
34
+ def real_paths_uncached
35
+ source_set.included_paths.lazy.map { |source_single| source_single_search(source_single) }
36
+ .select(&:present?)
37
+ end
38
+
39
+ # @param path [Pathname]
40
+ # @return [Boolean]
41
+ def select_path?(path)
42
+ path.present?
43
+ end
44
+
45
+ # @param source_single [EacTemplates::Sources::Single]
46
+ # @return [Pathname, nil]
47
+ def source_single_search(source_single)
48
+ r = source_single.search(subpath)
49
+ select_path?(r) ? r : nil
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/sources/single'
5
+
6
+ module EacTemplates
7
+ module Sources
8
+ class InternalSet < ::Set
9
+ # @param single [EacTemplates::Sources::Single]
10
+ # @return [self]
11
+ def add(single)
12
+ super(::EacTemplates::Sources::Single.assert(single))
13
+ end
14
+
15
+ # @param single [EacTemplates::Sources::Single]
16
+ # @return [self]
17
+ def <<(single)
18
+ add(single)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/core_ext/object/blank'
4
+ require 'eac_templates/sources/directory'
5
+ require 'eac_templates/sources/file'
6
+ require 'eac_templates/sources/internal_set'
7
+
8
+ module EacTemplates
9
+ module Sources
10
+ class Set
11
+ class << self
12
+ def default
13
+ @default ||= new
14
+ end
15
+ end
16
+
17
+ # @param subpath [Pathname]
18
+ # @return [EacTemplates::Sources::Directory]
19
+ def directory(subpath)
20
+ ::EacTemplates::Sources::Directory.new(self, subpath)
21
+ end
22
+
23
+ # @param subpath [Pathname]
24
+ # @return [EacTemplates::Sources::Directory]
25
+ def file(subpath)
26
+ ::EacTemplates::Sources::File.new(self, subpath)
27
+ end
28
+
29
+ def template(subpath, required = true)
30
+ found_file = file(subpath)
31
+ return found_file if found_file.found?
32
+
33
+ found_directory = directory(subpath)
34
+ return found_directory if found_directory.found?
35
+
36
+ return nil unless required
37
+
38
+ raise_template_not_found(subpath)
39
+ end
40
+
41
+ # @return [EacTemplates::Sources::InternalSet]
42
+ def included_paths
43
+ @included_paths ||= ::EacTemplates::Sources::InternalSet.new
44
+ end
45
+
46
+ private
47
+
48
+ def raise_template_not_found(subpath)
49
+ raise "Template not found for subpath \"#{subpath}\"" \
50
+ " (Included paths: #{included_paths.to_a.join(::File::PATH_SEPARATOR)})"
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacTemplates
6
+ module Sources
7
+ class Single
8
+ class << self
9
+ # @param object [EacTemplates::Sources::Single, Pathname]
10
+ # @return [EacTemplates::Sources::Single]
11
+ def assert(object)
12
+ return object if object.is_a?(self)
13
+
14
+ new(object.to_pathname)
15
+ end
16
+ end
17
+
18
+ common_constructor :path do
19
+ self.path = path.to_pathname.expand_path
20
+ end
21
+
22
+ # @return [Pathname, nil]
23
+ def search(subpath)
24
+ r = path.join(subpath)
25
+ r.exist? ? r : nil
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EacTemplates
6
+ module Sources
7
+ require_sub __FILE__
8
+ end
9
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_templates/variables/file'
4
+ require 'eac_templates/variables/fs_object'
5
+
6
+ module EacTemplates
7
+ module Variables
8
+ class Directory
9
+ attr_reader :path
10
+
11
+ def initialize(path)
12
+ @path = path.is_a?(::Pathname) ? path : ::Pathname.new(path.to_s)
13
+ end
14
+
15
+ def apply(variables_source, directory)
16
+ ::EacTemplates::Variables::FsObject.new(self, '.', directory, variables_source).apply
17
+ end
18
+
19
+ def child(subpath)
20
+ child_path = ::File.join(path, subpath)
21
+ return ::EacTemplates::Variables::File.new(child_path) if ::File.file?(child_path)
22
+ return ::EacTemplates::Variables::Directory.new(child_path) if ::File.directory?(child_path)
23
+
24
+ raise "Child \"#{subpath}\" from \"#{path}\" not found"
25
+ end
26
+
27
+ def children
28
+ path.children.map do |path_child|
29
+ child(path_child.basename.to_path)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def apply_fs_object(source_relative, target)
36
+ if ::File.directory?(source_absolute(source_relative))
37
+ apply_directory(source_relative, target)
38
+ elsif ::File.file?(source_absolute(source_relative))
39
+ end
40
+ end
41
+
42
+ def source_absolute(source_relative)
43
+ ::File.expand_path(source_relative, path)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'eac_templates/variables/providers'
5
+
6
+ module EacTemplates
7
+ module Variables
8
+ class File
9
+ VARIABLE_DELIMITER = ::Regexp.quote('%%')
10
+ VARIABLE_PATTERN = /#{VARIABLE_DELIMITER}([a-z0-9\._]*)#{VARIABLE_DELIMITER}/i.freeze
11
+
12
+ enable_simple_cache
13
+ common_constructor :path do
14
+ self.path = path.to_pathname
15
+ end
16
+
17
+ # +variables_provider+ A [Hash] or object which responds to +read_entry(entry_name)+.
18
+ def apply(variables_source)
19
+ variables_provider = ::EacTemplates::Variables::Providers.build(variables_source)
20
+ variables.inject(content) do |a, e|
21
+ a.gsub(variable_pattern(e), variables_provider.variable_value(e).to_s)
22
+ end
23
+ end
24
+
25
+ def apply_to_file(variables_source, output_file_path)
26
+ output_file_path.to_pathname.write(apply(variables_source))
27
+ end
28
+
29
+ private
30
+
31
+ def variables_uncached
32
+ content.scan(VARIABLE_PATTERN).map(&:first).map do |name|
33
+ sanitize_variable_name(name)
34
+ end.to_set
35
+ end
36
+
37
+ def content_uncached
38
+ path.read
39
+ end
40
+
41
+ def sanitize_variable_name(variable_name)
42
+ variable_name.to_s.downcase
43
+ end
44
+
45
+ def variable_pattern(name)
46
+ /#{VARIABLE_DELIMITER}#{::Regexp.quote(name)}#{VARIABLE_DELIMITER}/i
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_templates/variables/file'
4
+
5
+ module EacTemplates
6
+ module Variables
7
+ class FsObject
8
+ TEMPLATE_EXTNAME = '.template'
9
+
10
+ common_constructor :source_directory, :source_relative, :target_root_directory,
11
+ :variables_source
12
+
13
+ def apply
14
+ if file?
15
+ apply_file
16
+ elsif directory?
17
+ apply_directory
18
+ else
19
+ raise "Unknown filesystem type: #{source_absolute}"
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def apply_directory
26
+ ::FileUtils.mkdir_p(target_absolute)
27
+ Dir.entries(source_absolute).each do |entry|
28
+ child(entry).apply unless %w[. ..].include?(entry)
29
+ end
30
+ end
31
+
32
+ def apply_file
33
+ if ::File.extname(source_absolute) == TEMPLATE_EXTNAME
34
+ ::EacTemplates::Variables::File.new(source_absolute).apply_to_file(
35
+ variables_source, target_absolute
36
+ )
37
+ else
38
+ ::FileUtils.cp(source_absolute, target_absolute)
39
+ end
40
+ end
41
+
42
+ def child(entry)
43
+ self.class.new(source_directory, ::File.join(source_relative, entry),
44
+ target_root_directory, variables_source)
45
+ end
46
+
47
+ def file?
48
+ ::File.file?(source_absolute)
49
+ end
50
+
51
+ def directory?
52
+ ::File.directory?(source_absolute)
53
+ end
54
+
55
+ def source_absolute
56
+ ::File.expand_path(source_relative, source_directory.path)
57
+ end
58
+
59
+ def target_absolute
60
+ ::File.expand_path(source_relative, target_root_directory)
61
+ .gsub(/#{::Regexp.quote(TEMPLATE_EXTNAME)}\z/, '')
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module EacTemplates
4
+ module Variables
5
+ class NotFoundError < StandardError; end
6
+ end
7
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_templates/variables/not_found_error'
4
+
5
+ module EacTemplates
6
+ module Variables
7
+ module Providers
8
+ class Base
9
+ attr_reader :source
10
+
11
+ def initialize(source)
12
+ @source = source
13
+ end
14
+
15
+ def variable_value(name)
16
+ return variable_fetch(name) if variable_exist?(name)
17
+
18
+ raise VariableNotFoundError, "Variable \"#{name}\" not found in #{source}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end