Class: Kerbi::State::Entry

Inherits:
Object
  • Object
show all
Defined in:
lib/state/entry.rb

Overview

Represents a single Kerbi state entry.

Constant Summary collapse

CANDIDATE_PREFIX =

Tag prefix that identifies candidate states

Returns:

  • (String)
"[cand]-"
ATTRS =

Array of record attribute names in symbol form

Returns:

  • (Array<Symbol>)
%i[tag revision message values default_values created_at]
SETTABLE_ATTRS =

Subset of attribute names (symbol form) that the user can mass update (i.e Rails’ attr_accessible)

%i[message created_at]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(set, dict) ⇒ Entry

Returns a new instance of Entry.



65
66
67
68
69
70
71
72
# File 'lib/state/entry.rb', line 65

def initialize(set, dict)
  @set = set
  ATTRS.each do |attr|
    instance_variable_set("@#{attr}", dict[attr].freeze)
  end
  @_was_validated = false
  @validation_errors = []
end

Instance Attribute Details

#created_atTime

The default values computed at templating time

Returns:

  • (Time)


57
58
59
# File 'lib/state/entry.rb', line 57

def created_at
  @created_at
end

#default_valuesHash

The default values computed at templating time

Returns:

  • (Hash)


47
48
49
# File 'lib/state/entry.rb', line 47

def default_values
  @default_values
end

#messageString

Message for/by user, for user info purposes only

Returns:

  • (String)


42
43
44
# File 'lib/state/entry.rb', line 42

def message
  @message
end

#revisionString

SemVer of chart/mixer, for user info purposes only

Returns:

  • (String)


37
38
39
# File 'lib/state/entry.rb', line 37

def revision
  @revision
end

#setArray<Kerbi::State::EntrySet>

Parent collection. Necessary for computation that involve comparision.

Returns:



27
28
29
# File 'lib/state/entry.rb', line 27

def set
  @set
end

#tagString

Human readable string that identifies this state

Returns:

  • (String)


32
33
34
# File 'lib/state/entry.rb', line 32

def tag
  @tag
end

#validation_errorsArray<Hash> (readonly)

List of errors, encoded in a simple struct, picked up during a validation run

Returns:

  • (Array<Hash>)


63
64
65
# File 'lib/state/entry.rb', line 63

def validation_errors
  @validation_errors
end

#valuesHash

The final values computed at templating time

Returns:

  • (Hash)


52
53
54
# File 'lib/state/entry.rb', line 52

def values
  @values
end

Class Method Details

.from_dict(set, dict = {}) ⇒ Kerbi::State::Entry

Deserializes a record in dict-form and returns the corresponding Entry instance.

Parameters:

  • serialized (Hash)

    record

Returns:



208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/state/entry.rb', line 208

def self.from_dict(set, dict={})
  dict.deep_symbolize_keys!
  dict.slice!(*ATTRS)

  self.new(
    set,
    **dict,
    values: dict[:values] || {},
    default_values: dict[:default_values] || {},
    created_at: (Time.parse(dict[:created_at]) rescue nil)
  )
end

.versioned?(expr) ⇒ Boolean

Returns:

  • (Boolean)


221
222
223
# File 'lib/state/entry.rb', line 221

def self.versioned?(expr)
  Gem::Version.correct?(expr)
end

Instance Method Details

#assign_attr(attr_name, new_value) ⇒ String

Dynamically assign as a user.

Parameters:

  • attr_name (String|Symbol)
  • new_value (Object)

Returns:

  • (String)

    the old value, for convenience



125
126
127
128
129
130
131
132
133
# File 'lib/state/entry.rb', line 125

def assign_attr(attr_name, new_value)
  if SETTABLE_ATTRS.include?(attr_name.to_sym)
    old_value = send(attr_name)
    send("#{attr_name}=", new_value)
    old_value
  else
    raise Kerbi::NoSuchStateAttrName
  end
end

#candidate?TrueClass, FalseClass

A state entry is a ‘candidate’ if its tag has the candidate signature - that is it starts with [cand]-.

Returns:

  • (TrueClass, FalseClass)


77
78
79
# File 'lib/state/entry.rb', line 77

def candidate?
  tag.start_with?(CANDIDATE_PREFIX)
end

#committed?TrueClass, FalseClass

Convenience method that returns the negation of #candidate?

Returns:

  • (TrueClass, FalseClass)


84
85
86
# File 'lib/state/entry.rb', line 84

def committed?
  !candidate?
end

#demoteString

Adds the [cand]- flag to this entry’s tag, making this entry gain candidate status.

Raises an exception if this entry was already a candidate.

Returns:

  • (String)

    the old tag, for convenience

Raises:



166
167
168
169
170
171
# File 'lib/state/entry.rb', line 166

def demote
  raise Kerbi::StateNotDemotable unless committed?
  old_tag = tag
  self.tag = "#{CANDIDATE_PREFIX}#{tag}"
  old_tag
end

#overridden_keysArray<String>

Convenience method to get all overridden keys between the values and default_values dicts.

Returns:

  • (Array<String>)


177
178
179
# File 'lib/state/entry.rb', line 177

def overridden_keys
  (delta = overrides_delta) ? delta.keys.map(&:to_s) : []
end

#overrides_deltaHash

Computes a delta between this state’s values and its default values.

Returns:

  • (Hash)


112
113
114
115
116
117
118
# File 'lib/state/entry.rb', line 112

def overrides_delta
  if values.is_a?(Hash) & default_values.is_a?(Hash)
    Kerbi::Utils::Misc.deep_hash_diff(default_values, values)
  else
    nil
  end
end

#promoteString

Removes the [cand]- part of the tag, making this entry lose its candidate status.

Raises an exception if this entry was not a candidate.

Returns:

  • (String)

    the old tag, for convenience

Raises:



153
154
155
156
157
158
# File 'lib/state/entry.rb', line 153

def promote
  raise Kerbi::StateNotPromotable unless candidate?
  old_tag = tag
  self.tag = tag[CANDIDATE_PREFIX.length..]
  old_tag
end

#retag(new_tag_expr) ⇒ String

Replace current tag with a new one, where the new one can contain special interpolatable words like

Parameters:

  • new_tag_expr (String)

Returns:

  • (String)

    the old tag, for convenience



141
142
143
144
145
# File 'lib/state/entry.rb', line 141

def retag(new_tag_expr)
  old_tag = tag
  self.tag = set.resolve_write_tag_expr(new_tag_expr)
  old_tag
end

#to_hObject Also known as: serialize

Serializes the instance’s recordable attributes to a string-keyed Hash

Returns:

  • Hash



185
186
187
188
189
190
191
192
# File 'lib/state/entry.rb', line 185

def to_h
  special_ser = {
    values: values || {},
    default_values: default_values || {},
    created_at: created_at.to_s
  }
  Hash[ATTRS.map{|k|[k, send(k)]}].merge(special_ser)
end

#to_jsonString

Serializes the instance’s recordable attributes to a JSON string

Returns:

  • (String)


199
200
201
# File 'lib/state/entry.rb', line 199

def to_json
  JSON.dump(serialize)
end

#valid?Boolean

Returns:

  • (Boolean)


103
104
105
106
# File 'lib/state/entry.rb', line 103

def valid?
  raise "valid? called before #validate" unless @_was_validated
  validation_errors.empty?
end

#validateNilClass

Ghetto attribute validation. Pushes a attr => msg hash to the problems.

Returns:

  • (NilClass)


93
94
95
96
97
98
99
100
101
# File 'lib/state/entry.rb', line 93

def validate
  @validation_errors.push(
    attr: 'tag',
    msg: "Cannot be empty",
    value: tag
  ) unless tag.present?

  @_was_validated = true
end