travis-akerl 1.8.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +2512 -0
- data/Rakefile +64 -0
- data/assets/cacert.pem +69 -0
- data/assets/init/c.yml +4 -0
- data/assets/init/clojure.yml +1 -0
- data/assets/init/cpp.yml +4 -0
- data/assets/init/erlang.yml +3 -0
- data/assets/init/go.yml +4 -0
- data/assets/init/groovy.yml +1 -0
- data/assets/init/haskell.yml +1 -0
- data/assets/init/java.yml +4 -0
- data/assets/init/node_js.yml +5 -0
- data/assets/init/objective-c.yml +1 -0
- data/assets/init/perl.yml +4 -0
- data/assets/init/php.yml +4 -0
- data/assets/init/python.yml +5 -0
- data/assets/init/ruby.yml +6 -0
- data/assets/init/scala.yml +4 -0
- data/assets/notifications/Travis CI.app/Contents/Info.plist +52 -0
- data/assets/notifications/Travis CI.app/Contents/MacOS/Travis CI +0 -0
- data/assets/notifications/Travis CI.app/Contents/PkgInfo +1 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/Travis CI.icns +0 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/Credits.rtf +29 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/InfoPlist.strings +0 -0
- data/assets/notifications/Travis CI.app/Contents/Resources/en.lproj/MainMenu.nib +0 -0
- data/assets/notifications/Travis CI.app/Contents/_CodeSignature/CodeResources +173 -0
- data/assets/notifications/Travis CI.app/Contents/embedded.provisionprofile +0 -0
- data/assets/notifications/icon.png +0 -0
- data/assets/travis.sh +163 -0
- data/assets/travis.sh.erb +64 -0
- data/bin/travis +18 -0
- data/examples/org_overview.rb +3 -0
- data/examples/pro_auth.rb +23 -0
- data/examples/stream.rb +6 -0
- data/lib/travis/auto_login.rb +3 -0
- data/lib/travis/cli/accounts.rb +31 -0
- data/lib/travis/cli/api_command.rb +182 -0
- data/lib/travis/cli/branches.rb +25 -0
- data/lib/travis/cli/cache.rb +76 -0
- data/lib/travis/cli/cancel.rb +18 -0
- data/lib/travis/cli/command.rb +422 -0
- data/lib/travis/cli/console.rb +33 -0
- data/lib/travis/cli/disable.rb +15 -0
- data/lib/travis/cli/enable.rb +31 -0
- data/lib/travis/cli/encrypt.rb +115 -0
- data/lib/travis/cli/encrypt_file.rb +140 -0
- data/lib/travis/cli/endpoint.rb +35 -0
- data/lib/travis/cli/env.rb +66 -0
- data/lib/travis/cli/help.rb +23 -0
- data/lib/travis/cli/history.rb +49 -0
- data/lib/travis/cli/init.rb +82 -0
- data/lib/travis/cli/lint.rb +49 -0
- data/lib/travis/cli/login.rb +76 -0
- data/lib/travis/cli/logout.rb +14 -0
- data/lib/travis/cli/logs.rb +65 -0
- data/lib/travis/cli/monitor.rb +111 -0
- data/lib/travis/cli/open.rb +39 -0
- data/lib/travis/cli/parser.rb +43 -0
- data/lib/travis/cli/pubkey.rb +30 -0
- data/lib/travis/cli/raw.rb +20 -0
- data/lib/travis/cli/repo_command.rb +154 -0
- data/lib/travis/cli/report.rb +101 -0
- data/lib/travis/cli/repos.rb +53 -0
- data/lib/travis/cli/requests.rb +47 -0
- data/lib/travis/cli/restart.rb +18 -0
- data/lib/travis/cli/settings.rb +79 -0
- data/lib/travis/cli/setup/anynines.rb +21 -0
- data/lib/travis/cli/setup/appfog.rb +19 -0
- data/lib/travis/cli/setup/artifacts.rb +23 -0
- data/lib/travis/cli/setup/biicode.rb +19 -0
- data/lib/travis/cli/setup/cloud_66.rb +20 -0
- data/lib/travis/cli/setup/cloud_control.rb +21 -0
- data/lib/travis/cli/setup/cloud_files.rb +20 -0
- data/lib/travis/cli/setup/cloud_foundry.rb +23 -0
- data/lib/travis/cli/setup/code_deploy.rb +55 -0
- data/lib/travis/cli/setup/deis.rb +20 -0
- data/lib/travis/cli/setup/divshot.rb +18 -0
- data/lib/travis/cli/setup/elastic_beanstalk.rb +23 -0
- data/lib/travis/cli/setup/engine_yard.rb +24 -0
- data/lib/travis/cli/setup/gcs.rb +22 -0
- data/lib/travis/cli/setup/hackage.rb +18 -0
- data/lib/travis/cli/setup/heroku.rb +20 -0
- data/lib/travis/cli/setup/modulus.rb +18 -0
- data/lib/travis/cli/setup/ninefold.rb +20 -0
- data/lib/travis/cli/setup/nodejitsu.rb +27 -0
- data/lib/travis/cli/setup/npm.rb +20 -0
- data/lib/travis/cli/setup/open_shift.rb +20 -0
- data/lib/travis/cli/setup/opsworks.rb +22 -0
- data/lib/travis/cli/setup/pypi.rb +22 -0
- data/lib/travis/cli/setup/releases.rb +35 -0
- data/lib/travis/cli/setup/ruby_gems.rb +25 -0
- data/lib/travis/cli/setup/s3.rb +25 -0
- data/lib/travis/cli/setup/sauce_connect.rb +21 -0
- data/lib/travis/cli/setup/service.rb +73 -0
- data/lib/travis/cli/setup.rb +66 -0
- data/lib/travis/cli/show.rb +57 -0
- data/lib/travis/cli/sshkey.rb +118 -0
- data/lib/travis/cli/status.rb +19 -0
- data/lib/travis/cli/sync.rb +30 -0
- data/lib/travis/cli/token.rb +14 -0
- data/lib/travis/cli/version.rb +17 -0
- data/lib/travis/cli/whatsup.rb +30 -0
- data/lib/travis/cli/whoami.rb +15 -0
- data/lib/travis/cli.rb +126 -0
- data/lib/travis/client/account.rb +56 -0
- data/lib/travis/client/artifact.rb +88 -0
- data/lib/travis/client/auto_login.rb +45 -0
- data/lib/travis/client/broadcast.rb +14 -0
- data/lib/travis/client/build.rb +47 -0
- data/lib/travis/client/cache.rb +25 -0
- data/lib/travis/client/commit.rb +28 -0
- data/lib/travis/client/entity.rb +238 -0
- data/lib/travis/client/env_var.rb +102 -0
- data/lib/travis/client/error.rb +38 -0
- data/lib/travis/client/has_uuid.rb +13 -0
- data/lib/travis/client/job.rb +61 -0
- data/lib/travis/client/lint_result.rb +25 -0
- data/lib/travis/client/listener.rb +183 -0
- data/lib/travis/client/methods.rb +104 -0
- data/lib/travis/client/namespace.rb +85 -0
- data/lib/travis/client/not_loadable.rb +13 -0
- data/lib/travis/client/repository.rb +224 -0
- data/lib/travis/client/request.rb +36 -0
- data/lib/travis/client/restartable.rb +23 -0
- data/lib/travis/client/session.rb +339 -0
- data/lib/travis/client/settings.rb +25 -0
- data/lib/travis/client/singleton_setting.rb +36 -0
- data/lib/travis/client/ssh_key.rb +11 -0
- data/lib/travis/client/states.rb +98 -0
- data/lib/travis/client/user.rb +67 -0
- data/lib/travis/client/weak_entity.rb +26 -0
- data/lib/travis/client.rb +38 -0
- data/lib/travis/pro/auto_login.rb +3 -0
- data/lib/travis/pro.rb +5 -0
- data/lib/travis/tools/assets.rb +21 -0
- data/lib/travis/tools/completion.rb +54 -0
- data/lib/travis/tools/formatter.rb +50 -0
- data/lib/travis/tools/github.rb +293 -0
- data/lib/travis/tools/notification.rb +69 -0
- data/lib/travis/tools/safe_string.rb +22 -0
- data/lib/travis/tools/ssl_key.rb +48 -0
- data/lib/travis/tools/system.rb +88 -0
- data/lib/travis/version.rb +3 -0
- data/lib/travis.rb +8 -0
- data/spec/cli/api_command_spec.rb +38 -0
- data/spec/cli/cancel_spec.rb +15 -0
- data/spec/cli/encrypt_spec.rb +49 -0
- data/spec/cli/endpoint_spec.rb +39 -0
- data/spec/cli/help_spec.rb +33 -0
- data/spec/cli/history_spec.rb +38 -0
- data/spec/cli/init_spec.rb +227 -0
- data/spec/cli/login_spec.rb +13 -0
- data/spec/cli/logs_spec.rb +8 -0
- data/spec/cli/open_spec.rb +33 -0
- data/spec/cli/repo_command_spec.rb +25 -0
- data/spec/cli/restart_spec.rb +15 -0
- data/spec/cli/setup_spec.rb +5 -0
- data/spec/cli/show_spec.rb +9 -0
- data/spec/cli/status_spec.rb +28 -0
- data/spec/cli/token_spec.rb +22 -0
- data/spec/cli/version_spec.rb +18 -0
- data/spec/cli/whoami_spec.rb +34 -0
- data/spec/client/account_spec.rb +32 -0
- data/spec/client/auto_login_spec.rb +25 -0
- data/spec/client/broadcast_spec.rb +10 -0
- data/spec/client/build_spec.rb +31 -0
- data/spec/client/commit_spec.rb +22 -0
- data/spec/client/job_spec.rb +30 -0
- data/spec/client/methods_spec.rb +15 -0
- data/spec/client/namespace_spec.rb +19 -0
- data/spec/client/repository_spec.rb +39 -0
- data/spec/client/session_spec.rb +165 -0
- data/spec/client/user_spec.rb +16 -0
- data/spec/client_spec.rb +17 -0
- data/spec/pro_spec.rb +10 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/fake_api.rb +731 -0
- data/spec/support/fake_github.rb +24 -0
- data/spec/support/fake_travis_config.yml +14 -0
- data/spec/support/helpers.rb +45 -0
- data/spec/travis_spec.rb +10 -0
- data/travis.gemspec +371 -0
- metadata +534 -0
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Client
|
5
|
+
class Account < Entity
|
6
|
+
attributes :name, :login, :type, :repos_count, :subscribed, :education
|
7
|
+
|
8
|
+
one :account
|
9
|
+
many :accounts
|
10
|
+
|
11
|
+
inspect_info :login
|
12
|
+
id_field :login
|
13
|
+
|
14
|
+
def self.cast_id(id)
|
15
|
+
String(id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.id?(object)
|
19
|
+
object.is_a? String
|
20
|
+
end
|
21
|
+
|
22
|
+
def subscribed
|
23
|
+
load_attribute('subscribed') { true } if member?
|
24
|
+
end
|
25
|
+
|
26
|
+
def education
|
27
|
+
load_attribute('education') { false } if member?
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_trial?
|
31
|
+
!subscribed? and !education?
|
32
|
+
end
|
33
|
+
|
34
|
+
def repos_count
|
35
|
+
load_attribute("repos_count") { repositories.count }
|
36
|
+
end
|
37
|
+
|
38
|
+
def repositories
|
39
|
+
attributes['repositories'] ||= session.repos(:owner_name => login)
|
40
|
+
end
|
41
|
+
|
42
|
+
def member?
|
43
|
+
session.accounts.include? self
|
44
|
+
end
|
45
|
+
|
46
|
+
alias educational? education?
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def load_attribute(name, &block)
|
51
|
+
session.accounts if missing? name
|
52
|
+
block ? attributes.fetch(name.to_s, &block) : attributes[name.to_s]
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'travis/client'
|
3
|
+
require 'travis/tools/safe_string'
|
4
|
+
|
5
|
+
module Travis
|
6
|
+
module Client
|
7
|
+
class Artifact < Entity
|
8
|
+
CHUNKED = "application/json; chunked=true; version=2, application/json; version=2"
|
9
|
+
TEXT = "#{CHUNKED}, text/plain"
|
10
|
+
|
11
|
+
# @!parse attr_reader :job_id, :type, :body
|
12
|
+
attributes :job_id, :type, :body
|
13
|
+
|
14
|
+
# @!parse attr_reader :job
|
15
|
+
has :job
|
16
|
+
|
17
|
+
def delete_body(reason = {})
|
18
|
+
reason = { :reason => reason } unless reason.is_a? Hash
|
19
|
+
session.patch_raw("jobs/#{job_id}/log", reason)
|
20
|
+
reload
|
21
|
+
rescue Travis::Client::Error => error
|
22
|
+
raise unless error.message == '409'
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def encoded_body
|
27
|
+
Tools::SafeString.encoded(body)
|
28
|
+
end
|
29
|
+
|
30
|
+
def colorized_body
|
31
|
+
attributes['colorized_body'] ||= Tools::SafeString.colorized(body)
|
32
|
+
end
|
33
|
+
|
34
|
+
def clean_body
|
35
|
+
attributes['clean_body'] ||= Tools::SafeString.clean(body)
|
36
|
+
end
|
37
|
+
|
38
|
+
def current_body
|
39
|
+
attributes['current_body'] ||= begin
|
40
|
+
body = load_attribute('body')
|
41
|
+
if body.to_s.empty?
|
42
|
+
log = session.get_raw("jobs/#{job_id}/log", nil, "Accept" => TEXT)
|
43
|
+
body = String === log ? log : log['log']['body']
|
44
|
+
end
|
45
|
+
body
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def body(stream = block_given?)
|
50
|
+
return current_body unless block_given? or stream
|
51
|
+
return yield(current_body) unless stream and job.pending?
|
52
|
+
number = 0
|
53
|
+
|
54
|
+
session.listen(self) do |listener|
|
55
|
+
listener.on 'job:log' do |event|
|
56
|
+
next unless event.payload['number'] > number
|
57
|
+
number = event.payload['number']
|
58
|
+
yield event.payload['_log']
|
59
|
+
listener.disconnect if event.payload['final']
|
60
|
+
end
|
61
|
+
|
62
|
+
listener.on 'job:finished' do |event|
|
63
|
+
listener.disconnect
|
64
|
+
end
|
65
|
+
|
66
|
+
listener.on_connect do
|
67
|
+
data = session.get_raw("/logs/#{id}", nil, "Accept" => CHUNKED)['log']
|
68
|
+
if data['parts']
|
69
|
+
data['parts'].each { |p| yield p['content'] }
|
70
|
+
number = data['parts'].last['number'] if data['parts'].any?
|
71
|
+
else
|
72
|
+
yield data['body']
|
73
|
+
listener.disconnect
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def pusher_entity
|
80
|
+
job
|
81
|
+
end
|
82
|
+
|
83
|
+
one :log
|
84
|
+
many :logs
|
85
|
+
aka :artifact
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
require 'travis/tools/github'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Travis
|
6
|
+
module Client
|
7
|
+
class AutoLogin
|
8
|
+
NoTokenError = Class.new(RuntimeError)
|
9
|
+
attr_reader :session
|
10
|
+
|
11
|
+
def initialize(session, options = {})
|
12
|
+
@session = session.session
|
13
|
+
config_path = ENV.fetch('TRAVIS_CONFIG_PATH') { File.expand_path('.travis', Dir.home) }
|
14
|
+
@config_file = options.fetch(:config_file) { File.expand_path('config.yml', config_path) }
|
15
|
+
@auto_token = options.fetch(:auto_token) { true }
|
16
|
+
@raise = options.fetch(:raise) { true }
|
17
|
+
end
|
18
|
+
|
19
|
+
def authenticate
|
20
|
+
return if session.access_token = cli_token
|
21
|
+
github.with_token { |t| session.github_auth(t) }
|
22
|
+
end
|
23
|
+
|
24
|
+
def github
|
25
|
+
@github ||= Tools::Github.new(session.config['github']) do |g|
|
26
|
+
g.explode = true
|
27
|
+
g.manual_login = false
|
28
|
+
g.auto_token = @auto_token
|
29
|
+
g.after_tokens = proc { raise NoTokenError, "no suitable github token found" } if @raise
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def cli_token
|
34
|
+
result = cli_config
|
35
|
+
result &&= result['endpoints']
|
36
|
+
result &&= result[session.uri]
|
37
|
+
result && result['access_token']
|
38
|
+
end
|
39
|
+
|
40
|
+
def cli_config
|
41
|
+
@cli_config ||= YAML.load_file(@config_file) if File.exist? @config_file
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Client
|
5
|
+
class Broadcast < Entity
|
6
|
+
attributes :recipient_id, :recipient_type, :kind, :message, :expired, :created_at, :updated_at
|
7
|
+
|
8
|
+
one :broadcast
|
9
|
+
many :broadcasts
|
10
|
+
|
11
|
+
inspect_info :message
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Client
|
5
|
+
class Build < Entity
|
6
|
+
include States, Restartable
|
7
|
+
preloadable
|
8
|
+
|
9
|
+
# @!parse attr_reader :repository_id, :commit_id, :number, :pull_request, :pull_request_number, :pull_request_title, :config, :state, :started_at, :finished_at, :duration, :job_ids
|
10
|
+
attributes :repository_id, :commit_id, :number, :pull_request, :pull_request_number, :pull_request_title, :config, :state, :started_at, :finished_at, :duration, :job_ids
|
11
|
+
time :started_at, :finished_at
|
12
|
+
|
13
|
+
alias pull_request? pull_request
|
14
|
+
alias pr_number pull_request_number
|
15
|
+
|
16
|
+
# @!parse attr_reader :repository, :commit, :jobs
|
17
|
+
has :repository, :commit, :jobs
|
18
|
+
|
19
|
+
one :build
|
20
|
+
many :builds
|
21
|
+
aka :branch, :branches
|
22
|
+
|
23
|
+
def delete_logs(reason = {})
|
24
|
+
jobs.each do |job|
|
25
|
+
job.delete_log(reason)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def push?
|
30
|
+
not pull_request?
|
31
|
+
end
|
32
|
+
|
33
|
+
def branch_info
|
34
|
+
info = commit.branch
|
35
|
+
pull_request? ? info + " (PR ##{pr_number})" : info
|
36
|
+
end
|
37
|
+
|
38
|
+
def pusher_channels
|
39
|
+
repository.pusher_channels
|
40
|
+
end
|
41
|
+
|
42
|
+
def inspect_info
|
43
|
+
"#{repository.slug}##{number}"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'travis/client/weak_entity'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Client
|
5
|
+
class Cache < WeakEntity
|
6
|
+
# @!parse attr_reader :repository_id, :size, :slug, :branch, :last_modified
|
7
|
+
attributes :repository_id, :size, :slug, :branch, :last_modified
|
8
|
+
time :last_modified
|
9
|
+
|
10
|
+
# @!parse attr_reader :repository
|
11
|
+
has :repository
|
12
|
+
|
13
|
+
one :cache
|
14
|
+
many :caches
|
15
|
+
|
16
|
+
def delete
|
17
|
+
repository.delete_caches(:branch => branch, :match => slug)
|
18
|
+
end
|
19
|
+
|
20
|
+
def inspect_info
|
21
|
+
[repository.slug, branch, slug].compact.join(" ")
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Client
|
5
|
+
class Commit < Entity
|
6
|
+
include NotLoadable
|
7
|
+
|
8
|
+
# @!parse attr_reader :sha, :branch, :message, :committed_at, :author_name, :author_email, :committer_name, :committer_email, :compare_url
|
9
|
+
attributes :sha, :branch, :message, :committed_at, :author_name, :author_email, :committer_name, :committer_email, :compare_url
|
10
|
+
time :committed_at
|
11
|
+
|
12
|
+
one :commit
|
13
|
+
many :commits
|
14
|
+
|
15
|
+
def subject
|
16
|
+
message.to_s.lines.first.to_s.strip
|
17
|
+
end
|
18
|
+
|
19
|
+
def short_sha
|
20
|
+
sha.to_s[0..6]
|
21
|
+
end
|
22
|
+
|
23
|
+
def inspect_info
|
24
|
+
short_sha + " " + subject.inspect
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,238 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
require 'time'
|
3
|
+
|
4
|
+
module Travis
|
5
|
+
module Client
|
6
|
+
class Entity
|
7
|
+
attr_reader :attributes, :id, :session
|
8
|
+
attr_accessor :curry
|
9
|
+
|
10
|
+
MAP = {}
|
11
|
+
|
12
|
+
def self.relations
|
13
|
+
@relations ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.subclasses
|
17
|
+
MAP.values.uniq
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.subclass_for(key)
|
21
|
+
MAP.fetch(key.to_s)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.aka(*names)
|
25
|
+
names.each { |n| MAP[n.to_s] = self }
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.weak?
|
29
|
+
false
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.one(key = nil)
|
33
|
+
MAP[key.to_s] = self if key
|
34
|
+
@one ||= key.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.many(key = nil)
|
38
|
+
MAP[key.to_s] = self if key
|
39
|
+
@many ||= key.to_s
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.base_path
|
43
|
+
many
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.attributes(*list)
|
47
|
+
@attributes ||= []
|
48
|
+
|
49
|
+
list.each do |name|
|
50
|
+
name = name.to_s
|
51
|
+
fail "can't call an attribute id" if name == "id"
|
52
|
+
|
53
|
+
@attributes << name
|
54
|
+
define_method(name) { load_attribute(name) }
|
55
|
+
define_method("#{name}=") { |value| set_attribute(name, value) }
|
56
|
+
define_method("#{name}?") { !!send(name) }
|
57
|
+
end
|
58
|
+
|
59
|
+
@attributes
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.time(*list)
|
63
|
+
list.each do |name|
|
64
|
+
define_method("#{name}=") { |value| set_attribute(name, time(value)) }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.has(*list)
|
69
|
+
list.each do |name|
|
70
|
+
relations << name
|
71
|
+
define_method(name) { relation(name.to_s) }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.has_singleton(*list)
|
76
|
+
list.each do |name|
|
77
|
+
alias_method :"#{name}_id", :id unless method_defined? :"#{name}_id"
|
78
|
+
has(name)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.inspect_info(name)
|
83
|
+
alias_method(:inspect_info, name)
|
84
|
+
private(:inspect_info)
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.cast_id(id)
|
88
|
+
Integer(id)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.id?(object)
|
92
|
+
object.is_a? Integer
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.id_field(key = nil)
|
96
|
+
@id_field = key.to_s if key
|
97
|
+
@id_field || superclass.id_field
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.preloadable
|
101
|
+
def self.preloadable?
|
102
|
+
true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.preloadable?
|
107
|
+
false
|
108
|
+
end
|
109
|
+
|
110
|
+
id_field :id
|
111
|
+
|
112
|
+
def initialize(session, id)
|
113
|
+
raise Travis::Client::Error, '%p is not a valid id' % id unless self.class.id? id
|
114
|
+
@attributes = {}
|
115
|
+
@session = session
|
116
|
+
@id = self.class.cast_id(id) if id
|
117
|
+
end
|
118
|
+
|
119
|
+
def update_attributes(data)
|
120
|
+
data.each_pair do |key, value|
|
121
|
+
self[key] = value
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def attribute_names
|
126
|
+
self.class.attributes
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_h
|
130
|
+
Hash[attribute_names.map { |n| [n, self[n]] }]
|
131
|
+
end
|
132
|
+
|
133
|
+
def [](key)
|
134
|
+
key = key.to_s
|
135
|
+
send(key) if include? key
|
136
|
+
end
|
137
|
+
|
138
|
+
def []=(key, value)
|
139
|
+
key = key.to_s
|
140
|
+
send("#{key}=", value) if include? key
|
141
|
+
end
|
142
|
+
|
143
|
+
def include?(key)
|
144
|
+
attributes.include? key or attribute_names.include? key.to_s
|
145
|
+
end
|
146
|
+
|
147
|
+
def reload
|
148
|
+
relations.each { |e| session.reset(e) }
|
149
|
+
session.reset(self)
|
150
|
+
end
|
151
|
+
|
152
|
+
def load
|
153
|
+
session.reload(self) unless complete?
|
154
|
+
end
|
155
|
+
|
156
|
+
def missing?(key)
|
157
|
+
return false unless include? key
|
158
|
+
!attributes.include?(key.to_s)
|
159
|
+
end
|
160
|
+
|
161
|
+
def complete?
|
162
|
+
attribute_names.all? { |key| attributes.include? key }
|
163
|
+
end
|
164
|
+
|
165
|
+
def inspect
|
166
|
+
klass = self.class
|
167
|
+
klass = curry if curry and curry.name and curry.to_s.size < klass.to_s.size
|
168
|
+
"#<#{klass}: #{inspect_info}>"
|
169
|
+
end
|
170
|
+
|
171
|
+
def relations
|
172
|
+
self.class.relations.map { |r| public_send(r) }.flatten(1)
|
173
|
+
end
|
174
|
+
|
175
|
+
def restartable?
|
176
|
+
false
|
177
|
+
end
|
178
|
+
|
179
|
+
def cancelable?
|
180
|
+
false
|
181
|
+
end
|
182
|
+
|
183
|
+
private
|
184
|
+
|
185
|
+
def relation(name)
|
186
|
+
name = name.to_s
|
187
|
+
entity = Entity.subclass_for(name)
|
188
|
+
|
189
|
+
if entity.many == name
|
190
|
+
Array(send("#{entity.one}_ids")).map do |id|
|
191
|
+
session.find_one(entity, id)
|
192
|
+
end
|
193
|
+
else
|
194
|
+
id = send("#{name}_id")
|
195
|
+
session.find_one(entity, id) unless id.nil?
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def inspect_info
|
200
|
+
id
|
201
|
+
end
|
202
|
+
|
203
|
+
def set_attribute(name, value)
|
204
|
+
attributes[name.to_s] = value
|
205
|
+
end
|
206
|
+
|
207
|
+
def load_attribute(name)
|
208
|
+
session.reload(self) if missing? name
|
209
|
+
attributes[name.to_s]
|
210
|
+
end
|
211
|
+
|
212
|
+
# shamelessly stolen from sinatra
|
213
|
+
def time(value)
|
214
|
+
if value.respond_to? :to_time
|
215
|
+
value.to_time
|
216
|
+
elsif value.is_a? Time
|
217
|
+
value
|
218
|
+
elsif value.respond_to? :new_offset
|
219
|
+
d = value.new_offset 0
|
220
|
+
t = Time.utc d.year, d.mon, d.mday, d.hour, d.min, d.sec + d.sec_fraction
|
221
|
+
t.getlocal
|
222
|
+
elsif value.respond_to? :mday
|
223
|
+
Time.local(value.year, value.mon, value.mday)
|
224
|
+
elsif value.is_a? Numeric
|
225
|
+
Time.at value
|
226
|
+
elsif value.nil? or value.empty?
|
227
|
+
nil
|
228
|
+
else
|
229
|
+
Time.parse value.to_s
|
230
|
+
end
|
231
|
+
rescue ArgumentError => boom
|
232
|
+
raise boom
|
233
|
+
rescue Exception
|
234
|
+
raise ArgumentError, "unable to convert #{value.inspect} to a Time object"
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
require 'delegate'
|
3
|
+
|
4
|
+
module Travis
|
5
|
+
module Client
|
6
|
+
class EnvVar < Entity
|
7
|
+
class List < DelegateClass(Array)
|
8
|
+
attr_reader :repository
|
9
|
+
|
10
|
+
def initialize(repository, &block)
|
11
|
+
@repository = repository
|
12
|
+
@generator = block || ::Proc.new { session.get(EnvVar.path(repository))['env_vars'] }
|
13
|
+
super(nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def list=(list)
|
17
|
+
__setobj__ list.dup.freeze
|
18
|
+
end
|
19
|
+
|
20
|
+
def __getobj__
|
21
|
+
super || (self.list = @generator.call)
|
22
|
+
end
|
23
|
+
|
24
|
+
def reload
|
25
|
+
__setobj__ nil
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def session
|
30
|
+
repository.session
|
31
|
+
end
|
32
|
+
|
33
|
+
def repository_id
|
34
|
+
repository.id
|
35
|
+
end
|
36
|
+
|
37
|
+
def add(name, value, options = {})
|
38
|
+
body = JSON.dump(:env_var => options.merge(:name => name, :value => value))
|
39
|
+
result = session.post(EnvVar.path(self), body)
|
40
|
+
self.list += [result['env_var']]
|
41
|
+
end
|
42
|
+
|
43
|
+
def upsert(name, value, options = {})
|
44
|
+
entries = select { |e| e.name == name }
|
45
|
+
if entries.any?
|
46
|
+
entries.first.update(options.merge(:value => value))
|
47
|
+
entries[1..-1].each { |e| e.delete }
|
48
|
+
else
|
49
|
+
add(name, value, options)
|
50
|
+
end
|
51
|
+
reload
|
52
|
+
end
|
53
|
+
|
54
|
+
def [](key)
|
55
|
+
return super if key.is_a? Integer
|
56
|
+
detect { |e| e.name == key.to_s }
|
57
|
+
end
|
58
|
+
|
59
|
+
def []=(key, value)
|
60
|
+
return super if key.is_a? Integer
|
61
|
+
upsert(key.to_s, value)
|
62
|
+
end
|
63
|
+
|
64
|
+
alias list __getobj__
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.path(object)
|
68
|
+
repository_id = Repository === object ? object.id : object.repository_id
|
69
|
+
raise "repository unknown" unless repository_id
|
70
|
+
"/settings/env_vars/#{object.id if object.is_a? EnvVar}?repository_id=#{repository_id}"
|
71
|
+
end
|
72
|
+
|
73
|
+
include NotLoadable
|
74
|
+
extend HasUuid
|
75
|
+
one :env_var
|
76
|
+
many :env_vars
|
77
|
+
|
78
|
+
# @!parse attr_reader :name, :public, :repository_id
|
79
|
+
attributes :name, :value, :public, :repository_id
|
80
|
+
|
81
|
+
# @!parse attr_reader :repository
|
82
|
+
has :repository
|
83
|
+
|
84
|
+
def update(options)
|
85
|
+
options = { :value => options } unless options.is_a? Hash
|
86
|
+
result = session.patch(EnvVar.path(self), JSON.dump(:env_var => options))
|
87
|
+
attributes.replace(result['env_var'].attributes)
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def delete
|
92
|
+
session.delete_raw EnvVar.path(self)
|
93
|
+
repository.env_vars.reload
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
def inspect_info
|
98
|
+
"#{name}=#{value ? value.inspect : "[secure]"}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'travis/client'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Client
|
5
|
+
class Error < StandardError
|
6
|
+
end
|
7
|
+
|
8
|
+
class SSLError < Error
|
9
|
+
end
|
10
|
+
|
11
|
+
class NotFound < Error
|
12
|
+
end
|
13
|
+
|
14
|
+
class NotLoggedIn < Error
|
15
|
+
end
|
16
|
+
|
17
|
+
class ValidationFailed < Error
|
18
|
+
attr_reader :errors
|
19
|
+
|
20
|
+
def initialize(message = nil, *args)
|
21
|
+
message = parse_message(message) if message
|
22
|
+
super(message, *args)
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_message(message)
|
26
|
+
response = JSON.load(message)
|
27
|
+
message = response['message'].to_s
|
28
|
+
if @errors = response['errors'] and @errors.any?
|
29
|
+
readable = @errors.map { |e| "#{e['field']}: #{e['code'].gsub('_', ' ')}" }
|
30
|
+
message += " (#{readable.join(', ')})"
|
31
|
+
end
|
32
|
+
message
|
33
|
+
rescue JSON::ParserError
|
34
|
+
message
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|