travis 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +154 -0
  3. data/Rakefile +38 -0
  4. data/bin/travis +4 -0
  5. data/lib/travis.rb +8 -0
  6. data/lib/travis/cacert.pem +3895 -0
  7. data/lib/travis/cli.rb +83 -0
  8. data/lib/travis/cli/api_command.rb +65 -0
  9. data/lib/travis/cli/command.rb +212 -0
  10. data/lib/travis/cli/encrypt.rb +57 -0
  11. data/lib/travis/cli/endpoint.rb +13 -0
  12. data/lib/travis/cli/help.rb +21 -0
  13. data/lib/travis/cli/login.rb +57 -0
  14. data/lib/travis/cli/parser.rb +43 -0
  15. data/lib/travis/cli/raw.rb +16 -0
  16. data/lib/travis/cli/repo_command.rb +54 -0
  17. data/lib/travis/cli/version.rb +12 -0
  18. data/lib/travis/cli/whoami.rb +12 -0
  19. data/lib/travis/client.rb +20 -0
  20. data/lib/travis/client/entity.rb +139 -0
  21. data/lib/travis/client/error.rb +11 -0
  22. data/lib/travis/client/methods.rb +45 -0
  23. data/lib/travis/client/namespace.rb +78 -0
  24. data/lib/travis/client/repository.rb +66 -0
  25. data/lib/travis/client/session.rb +191 -0
  26. data/lib/travis/client/user.rb +20 -0
  27. data/lib/travis/pro.rb +5 -0
  28. data/lib/travis/tools/token_finder.rb +51 -0
  29. data/lib/travis/version.rb +3 -0
  30. data/spec/cli/encrypt_spec.rb +18 -0
  31. data/spec/cli/endpoint_spec.rb +23 -0
  32. data/spec/cli/help_spec.rb +33 -0
  33. data/spec/cli/login_spec.rb +13 -0
  34. data/spec/cli/version_spec.rb +18 -0
  35. data/spec/cli/whoami_spec.rb +27 -0
  36. data/spec/client/methods_spec.rb +15 -0
  37. data/spec/client/namespace_spec.rb +19 -0
  38. data/spec/client/repository_spec.rb +15 -0
  39. data/spec/client/session_spec.rb +145 -0
  40. data/spec/client/user_spec.rb +16 -0
  41. data/spec/client_spec.rb +5 -0
  42. data/spec/pro_spec.rb +10 -0
  43. data/spec/spec_helper.rb +16 -0
  44. data/spec/support/fake_api.rb +89 -0
  45. data/spec/support/fake_github.rb +20 -0
  46. data/spec/support/helpers.rb +43 -0
  47. data/spec/travis_spec.rb +9 -0
  48. data/travis.gemspec +84 -0
  49. 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
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Travis::Client do
4
+ its(:new) { should be_a(Travis::Client::Session) }
5
+ end
@@ -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
@@ -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
@@ -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