travis 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README.md +154 -0
- data/Rakefile +38 -0
- data/bin/travis +4 -0
- data/lib/travis.rb +8 -0
- data/lib/travis/cacert.pem +3895 -0
- data/lib/travis/cli.rb +83 -0
- data/lib/travis/cli/api_command.rb +65 -0
- data/lib/travis/cli/command.rb +212 -0
- data/lib/travis/cli/encrypt.rb +57 -0
- data/lib/travis/cli/endpoint.rb +13 -0
- data/lib/travis/cli/help.rb +21 -0
- data/lib/travis/cli/login.rb +57 -0
- data/lib/travis/cli/parser.rb +43 -0
- data/lib/travis/cli/raw.rb +16 -0
- data/lib/travis/cli/repo_command.rb +54 -0
- data/lib/travis/cli/version.rb +12 -0
- data/lib/travis/cli/whoami.rb +12 -0
- data/lib/travis/client.rb +20 -0
- data/lib/travis/client/entity.rb +139 -0
- data/lib/travis/client/error.rb +11 -0
- data/lib/travis/client/methods.rb +45 -0
- data/lib/travis/client/namespace.rb +78 -0
- data/lib/travis/client/repository.rb +66 -0
- data/lib/travis/client/session.rb +191 -0
- data/lib/travis/client/user.rb +20 -0
- data/lib/travis/pro.rb +5 -0
- data/lib/travis/tools/token_finder.rb +51 -0
- data/lib/travis/version.rb +3 -0
- data/spec/cli/encrypt_spec.rb +18 -0
- data/spec/cli/endpoint_spec.rb +23 -0
- data/spec/cli/help_spec.rb +33 -0
- data/spec/cli/login_spec.rb +13 -0
- data/spec/cli/version_spec.rb +18 -0
- data/spec/cli/whoami_spec.rb +27 -0
- data/spec/client/methods_spec.rb +15 -0
- data/spec/client/namespace_spec.rb +19 -0
- data/spec/client/repository_spec.rb +15 -0
- data/spec/client/session_spec.rb +145 -0
- data/spec/client/user_spec.rb +16 -0
- data/spec/client_spec.rb +5 -0
- data/spec/pro_spec.rb +10 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/fake_api.rb +89 -0
- data/spec/support/fake_github.rb +20 -0
- data/spec/support/helpers.rb +43 -0
- data/spec/travis_spec.rb +9 -0
- data/travis.gemspec +84 -0
- metadata +240 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::CLI::Whoami do
|
4
|
+
example "travis whoami" do
|
5
|
+
run_cli('whoami').should_not be_success
|
6
|
+
stdout.should be_empty
|
7
|
+
stderr.should be == "not logged in, please run #$0 login\n"
|
8
|
+
end
|
9
|
+
|
10
|
+
example "travis whoami --pro" do
|
11
|
+
run_cli('whoami', '--pro').should_not be_success
|
12
|
+
stdout.should be_empty
|
13
|
+
stderr.should be == "not logged in, please run #$0 login --pro\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
example "travis whoami -t token" do
|
17
|
+
run_cli('whoami', '-t', 'token').should be_success
|
18
|
+
stdout.should be == "rkh\n"
|
19
|
+
stderr.should be_empty
|
20
|
+
end
|
21
|
+
|
22
|
+
example "travis whoami -t token -i" do
|
23
|
+
run_cli('whoami', '-t', 'token', '-i').should be_success
|
24
|
+
stdout.should be == "You are \e[1m\e[4mrkh\e[0m (Konstantin Haase)\n"
|
25
|
+
stderr.should be_empty
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::Client::Methods do
|
4
|
+
let(:session) { Travis::Client.new }
|
5
|
+
subject { OpenStruct.new(:session => session).extend(Travis::Client::Methods) }
|
6
|
+
before { subject.access_token = 'token' }
|
7
|
+
|
8
|
+
its(:api_endpoint) { should be == 'https://api.travis-ci.org/' }
|
9
|
+
its(:repos) { should be == session.find_many(Travis::Client::Repository) }
|
10
|
+
its(:user) { should be == session.find_one(Travis::Client::User) }
|
11
|
+
|
12
|
+
it 'fetches a single repo' do
|
13
|
+
subject.repo(891).slug.should be == 'rails/rails'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::Client::Namespace do
|
4
|
+
it { should be_a(Travis::Client::Methods) }
|
5
|
+
|
6
|
+
it 'creates a dummy for repos' do
|
7
|
+
repo = subject::Repository
|
8
|
+
repo.find_one('rails/rails').should be_a(Travis::Client::Repository)
|
9
|
+
repo.find_many.should be_an(Array)
|
10
|
+
repo.current.should be == repo.find_many
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'creates a dummy for user' do
|
14
|
+
subject.access_token = 'token'
|
15
|
+
user = subject::User
|
16
|
+
user.find_one.should be_a(Travis::Client::User)
|
17
|
+
user.current.should be == user.find_one
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::Client::Repository do
|
4
|
+
subject { Travis::Client.new.repo('rails/rails') }
|
5
|
+
its(:slug) { should be == 'rails/rails' }
|
6
|
+
its(:description) { should_not be_empty }
|
7
|
+
its(:last_build_id) { should be == 4125095 }
|
8
|
+
its(:last_build_number) { should be == '6180' }
|
9
|
+
its(:last_build_state) { should be == 'failed' }
|
10
|
+
its(:last_build_duration) { should be == 5019 }
|
11
|
+
its(:last_build_started_at) { should be_a(Time) }
|
12
|
+
its(:last_build_finished_at) { should be_nil }
|
13
|
+
its(:inspect) { should be == "#<Travis::Client::Repository: rails/rails>" }
|
14
|
+
its(:key) { should be_a(Travis::Client::Repository::Key) }
|
15
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::Client::Session do
|
4
|
+
it { should be_a(Travis::Client::Methods) }
|
5
|
+
|
6
|
+
describe "uri" do
|
7
|
+
its(:uri) { should be == "https://api.travis-ci.org/" }
|
8
|
+
|
9
|
+
it 'can be set as argument' do
|
10
|
+
Travis::Client::Session.new('http://foo/').uri.should be == 'http://foo/'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'can be set as hash argument' do
|
14
|
+
Travis::Client::Session.new(:uri => 'http://foo/').uri.should be == 'http://foo/'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "access_token" do
|
19
|
+
its(:access_token) { should be_nil }
|
20
|
+
|
21
|
+
it 'gives authenticated access if set' do
|
22
|
+
subject.access_token = 'token'
|
23
|
+
subject.user.login.should be == 'rkh'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'raises if token is not set' do
|
27
|
+
expect { subject.user.login }.to raise_error(Travis::Client::Error)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "connection" do
|
32
|
+
its(:connection) { should be_a(Faraday::Connection) }
|
33
|
+
|
34
|
+
it 'creates a new connection when changing the uri' do
|
35
|
+
old_connection = subject.connection
|
36
|
+
subject.uri = 'http://localhost:3000'
|
37
|
+
subject.connection.should_not be == old_connection
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "headers" do
|
42
|
+
it 'propagates headers to connection headers' do
|
43
|
+
subject.headers['foo'] = 'bar'
|
44
|
+
subject.connection.headers.should include('foo')
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'propagates headers to new connections' do
|
48
|
+
subject.headers['foo'] = 'bar'
|
49
|
+
subject.connection = Faraday::Connection.new
|
50
|
+
subject.connection.headers.should include('foo')
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'is possible to set headers as constructor option' do
|
54
|
+
Travis::Client::Session.new(:headers => {'foo' => 'bar'}, :uri => 'http://localhost:3000/').
|
55
|
+
connection.headers['foo'].should be == 'bar'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "find_one" do
|
60
|
+
it 'finds one instance' do
|
61
|
+
repo = subject.find_one(Travis::Client::Repository, 'rails/rails')
|
62
|
+
repo.should be_a(Travis::Client::Repository)
|
63
|
+
repo.slug.should be == 'rails/rails'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe "find_many" do
|
68
|
+
it 'finds many instances' do
|
69
|
+
repos = subject.find_many(Travis::Client::Repository)
|
70
|
+
repos.should be_an(Array)
|
71
|
+
repos.each { |repo| repo.should be_a(Travis::Client::Repository) }
|
72
|
+
repos.first.slug.should be == "pypug/django-mango"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "find_one_or_many" do
|
77
|
+
it 'finds one instance' do
|
78
|
+
subject.access_token = 'token'
|
79
|
+
subject.find_one_or_many(Travis::Client::User).should be_a(Travis::Client::User)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'finds many instances' do
|
83
|
+
subject.find_one_or_many(Travis::Client::Repository).should be_an(Array)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "reload" do
|
88
|
+
it 'reloads an instance' do
|
89
|
+
Travis::Client::Session::FakeAPI.rails_description = "Ruby on Rails"
|
90
|
+
rails = subject.find_one(Travis::Client::Repository, 'rails/rails')
|
91
|
+
rails.description.should be == 'Ruby on Rails'
|
92
|
+
Travis::Client::Session::FakeAPI.rails_description = 'Rails on the Rubies'
|
93
|
+
rails.description.should be == 'Ruby on Rails'
|
94
|
+
subject.reload(rails)
|
95
|
+
rails.description.should be == 'Rails on the Rubies'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "get" do
|
100
|
+
it 'fetches a payload and substitutes values with entities' do
|
101
|
+
result = subject.get('/repos/')
|
102
|
+
result['repos'].first.slug.should be == "pypug/django-mango"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe "clear_cache" do
|
107
|
+
it 'resets all the entities' do
|
108
|
+
Travis::Client::Session::FakeAPI.rails_description = "Ruby on Rails"
|
109
|
+
rails = subject.find_one(Travis::Client::Repository, 'rails/rails')
|
110
|
+
rails.description.should be == 'Ruby on Rails'
|
111
|
+
Travis::Client::Session::FakeAPI.rails_description = 'Rails on the Rubies'
|
112
|
+
rails.description.should be == 'Ruby on Rails'
|
113
|
+
subject.clear_cache
|
114
|
+
rails.description.should be == 'Rails on the Rubies'
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'keeps entries in the identity map' do
|
118
|
+
rails = subject.repo('rails/rails')
|
119
|
+
subject.clear_cache
|
120
|
+
subject.repo('rails/rails').should be_equal(rails)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "clear_cache!" do
|
125
|
+
it 'resets all the entities' do
|
126
|
+
Travis::Client::Session::FakeAPI.rails_description = "Ruby on Rails"
|
127
|
+
rails = subject.find_one(Travis::Client::Repository, 'rails/rails')
|
128
|
+
rails.description.should be == 'Ruby on Rails'
|
129
|
+
Travis::Client::Session::FakeAPI.rails_description = 'Rails on the Rubies'
|
130
|
+
rails.description.should be == 'Ruby on Rails'
|
131
|
+
subject.clear_cache!
|
132
|
+
rails.description.should be == 'Rails on the Rubies'
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'does not keep entries in the identity map' do
|
136
|
+
rails = subject.repo('rails/rails')
|
137
|
+
subject.clear_cache!
|
138
|
+
subject.repo('rails/rails').should_not be_equal(rails)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "session" do
|
143
|
+
its(:session) { should eq(subject) }
|
144
|
+
end
|
145
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::Client::User do
|
4
|
+
# attributes :login, :name, :email, :gravatar_id, :locale, :is_syncing, :synced_at, :correct_scopes
|
5
|
+
subject { Travis::Client.new(:access_token => 'token').user }
|
6
|
+
its(:login) { should be == 'rkh' }
|
7
|
+
its(:name) { should be == 'Konstantin Haase' }
|
8
|
+
its(:email) { should be == 'konstantin.haase@gmail.com' }
|
9
|
+
its(:gravatar_id) { should be == '5c2b452f6eea4a6d84c105ebd971d2a4' }
|
10
|
+
its(:locale) { should be == 'en' }
|
11
|
+
its(:is_syncing) { should be_false }
|
12
|
+
its(:synced_at) { should be_a(Time) }
|
13
|
+
|
14
|
+
it { should_not be_syncing }
|
15
|
+
it { should be_correct_scopes }
|
16
|
+
end
|
data/spec/client_spec.rb
ADDED
data/spec/pro_spec.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis::Pro do
|
4
|
+
it { should be_a(Travis::Client::Namespace) }
|
5
|
+
its(:api_endpoint) { should be == 'https://api.travis-ci.com/' }
|
6
|
+
|
7
|
+
it 'has a nice inspect on entities' do
|
8
|
+
Travis::Pro::Repository.find('rails/rails').inspect.should be == "#<Travis::Pro::Repository: rails/rails>"
|
9
|
+
end
|
10
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'support/fake_api'
|
2
|
+
require 'support/fake_github'
|
3
|
+
require 'support/helpers'
|
4
|
+
|
5
|
+
require 'fileutils'
|
6
|
+
require 'travis'
|
7
|
+
|
8
|
+
RSpec.configure do |c|
|
9
|
+
c.include Helpers
|
10
|
+
c.before do
|
11
|
+
temp_dir = File.expand_path('../tmp', __FILE__)
|
12
|
+
FileUtils.rm_rf(temp_dir)
|
13
|
+
FileUtils.mkdir_p(temp_dir)
|
14
|
+
ENV['TRAVIS_CONFIG_PATH'] = File.expand_path('travis', temp_dir)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'travis/client/session'
|
3
|
+
|
4
|
+
RAILS_KEY = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnOGqjSJGeWIlTFLm5qjEIs/7l\nEx4v0LMGld6+7RwaFjIptr/slaJXPsE8gJxxaDs5aqpD2wT0IXLYw4RDhlwOYnHI\nXjlPwak+sJycfVolhY9QAJJbADD+kwjlnnDAe5QzQg1xVLusUr9QXzZ93nftb0m7\n+Lntq91SxE1r8F/+zQIDAQAB\n-----END PUBLIC KEY-----\n"
|
5
|
+
|
6
|
+
module Travis
|
7
|
+
module Client
|
8
|
+
class Session
|
9
|
+
class FakeAPI < Sinatra::Base
|
10
|
+
disable :protection
|
11
|
+
set(:rails_description, "Ruby on Rails")
|
12
|
+
|
13
|
+
before do
|
14
|
+
content_type :json
|
15
|
+
end
|
16
|
+
|
17
|
+
def authorized?
|
18
|
+
env['HTTP_AUTHORIZATION'] == 'token token'
|
19
|
+
end
|
20
|
+
|
21
|
+
get '/users/' do
|
22
|
+
halt(403, 'wrong token') unless authorized?
|
23
|
+
{"user"=>
|
24
|
+
{"id"=>267,
|
25
|
+
"name"=>"Konstantin Haase",
|
26
|
+
"login"=>"rkh",
|
27
|
+
"email"=>"konstantin.haase@gmail.com",
|
28
|
+
"gravatar_id"=>"5c2b452f6eea4a6d84c105ebd971d2a4",
|
29
|
+
"locale"=>"en",
|
30
|
+
"is_syncing"=>false,
|
31
|
+
"synced_at"=>"2012-10-27T12:52:25Z",
|
32
|
+
"correct_scopes"=>true}}.to_json
|
33
|
+
end
|
34
|
+
|
35
|
+
get '/repos/' do
|
36
|
+
{"repos"=>
|
37
|
+
[{"id"=>107495,
|
38
|
+
"slug"=>"pypug/django-mango",
|
39
|
+
"description"=>"More Mango, less Django!",
|
40
|
+
"last_build_id"=>4125823,
|
41
|
+
"last_build_number"=>"39",
|
42
|
+
"last_build_state"=>"failed",
|
43
|
+
"last_build_duration"=>31,
|
44
|
+
"last_build_language"=>nil,
|
45
|
+
"last_build_started_at"=>"2013-01-13T16:58:43Z",
|
46
|
+
"last_build_finished_at"=>"2013-01-13T16:55:08Z"}]}.to_json
|
47
|
+
end
|
48
|
+
|
49
|
+
get '/repos/travis-ci/travis' do
|
50
|
+
# hack hack
|
51
|
+
request.path_info = '/repos/rails/rails'
|
52
|
+
pass
|
53
|
+
end
|
54
|
+
|
55
|
+
get '/repos/891' do
|
56
|
+
request.path_info = '/repos/rails/rails'
|
57
|
+
pass
|
58
|
+
end
|
59
|
+
|
60
|
+
get '/repos/rails/rails' do
|
61
|
+
{"repo"=>
|
62
|
+
{"id"=>891,
|
63
|
+
"slug"=>"rails/rails",
|
64
|
+
"description"=>settings.rails_description,
|
65
|
+
"last_build_id"=>4125095,
|
66
|
+
"last_build_number"=>"6180",
|
67
|
+
"last_build_state"=>"failed",
|
68
|
+
"last_build_duration"=>5019,
|
69
|
+
"last_build_language"=>nil,
|
70
|
+
"last_build_started_at"=>"2013-01-13T15:55:17Z",
|
71
|
+
"last_build_finished_at"=>nil}}.to_json
|
72
|
+
end
|
73
|
+
|
74
|
+
get '/repos/891/key' do
|
75
|
+
{"key"=>RAILS_KEY}.to_json
|
76
|
+
end
|
77
|
+
|
78
|
+
post '/auth/github' do
|
79
|
+
halt(403) unless params[:github_token] == 'github_token'
|
80
|
+
{ 'access_token' => 'token' }.to_json
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def faraday_adapter
|
85
|
+
[:rack, FakeAPI.new]
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'gh'
|
2
|
+
|
3
|
+
module GH
|
4
|
+
class FakeRemote < Remote
|
5
|
+
def setup(host, options)
|
6
|
+
@authenticated = options[:password] == 'password'
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def post(key, body)
|
11
|
+
raise GH::Error unless @authenticated and key == '/authorizations'
|
12
|
+
frontend.load("url" => "https://api.github.com/authorizations/1", "token" => "github_token")
|
13
|
+
end
|
14
|
+
|
15
|
+
def head(*) end
|
16
|
+
def delete(*) end
|
17
|
+
end
|
18
|
+
|
19
|
+
DefaultStack.replace(Remote, FakeRemote)
|
20
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'stringio'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Helpers
|
6
|
+
attr_reader :last_run
|
7
|
+
|
8
|
+
def capture
|
9
|
+
_stdout, $stdout = $stdout, StringIO.new
|
10
|
+
_stderr, $stderr = $stderr, StringIO.new
|
11
|
+
_stdin, $stdin = $stdin, StringIO.new
|
12
|
+
yield
|
13
|
+
capture_result(true)
|
14
|
+
rescue SystemExit => e
|
15
|
+
capture_result(e.success?)
|
16
|
+
ensure
|
17
|
+
$stdout = _stdout if _stdout
|
18
|
+
$stderr = _stderr if _stderr
|
19
|
+
$stdin = _stdin if _stdin
|
20
|
+
end
|
21
|
+
|
22
|
+
def run_cli(*args)
|
23
|
+
capture do
|
24
|
+
yield $stdin if block_given?
|
25
|
+
$stdin.rewind
|
26
|
+
Travis::CLI.run(*args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def stderr
|
31
|
+
last_run.err if last_run
|
32
|
+
end
|
33
|
+
|
34
|
+
def stdout
|
35
|
+
last_run.out if last_run
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def capture_result(success)
|
41
|
+
@last_run = OpenStruct.new(:out => $stdout.string, :err => $stderr.string, :success? => success)
|
42
|
+
end
|
43
|
+
end
|
data/spec/travis_spec.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Travis do
|
4
|
+
its(:api_endpoint) { should be == 'https://api.travis-ci.org/' }
|
5
|
+
|
6
|
+
it 'has a nice inspect on entities' do
|
7
|
+
Travis::Repository.find('rails/rails').inspect.should be == "#<Travis::Repository: rails/rails>"
|
8
|
+
end
|
9
|
+
end
|