rewrite all the things
This commit is contained in:
parent
f67e72602b
commit
7baf61054c
7
.travis.yml
Normal file
7
.travis.yml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
language: ruby
|
||||||
|
rvm:
|
||||||
|
- 1.9.3
|
||||||
|
before_script:
|
||||||
|
- 'RAILS_ENV=test rake db:create db:schema:load --trace'
|
||||||
|
notifications:
|
||||||
|
irc: "irc.freenode.org#travis"
|
35
Gemfile
35
Gemfile
|
@ -1,23 +1,34 @@
|
||||||
source :rubygems
|
source :rubygems
|
||||||
|
|
||||||
ruby '1.9.3' rescue nil
|
ruby '1.9.3' rescue nil
|
||||||
|
|
||||||
gem 'travis-core', github: 'travis-ci/travis-core'
|
|
||||||
gem 'travis-support', github: 'travis-ci/travis-support'
|
gem 'travis-support', github: 'travis-ci/travis-support'
|
||||||
|
gem 'travis-core', github: 'travis-ci/travis-core'
|
||||||
|
gem 'hubble', github: 'roidrage/hubble'
|
||||||
|
|
||||||
|
gem 'backports', '~> 2.5'
|
||||||
|
gem 'pg', '~> 0.13.2'
|
||||||
|
gem 'newrelic_rpm', '~> 3.3.0'
|
||||||
|
gem 'thin', '~> 1.4'
|
||||||
gem 'sinatra'
|
gem 'sinatra'
|
||||||
gem 'sinatra-contrib'
|
gem 'sinatra-contrib'
|
||||||
# gem 'sinatra-cross_origin', github: 'britg/sinatra-cross_origin'
|
gem 'redcarpet'
|
||||||
gem 'rack-contrib', github: 'rack/rack-contrib', require: 'rack/contrib'
|
|
||||||
|
|
||||||
gem 'rake', '~> 0.9.2.2'
|
group :production do
|
||||||
gem 'versionist', '~> 0.2.0'
|
gem 'rack-ssl'
|
||||||
|
end
|
||||||
|
|
||||||
# db
|
group :test do
|
||||||
gem 'pg', '~> 0.13.2'
|
gem 'rspec', '~> 2.11'
|
||||||
gem 'newrelic_rpm', '~> 3.3.0'
|
gem 'factory_girl', '~> 2.4.0'
|
||||||
gem 'hubble', git: 'git://github.com/roidrage/hubble'
|
end
|
||||||
|
|
||||||
# heroku
|
group :development do
|
||||||
gem 'unicorn', '~> 4.1.1'
|
gem 'yard-sinatra', github: 'rkh/yard-sinatra'
|
||||||
|
gem 'foreman'
|
||||||
|
gem 'rerun'
|
||||||
|
end
|
||||||
|
|
||||||
|
group :development, :test do
|
||||||
|
gem 'rake', '~> 0.9.2'
|
||||||
|
gem 'micro_migrations', git: 'git://gist.github.com/2087829.git'
|
||||||
|
end
|
||||||
|
|
86
Gemfile.lock
86
Gemfile.lock
|
@ -1,12 +1,18 @@
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/rack/rack-contrib.git
|
remote: git://gist.github.com/2087829.git
|
||||||
revision: b7e7c38fd02c3b5da91aa57af78b3f571c6ebcd0
|
revision: c766c06b0bdbda3bd96c3f4e376249cafcbbfaaa
|
||||||
specs:
|
specs:
|
||||||
rack-contrib (1.1.0)
|
micro_migrations (0.0.1)
|
||||||
rack (>= 0.9.1)
|
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/roidrage/hubble
|
remote: git://github.com/rkh/yard-sinatra.git
|
||||||
|
revision: 3b1064eef407d2d288a5b96d258178a1e67b3b80
|
||||||
|
specs:
|
||||||
|
yard-sinatra (1.0.0)
|
||||||
|
yard (~> 0.7)
|
||||||
|
|
||||||
|
GIT
|
||||||
|
remote: git://github.com/roidrage/hubble.git
|
||||||
revision: 5220415d5542a2868d54f7be9f35fc1d66126b8e
|
revision: 5220415d5542a2868d54f7be9f35fc1d66126b8e
|
||||||
specs:
|
specs:
|
||||||
hubble (0.1.2)
|
hubble (0.1.2)
|
||||||
|
@ -63,25 +69,29 @@ GEM
|
||||||
activesupport (= 3.2.6)
|
activesupport (= 3.2.6)
|
||||||
arel (~> 3.0.2)
|
arel (~> 3.0.2)
|
||||||
tzinfo (~> 0.3.29)
|
tzinfo (~> 0.3.29)
|
||||||
activeresource (3.2.6)
|
|
||||||
activemodel (= 3.2.6)
|
|
||||||
activesupport (= 3.2.6)
|
|
||||||
activesupport (3.2.6)
|
activesupport (3.2.6)
|
||||||
i18n (~> 0.6)
|
i18n (~> 0.6)
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
addressable (2.2.8)
|
addressable (2.3.1)
|
||||||
arel (3.0.2)
|
arel (3.0.2)
|
||||||
atomic (1.0.1)
|
atomic (1.0.1)
|
||||||
avl_tree (1.1.3)
|
avl_tree (1.1.3)
|
||||||
backports (2.6.1)
|
backports (2.6.2)
|
||||||
builder (3.0.0)
|
builder (3.0.0)
|
||||||
|
daemons (1.1.8)
|
||||||
data_migrations (0.0.1)
|
data_migrations (0.0.1)
|
||||||
activerecord
|
activerecord
|
||||||
rake
|
rake
|
||||||
|
diff-lcs (1.1.3)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (0.12.10)
|
eventmachine (0.12.10)
|
||||||
|
factory_girl (2.4.2)
|
||||||
|
activesupport
|
||||||
faraday (0.8.1)
|
faraday (0.8.1)
|
||||||
multipart-post (~> 1.1)
|
multipart-post (~> 1.1)
|
||||||
|
ffi (1.1.0)
|
||||||
|
foreman (0.53.0)
|
||||||
|
thor (>= 0.13.6)
|
||||||
gh (0.7.3)
|
gh (0.7.3)
|
||||||
addressable
|
addressable
|
||||||
backports (~> 2.3)
|
backports (~> 2.3)
|
||||||
|
@ -95,7 +105,10 @@ GEM
|
||||||
i18n (0.6.0)
|
i18n (0.6.0)
|
||||||
journey (1.0.4)
|
journey (1.0.4)
|
||||||
json (1.6.7)
|
json (1.6.7)
|
||||||
kgio (2.7.4)
|
listen (0.4.7)
|
||||||
|
rb-fchange (~> 0.0.5)
|
||||||
|
rb-fsevent (~> 0.9.1)
|
||||||
|
rb-inotify (~> 0.8.8)
|
||||||
mail (2.4.4)
|
mail (2.4.4)
|
||||||
i18n (>= 0.4.0)
|
i18n (>= 0.4.0)
|
||||||
mime-types (~> 1.16)
|
mime-types (~> 1.16)
|
||||||
|
@ -131,14 +144,6 @@ GEM
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.1)
|
rack-test (0.6.1)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (3.2.6)
|
|
||||||
actionmailer (= 3.2.6)
|
|
||||||
actionpack (= 3.2.6)
|
|
||||||
activerecord (= 3.2.6)
|
|
||||||
activeresource (= 3.2.6)
|
|
||||||
activesupport (= 3.2.6)
|
|
||||||
bundler (~> 1.0)
|
|
||||||
railties (= 3.2.6)
|
|
||||||
railties (3.2.6)
|
railties (3.2.6)
|
||||||
actionpack (= 3.2.6)
|
actionpack (= 3.2.6)
|
||||||
activesupport (= 3.2.6)
|
activesupport (= 3.2.6)
|
||||||
|
@ -146,12 +151,27 @@ GEM
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
rdoc (~> 3.4)
|
rdoc (~> 3.4)
|
||||||
thor (>= 0.14.6, < 2.0)
|
thor (>= 0.14.6, < 2.0)
|
||||||
raindrops (0.10.0)
|
|
||||||
rake (0.9.2.2)
|
rake (0.9.2.2)
|
||||||
|
rb-fchange (0.0.5)
|
||||||
|
ffi
|
||||||
|
rb-fsevent (0.9.1)
|
||||||
|
rb-inotify (0.8.8)
|
||||||
|
ffi (>= 0.5.0)
|
||||||
rdoc (3.12)
|
rdoc (3.12)
|
||||||
json (~> 1.4)
|
json (~> 1.4)
|
||||||
|
redcarpet (2.1.1)
|
||||||
redis (3.0.1)
|
redis (3.0.1)
|
||||||
|
rerun (0.7.1)
|
||||||
|
listen
|
||||||
rollout (1.1.0)
|
rollout (1.1.0)
|
||||||
|
rspec (2.11.0)
|
||||||
|
rspec-core (~> 2.11.0)
|
||||||
|
rspec-expectations (~> 2.11.0)
|
||||||
|
rspec-mocks (~> 2.11.0)
|
||||||
|
rspec-core (2.11.1)
|
||||||
|
rspec-expectations (2.11.2)
|
||||||
|
diff-lcs (~> 1.1.3)
|
||||||
|
rspec-mocks (2.11.1)
|
||||||
signature (0.1.3)
|
signature (0.1.3)
|
||||||
simple_states (0.1.1)
|
simple_states (0.1.1)
|
||||||
activesupport
|
activesupport
|
||||||
|
@ -171,33 +191,37 @@ GEM
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (~> 1.1, != 1.3.0)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
|
thin (1.4.1)
|
||||||
|
daemons (>= 1.0.9)
|
||||||
|
eventmachine (>= 0.12.6)
|
||||||
|
rack (>= 1.0.0)
|
||||||
thor (0.14.6)
|
thor (0.14.6)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
treetop (1.4.10)
|
treetop (1.4.10)
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.33)
|
tzinfo (0.3.33)
|
||||||
unicorn (4.1.1)
|
|
||||||
kgio (~> 2.4)
|
|
||||||
rack
|
|
||||||
raindrops (~> 0.6)
|
|
||||||
versionist (0.2.3)
|
|
||||||
rails (~> 3.0)
|
|
||||||
yard (~> 0.7)
|
|
||||||
yard (0.8.2.1)
|
yard (0.8.2.1)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
|
backports (~> 2.5)
|
||||||
|
factory_girl (~> 2.4.0)
|
||||||
|
foreman
|
||||||
hubble!
|
hubble!
|
||||||
|
micro_migrations!
|
||||||
newrelic_rpm (~> 3.3.0)
|
newrelic_rpm (~> 3.3.0)
|
||||||
pg (~> 0.13.2)
|
pg (~> 0.13.2)
|
||||||
rack-contrib!
|
rack-ssl
|
||||||
rake (~> 0.9.2.2)
|
rake (~> 0.9.2)
|
||||||
|
redcarpet
|
||||||
|
rerun
|
||||||
|
rspec (~> 2.11)
|
||||||
sinatra
|
sinatra
|
||||||
sinatra-contrib
|
sinatra-contrib
|
||||||
|
thin (~> 1.4)
|
||||||
travis-core!
|
travis-core!
|
||||||
travis-support!
|
travis-support!
|
||||||
unicorn (~> 4.1.1)
|
yard-sinatra!
|
||||||
versionist (~> 0.2.0)
|
|
||||||
|
|
60
README.md
Normal file
60
README.md
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# The public Travis API
|
||||||
|
|
||||||
|
This is the app (eventually) running on https://api.travis-ci.org/
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Setup:
|
||||||
|
|
||||||
|
$ bundle install
|
||||||
|
|
||||||
|
Run tests:
|
||||||
|
|
||||||
|
$ RAILS_ENV=test rake db:create db:schema:load
|
||||||
|
$ rake spec
|
||||||
|
|
||||||
|
Run the server:
|
||||||
|
|
||||||
|
$ rake db:create db:schema:load
|
||||||
|
$ foreman start
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
1. Fork it
|
||||||
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||||
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||||
|
4. Push to the branch (`git push origin my-new-feature`)
|
||||||
|
5. Create new Pull Request
|
||||||
|
|
||||||
|
### API documentation
|
||||||
|
|
||||||
|
We use source code comments to add documentation. If the server is running, you
|
||||||
|
can browse an HTML documenation at [`/docs`](http://localhost:5000/docs).
|
||||||
|
|
||||||
|
### Project architecture
|
||||||
|
|
||||||
|
lib
|
||||||
|
`-- travis
|
||||||
|
`-- api
|
||||||
|
`-- app
|
||||||
|
|-- endpoint # API endpoints
|
||||||
|
|-- extensions # Sinatra extensions
|
||||||
|
|-- helpers # Sinatra helpers
|
||||||
|
`-- middleware # Rack middleware
|
||||||
|
|
||||||
|
Classes inheriting from `Endpoint` or `Middleware`, they will automatically be
|
||||||
|
set up properly.
|
||||||
|
|
||||||
|
Each endpoint class gets mapped to a prefix, which defaults to the snake-case
|
||||||
|
class name (i.e. `Travis::Api::App::Profile` will map to `/profile`).
|
||||||
|
It can be overridden by setting `:prefix`:
|
||||||
|
|
||||||
|
``` ruby
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class MyRouts < Endpoint
|
||||||
|
set :prefix, '/awesome'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
13
Rakefile
Normal file
13
Rakefile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
require 'bundler/setup'
|
||||||
|
ENV['SCHEMA'] = "#{Gem.loaded_specs['travis-core'].full_gem_path}/db/schema.rb"
|
||||||
|
|
||||||
|
require 'micro_migrations'
|
||||||
|
require 'travis'
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'rspec/core/rake_task'
|
||||||
|
RSpec::Core::RakeTask.new
|
||||||
|
task default: :spec
|
||||||
|
rescue LoadError
|
||||||
|
warn "could not load rspec"
|
||||||
|
end
|
|
@ -1,5 +1,2 @@
|
||||||
$:.unshift 'lib'
|
|
||||||
|
|
||||||
require 'travis/api/app'
|
require 'travis/api/app'
|
||||||
|
run Travis::Api::App.new
|
||||||
run Travis::Api::App
|
|
||||||
|
|
|
@ -1,105 +1,64 @@
|
||||||
require 'sinatra'
|
# Make sure we set that before everything
|
||||||
require 'sinatra/reloader'
|
ENV['RACK_ENV'] ||= ENV['RAILS_ENV'] || ENV['ENV']
|
||||||
require 'travis/api/cors'
|
ENV['RAILS_ENV'] = ENV['RACK_ENV']
|
||||||
require 'json'
|
|
||||||
require 'travis'
|
require 'travis'
|
||||||
|
require 'backports'
|
||||||
|
require 'rack'
|
||||||
|
require 'rack/protection'
|
||||||
|
require 'active_record'
|
||||||
|
|
||||||
Travis::Database.connect
|
# Rack class implementing the HTTP API.
|
||||||
|
# Instances respond to #call.
|
||||||
|
#
|
||||||
|
# run Travis::Api::App.new
|
||||||
|
#
|
||||||
|
# Requires TLS in production.
|
||||||
|
class Travis::Api::App
|
||||||
|
autoload :Responder, 'travis/api/app/responder'
|
||||||
|
autoload :Endpoint, 'travis/api/app/endpoint'
|
||||||
|
autoload :Extensions, 'travis/api/app/extensions'
|
||||||
|
autoload :Helpers, 'travis/api/app/helpers'
|
||||||
|
autoload :Middleware, 'travis/api/app/middleware'
|
||||||
|
|
||||||
module Travis
|
Rack.autoload :SSL, 'rack/ssl'
|
||||||
module Api
|
|
||||||
class App < Sinatra::Application
|
|
||||||
autoload :Service, 'travis/api/app/service'
|
|
||||||
disable :protection
|
|
||||||
|
|
||||||
use ActiveRecord::ConnectionAdapters::ConnectionManagement
|
# Used to track if setup already ran.
|
||||||
use Travis::API::CORS
|
def self.setup?
|
||||||
|
@setup ||= false
|
||||||
|
end
|
||||||
|
|
||||||
error ActiveRecord::RecordNotFound do
|
# Loads all endpoints and middleware and hooks them up properly.
|
||||||
not_found
|
# Calls #setup on any middleware and endpoint.
|
||||||
end
|
#
|
||||||
|
# This method is not threadsafe, but called when loading
|
||||||
|
# the environment, so no biggy.
|
||||||
|
def self.setup(options = {})
|
||||||
|
return if setup?
|
||||||
|
Travis::Database.connect
|
||||||
|
|
||||||
configure :development do
|
Responder.set(options) if options
|
||||||
register Sinatra::Reloader
|
Backports.require_relative_dir 'app/middleware'
|
||||||
set :show_exceptions, :after_handler
|
Backports.require_relative_dir 'app/endpoint'
|
||||||
end
|
Responder.subclasses.each(&:setup)
|
||||||
|
|
||||||
before do
|
@setup = true
|
||||||
content_type :json
|
end
|
||||||
end
|
|
||||||
|
|
||||||
get '/repositories' do
|
attr_accessor :app
|
||||||
respond_with Service::Repos.new(params).collection
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/repositories/:id' do
|
def initialize
|
||||||
respond_with Service::Repos.new(params).item
|
Travis::Api::App.setup
|
||||||
# raise if not params[:format] == 'png'
|
@app = Rack::Builder.app do
|
||||||
end
|
use Rack::Protection::PathTraversal
|
||||||
|
use Rack::SSL if Endpoint.production?
|
||||||
get '/builds' do
|
Middleware.subclasses.each { |m| use(m) }
|
||||||
respond_with Service::Builds.new(params).collection
|
Endpoint.subclasses.each { |e| map(e.prefix) { run(e) } }
|
||||||
end
|
|
||||||
|
|
||||||
get '/builds/:id' do
|
|
||||||
respond_with Service::Builds.new(params).item
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/branches' do
|
|
||||||
# respond_with Service::Repos.new(params).item, :type => :branches
|
|
||||||
{ branches: [] }.to_json
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/jobs' do
|
|
||||||
respond_with Service::Jobs.new(params).collection, :type => 'jobs'
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/jobs/:id' do
|
|
||||||
respond_with Service::Jobs.new(params).item, :type => 'job'
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/artifacts/:id' do
|
|
||||||
respond_with Service::Artifacts.new(params).item
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/workers' do
|
|
||||||
respond_with Service::Workers.new(params).collection
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/hooks' do
|
|
||||||
authenticate_user!
|
|
||||||
respond_with Service::Hooks.new(user, params).item
|
|
||||||
# rescue_from ActiveRecord::RecordInvalid, :with => Proc.new { head :not_acceptable }
|
|
||||||
end
|
|
||||||
|
|
||||||
put '/hooks/:id' do
|
|
||||||
authenticate_user!
|
|
||||||
respond_with Service::Hooks.new(user, params).update
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/profile' do
|
|
||||||
authenticate_user!
|
|
||||||
respond_with Service::Profile.new(user).update
|
|
||||||
end
|
|
||||||
|
|
||||||
post '/profile/sync' do
|
|
||||||
authenticate_user!
|
|
||||||
respond_with Service::Profile.new(user).sync
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def authenticate_user!
|
|
||||||
@user = User.find_by_login('svenfuchs')
|
|
||||||
end
|
|
||||||
|
|
||||||
def respond_with(resource, options = {})
|
|
||||||
Travis::Api.data(resource, { :params => params, :version => version }.merge(options)).to_json
|
|
||||||
end
|
|
||||||
|
|
||||||
def version
|
|
||||||
'v2'
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Rack protocol
|
||||||
|
def call(env)
|
||||||
|
app.call(env)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
16
lib/travis/api/app/endpoint.rb
Normal file
16
lib/travis/api/app/endpoint.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
# Superclass for HTTP endpoints. Takes care of prefixing.
|
||||||
|
class Endpoint < Responder
|
||||||
|
set(:prefix) { "/" << name[/[^:]+$/].underscore }
|
||||||
|
before { content_type :json }
|
||||||
|
|
||||||
|
error(ActiveRecord::RecordNotFound, Sinatra::NotFound) { not_found }
|
||||||
|
not_found { content_type =~ /json/ ? { 'file' => 'not found' } : 'file not found' }
|
||||||
|
|
||||||
|
# TODO: Dummy method.
|
||||||
|
def self.scope(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
lib/travis/api/app/endpoint/artifacts.rb
Normal file
11
lib/travis/api/app/endpoint/artifacts.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Artifacts < Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
get('/:id') { |id| Artifact.find(id) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
lib/travis/api/app/endpoint/branches.rb
Normal file
11
lib/travis/api/app/endpoint/branches.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Branches < Endpoint
|
||||||
|
# TODO: Add better implementation and documentation.
|
||||||
|
get('/') {{ branches: [] }}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
28
lib/travis/api/app/endpoint/builds.rb
Normal file
28
lib/travis/api/app/endpoint/builds.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Builds < Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
get '/' do
|
||||||
|
scope = repository.builds.by_event_type(params[:event_type] || 'push')
|
||||||
|
scope = params[:after] ? scope.older_than(params[:after]) : scope.recent
|
||||||
|
scope
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: Add documentation.
|
||||||
|
get '/:id' do
|
||||||
|
one = params[:repository_id] ? repository.builds : Build
|
||||||
|
one.includes(:commit, :matrix => [:commit, :log]).find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def repository
|
||||||
|
pass if params.empty?
|
||||||
|
Repository.find_by(params) || not_found
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
185
lib/travis/api/app/endpoint/documentation.rb
Normal file
185
lib/travis/api/app/endpoint/documentation.rb
Normal file
|
@ -0,0 +1,185 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# Generated API documentation.
|
||||||
|
class Documentation < Endpoint
|
||||||
|
set prefix: '/docs'
|
||||||
|
enable :inline_templates
|
||||||
|
|
||||||
|
# HTML view for [/endpoints](#/endpoints/).
|
||||||
|
get '/' do
|
||||||
|
content_type :html
|
||||||
|
endpoints = Endpoints.endpoints
|
||||||
|
erb :index, {}, :endpoints => endpoints.keys.sort.map { |k| endpoints[k] }
|
||||||
|
end
|
||||||
|
|
||||||
|
helpers do
|
||||||
|
def icon_for(verb)
|
||||||
|
# GET, POST, PATCH, PUT, DELETE"
|
||||||
|
case verb
|
||||||
|
when 'GET' then 'file'
|
||||||
|
when 'POST' then 'edit'
|
||||||
|
when 'PATCH' then 'wrench'
|
||||||
|
when 'PUT' then 'share'
|
||||||
|
when 'DELETE' then 'trash'
|
||||||
|
else 'question-sign'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def slug_for(route)
|
||||||
|
return route['uri'] if route['verb'] == 'GET'
|
||||||
|
route['verb'] + " " + route['uri']
|
||||||
|
end
|
||||||
|
|
||||||
|
def docs_for(entry)
|
||||||
|
markdown(entry['doc']).
|
||||||
|
gsub('<pre', '<pre class="prettyprint linenums lang-js pre-scrollable"').
|
||||||
|
gsub(/<\/?code>/, '').
|
||||||
|
gsub(/TODO:?/, '<span class="label label-warning">TODO</span>')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
__END__
|
||||||
|
|
||||||
|
@@ index
|
||||||
|
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Travis API documentation</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
|
||||||
|
<!-- we might wanna change this -->
|
||||||
|
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css" rel="stylesheet" />
|
||||||
|
<link href="http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css" rel="stylesheet" />
|
||||||
|
<link href="http://twitter.github.com/bootstrap/assets/js/google-code-prettify/prettify.css" rel="stylesheet" />
|
||||||
|
<script src="http://twitter.github.com/bootstrap/assets/js/jquery.js"></script>
|
||||||
|
<script src="http://twitter.github.com/bootstrap/assets/js/google-code-prettify/prettify.js"></script>
|
||||||
|
<script src="http://twitter.github.com/bootstrap/assets/js/bootstrap.min.js"></script>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
header {
|
||||||
|
position: relative;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 36px;
|
||||||
|
}
|
||||||
|
header h1 {
|
||||||
|
text-shadow: 2px 2px 5px #000;
|
||||||
|
margin-bottom: 9px;
|
||||||
|
font-size: 81px;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
header p {
|
||||||
|
margin-bottom: 18px;
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.page-header {
|
||||||
|
margin-top: 90px;
|
||||||
|
}
|
||||||
|
.route {
|
||||||
|
margin-bottom: 36px;
|
||||||
|
}
|
||||||
|
.page-header a {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.nav-list a {
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body onload="prettyPrint()">
|
||||||
|
<div class="container-fluid">
|
||||||
|
<div class="row-fluid">
|
||||||
|
<header class="span12">
|
||||||
|
<h1>The Travis API</h1>
|
||||||
|
<p>All the routes, just waiting for you to build something awesome.</p>
|
||||||
|
</header>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
|
||||||
|
<aside class="span3">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>Navigation</h1>
|
||||||
|
</div>
|
||||||
|
<div class="well" style="padding: 8px 0;">
|
||||||
|
<ul class="nav nav-list">
|
||||||
|
<% endpoints.each do |endpoint| %>
|
||||||
|
<li class="nav-header"><a href="#<%= endpoint['name'] %>"><%= endpoint['name'] %></a></li>
|
||||||
|
<% endpoint['routes'].each do |route| %>
|
||||||
|
<li>
|
||||||
|
<a href="#<%= slug_for(route) %>">
|
||||||
|
<i class="icon-<%= icon_for route['verb'] %>"></i>
|
||||||
|
<tt><%= route['uri'] %></tt>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
<li class="divider"></li>
|
||||||
|
<li class="nav-header">
|
||||||
|
External Links
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://travis-ci.org">
|
||||||
|
<i class="icon-globe"></i>
|
||||||
|
Travis CI
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/travis-ci/travis-api">
|
||||||
|
<i class="icon-cog"></i>
|
||||||
|
Source Code
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/travis-ci/travis-api/issues">
|
||||||
|
<i class="icon-list-alt"></i>
|
||||||
|
API issues
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/travis-ci/travis-ember">
|
||||||
|
<i class="icon-play-circle"></i>
|
||||||
|
Example Client
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
<section class="span9">
|
||||||
|
|
||||||
|
<% endpoints.each do |endpoint| %>
|
||||||
|
<div id="<%= endpoint['name'] %>">
|
||||||
|
<div class="page-header">
|
||||||
|
<h1>
|
||||||
|
<a href="#<%= endpoint['name'] %>"><%= endpoint['name'] %></a>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<%= docs_for endpoint %>
|
||||||
|
<% endpoint['routes'].each do |route| %>
|
||||||
|
<div class="route" id="<%= slug_for(route) %>">
|
||||||
|
<pre><h3><%= route['verb'] %> <%= route['uri'] %></h3></pre>
|
||||||
|
<p>
|
||||||
|
<h5>Required autorization scope: <span class="label"><%= route['scope'] %></span></h5>
|
||||||
|
</p>
|
||||||
|
<%= docs_for route %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
68
lib/travis/api/app/endpoint/endpoints.rb
Normal file
68
lib/travis/api/app/endpoint/endpoints.rb
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
require 'yard/sinatra'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# Documents all available API endpoints for the currently deployed version.
|
||||||
|
# Text is actually parsed from the source code upon server start.
|
||||||
|
class Endpoints < Endpoint
|
||||||
|
set :endpoints, {}
|
||||||
|
|
||||||
|
set :setup do
|
||||||
|
endpoint_files = Dir.glob(File.expand_path("../*.rb", __FILE__))
|
||||||
|
YARD::Registry.load(endpoint_files, true)
|
||||||
|
|
||||||
|
YARD::Sinatra.routes.each do |route|
|
||||||
|
namespace = route.namespace
|
||||||
|
controller = namespace.to_s.constantize
|
||||||
|
route_info = {
|
||||||
|
'uri' => (controller.prefix + route.http_path[1..-2]).gsub('//', '/'),
|
||||||
|
'verb' => route.http_verb,
|
||||||
|
'doc' => route.docstring,
|
||||||
|
'scope' => /scope\W+(\w+)/.match(route.source).try(:[], 1) || 'public'
|
||||||
|
}
|
||||||
|
endpoint = endpoints[controller.prefix] ||= {
|
||||||
|
'name' => namespace.name,
|
||||||
|
'doc' => namespace.docstring,
|
||||||
|
'prefix' => controller.prefix,
|
||||||
|
'routes' => []
|
||||||
|
}
|
||||||
|
endpoint['routes'] << route_info
|
||||||
|
end
|
||||||
|
|
||||||
|
set :json, endpoints.keys.sort.map { |k| endpoints[k] }.to_json
|
||||||
|
endpoints.each_value { |r| r[:json] = r.to_json if r.respond_to? :to_hash }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Lists all available API endpoints by URI prefix.
|
||||||
|
#
|
||||||
|
# Values in the resulting array correspond to return values of
|
||||||
|
# [`/endpoints/:prefix`](#/endpoints/:prefix).
|
||||||
|
get '/' do
|
||||||
|
settings.json
|
||||||
|
end
|
||||||
|
|
||||||
|
# Infos about a specific controller.
|
||||||
|
#
|
||||||
|
# Example response:
|
||||||
|
#
|
||||||
|
# {
|
||||||
|
# name: "Endpoints",
|
||||||
|
# doc: "Documents all available API endpoints...",
|
||||||
|
# prefix: "/endpoints",
|
||||||
|
# routes: [
|
||||||
|
# {
|
||||||
|
# uri: "/endpoints/:prefix",
|
||||||
|
# verb: "GET",
|
||||||
|
# doc: "Infos about...",
|
||||||
|
# scope: "public"
|
||||||
|
# }
|
||||||
|
# ]
|
||||||
|
# }
|
||||||
|
get '/:prefix' do |prefix|
|
||||||
|
pass unless endpoint = settings.endpoints["/#{prefix}"]
|
||||||
|
endpoint[:json]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
lib/travis/api/app/endpoint/home.rb
Normal file
15
lib/travis/api/app/endpoint/home.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
class Home < Endpoint
|
||||||
|
set(:prefix, '/')
|
||||||
|
|
||||||
|
# Landing point. Redirects web browsers to [API documentation](#/docs/).
|
||||||
|
get '/' do
|
||||||
|
redirect to('/docs/') if request.preferred_type('application/json', 'text/html') == 'text/html'
|
||||||
|
{ 'hello' => 'world' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
14
lib/travis/api/app/endpoint/hooks.rb
Normal file
14
lib/travis/api/app/endpoint/hooks.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Hooks < Endpoint
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
get('/', scope: :private) { raise NotImplementedError }
|
||||||
|
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
put('/:id', scope: :admin) { raise NotImplementedError }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
14
lib/travis/api/app/endpoint/jobs.rb
Normal file
14
lib/travis/api/app/endpoint/jobs.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Jobs < Endpoint
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
get('/') { raise NotImplementedError }
|
||||||
|
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
get('/:id') { raise NotImplementedError }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
14
lib/travis/api/app/endpoint/profile.rb
Normal file
14
lib/travis/api/app/endpoint/profile.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Profile < Endpoint
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
get('/', scope: :private) { raise NotImplementedError }
|
||||||
|
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
post('/sync', scope: :private) { raise NotImplementedError }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
lib/travis/api/app/endpoint/repositories.rb
Normal file
20
lib/travis/api/app/endpoint/repositories.rb
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Repositories < Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
get '/' do
|
||||||
|
scope = Repository.timeline.recent
|
||||||
|
scope = scope.by_owner_name(params[:owner_name]) if params[:owner_name]
|
||||||
|
scope = scope.by_slug(params[:slug]) if params[:slug]
|
||||||
|
scope = scope.search(params[:search]) if params[:search].present?
|
||||||
|
scope
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: Add documentation.
|
||||||
|
get('/:id') { Repository.find_by(params) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
lib/travis/api/app/endpoint/workers.rb
Normal file
11
lib/travis/api/app/endpoint/workers.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Endpoint
|
||||||
|
# TODO: Add documentation.
|
||||||
|
class Workers < Endpoint
|
||||||
|
# TODO: Add implementation and documentation.
|
||||||
|
get('/') { Worker.order(:host, :name) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
8
lib/travis/api/app/extensions.rb
Normal file
8
lib/travis/api/app/extensions.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
# Namespace for Sinatra extensions.
|
||||||
|
module Extensions
|
||||||
|
Backports.require_relative_dir 'extensions'
|
||||||
|
end
|
||||||
|
end
|
28
lib/travis/api/app/extensions/smart_constants.rb
Normal file
28
lib/travis/api/app/extensions/smart_constants.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
module Extensions
|
||||||
|
# Allows writing
|
||||||
|
#
|
||||||
|
# helpers :some_helper
|
||||||
|
#
|
||||||
|
# Instead of
|
||||||
|
#
|
||||||
|
# helpers Travis::Api::App::Helpers::SomeHelper
|
||||||
|
module SmartConstants
|
||||||
|
def helpers(*list, &block)
|
||||||
|
super(*resolve_constants(list, Helpers), &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def register(*list, &block)
|
||||||
|
super(*resolve_constants(list, Extensions), &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def resolve_constants(list, namespace)
|
||||||
|
list.map { |e| Symbol === e ? namespace.const_get(e.to_s.camelize) : e }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
25
lib/travis/api/app/extensions/subclass_tracker.rb
Normal file
25
lib/travis/api/app/extensions/subclass_tracker.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
module Extensions
|
||||||
|
# Keeps track of subclasses. Used for endpoint and middleware detection.
|
||||||
|
# This will prevent garbage collection of subclasses.
|
||||||
|
module SubclassTracker
|
||||||
|
def direct_subclasses
|
||||||
|
@direct_subclasses ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
# List of "leaf" subclasses (ie subclasses without subclasses).
|
||||||
|
def subclasses
|
||||||
|
return [self] if direct_subclasses.empty?
|
||||||
|
direct_subclasses.map(&:subclasses).flatten.uniq
|
||||||
|
end
|
||||||
|
|
||||||
|
def inherited(subclass)
|
||||||
|
super
|
||||||
|
subclass.set app_file: caller_files.first
|
||||||
|
direct_subclasses << subclass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
8
lib/travis/api/app/helpers.rb
Normal file
8
lib/travis/api/app/helpers.rb
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
# Namespace for helpers.
|
||||||
|
module Helpers
|
||||||
|
Backports.require_relative_dir 'helpers'
|
||||||
|
end
|
||||||
|
end
|
32
lib/travis/api/app/helpers/json_renderer.rb
Normal file
32
lib/travis/api/app/helpers/json_renderer.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
module Helpers
|
||||||
|
# Allows routes to return either hashes or anything Travis::API.data can
|
||||||
|
# convert (in addition to the return values supported by Sinatra, of
|
||||||
|
# course). These values will be encoded in JSON.
|
||||||
|
module JsonRenderer
|
||||||
|
def respond_with(resource, options = {})
|
||||||
|
halt render_json(resource, options)
|
||||||
|
end
|
||||||
|
|
||||||
|
def body(value = nil, &block)
|
||||||
|
value = render_json(value) if value
|
||||||
|
super(value, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def render_json(resource, options = {})
|
||||||
|
options[:version] ||= 'v2' # TODO: Content negotiation
|
||||||
|
options[:params] ||= params
|
||||||
|
|
||||||
|
builder = Travis::Api.builder(resource, options)
|
||||||
|
resource = builder.new(resource, options[:params]).data.to_json if builder
|
||||||
|
resource = resource.to_json if resource.is_a? Hash
|
||||||
|
|
||||||
|
resource
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
7
lib/travis/api/app/middleware.rb
Normal file
7
lib/travis/api/app/middleware.rb
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
# Superclass for all middleware.
|
||||||
|
class Middleware < Responder
|
||||||
|
end
|
||||||
|
end
|
9
lib/travis/api/app/middleware/access_token.rb
Normal file
9
lib/travis/api/app/middleware/access_token.rb
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Middleware
|
||||||
|
# Checks access tokens and sets appropriate scopes.
|
||||||
|
class AccessToken < Middleware
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,10 +1,12 @@
|
||||||
require 'sinatra/base'
|
require 'travis/api/app'
|
||||||
|
|
||||||
module Travis
|
|
||||||
module API
|
|
||||||
class CORS < Sinatra::Base
|
|
||||||
disable :protection
|
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Middleware
|
||||||
|
# Implements Cross-Origin Resource Sharing. Supported by all major browsers.
|
||||||
|
# See http://www.w3.org/TR/cors/
|
||||||
|
#
|
||||||
|
# TODO: Be smarter about origin.
|
||||||
|
class Cors < Middleware
|
||||||
before do
|
before do
|
||||||
headers['Access-Control-Allow-Origin'] = "*"
|
headers['Access-Control-Allow-Origin'] = "*"
|
||||||
headers['Access-Control-Allow-Credentials'] = "true"
|
headers['Access-Control-Allow-Credentials'] = "true"
|
||||||
|
@ -13,7 +15,7 @@ module Travis
|
||||||
|
|
||||||
options // do
|
options // do
|
||||||
headers['Access-Control-Allow-Methods'] = "GET, POST, PATCH, PUT, DELETE"
|
headers['Access-Control-Allow-Methods'] = "GET, POST, PATCH, PUT, DELETE"
|
||||||
headers['Access-Control-Allow-Headers'] = "Content-Type, Authorization"
|
headers['Access-Control-Allow-Headers'] = "Content-Type, Authorization, Accept"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
15
lib/travis/api/app/middleware/logging.rb
Normal file
15
lib/travis/api/app/middleware/logging.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
class Middleware
|
||||||
|
# Makes sure we use Travis.logger everywhere.
|
||||||
|
class Logging < Middleware
|
||||||
|
set(:setup) { ActiveRecord::Base.logger = Travis.logger }
|
||||||
|
|
||||||
|
before do
|
||||||
|
env['rack.logger'] = Travis.logger
|
||||||
|
env['rack.errors'] = Travis.logger.instance_variable_get(:@logdev).dev rescue nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
27
lib/travis/api/app/responder.rb
Normal file
27
lib/travis/api/app/responder.rb
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
require 'travis/api/app'
|
||||||
|
require 'sinatra/base'
|
||||||
|
|
||||||
|
class Travis::Api::App
|
||||||
|
# Superclass for any endpoint and middleware.
|
||||||
|
# Pulls in relevant helpers and extensions.
|
||||||
|
class Responder < Sinatra::Base
|
||||||
|
register Extensions::SmartConstants
|
||||||
|
|
||||||
|
configure do
|
||||||
|
# We pull in certain protection middleware in App.
|
||||||
|
# Being token based makes us invulnerable to common
|
||||||
|
# CSRF attack.
|
||||||
|
#
|
||||||
|
# Logging is set up by custom middleware
|
||||||
|
disable :protection, :logging, :setup
|
||||||
|
register :subclass_tracker
|
||||||
|
helpers :json_renderer
|
||||||
|
end
|
||||||
|
|
||||||
|
configure :development do
|
||||||
|
# We want error pages in development, but only
|
||||||
|
# when we don't have an error handler specified
|
||||||
|
set :show_exceptions, :after_handler
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,20 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
autoload :Artifacts, 'travis/api/app/service/artifacts'
|
|
||||||
autoload :Builds, 'travis/api/app/service/builds'
|
|
||||||
autoload :Hooks, 'travis/api/app/service/hooks'
|
|
||||||
autoload :Jobs, 'travis/api/app/service/jobs'
|
|
||||||
autoload :Repos, 'travis/api/app/service/repos'
|
|
||||||
autoload :Workers, 'travis/api/app/service/workers'
|
|
||||||
|
|
||||||
attr_reader :params
|
|
||||||
|
|
||||||
def initialize(params)
|
|
||||||
@params = params
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,14 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Artifacts < Service
|
|
||||||
def item
|
|
||||||
Artifact.find(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Builds < Service
|
|
||||||
def collection
|
|
||||||
scope = repository.builds.by_event_type(params[:event_type] || 'push')
|
|
||||||
scope = params[:after] ? scope.older_than(params[:after]) : scope.recent
|
|
||||||
scope
|
|
||||||
end
|
|
||||||
|
|
||||||
def item
|
|
||||||
one = params[:repository_id] ? repository.builds : Build
|
|
||||||
one.includes(:commit, :matrix => [:commit, :log]).find(params[:id])
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def repository
|
|
||||||
Repository.find_by(params) || not_found # TODO needs to return nil if params are empty
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Hooks < Service
|
|
||||||
attr_reader :user
|
|
||||||
|
|
||||||
def initialize(user, params)
|
|
||||||
super(params)
|
|
||||||
@user = user
|
|
||||||
end
|
|
||||||
|
|
||||||
def collection
|
|
||||||
user.service_hooks
|
|
||||||
end
|
|
||||||
|
|
||||||
def update
|
|
||||||
hook.set(payload[:active], user)
|
|
||||||
hook
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def hook
|
|
||||||
repository.service_hook
|
|
||||||
end
|
|
||||||
|
|
||||||
def repository
|
|
||||||
Repository.find_or_create_by_owner_name_and_name(params[:owner_name], params[:name])
|
|
||||||
end
|
|
||||||
|
|
||||||
def payload
|
|
||||||
params[:service_hook] || {}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,23 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Jobs < Service
|
|
||||||
def collection
|
|
||||||
if params[:ids]
|
|
||||||
Job::Test.where(:id => params[:ids]).includes(:commit, :log)
|
|
||||||
else
|
|
||||||
jobs = Job::Test.queued.includes(:commit, :log)
|
|
||||||
jobs = jobs.where(:queue => params[:queue]) if params[:queue]
|
|
||||||
jobs
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def item
|
|
||||||
Job::Test.find(params[:id])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,32 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Profile < Service
|
|
||||||
attr_reader :user
|
|
||||||
|
|
||||||
def initialize(user)
|
|
||||||
@user = user
|
|
||||||
end
|
|
||||||
|
|
||||||
def item
|
|
||||||
user
|
|
||||||
end
|
|
||||||
|
|
||||||
def sync
|
|
||||||
unless user.is_syncing?
|
|
||||||
publisher.publish({ user_id: user.id }, type: 'sync')
|
|
||||||
user.update_attribute(:is_syncing, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def publisher
|
|
||||||
Travis::Amqp::Publisher.new('sync.user')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,27 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Repos
|
|
||||||
attr_reader :params
|
|
||||||
|
|
||||||
def initialize(params)
|
|
||||||
@params = params
|
|
||||||
end
|
|
||||||
|
|
||||||
def collection
|
|
||||||
scope = Repository.timeline.recent
|
|
||||||
scope = scope.by_owner_name(params[:owner_name]) if params[:owner_name]
|
|
||||||
scope = scope.by_slug(params[:slug]) if params[:slug]
|
|
||||||
scope = scope.search(params[:search]) if params[:search].present?
|
|
||||||
scope
|
|
||||||
end
|
|
||||||
|
|
||||||
def item
|
|
||||||
Repository.find_by(params)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,14 +0,0 @@
|
||||||
module Travis
|
|
||||||
module Api
|
|
||||||
class App
|
|
||||||
class Service
|
|
||||||
class Workers < Service
|
|
||||||
def collection
|
|
||||||
Worker.order(:host, :name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
8
script/server
Executable file
8
script/server
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
cd "$(dirname "$0")/.."
|
||||||
|
[ $PORT ] || PORT=5000
|
||||||
|
[ $RACK_ENV ] || RACK_ENV=development
|
||||||
|
|
||||||
|
cmd="ruby -I lib -S bundle exec ruby -I lib -S thin start -p $PORT -e $RACK_ENV --threaded"
|
||||||
|
[[ $RACK_ENV == "development" ]] && exec rerun "$cmd -a 127.0.0.1"
|
||||||
|
exec $cmd
|
10
spec/app_spec.rb
Normal file
10
spec/app_spec.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App do
|
||||||
|
describe :setup? do
|
||||||
|
it 'indicates if #setup has been called' do
|
||||||
|
Travis::Api::App.setup
|
||||||
|
Travis::Api::App.should be_setup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
15
spec/default_spec.rb
Normal file
15
spec/default_spec.rb
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Home do
|
||||||
|
describe 'GET /' do
|
||||||
|
it 'replies with a json response by default' do
|
||||||
|
get('/')["Content-Type"].should include("json")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects HTML requests to /docs' do
|
||||||
|
get '/', {}, 'HTTP_ACCEPT' => 'text/html'
|
||||||
|
status.should == 302
|
||||||
|
headers['Location'].should end_with('/docs/')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
12
spec/endpoint/artifacts_spec.rb
Normal file
12
spec/endpoint/artifacts_spec.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Artifacts do
|
||||||
|
let(:artifact) { Factory(:log) }
|
||||||
|
let(:id) { artifact.id }
|
||||||
|
|
||||||
|
describe 'GET /artifacts/:id' do
|
||||||
|
it 'loads the artifact' do
|
||||||
|
get("/artifacts/#{id}").should be_ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
5
spec/endpoint/branches_spec.rb
Normal file
5
spec/endpoint/branches_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Branches do
|
||||||
|
it 'has to be implemented'
|
||||||
|
end
|
5
spec/endpoint/builds_spec.rb
Normal file
5
spec/endpoint/builds_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Builds do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/documentation_spec.rb
Normal file
5
spec/endpoint/documentation_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Documentation do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/endpoints_spec.rb
Normal file
5
spec/endpoint/endpoints_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Endpoints do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/hooks_spec.rb
Normal file
5
spec/endpoint/hooks_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Hooks do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/jobs_spec.rb
Normal file
5
spec/endpoint/jobs_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Jobs do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/profile_spec.rb
Normal file
5
spec/endpoint/profile_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Profile do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/repositories_spec.rb
Normal file
5
spec/endpoint/repositories_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Repositories do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
5
spec/endpoint/workers_spec.rb
Normal file
5
spec/endpoint/workers_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint::Workers do
|
||||||
|
it 'has to be tested'
|
||||||
|
end
|
18
spec/endpoint_spec.rb
Normal file
18
spec/endpoint_spec.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Endpoint do
|
||||||
|
class MyEndpoint < Travis::Api::App::Endpoint
|
||||||
|
set :prefix, '/my_endpoint'
|
||||||
|
get('/') { 'ok' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets up endpoints automatically under given prefix' do
|
||||||
|
get('/my_endpoint/').should be_ok
|
||||||
|
body.should == "ok"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'does not require a trailing slash' do
|
||||||
|
get('/my_endpoint').should be_ok
|
||||||
|
body.should == "ok"
|
||||||
|
end
|
||||||
|
end
|
22
spec/extensions/smart_constants_spec.rb
Normal file
22
spec/extensions/smart_constants_spec.rb
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Extensions::SmartConstants do
|
||||||
|
let(:some_app) do
|
||||||
|
Sinatra.new { register Travis::Api::App::Extensions::SmartConstants }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :helpers do
|
||||||
|
it 'works' do # :)
|
||||||
|
some_app.helpers :json_renderer
|
||||||
|
some_app.ancestors.should include(Travis::Api::App::Helpers::JsonRenderer)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :register do
|
||||||
|
it 'works' do # :)
|
||||||
|
some_app.register :subclass_tracker
|
||||||
|
some_app.should be_a(Travis::Api::App::Extensions::SubclassTracker)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
31
spec/extensions/subclass_tracker_spec.rb
Normal file
31
spec/extensions/subclass_tracker_spec.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Extensions::SubclassTracker do
|
||||||
|
let!(:root) { Sinatra.new { register Travis::Api::App::Extensions::SubclassTracker } }
|
||||||
|
let!(:left) { Class.new(root) }
|
||||||
|
let!(:right) { Class.new(root) }
|
||||||
|
let!(:sub1) { Class.new(right) }
|
||||||
|
let!(:sub2) { Class.new(right) }
|
||||||
|
|
||||||
|
it 'tracks direct subclasses' do
|
||||||
|
classes = root.direct_subclasses
|
||||||
|
classes.size.should == 2
|
||||||
|
classes.should include(left)
|
||||||
|
classes.should include(right)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'tracks leaf subclasses' do
|
||||||
|
classes = root.subclasses
|
||||||
|
classes.size.should == 3
|
||||||
|
classes.should include(left)
|
||||||
|
classes.should include(sub1)
|
||||||
|
classes.should include(sub2)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'tracks subclasses of subclasses properly' do
|
||||||
|
classes = right.subclasses
|
||||||
|
classes.size.should == 2
|
||||||
|
classes.should include(sub1)
|
||||||
|
classes.should include(sub2)
|
||||||
|
end
|
||||||
|
end
|
16
spec/helpers/json_renderer_spec.rb
Normal file
16
spec/helpers/json_renderer_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
require 'json'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Helpers::JsonRenderer do
|
||||||
|
before do
|
||||||
|
mock_app do
|
||||||
|
helpers Travis::Api::App::Helpers::JsonRenderer
|
||||||
|
get('/') { {'foo' => 'bar'} }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders body as json' do
|
||||||
|
get('/').should be_ok
|
||||||
|
JSON.load(body).should == {'foo' => 'bar'}
|
||||||
|
end
|
||||||
|
end
|
16
spec/middleware/access_token_spec.rb
Normal file
16
spec/middleware/access_token_spec.rb
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Middleware::AccessToken do
|
||||||
|
before do
|
||||||
|
mock_app do
|
||||||
|
use Travis::Api::App::Middleware::AccessToken
|
||||||
|
get('/check_cors') { 'ok' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets associated scope properly'
|
||||||
|
it 'lets through requests without a token'
|
||||||
|
it 'reject requests with an invalide token'
|
||||||
|
it 'rejects expired tokens'
|
||||||
|
it 'checks that the token corresponds to Origin'
|
||||||
|
end
|
50
spec/middleware/cors_spec.rb
Normal file
50
spec/middleware/cors_spec.rb
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Middleware::Cors do
|
||||||
|
before do
|
||||||
|
mock_app do
|
||||||
|
use Travis::Api::App::Middleware::Cors
|
||||||
|
get('/check_cors') { 'ok' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'normal request' do
|
||||||
|
before { get('/check_cors').should be_ok }
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Origin' do
|
||||||
|
headers['Access-Control-Allow-Origin'].should == "*"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Credentials' do
|
||||||
|
headers['Access-Control-Allow-Credentials'].should == "true"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Expose-Headers' do
|
||||||
|
headers['Access-Control-Expose-Headers'].should == "Content-Type"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'OPTIONS requests' do
|
||||||
|
before { options('/').should be_ok }
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Origin' do
|
||||||
|
headers['Access-Control-Allow-Origin'].should == "*"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Credentials' do
|
||||||
|
headers['Access-Control-Allow-Credentials'].should == "true"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Expose-Headers' do
|
||||||
|
headers['Access-Control-Expose-Headers'].should == "Content-Type"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Methods' do
|
||||||
|
headers['Access-Control-Allow-Methods'].should == "GET, POST, PATCH, PUT, DELETE"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets Access-Control-Allow-Headers' do
|
||||||
|
headers['Access-Control-Allow-Headers'].should == "Content-Type, Authorization, Accept"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
19
spec/middleware/logging_spec.rb
Normal file
19
spec/middleware/logging_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Middleware::Logging do
|
||||||
|
it 'configures ActiveRecord' do
|
||||||
|
ActiveRecord::Base.logger.should == Travis.logger
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets the logger' do
|
||||||
|
mock_app do
|
||||||
|
use Travis::Api::App::Middleware::Logging
|
||||||
|
get '/check_logger' do
|
||||||
|
logger.should == Travis.logger
|
||||||
|
'ok'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
get('/check_logger').should be_ok
|
||||||
|
end
|
||||||
|
end
|
12
spec/middleware_spec.rb
Normal file
12
spec/middleware_spec.rb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Travis::Api::App::Middleware do
|
||||||
|
class MyMiddleware < Travis::Api::App::Middleware
|
||||||
|
get('/my_middleware') { 'ok' }
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'sets up middleware automatically' do
|
||||||
|
get('/my_middleware').should be_ok
|
||||||
|
body.should == "ok"
|
||||||
|
end
|
||||||
|
end
|
17
spec/spec_helper.rb
Normal file
17
spec/spec_helper.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
ENV['RACK_ENV'] = ENV['RAILS_ENV'] = ENV['ENV'] = 'test'
|
||||||
|
|
||||||
|
require 'rspec'
|
||||||
|
require 'travis/api/app'
|
||||||
|
require 'sinatra/test_helpers'
|
||||||
|
require 'logger'
|
||||||
|
|
||||||
|
Travis.logger = Logger.new(StringIO.new)
|
||||||
|
Travis::Api::App.setup
|
||||||
|
|
||||||
|
Backports.require_relative_dir 'support'
|
||||||
|
|
||||||
|
RSpec.configure do |config|
|
||||||
|
config.expect_with :rspec, :stdlib
|
||||||
|
config.include Sinatra::TestHelpers
|
||||||
|
config.before(:each) { set_app Travis::Api::App.new }
|
||||||
|
end
|
99
spec/support/factories.rb
Normal file
99
spec/support/factories.rb
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
require 'factory_girl'
|
||||||
|
|
||||||
|
FactoryGirl.define do
|
||||||
|
factory :build do
|
||||||
|
repository { Repository.first || Factory(:repository) }
|
||||||
|
association :request
|
||||||
|
association :commit
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :commit do
|
||||||
|
repository { Repository.first || Factory(:repository) }
|
||||||
|
commit '62aae5f70ceee39123ef'
|
||||||
|
branch 'master'
|
||||||
|
message 'the commit message'
|
||||||
|
committed_at '2011-11-11T11:11:11Z'
|
||||||
|
committer_name 'Sven Fuchs'
|
||||||
|
committer_email 'svenfuchs@artweb-design.de'
|
||||||
|
author_name 'Sven Fuchs'
|
||||||
|
author_email 'svenfuchs@artweb-design.de'
|
||||||
|
compare_url 'https://github.com/svenfuchs/minimal/compare/master...develop'
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :test, :class => 'Job::Test' do
|
||||||
|
repository { Repository.first || Factory(:repository) }
|
||||||
|
commit { Factory(:commit) }
|
||||||
|
source { Factory(:build) }
|
||||||
|
log { Factory(:log) }
|
||||||
|
queue "ruby"
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :log, :class => 'Artifact::Log' do
|
||||||
|
content '$ bundle install --pa'
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :request do
|
||||||
|
repository { Repository.first || Factory(:repository) }
|
||||||
|
association :commit
|
||||||
|
token 'the-token'
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :repository do
|
||||||
|
name 'minimal'
|
||||||
|
owner_name 'svenfuchs'
|
||||||
|
owner_email 'svenfuchs@artweb-design.de'
|
||||||
|
url { |r| "http://github.com/#{r.owner_name}/#{r.name}" }
|
||||||
|
last_duration 60
|
||||||
|
created_at { |r| Time.utc(2011, 01, 30, 5, 25) }
|
||||||
|
updated_at { |r| r.created_at + 5.minutes }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :minimal, :parent => :repository do
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :enginex, :class => Repository do
|
||||||
|
name 'enginex'
|
||||||
|
owner_name 'josevalim'
|
||||||
|
last_duration 30
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :running_build, :parent => :build do
|
||||||
|
repository { Factory(:repository, :name => 'running_build') }
|
||||||
|
state 'started'
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :successful_build, :parent => :build do
|
||||||
|
repository { Factory(:repository, :name => 'successful_build', :last_build_result => 0) }
|
||||||
|
result 0
|
||||||
|
state 'finished'
|
||||||
|
started_at { Time.now.utc }
|
||||||
|
finished_at { Time.now.utc }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :broken_build, :parent => :build do
|
||||||
|
repository { Factory(:repository, :name => 'broken_build', :last_build_result => 1) }
|
||||||
|
result 1
|
||||||
|
state 'finished'
|
||||||
|
started_at { Time.now.utc }
|
||||||
|
finished_at { Time.now.utc }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :user do
|
||||||
|
name 'Sven Fuchs'
|
||||||
|
login 'svenfuchs'
|
||||||
|
email 'sven@fuchs.com'
|
||||||
|
tokens { [Token.new] }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :worker do
|
||||||
|
name 'worker-1'
|
||||||
|
host 'ruby-1.workers.travis-ci.org'
|
||||||
|
state :working
|
||||||
|
last_seen_at { Time.now.utc }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :ssl_key do
|
||||||
|
private_key "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQDGed1uxl9szL0PVE/B6v9PDso+xRHs9e9YDB8Dm+QYFDyddud1\nn1134ZY39Dxg6zNhXDGKYilHP4E9boIuvgfSADN12eD1clogX46M4oBGgUAhtr5Q\nvGLn9TEW4IbeI+nDshMJLTLethCmB6Hwm5Ld9QnRVT6U/AztOTv9eJ/xKQIDAQAB\nAoGABQ3zcq/AnF+2bN6DzXdzmwrQYbrZEwTMXJyqaYgdzfMt/ACcMmWllrj6/1/L\n7dfvjgowBMstK/BVFUBsNk6GmmoCDHFAU+BgeyyqUxyeb63+0dIDwVYx9LHTL4dr\n9a8cVyeefqc3mqB13B9NUlS40Ij4kuK6EOGP3DZwC1FQVwECQQDtBQFqgRuNdfbV\naGIcXnuMnD4BGrnFHm0IBdLYsK4ULL85gFbhEew6DTYGYlGqX1dXbXYue8F18D8i\nzqL6HOBhAkEA1l6zvLdC2t3J9UnwpkwU0jSPX4BpHH7IkrCoGRggjwtbSxJFcCKB\nRrbPFDNAwchsa2/ldXSBrFg6Y7GlwF3lyQJAaJk+6LuVZzZZ+hAYzCA+Me15x479\n0Kn+v/2h8RL3n9ungD7NGIKKV4wg/WxCUgfFScX608S1udCObFP4xJwdwQJBALtl\nwEQqBGSmXCV0xM3rVoxH7En1TG3fm2E400pUoCnMKLugtlkHoPF7X91tzJ9aoQTu\npa2e8rkBy9FY++gFbZkCQAJ46lGEXZJqcACvLX0t/+RrvmqWMxCydLFG50kOnD8b\nVNILVyUn1lYasTs4aMYr6BRtVZoCxqV5/+rkMhb1eOM=\n-----END RSA PRIVATE KEY-----\n"
|
||||||
|
public_key "-----BEGIN RSA PUBLIC KEY-----\nMIGJAoGBAMZ53W7GX2zMvQ9UT8Hq/08Oyj7FEez171gMHwOb5BgUPJ1253WfXXfh\nljf0PGDrM2FcMYpiKUc/gT1ugi6+B9IAM3XZ4PVyWiBfjozigEaBQCG2vlC8Yuf1\nMRbght4j6cOyEwktMt62EKYHofCbkt31CdFVPpT8DO05O/14n/EpAgMBAAE=\n-----END RSA PUBLIC KEY-----\n"
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +0,0 @@
|
||||||
# encoding: utf-8
|
|
||||||
|
|
||||||
Gem::Specification.new do |s|
|
|
||||||
s.name = 'travis-api'
|
|
||||||
s.version = '0.0.1'
|
|
||||||
s.require_path = 'lib'
|
|
||||||
end
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user