class Docker::Template::Meta

Constants

DEFAULTS

– rubocop:enable Style/MultilineBlockLayout –

Attributes

data[R]

Public Class Methods

new(overrides, root: nil) click to toggle source

– @param data [Hash, self.class] - the main data. @param root [Hash, self.class] - the root data. Create a new instance of `self.class`.

@example “`

self.class.new({
  :hello => :world
})

“` – rubocop:disable Metrics/AbcSize –

# File lib/docker/template/meta.rb, line 105
def initialize(overrides, root: nil)
  overrides = overrides.to_h :raw => true if overrides.is_a?(self.class)
  root = root.to_h :raw => true if root.is_a?(self.class)

  if root.nil?
    if Template.project?
      load_project_config(
        overrides
      )

    else
      load_normal_config(
        overrides
      )
    end

    @root = true
  else
    @data = overrides.stringify.with_indifferent_access
    @root_data = root.stringify.with_indifferent_access
  end

  debug!
  normalize!
  return
end
opts_file(force: nil) click to toggle source
# File lib/docker/template/meta.rb, line 84
def opts_file(force: nil)
  if force == :project || Template.project?
    then "docker/template.yml" else "opts.yml"
  end
end

Public Instance Methods

[](key) click to toggle source

– @param key [Anything()] the key you wish to pull. @note we make the getter slightly more indifferent because of tags. Pull an indifferent key from the hash. –

# File lib/docker/template/meta.rb, line 219
def [](key)
  val = begin
    if key =~ /^\d+\.\d+$/
      @data[key] || @data[
        key.to_f
      ]

    elsif key =~ /^\d+$/
      @data[key] || @data[
        key.to_i
      ]

    else
      @data[key]
    end
  end

  if val.is_a?(Hash)
    return self.class.new(val, {
      :root => root_data
    })
  end

  val
end
[]=(key, val) click to toggle source

# File lib/docker/template/meta.rb, line 247
def []=(key, val)
  hash = { key => val }.stringify
  @data.update(
    hash
  )
end
alias?() click to toggle source

– Checks to see if the current meta is an alias of another. This happens when the user has the tag in aliases but it's not complex. –

# File lib/docker/template/meta.rb, line 450
def alias?
  !!(aliased_tag && aliased_tag != tag)
end
aliased_group(tag: current_tag) click to toggle source

# File lib/docker/template/meta.rb, line 489
def aliased_group(tag: current_tag)
  root_data[:tags][aliased_tag({
    :tag => tag
  })]
end
aliased_tag(tag: current_tag) click to toggle source

# File lib/docker/template/meta.rb, line 475
def aliased_tag(tag: current_tag)
  aliases = root_data[:aliases]
  if aliases.nil? || !aliases.key?(tag)
    tag

  else
    aliases[
      tag
    ]
  end
end
by_group(group: current_group, query_data: @data) click to toggle source

# File lib/docker/template/meta.rb, line 413
def by_group(group: current_group, query_data: @data)
  if query_data.is_a?(self.class)
    then query_data.by_group({
      :group => group
    })

  elsif !query_data || !query_data.is_a?(Hash)
    return nil

  else
    query_data.fetch("group", {}).fetch(
      group, nil
    )
  end
end
by_parent_group(tag: current_tag, query_data: @data) click to toggle source

# File lib/docker/template/meta.rb, line 431
def by_parent_group(tag: current_tag, query_data: @data)
  if aliased_tag == current_tag || !complex_alias?
    return nil

  else
    by_group({
      :query_data => query_data,
      :group => aliased_group({
        :tag => tag
      })
    })
  end
end
by_parent_tag(tag: current_tag, query_data: @data) click to toggle source

# File lib/docker/template/meta.rb, line 397
def by_parent_tag(tag: current_tag, query_data: @data)
  if aliased_tag == current_tag || !complex_alias?
    return nil

  else
    by_tag({
      :query_data => query_data,
      :tag => aliased_tag({
        :tag => tag
      })
    })
  end
end
by_tag(tag: current_tag, query_data: @data) click to toggle source

# File lib/docker/template/meta.rb, line 379
def by_tag(tag: current_tag, query_data: @data)
  if query_data.is_a?(self.class)
    then query_data.by_tag({
      :tag => tag
    })

  elsif !query_data || !query_data.is_a?(Hash)
    return nil

  else
    query_data.fetch("tag", {}).fetch(
      tag, nil
    )
  end
end
complex_alias?() click to toggle source

– A complex alias happens when the user has an alias but also tries to add extra data, this allows them to use data from all parties. This allows them to reap the benefits of having shared data but sometimes independent data that diverges into it's own. –

# File lib/docker/template/meta.rb, line 461
def complex_alias?
  if !alias?
    return false

  else
    !!root_data.find do |_, v|
      (v.is_a?(self.class) || v.is_a?(Hash)) && queryable?(:query_data => v) \
        && by_tag(:query_data => v)
    end
  end
end
current_group() click to toggle source

# File lib/docker/template/meta.rb, line 625
def current_group
  root_data[:tags][current_tag] ||
    "normal"
end
Also aliased as: group
debug!() click to toggle source

# File lib/docker/template/meta.rb, line 150
def debug!
  if root? && root_data["debug"]
    if !key?(:env) || self[:env].queryable?
      self[:env] ||= {}

      merge!({
        :env => {
          :all => {
            :DEBUG => true
          }
        }
      })
    end
  end
end
fallback(group: current_group, tag: current_tag, query_data: @data) click to toggle source

– Fallback, determining which route is the best. Tag > Group > All. – rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity –

# File lib/docker/template/meta.rb, line 338
def fallback(group: current_group, tag: current_tag, query_data: @data)
  if query_data.is_a?(self.class)
    then query_data.fallback({
      :group => group, :tag => tag
    })

  elsif !query_data || !query_data.is_a?(Hash) || query_data.empty?
    return nil

  else
    if !(v = by_tag(:tag => tag, :query_data => query_data)).nil? then return v
      elsif !(v = by_parent_tag(:tag => tag, :query_data => query_data)).nil? then return v
      elsif !(v = by_group(:group => group, :query_data => query_data)).nil? then return v
      elsif !(v = by_parent_group(:tag => tag, :query_data => query_data)).nil? then return v
      else return for_all(:query_data => query_data)
    end
  end
end
for_all(query_data: @data) click to toggle source

– rubocop:enable Metrics/CyclomaticComplexity rubocop:enable Metrics/PerceivedComplexity –

# File lib/docker/template/meta.rb, line 362
def for_all(query_data: @data)
  if query_data.is_a?(self.class)
    then query_data \
      .for_all

  elsif !query_data || !query_data.is_a?(Hash)
    return nil

  else
    query_data.fetch(
      "all", nil
    )
  end
end
groups() click to toggle source

– HELPER: Get a list of all the groups. –

# File lib/docker/template/meta.rb, line 642
def groups
  root_data["tags"].values.uniq
end
include?(val) click to toggle source

– Check if a part of the hash or a value is inside. @param val [Anytning(), Hash] - The key or key => val you wish check. @example meta.include?(:key => :val) => true|false @example meta.include?(:key) => true|false –

# File lib/docker/template/meta.rb, line 196
def include?(val)
  if val.is_a?(Hash)
    then val.stringify.each do |k, v|
      unless @data.key?(k) && @data[k] == v
        return false
      end
    end

  else
    return @data.include?(
      val
    )
  end

  true
end
merge(new_) click to toggle source

– Merge a hash into the meta. If you merge non-queryable data it will then get merged into the queryable data. –

# File lib/docker/template/meta.rb, line 281
def merge(new_)
  if !queryable?(:query_data => new_) && queryable?
    new_ = {
      :all => new_
    }
  end

  new_ = new_.stringify
  self.class.new(@data.deep_merge(new_), {
    :root => root_data
  })
end
Also aliased as: deep_merge
merge!(new_) click to toggle source

– Destructive merging (@see self#merge) –

# File lib/docker/template/meta.rb, line 298
def merge!(new_)
  if !queryable?(:query_data => new_) && queryable?
    new_ = {
      :all => new_
    }
  end

  @data = @data.deep_merge(
    new_.stringify
  )

  self
end
mergeable_array?(key = nil) click to toggle source

# File lib/docker/template/meta.rb, line 605
def mergeable_array?(key = nil)
  return false unless queryable?
  vals = [by_parent_tag, by_parent_group, \
    by_tag, for_all, by_group].compact

  if key
    vals = vals.map do |val|
      val[key]
    end
  end

  !vals.empty? && !vals.any? do |val|
    !val.is_a?(
      Array
    )
  end
end
mergeable_hash?(key = nil) click to toggle source

– rubocop:enable Metrics/AbcSize –

# File lib/docker/template/meta.rb, line 585
def mergeable_hash?(key = nil)
  return false unless queryable?
  vals = [by_parent_tag, by_parent_group, \
    by_tag, for_all, by_group].compact

  if key
    vals = vals.map do |val|
      val[key]
    end
  end

  !vals.empty? && !vals.any? do |val|
    !val.is_a?(Hash) && !val.is_a?(
      self.class
    )
  end
end
normalize!() click to toggle source

# File lib/docker/template/meta.rb, line 134
def normalize!
  if root?
    opts = {
      :allowed_keys => [],
      :allowed_vals => []
    }

    merge!({
      "tags"    => @data[   "tags"].stringify(**opts),
      "aliases" => @data["aliases"].stringify(**opts)
    })
  end
end
queryable?(query_data: @data) click to toggle source

– Check if a hash is queryable. AKA has “all”, “group”, “tag”. –

# File lib/docker/template/meta.rb, line 316
def queryable?(query_data: @data)
  if query_data.is_a?(self.class)
    then query_data
      .queryable?

  elsif !query_data || !query_data.is_a?(Hash) || query_data.empty?
    return false

  else
    (query_data.keys - %w(
      group tag all
    )).empty?
  end
end
root() click to toggle source

# File lib/docker/template/meta.rb, line 174
def root
  if Template.project?
    then return Template.root.join(root_data[
      :project_data_dir
    ])

  else
    Template.root.join(
      root_data[:repos_dir], root_data[
        :name
      ]
    )
  end
end
root_data() click to toggle source

# File lib/docker/template/meta.rb, line 168
def root_data
  return @root_data || @data
end
tags() click to toggle source

– HELPER: Get a list of all the tags. –

# File lib/docker/template/meta.rb, line 634
def tags
  (root_data[:tags] || {}).keys | (root_data[:aliases] || {}).keys
end
to_a(raw: false, shell: false) click to toggle source

– rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/PerceivedComplexity –

# File lib/docker/template/meta.rb, line 519
def to_a(raw: false, shell: false)
  if raw
    return to_h({
      :raw => true
    }).to_a

  elsif !mergeable_array?
    to_h.each_with_object([]) do |(k, v), a|
      a << "#{k}=#{
        shell ? v.to_s.shellescape : v
      }"
    end
  else
    (for_all || []) | (by_parent_group || []) | (by_group || []) | \
      (by_parent_tag || []) | (by_tag || [])
  end
end
to_enum() click to toggle source

# File lib/docker/template/meta.rb, line 264
def to_enum
  @data.each_with_object({}) do |(k, v), h|
    if v.is_a?(Hash)
      then v = self.class.new(v, {
        :root => root_data
      })
    end

    h[k] = v
  end.to_enum
end
to_h(raw: false) click to toggle source

– rubocop:eanble Metrics/CyclomaticComplexity rubocop:eanble Metrics/PerceivedComplexity – Convert a `Meta' into a normal hash. If `self' is queryable then we go and start merging values smartly. This means that we will merge all the arrays into one another and we will merge hashes into hashes. – rubocop:disable Metrics/AbcSize –

# File lib/docker/template/meta.rb, line 548
def to_h(raw: false)
  return @data.to_h if raw || !queryable? || !mergeable_hash?
  keys = [for_all, by_group, by_parent_group, by_tag, \
    by_parent_tag].compact.map(&:keys)

  keys.reduce(:+).each_with_object({}) do |k, h|
    vals = [for_all, by_group, by_parent_group, by_tag, \
      by_parent_tag].compact

    h[k] = \
      if mergeable_array?(k)
        vals.map { |v| v[k].to_a } \
          .compact.reduce(
            :+
          )

      elsif mergeable_hash?(k)
        vals.map { |v| v[k].to_h } \
          .compact.reduce(
            :deep_merge
          )

      else
        vals.find do |v|
          v.key?(
            k
          )
        end \
        [k]
      end
  end
end
to_s(raw: false, shell: false) click to toggle source

– Converts the current meta into a string. –

# File lib/docker/template/meta.rb, line 499
def to_s(raw: false, shell: false)
  if !raw && (mergeable_hash? || mergeable_array?)
    to_a(:shell => shell).join(" #{
      "\n" if shell
    }")

  elsif !raw && queryable?
    then fallback \
      .to_s

  else
    @data.to_s
  end
end
update(hash) click to toggle source

# File lib/docker/template/meta.rb, line 256
def update(hash)
  @data.update(
    hash.stringify
  )
end

Private Instance Methods

deep_merge(new_)

Alias for: merge
group()
Alias for: current_group
load_normal_config(overrides) click to toggle source

# File lib/docker/template/meta.rb, line 698
def load_normal_config(overrides)
  overrides = overrides.stringify
  gdata = Template.root.join(self.class.opts_file).read_yaml
  @data = DEFAULTS.deep_merge(gdata.stringify).deep_merge(overrides)
  tdata = Template.root.join(@data[:repos_dir], @data[:name], self.class.opts_file).read_yaml
  @data = @data.deep_merge(tdata.stringify).deep_merge(overrides)
  @data = @data.stringify.with_indifferent_access
end
load_project_config(overrides) click to toggle source

# File lib/docker/template/meta.rb, line 710
def load_project_config(overrides)
  overrides = overrides.stringify
  gdata = Template.root.join(self.class.opts_file).read_yaml
  @data = DEFAULTS.deep_merge(gdata.stringify).deep_merge(overrides)
  @data = @data.stringify.with_indifferent_access
end
merge_or_override(val, new_val) click to toggle source

# File lib/docker/template/meta.rb, line 649
def merge_or_override(val, new_val)
  return new_val unless val
  return val if val.is_a?(String) && !new_val || !new_val.is_a?(val.class)
  return new_val.merge(val) if val.respond_to?(:merge)
  return new_val | val if val.respond_to?(:|)
end
method_missing(method, *args, shell: false, &block) click to toggle source

Calls superclass method
# File lib/docker/template/meta.rb, line 673
def method_missing(method, *args, shell: false, &block)
  key  = method.to_s.gsub(/\?$/, "")
  val  = self[key] || self[key.singularize] \
          || self[key.pluralize]

  if !args.empty? || block_given?
    super

  elsif method !~ /\?$/
    string_wrapper(val, {
      :shell => shell
    })

  else
    val = val.fallback if val.is_a?(self.class) && val.queryable?
    [true, false].include?(val) ? val : \
      if val.respond_to?(:empty?)
        then !val.empty? else !!val
      end
  end
end
string_wrapper(obj, shell: false) click to toggle source

# File lib/docker/template/meta.rb, line 659
def string_wrapper(obj, shell: false)
  return obj if obj == true || obj == false || obj.nil?
  return obj.fallback if obj.is_a?(self.class) && obj.queryable? \
    && !(o = obj.fallback).nil? && (o == true || o == false)

  return obj.to_s(:shell => shell) if obj.is_a?(self.class)
  !obj.is_a?(Array) ? obj.to_s : obj.join(
    "\s"
  )
end