travis-akerl 1.8.9
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.
- 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
|