Module: Metanorma::Core::FlavorLoader

Defined in:
lib/metanorma/core/flavor_loader.rb

Overview

Locate and load the right flavor gem (e.g. metanorma-iso, metanorma-itu) for a given standard type, registering its processor with Registry as a side effect.

Standard types may be specified as a “taste” name (e.g. :bipm, :icc) which is mapped to its canonical flavor via TasteRegister. Flavor gems follow the metanorma-<flavor> naming convention.

The load_flavor entry point both resolves and loads, and is idempotent: if the flavor’s processor is already registered, no gem load is attempted.

Class Method Summary collapse

Class Method Details

.flavor_unsupported(gem_name, stdtype) ⇒ void

This method returns an undefined value.

Fatal-abort path for the case where the flavor gem loaded but did not register a processor for the requested standard type.

Parameters:

  • gem_name (String)

    gem name that loaded.

  • stdtype (Symbol, String)

    standard type that the gem did not register a processor for.



114
115
116
117
118
# File 'lib/metanorma/core/flavor_loader.rb', line 114

def flavor_unsupported(gem_name, stdtype)
  Metanorma::Util.log("[metanorma] Error: The `#{gem_name}` gem does " \
                      "not support the standard type #{stdtype}. " \
                      "Exiting.", :fatal)
end

.load_flavor(stdtype) ⇒ Symbol

Load the flavor gem for stdtype if its processor is not yet registered, and return the canonical flavor symbol.

On a fatal LoadError, an error log file is written and abort is called via Util#log (severity :fatal). If the gem loads but does not register a processor under the expected canonical name, the same fatal-abort path runs.

Parameters:

  • stdtype (Symbol, String)

    standard type or taste name.

Returns:

  • (Symbol)

    canonical flavor symbol.



53
54
55
56
57
58
59
60
61
62
# File 'lib/metanorma/core/flavor_loader.rb', line 53

def load_flavor(stdtype)
  canonical = taste2flavor(stdtype)
  gem_name = stdtype2flavor_gem(canonical)
  registry = Metanorma::Registry.instance
  registry.supported_backends.include?(canonical) or
    require_flavor_gem(gem_name, stdtype)
  registry.supported_backends.include?(canonical) or
    flavor_unsupported(gem_name, stdtype)
  canonical
end

.require_flavor_gem(gem_name, stdtype) ⇒ Object

Require the flavor gem and log success / failure. On LoadError, delegates to write_flavor_error_log which produces a fatal abort. Used internally by load_flavor.

Parameters:

  • gem_name (String)

    gem name (e.g. “metanorma-iso”).

  • stdtype (Symbol, String)

    standard type for the user-facing info log line.



71
72
73
74
75
76
77
78
79
# File 'lib/metanorma/core/flavor_loader.rb', line 71

def require_flavor_gem(gem_name, stdtype)
  Metanorma::Util.log("[metanorma] Info: Loading `#{gem_name}` gem " \
                      "for standard type `#{stdtype}`.", :info)
  require gem_name
  Metanorma::Util.log("[metanorma] Info: gem `#{gem_name}` loaded.",
                      :info)
rescue LoadError => e
  write_flavor_error_log(e, gem_name)
end

.stdtype2flavor_gem(stdtype) ⇒ String

Map a canonical flavor symbol to its gem name.

Parameters:

  • stdtype (Symbol, String)

    canonical flavor symbol.

Returns:

  • (String)

    gem name (e.g. “metanorma-iso”).



39
40
41
# File 'lib/metanorma/core/flavor_loader.rb', line 39

def stdtype2flavor_gem(stdtype)
  "metanorma-#{stdtype}"
end

.taste2flavor(stdtype) ⇒ Symbol

Resolve a standard type or taste name to its canonical flavor symbol via the TasteRegister.

Parameters:

  • stdtype (Symbol, String)

    standard type or taste name.

Returns:

  • (Symbol)

    canonical flavor symbol (the input if no taste alias matched).



28
29
30
31
32
33
# File 'lib/metanorma/core/flavor_loader.rb', line 28

def taste2flavor(stdtype)
  stdtype = stdtype.to_sym
  tastes = Metanorma::TasteRegister.instance.aliases
  tastes[stdtype] and stdtype = tastes[stdtype].to_sym
  stdtype
end

.write_flavor_error_log(err, gem_name) ⇒ void

This method returns an undefined value.

Write a dated error-log file capturing a failed gem load and abort with a user-facing fatal message that points the user at the metanorma issue tracker.

Parameters:

  • err (Exception)

    the LoadError raised by require.

  • gem_name (String)

    gem name that failed to load.



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/metanorma/core/flavor_loader.rb', line 88

def write_flavor_error_log(err, gem_name)
  error_log = "#{Date.today}-error.log"
  File.write(error_log, err)
  msg = <<~MSG
    Error: #{err.message}
    Metanorma has encountered an exception.

    If this problem persists, please report this issue at the following link:

    * https://github.com/metanorma/metanorma/issues/new

    Please attach the #{error_log} file.
    Your valuable feedback is very much appreciated!

    - The Metanorma team
  MSG
  Metanorma::Util.log(msg, :fatal)
end