travis 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|