v3: refactor model rendering
This commit is contained in:
parent
b84a0a492b
commit
bc638ccb19
|
@ -6,19 +6,6 @@ module Travis::API::V3
|
||||||
extend ConstantResolver
|
extend ConstantResolver
|
||||||
extend self
|
extend self
|
||||||
|
|
||||||
def format_date(date)
|
|
||||||
date && date.strftime('%Y-%m-%dT%H:%M:%SZ')
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_attributes(object, *attributes, **defaults)
|
|
||||||
attributes.map { |a| [a, get_attribute(object, a, **defaults)] }.to_h
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_attribute(object, attribute, **defaults)
|
|
||||||
value = object.public_send(attribute)
|
|
||||||
value.nil? ? defaults[attribute] : value
|
|
||||||
end
|
|
||||||
|
|
||||||
def clear(**args)
|
def clear(**args)
|
||||||
args.select { |key, value| !value.nil? }
|
args.select { |key, value| !value.nil? }
|
||||||
end
|
end
|
||||||
|
|
65
lib/travis/api/v3/renderer/model_renderer.rb
Normal file
65
lib/travis/api/v3/renderer/model_renderer.rb
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
module Travis::API::V3
|
||||||
|
class Renderer::ModelRenderer
|
||||||
|
PRIMITIVE = [String, Symbol, Numeric, true, false, nil]
|
||||||
|
private_constant :PRIMITIVE
|
||||||
|
|
||||||
|
def self.type(type = nil)
|
||||||
|
@type = type if type
|
||||||
|
@type = name[/[^:]+$/].underscore.to_sym unless defined? @type # allows setting type to nil
|
||||||
|
@type
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.representation(name, *fields)
|
||||||
|
fields.each { |field| class_eval "def #{field}; @model.#{field}; end" unless method_defined?(field) }
|
||||||
|
representations[name] = fields
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.representations
|
||||||
|
@representations ||= {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.render(model, representation = :standard, **options)
|
||||||
|
new(model, **options).render(representation)
|
||||||
|
end
|
||||||
|
|
||||||
|
attr_reader :model, :options, :script_name
|
||||||
|
attr_writer :href
|
||||||
|
|
||||||
|
def initialize(model, script_name: nil, **options)
|
||||||
|
@model = model
|
||||||
|
@options = options
|
||||||
|
@script_name = script_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def href
|
||||||
|
return @href if defined? @href # allows setting href to nil
|
||||||
|
return unless self.class.type and model.respond_to? :id and model.id
|
||||||
|
@href = Renderer.href(self.class.type, script_name: script_name, id: model.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(representation)
|
||||||
|
result = {}
|
||||||
|
result[:@type] = self.class.type if self.class.type
|
||||||
|
result[:@href] = href if href
|
||||||
|
fields = self.class.representations.fetch(representation)
|
||||||
|
|
||||||
|
fields.each { |field| result[field] = render_value(send(field)) }
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_model(model, type: model.class.name.to_sym, mode: :minimal, **options)
|
||||||
|
Renderer[type].render(model, mode, script_name: script_name, **options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_value(value)
|
||||||
|
case value
|
||||||
|
when Hash then value.map { |k, v| [k, render_value(v)] }.to_h
|
||||||
|
when Array then value.map { |v | render_value(v) }
|
||||||
|
when *PRIMITIVE then value
|
||||||
|
when Time then value.strftime('%Y-%m-%dT%H:%M:%SZ')
|
||||||
|
when Travis::Model then render_model(value)
|
||||||
|
else raise ArgumentError, 'cannot render %p (%p)' % [value.class, value]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,18 +1,8 @@
|
||||||
|
require 'travis/api/v3/renderer/model_renderer'
|
||||||
|
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
module Renderer::Organization
|
class Renderer::Organization < Renderer::ModelRenderer
|
||||||
DIRECT_ATTRIBUTES = %i[id login name github_id]
|
representation(:minimal, :id, :login)
|
||||||
extend self
|
representation(:standard, :id, :login, :name, :github_id)
|
||||||
|
|
||||||
def render(organization, script_name: nil, **)
|
|
||||||
{
|
|
||||||
:@type => 'organization'.freeze,
|
|
||||||
:@href => Renderer.href(:organization, id: organization.id, script_name: script_name),
|
|
||||||
**direct_attributes(organization)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def direct_attributes(repository)
|
|
||||||
DIRECT_ATTRIBUTES.map { |a| [a, repository.public_send(a)] }.to_h
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,38 +1,36 @@
|
||||||
|
require 'travis/api/v3/renderer/model_renderer'
|
||||||
|
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
module Renderer::Repository
|
class Renderer::Repository < Renderer::ModelRenderer
|
||||||
DIRECT_ATTRIBUTES = %i[id name slug description github_language private active default_branch]
|
representation(:minimal, :id, :slug)
|
||||||
DEFAULTS = { active: false, default_branch: 'master' }
|
representation(:standard, :id, :name, :slug, :description, :github_language, :active, :private, :default_branch, :owner, :last_build)
|
||||||
extend self
|
|
||||||
|
|
||||||
def render(repository, script_name: nil, **)
|
def default_branch
|
||||||
|
model.default_branch || 'master'.freeze
|
||||||
|
end
|
||||||
|
|
||||||
|
def active
|
||||||
|
!!model.active
|
||||||
|
end
|
||||||
|
|
||||||
|
def owner
|
||||||
{
|
{
|
||||||
:@type => 'repository'.freeze,
|
:@type => model.owner_type && model.owner_type.downcase,
|
||||||
:@href => Renderer.href(:repository, id: repository.id, script_name: script_name),
|
:id => model.owner_id,
|
||||||
**Renderer.get_attributes(repository, *DIRECT_ATTRIBUTES, **DEFAULTS), **nested_resources(repository)
|
:login => model.owner_name
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def nested_resources(repository)
|
def last_build
|
||||||
{
|
return nil unless model.last_build_id
|
||||||
owner: {
|
|
||||||
:@type => repository.owner_type && repository.owner_type.downcase,
|
|
||||||
:id => repository.owner_id,
|
|
||||||
:login => repository.owner_name
|
|
||||||
},
|
|
||||||
last_build: last_build(repository)
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def last_build(repository)
|
|
||||||
return nil unless repository.last_build_id
|
|
||||||
{
|
{
|
||||||
:@type => 'build'.freeze,
|
:@type => 'build'.freeze,
|
||||||
:id => repository.last_build_id,
|
:id => model.last_build_id,
|
||||||
:number => repository.last_build_number,
|
:number => model.last_build_number,
|
||||||
:state => repository.last_build_state.to_s,
|
:state => model.last_build_state.to_s,
|
||||||
:duration => repository.last_build_duration,
|
:duration => model.last_build_duration,
|
||||||
:started_at => Renderer.format_date(repository.last_build_started_at),
|
:started_at => model.last_build_started_at,
|
||||||
:finished_at => Renderer.format_date(repository.last_build_finished_at),
|
:finished_at => model.last_build_finished_at,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user