refactor responders
This commit is contained in:
parent
fa4c5db39b
commit
494a85d968
|
@ -40,7 +40,7 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/travis-ci/travis-core.git
|
remote: git://github.com/travis-ci/travis-core.git
|
||||||
revision: 7c84635b5c180a716150c4300bff3ea8f381248c
|
revision: d30228a62f87698d20d1373e12d7e4fdda654c26
|
||||||
branch: sf-travis-api
|
branch: sf-travis-api
|
||||||
specs:
|
specs:
|
||||||
travis-core (0.0.1)
|
travis-core (0.0.1)
|
||||||
|
@ -129,7 +129,7 @@ GEM
|
||||||
activesupport
|
activesupport
|
||||||
faraday (0.8.4)
|
faraday (0.8.4)
|
||||||
multipart-post (~> 1.1)
|
multipart-post (~> 1.1)
|
||||||
foreman (0.60.0)
|
foreman (0.60.2)
|
||||||
thor (>= 0.13.6)
|
thor (>= 0.13.6)
|
||||||
hashr (0.0.22)
|
hashr (0.0.22)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
|
|
|
@ -9,9 +9,10 @@ class Travis::Api::App
|
||||||
set(:prefix) { "/" << name[/[^:]+$/].underscore }
|
set(:prefix) { "/" << name[/[^:]+$/].underscore }
|
||||||
set disable_root_endpoint: false
|
set disable_root_endpoint: false
|
||||||
register :scoping
|
register :scoping
|
||||||
helpers :current_user, :services
|
helpers :current_user, :services, :flash
|
||||||
|
|
||||||
# TODO hmmm?
|
# TODO hmmm?
|
||||||
|
before { flash.clear }
|
||||||
before { content_type :json }
|
before { content_type :json }
|
||||||
|
|
||||||
error(ActiveRecord::RecordNotFound, Sinatra::NotFound) { not_found }
|
error(ActiveRecord::RecordNotFound, Sinatra::NotFound) { not_found }
|
||||||
|
|
|
@ -4,7 +4,7 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Accounts < Endpoint
|
class Accounts < Endpoint
|
||||||
get '/', scope: :private do
|
get '/', scope: :private do
|
||||||
respond_with all(params).run, type: :accounts
|
respond_with all(params), type: :accounts
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Travis::Api::App
|
||||||
class Artifacts < Endpoint
|
class Artifacts < Endpoint
|
||||||
# Fetches an artifact by it's *id*.
|
# Fetches an artifact by it's *id*.
|
||||||
get '/:id' do |id|
|
get '/:id' do |id|
|
||||||
respond_with one(params).run || not_found
|
respond_with one(params) || not_found
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,12 +4,12 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Branches < Endpoint
|
class Branches < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
respond_with all(params).run, type: :branches
|
respond_with all(params), type: :branches
|
||||||
end
|
end
|
||||||
|
|
||||||
# get '/:owner_name/:name/branches' do # v1
|
# get '/:owner_name/:name/branches' do # v1
|
||||||
# get '/repos/:owner_name/:name/branches' do # v2
|
# get '/repos/:owner_name/:name/branches' do # v2
|
||||||
# respond_with all(params).run, type: :branches
|
# respond_with all(params), type: :branches
|
||||||
# end
|
# end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,29 +4,29 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Builds < Endpoint
|
class Builds < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
respond_with all(params).run
|
respond_with all(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
respond_with one(params).run || not_found
|
respond_with one(params).run || not_found # TODO hrmmmmmm
|
||||||
end
|
end
|
||||||
|
|
||||||
# get '/repositories/:repository_id/builds' do # v1
|
# get '/repositories/:repository_id/builds' do # v1
|
||||||
# get '/repos/:repository_id/builds' do # v2
|
# get '/repos/:repository_id/builds' do # v2
|
||||||
# respond_with all(params).run
|
# respond_with all(params)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# get '/repositories/:repository_id/builds/1' do # v1
|
# get '/repositories/:repository_id/builds/1' do # v1
|
||||||
# respond_with all(params).run
|
# respond_with all(params)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# get '/:owner_name/:name/builds' do # v1
|
# get '/:owner_name/:name/builds' do # v1
|
||||||
# get '/repos/:owner_name/:name/builds' do # v2
|
# get '/repos/:owner_name/:name/builds' do # v2
|
||||||
# respond_with all(params).run
|
# respond_with all(params)
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# get '/:owner_name/:name/builds/:id' do # v1
|
# get '/:owner_name/:name/builds/:id' do # v1
|
||||||
# respond_with all(params).run
|
# respond_with all(params)
|
||||||
# end
|
# end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Hooks < Endpoint
|
class Hooks < Endpoint
|
||||||
get '/', scope: :private do
|
get '/', scope: :private do
|
||||||
respond_with all(params).run, type: :hooks
|
respond_with all(params), type: :hooks
|
||||||
end
|
end
|
||||||
|
|
||||||
put '/:id?', scope: :private do
|
put '/:id?', scope: :private do
|
||||||
update(id: params[:id] || params[:hook][:id], active: params[:hook][:active]).run
|
update(id: params[:id] || params[:hook][:id], active: params[:hook][:active])
|
||||||
204
|
204
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Jobs < Endpoint
|
class Jobs < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
respond_with all(params).run
|
respond_with all(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
respond_with one(params).run || not_found
|
respond_with one(params).run || not_found # TODO hrmmmmmm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Travis::Api::App
|
||||||
# TODO v2 should be /repos
|
# TODO v2 should be /repos
|
||||||
class Repositories < Endpoint
|
class Repositories < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
respond_with all(params).run
|
respond_with all(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
|
|
|
@ -4,8 +4,7 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Requests < Endpoint
|
class Requests < Endpoint
|
||||||
post '/' do
|
post '/' do
|
||||||
service(:requests, :requeue, params).run
|
respond_with service(:requests, :requeue, params)
|
||||||
204
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,16 +24,16 @@ class Travis::Api::App
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/permissions', scope: :private do
|
get '/permissions', scope: :private do
|
||||||
respond_with service(:users, :permissions).run, type: :permissions
|
respond_with service(:users, :permissions), type: :permissions
|
||||||
end
|
end
|
||||||
|
|
||||||
put '/:id?', scope: :private do
|
put '/:id?', scope: :private do
|
||||||
update(params[:user]).run
|
update(params[:user])
|
||||||
204
|
204
|
||||||
end
|
end
|
||||||
|
|
||||||
post '/sync', scope: :private do
|
post '/sync', scope: :private do
|
||||||
service(:users, :sync).run
|
service(:users, :sync)
|
||||||
204
|
204
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,11 +4,11 @@ class Travis::Api::App
|
||||||
class Endpoint
|
class Endpoint
|
||||||
class Workers < Endpoint
|
class Workers < Endpoint
|
||||||
get '/' do
|
get '/' do
|
||||||
respond_with all(params).run
|
respond_with all(params)
|
||||||
end
|
end
|
||||||
|
|
||||||
get '/:id' do
|
get '/:id' do
|
||||||
respond_with one(params).run || not_found
|
respond_with one(params).run || not_found # TODO hrmmmmm
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
11
lib/travis/api/app/helpers/flash.rb
Normal file
11
lib/travis/api/app/helpers/flash.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
module Helpers
|
||||||
|
module Flash
|
||||||
|
def flash
|
||||||
|
@flash ||= []
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,19 +2,18 @@ require 'travis/api/app'
|
||||||
|
|
||||||
class Travis::Api::App
|
class Travis::Api::App
|
||||||
module Helpers
|
module Helpers
|
||||||
module Responders
|
|
||||||
autoload :Base, 'travis/api/app/helpers/responders/base'
|
|
||||||
autoload :Image, 'travis/api/app/helpers/responders/image'
|
|
||||||
autoload :Json, 'travis/api/app/helpers/responders/json'
|
|
||||||
autoload :Xml, 'travis/api/app/helpers/responders/xml'
|
|
||||||
end
|
|
||||||
|
|
||||||
# Allows routes to return either hashes or anything Travis::API.data can
|
# Allows routes to return either hashes or anything Travis::API.data can
|
||||||
# convert (in addition to the return values supported by Sinatra, of
|
# convert (in addition to the return values supported by Sinatra, of
|
||||||
# course). These values will be encoded in JSON.
|
# course). These values will be encoded in JSON.
|
||||||
module RespondWith
|
module RespondWith
|
||||||
def respond_with(resource, options = {})
|
def respond_with(resource, options = {})
|
||||||
halt responder.new(request, headers, resource, options).render
|
options[:format] ||= format_from_content_type || params[:format] || :json
|
||||||
|
responders.each do |responder|
|
||||||
|
responder = responder.new(self, resource, options)
|
||||||
|
resource = responder.apply if responder.apply?
|
||||||
|
end
|
||||||
|
resource = resource.to_json unless resource.is_a?(String) # TODO when does this happen?
|
||||||
|
halt resource
|
||||||
end
|
end
|
||||||
|
|
||||||
def body(value = nil, options = {}, &block)
|
def body(value = nil, options = {}, &block)
|
||||||
|
@ -24,12 +23,8 @@ class Travis::Api::App
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def responder
|
def responders
|
||||||
Responders.const_get(responder_type.to_s.camelize) # or raise shit
|
[Responders::Service, Responders::Json, Responders::Image, Responders::Xml]
|
||||||
end
|
|
||||||
|
|
||||||
def responder_type
|
|
||||||
format_from_content_type || params[:format] || 'json'
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# TODO is there no support for this kind of mime types?
|
# TODO is there no support for this kind of mime types?
|
||||||
|
|
13
lib/travis/api/app/helpers/responders.rb
Normal file
13
lib/travis/api/app/helpers/responders.rb
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
module Helpers
|
||||||
|
module Responders
|
||||||
|
autoload :Base, 'travis/api/app/helpers/responders/base'
|
||||||
|
autoload :Image, 'travis/api/app/helpers/responders/image'
|
||||||
|
autoload :Json, 'travis/api/app/helpers/responders/json'
|
||||||
|
autoload :Service, 'travis/api/app/helpers/responders/service'
|
||||||
|
autoload :Xml, 'travis/api/app/helpers/responders/xml'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,12 +1,31 @@
|
||||||
module Travis::Api::App::Helpers::Responders
|
module Travis::Api::App::Helpers::Responders
|
||||||
class Base
|
class Base
|
||||||
attr_reader :request, :headers, :resource, :options
|
attr_reader :endpoint, :resource, :options
|
||||||
|
|
||||||
def initialize(request, headers, resource, options = {})
|
def initialize(endpoint, resource, options = {})
|
||||||
@request = request
|
@endpoint = endpoint
|
||||||
@headers = headers
|
|
||||||
@resource = resource
|
@resource = resource
|
||||||
@options = options
|
@options = options
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def halt(*args)
|
||||||
|
endpoint.halt(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def flash
|
||||||
|
endpoint.flash
|
||||||
|
end
|
||||||
|
|
||||||
|
def request
|
||||||
|
endpoint.request
|
||||||
|
end
|
||||||
|
|
||||||
|
def params
|
||||||
|
endpoint.params
|
||||||
|
end
|
||||||
|
|
||||||
|
def headers
|
||||||
|
endpoint.headers
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,9 +2,13 @@ module Travis::Api::App::Helpers::Responders
|
||||||
class Image < Base
|
class Image < Base
|
||||||
NAMES = { nil => 'unknown', 0 => 'passing', 1 => 'failing' }
|
NAMES = { nil => 'unknown', 0 => 'passing', 1 => 'failing' }
|
||||||
|
|
||||||
def render
|
def apply?
|
||||||
|
options[:format] == 'png'
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply
|
||||||
headers['Expires'] = Time.now.utc.httpdate
|
headers['Expires'] = Time.now.utc.httpdate
|
||||||
send_file filename(resource), type: :png, disposition: :inline
|
halt send_file(filename(resource), type: :png, disposition: :inline)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
|
@ -3,22 +3,25 @@ module Travis::Api::App::Helpers::Responders
|
||||||
ACCEPT_VERSION = /vnd\.travis-ci\.(\d+)\+/
|
ACCEPT_VERSION = /vnd\.travis-ci\.(\d+)\+/
|
||||||
DEFAULT_VERSION = 'v2'
|
DEFAULT_VERSION = 'v2'
|
||||||
|
|
||||||
def render
|
def apply?
|
||||||
options[:version] ||= version
|
!resource.is_a?(String) && options[:format] == 'json'
|
||||||
builder = Travis::Api.builder(resource, options) || raise_undefined_builder
|
end
|
||||||
resource = builder.new(self.resource, request.params).data
|
|
||||||
resource = resource.to_json unless resource.is_a?(String)
|
def apply
|
||||||
resource
|
resource = builder.new(self.resource, request.params).data if builder
|
||||||
|
resource ||= self.resource || {}
|
||||||
|
resource.merge!(flash: flash) unless flash.empty?
|
||||||
|
halt resource.to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def builder
|
||||||
|
@builder ||= Travis::Api.builder(resource, { :version => version }.merge(options))
|
||||||
|
end
|
||||||
|
|
||||||
def version
|
def version
|
||||||
request.accept.join =~ ACCEPT_VERSION && "v#{$1}" || DEFAULT_VERSION
|
request.accept.join =~ ACCEPT_VERSION && "v#{$1}" || DEFAULT_VERSION
|
||||||
end
|
end
|
||||||
|
|
||||||
def raise_undefined_builder
|
|
||||||
raise("could not determine a builder for #{resource}, #{options}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
15
lib/travis/api/app/helpers/responders/service.rb
Normal file
15
lib/travis/api/app/helpers/responders/service.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module Travis::Api::App::Helpers::Responders
|
||||||
|
class Service < Base
|
||||||
|
def apply?
|
||||||
|
resource.respond_to?(:run)
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply
|
||||||
|
# TODO add caching headers depending on the resource
|
||||||
|
result = resource.run || {}
|
||||||
|
flash.concat(resource.messages) if resource.respond_to?(:messages)
|
||||||
|
result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -14,8 +14,12 @@ module Travis::Api::App::Helpers::Responders
|
||||||
'finished' => 'Sleeping'
|
'finished' => 'Sleeping'
|
||||||
}
|
}
|
||||||
|
|
||||||
def render
|
def apply?
|
||||||
TEMPLATE % data
|
options[:format] == 'xml'
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply
|
||||||
|
halt TEMPLATE % data
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
Loading…
Reference in New Issue
Block a user