class Kennel::Models::Record

Constants

LOCK
READONLY_ATTRIBUTES
TRACKING_FIELDS

Attributes

project[R]

Public Class Methods

api_resource_map() click to toggle source
# File lib/kennel/models/record.rb, line 23
def api_resource_map
  subclasses.map { |s| [s.api_resource, s] }.to_h
end
new(project, *args) click to toggle source
Calls superclass method Kennel::SettingsAsMethods::new
# File lib/kennel/models/record.rb, line 58
def initialize(project, *args)
  raise ArgumentError, "First argument must be a project, not #{project.class}" unless project.is_a?(Project)
  @project = project
  super(*args)
end
parse_any_url(url) click to toggle source
# File lib/kennel/models/record.rb, line 15
def parse_any_url(url)
  subclasses.detect do |s|
    if id = s.parse_url(url)
      break s.api_resource, id
    end
  end
end
parse_tracking_id(a) click to toggle source
# File lib/kennel/models/record.rb, line 27
def parse_tracking_id(a)
  a[self::TRACKING_FIELD].to_s[/-- Managed by kennel (\S+:\S+)/, 1]
end
remove_tracking_id(a) click to toggle source

TODO: combine with parse into a single method or a single regex

# File lib/kennel/models/record.rb, line 32
def remove_tracking_id(a)
  value = a[self::TRACKING_FIELD]
  a[self::TRACKING_FIELD] =
    value.dup.sub!(/\n?-- Managed by kennel .*/, "") ||
    raise("did not find tracking id in #{value}")
end

Private Class Methods

ignore_default(expected, actual, defaults) click to toggle source
# File lib/kennel/models/record.rb, line 45
def ignore_default(expected, actual, defaults)
  definitions = [actual, expected]
  defaults.each do |key, default|
    if definitions.all? { |r| !r.key?(key) || r[key] == default }
      actual.delete(key)
      expected.delete(key)
    end
  end
end
normalize(_expected, actual) click to toggle source
# File lib/kennel/models/record.rb, line 41
def normalize(_expected, actual)
  self::READONLY_ATTRIBUTES.each { |k| actual.delete k }
end

Public Instance Methods

add_tracking_id() click to toggle source
# File lib/kennel/models/record.rb, line 87
def add_tracking_id
  json = as_json
  if self.class.parse_tracking_id(json)
    invalid! "remove \"-- Managed by kennel\" line it from #{self.class::TRACKING_FIELD} to copy a resource"
  end
  json[self.class::TRACKING_FIELD] =
    "#{json[self.class::TRACKING_FIELD]}\n" \
    "-- Managed by kennel #{tracking_id} in #{project.class.file_location}, do not modify manually".lstrip
end
diff(actual) click to toggle source
# File lib/kennel/models/record.rb, line 64
def diff(actual)
  expected = as_json
  expected.delete(:id)

  self.class.send(:normalize, expected, actual)

  # strict: ignore Integer vs Float
  # similarity: show diff when not 100% similar
  # use_lcs: saner output
  Hashdiff.diff(actual, expected, use_lcs: false, strict: false, similarity: 1)
end
remove_tracking_id() click to toggle source
# File lib/kennel/models/record.rb, line 97
def remove_tracking_id
  self.class.remove_tracking_id(as_json)
end
resolve_linked_tracking_ids!(*) click to toggle source
# File lib/kennel/models/record.rb, line 84
def resolve_linked_tracking_ids!(*)
end
tracking_id() click to toggle source
# File lib/kennel/models/record.rb, line 76
def tracking_id
  @tracking_id ||= begin
    id = "#{project.kennel_id}:#{kennel_id}"
    raise ValidationError, "#{id} kennel_id cannot include whitespace" if id.match?(/\s/) # <-> parse_tracking_id
    id
  end
end

Private Instance Methods

invalid!(message) click to toggle source

let users know which project/resource failed when something happens during diffing where the backtrace is hidden

# File lib/kennel/models/record.rb, line 122
def invalid!(message)
  raise ValidationError, "#{tracking_id} #{message}"
end
raise_with_location(error, message) click to toggle source
# File lib/kennel/models/record.rb, line 126
def raise_with_location(error, message)
  super error, "#{message} for project #{project.kennel_id}"
end