tddium 1.25.5
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 +15 -0
- data/bin/tddium +29 -0
- data/lib/tddium.rb +19 -0
- data/lib/tddium/agent.rb +3 -0
- data/lib/tddium/agent/tddium.rb +122 -0
- data/lib/tddium/cli.rb +26 -0
- data/lib/tddium/cli/api.rb +319 -0
- data/lib/tddium/cli/commands/account.rb +49 -0
- data/lib/tddium/cli/commands/activate.rb +14 -0
- data/lib/tddium/cli/commands/config.rb +55 -0
- data/lib/tddium/cli/commands/describe.rb +96 -0
- data/lib/tddium/cli/commands/find_failing.rb +62 -0
- data/lib/tddium/cli/commands/github.rb +53 -0
- data/lib/tddium/cli/commands/heroku.rb +15 -0
- data/lib/tddium/cli/commands/hg.rb +48 -0
- data/lib/tddium/cli/commands/keys.rb +83 -0
- data/lib/tddium/cli/commands/login.rb +37 -0
- data/lib/tddium/cli/commands/logout.rb +14 -0
- data/lib/tddium/cli/commands/password.rb +26 -0
- data/lib/tddium/cli/commands/rerun.rb +50 -0
- data/lib/tddium/cli/commands/server.rb +22 -0
- data/lib/tddium/cli/commands/spec.rb +306 -0
- data/lib/tddium/cli/commands/status.rb +107 -0
- data/lib/tddium/cli/commands/stop.rb +19 -0
- data/lib/tddium/cli/commands/suite.rb +110 -0
- data/lib/tddium/cli/commands/web.rb +22 -0
- data/lib/tddium/cli/config.rb +245 -0
- data/lib/tddium/cli/params_helper.rb +36 -0
- data/lib/tddium/cli/prompt.rb +128 -0
- data/lib/tddium/cli/show.rb +122 -0
- data/lib/tddium/cli/suite.rb +179 -0
- data/lib/tddium/cli/tddium.rb +153 -0
- data/lib/tddium/cli/text_helper.rb +16 -0
- data/lib/tddium/cli/timeformat.rb +21 -0
- data/lib/tddium/cli/util.rb +132 -0
- data/lib/tddium/constant.rb +509 -0
- data/lib/tddium/scm.rb +8 -0
- data/lib/tddium/scm/git.rb +188 -0
- data/lib/tddium/scm/git_log_parser.rb +67 -0
- data/lib/tddium/scm/hg.rb +160 -0
- data/lib/tddium/scm/hg_log_parser.rb +66 -0
- data/lib/tddium/scm/scm.rb +20 -0
- data/lib/tddium/script.rb +12 -0
- data/lib/tddium/script/git-remote-hg +1258 -0
- data/lib/tddium/ssh.rb +66 -0
- data/lib/tddium/util.rb +35 -0
- data/lib/tddium/version.rb +5 -0
- metadata +394 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "account", "View account information"
|
6
|
+
def account
|
7
|
+
user_details = tddium_setup({:scm => false})
|
8
|
+
|
9
|
+
if user_details then
|
10
|
+
# User is already logged in, so just display the info
|
11
|
+
show_user_details(user_details)
|
12
|
+
else
|
13
|
+
exit_failure Text::Error::USE_ACTIVATE
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "account:add [ROLE] [EMAIL]", "Authorize and invite a user to use your organization"
|
18
|
+
define_method "account:add" do |role, email|
|
19
|
+
tddium_setup({:scm => false})
|
20
|
+
|
21
|
+
r = Regexp.new(/\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/)
|
22
|
+
if r !~ email then
|
23
|
+
exit_failure Text::Error::ADD_MEMBER_ERROR % [email, "Not a valid e-mail address: must be of the form user@host.domain"]
|
24
|
+
end
|
25
|
+
|
26
|
+
params = {:role=>role, :email=>email}
|
27
|
+
begin
|
28
|
+
say Text::Process::ADDING_MEMBER % [params[:email], params[:role]]
|
29
|
+
result = @tddium_api.set_memberships(params)
|
30
|
+
say Text::Process::ADDED_MEMBER % email
|
31
|
+
rescue TddiumClient::Error::API => e
|
32
|
+
exit_failure Text::Error::ADD_MEMBER_ERROR % [email, e.message]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "account:remove [EMAIL]", "Remove a user from an organization"
|
37
|
+
define_method "account:remove" do |email|
|
38
|
+
tddium_setup({:scm => false})
|
39
|
+
|
40
|
+
begin
|
41
|
+
say Text::Process::REMOVING_MEMBER % email
|
42
|
+
result = @tddium_api.delete_memberships(email)
|
43
|
+
say Text::Process::REMOVED_MEMBER % email
|
44
|
+
rescue TddiumClient::Error::API => e
|
45
|
+
exit_failure Text::Error::REMOVE_MEMBER_ERROR % [email, e.message]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "activate", "Activate an account (deprecated)"
|
6
|
+
method_option :email, :type => :string, :default => nil
|
7
|
+
method_option :password, :type => :string, :default => nil
|
8
|
+
method_option :ssh_key_file, :type => :string, :default => nil
|
9
|
+
def activate
|
10
|
+
say "To activate your account, please visit"
|
11
|
+
say "https://ci.solanolabs.com/"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "config [suite | repo | org[:ACCOUNT]]", "Display config variables.
|
6
|
+
The scope argument can be 'suite', 'repo', 'org' (if you are a member of
|
7
|
+
one organization), or 'org:an_organization_name' (if you are a member of
|
8
|
+
multiple organizations). The default is 'suite'."
|
9
|
+
def config(scope="suite")
|
10
|
+
tddium_setup({:repo => true, :suite => true})
|
11
|
+
|
12
|
+
begin
|
13
|
+
config_details = @tddium_api.get_config_key(scope)
|
14
|
+
show_config_details(scope, config_details['env'])
|
15
|
+
rescue TddiumClient::Error::API => e
|
16
|
+
exit_failure Text::Error::LIST_CONFIG_ERROR
|
17
|
+
rescue Exception => e
|
18
|
+
exit_failure e.message
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "config:add [SCOPE] [KEY] [VALUE]", "Set KEY=VALUE at SCOPE.
|
23
|
+
The scope argument can be 'suite', 'repo', 'org' (if you are a member of
|
24
|
+
one organization), or 'org:an_organization_name' (if you are a member of
|
25
|
+
multiple organizations)."
|
26
|
+
define_method "config:add" do |scope, key, value|
|
27
|
+
tddium_setup({:repo => true, :suite => true})
|
28
|
+
|
29
|
+
begin
|
30
|
+
say Text::Process::ADD_CONFIG % [key, value, scope]
|
31
|
+
result = @tddium_api.set_config_key(scope, key, value)
|
32
|
+
say Text::Process::ADD_CONFIG_DONE % [key, value, scope]
|
33
|
+
rescue TddiumClient::Error::API => e
|
34
|
+
exit_failure Text::Error::ADD_CONFIG_ERROR
|
35
|
+
rescue Exception => e
|
36
|
+
exit_failure e.message
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "config:remove [SCOPE] [KEY]", "Remove config variable NAME from SCOPE."
|
41
|
+
define_method "config:remove" do |scope, key|
|
42
|
+
tddium_setup({:repo => true, :suite => true})
|
43
|
+
|
44
|
+
begin
|
45
|
+
say Text::Process::REMOVE_CONFIG % [key, scope]
|
46
|
+
result = @tddium_api.delete_config_key(scope, key)
|
47
|
+
say Text::Process::REMOVE_CONFIG_DONE % [key, scope]
|
48
|
+
rescue TddiumClient::Error::API => e
|
49
|
+
exit_failure Text::Error::REMOVE_CONFIG_ERROR
|
50
|
+
rescue Exception => e
|
51
|
+
exit_failure e.message
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
map "show" => :describe
|
6
|
+
desc "describe [SESSION]", "Describe the state of a session, if it
|
7
|
+
is provided; otherwise, the latest session on current branch."
|
8
|
+
method_option :account, :type => :string, :default => nil,
|
9
|
+
:aliases => %w(--org --organization)
|
10
|
+
method_option :all, :type=>:boolean, :default=>false
|
11
|
+
method_option :type, :type=>:string, :default=>nil
|
12
|
+
method_option :json, :type=>:boolean, :default=>false
|
13
|
+
method_option :names, :type=>:boolean, :default=>false
|
14
|
+
def describe(session_id=nil)
|
15
|
+
tddium_setup({:repo => false})
|
16
|
+
|
17
|
+
status_message = ''
|
18
|
+
if !session_id then
|
19
|
+
# params to get the most recent session id on current branch
|
20
|
+
suite_params = {
|
21
|
+
:suite_id => @tddium_api.current_suite_id,
|
22
|
+
:active => false,
|
23
|
+
:limit => 1
|
24
|
+
} if suite_for_current_branch?
|
25
|
+
|
26
|
+
sessions = suite_params ? @tddium_api.get_sessions(suite_params) : []
|
27
|
+
if sessions.empty? then
|
28
|
+
exit_failure Text::Status::NO_INACTIVE_SESSION
|
29
|
+
end
|
30
|
+
|
31
|
+
session_id = sessions[0]['id']
|
32
|
+
|
33
|
+
session_status = sessions[0]['status'].upcase
|
34
|
+
session_commit = sessions[0]['commit']
|
35
|
+
current_commit = @scm.current_commit
|
36
|
+
if session_commit == current_commit
|
37
|
+
commit_message = "equal to your current commit"
|
38
|
+
else
|
39
|
+
cnt_ahead = @scm.number_of_commits(session_commit, current_commit)
|
40
|
+
if cnt_ahead == 0
|
41
|
+
cnt_behind = @scm.number_of_commits(current_commit, session_commit)
|
42
|
+
commit_message = "your workspace is behind by #{cnt_behind} commits"
|
43
|
+
else
|
44
|
+
commit_message = "your workspace is ahead by #{cnt_ahead} commits"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
duration = sessions[0]['duration']
|
49
|
+
start_timeago = "%s ago" % Tddium::TimeFormat.seconds_to_human_time(Time.now - Time.parse(sessions[0]["start_time"]))
|
50
|
+
if duration.nil?
|
51
|
+
finish_timeago = "no info about duration found, started #{start_timeago}"
|
52
|
+
elsif session_status == 'RUNNING'
|
53
|
+
finish_timeago = "in process, started #{start_timeago}"
|
54
|
+
else
|
55
|
+
finish_time = Time.parse(sessions[0]["start_time"]) + duration
|
56
|
+
finish_timeago = "%s ago" % Tddium::TimeFormat.seconds_to_human_time(Time.now - finish_time)
|
57
|
+
end
|
58
|
+
|
59
|
+
status_message = Text::Status::SESSION_STATUS % [session_commit, commit_message, session_status, finish_timeago]
|
60
|
+
end
|
61
|
+
|
62
|
+
result = @tddium_api.query_session(session_id)
|
63
|
+
|
64
|
+
filtered = result['session']['tests']
|
65
|
+
if !options[:all]
|
66
|
+
filtered = filtered.select{|x| x['status'] == 'failed'}
|
67
|
+
end
|
68
|
+
|
69
|
+
if options[:type]
|
70
|
+
filtered = filtered.select{|x| x['test_type'].downcase == options[:type].downcase}
|
71
|
+
end
|
72
|
+
|
73
|
+
if options[:json]
|
74
|
+
puts JSON.pretty_generate(result['session'])
|
75
|
+
elsif options[:names]
|
76
|
+
say filtered.map{|x| x['test_name']}.join(" ")
|
77
|
+
else
|
78
|
+
filtered.sort!{|a,b| [a['test_type'], a['test_name']] <=> [b['test_type'], b['test_name']]}
|
79
|
+
|
80
|
+
say Text::Process::DESCRIBE_SESSION % [session_id, status_message, options[:all] ? 'all' : 'failed']
|
81
|
+
|
82
|
+
table =
|
83
|
+
[["Test", "Status", "Duration"],
|
84
|
+
["----", "------", "--------"]] +
|
85
|
+
filtered.map do |x|
|
86
|
+
[
|
87
|
+
x['test_name'],
|
88
|
+
x['status'],
|
89
|
+
x['elapsed_time'] ? "#{x['elapsed_time']}s" : "-"
|
90
|
+
]
|
91
|
+
end
|
92
|
+
print_table table
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "find_failing FILES", "Find failing ordering by binary searching a failing test run"
|
6
|
+
desc "find_failing files+ failing_file", "Find out which file causes pollution / makes the failing file fail"
|
7
|
+
def find_failing(*files)
|
8
|
+
failing = files.pop
|
9
|
+
if !files.include?(failing)
|
10
|
+
exit_failure "Files have to include the failing file, use the copy helper"
|
11
|
+
elsif files.size < 2
|
12
|
+
exit_failure "Files have to be more than 2, use the copy helper"
|
13
|
+
elsif !success?([failing])
|
14
|
+
exit_failure "#{failing} fails when run on it's own"
|
15
|
+
elsif success?(files)
|
16
|
+
exit_failure "tests pass locally"
|
17
|
+
else
|
18
|
+
loop do
|
19
|
+
a = remove_from(files, files.size / 2, :not => failing)
|
20
|
+
b = files - (a - [failing])
|
21
|
+
status, files = find_failing_set([a, b], failing)
|
22
|
+
if status == :finished
|
23
|
+
say "Fails when #{files.join(", ")} are run together"
|
24
|
+
break
|
25
|
+
elsif status == :continue
|
26
|
+
next
|
27
|
+
else
|
28
|
+
exit_failure "unable to isolate failure to 2 files"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def find_failing_set(sets, failing)
|
37
|
+
sets.each do |set|
|
38
|
+
next if set == [failing]
|
39
|
+
if !success?(set)
|
40
|
+
if set.size == 2
|
41
|
+
return [:finished, set]
|
42
|
+
else
|
43
|
+
return [:continue, set]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
return [:failure, []]
|
48
|
+
end
|
49
|
+
|
50
|
+
def remove_from(set, x, options)
|
51
|
+
set.dup.delete_if { |f| f != options[:not] && (x -= 1) >= 0 }
|
52
|
+
end
|
53
|
+
|
54
|
+
def success?(files)
|
55
|
+
command = "bundle exec ruby #{files.map { |f| "-r./#{f.sub(/\.rb$/, "")}" }.join(" ")} -e ''"
|
56
|
+
say "Running: #{command}"
|
57
|
+
status = system(command)
|
58
|
+
say "Status: #{status ? "Success" : "Failure"}"
|
59
|
+
status
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "github:migrate_hooks", "Authorize and switch the repo to use the tddium webhook with the proper token"
|
6
|
+
define_method "github:migrate_hooks" do
|
7
|
+
suites = @tddium_api.get_suites
|
8
|
+
if suites.any?
|
9
|
+
say 'Please enter your github credentials; we do not store them anywhere'
|
10
|
+
username = HighLine.ask("username: ")
|
11
|
+
password = HighLine.ask("password: "){ |q| q.echo = "*" }
|
12
|
+
@github = Github.new(login: username, password: password)
|
13
|
+
|
14
|
+
suites.each do |suite|
|
15
|
+
login = suite['org_name'] || username
|
16
|
+
unless has_hook_token?(suite, login)
|
17
|
+
if confirm_for_repo?(suite['repo_name'])
|
18
|
+
set_hook_token(suite, login)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
else
|
23
|
+
say 'You do not have any suites configured with tddium'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def has_hook_token?(suite, login)
|
30
|
+
@github.repos.hooks.list(login, suite['repo_name']).any? do |hook|
|
31
|
+
hook["config"].try(:[], "token") == suite['repo_ci_hook_key'] && hook["active"]
|
32
|
+
end
|
33
|
+
rescue => e
|
34
|
+
say e.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def confirm_for_repo?(name)
|
38
|
+
msg = "Do you want to switch the repo '#{name}' to use the tddium webhook with the proper token? (Yes/No/All)"
|
39
|
+
(@prev && @prev == 'All') ||
|
40
|
+
((@prev = HighLine.ask(msg){ |q| q.validate = /Yes|No|All/ }) && ['Yes','All'].include?(@prev))
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_hook_token(suite, login)
|
44
|
+
@github.repos.hooks.create(login, suite['repo_name'], {
|
45
|
+
active: true,
|
46
|
+
name: :tddium,
|
47
|
+
config: {
|
48
|
+
token: suite['repo_ci_hook_key']
|
49
|
+
}
|
50
|
+
})
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "heroku", "Connect Heroku account with Solano CI (deprecated)"
|
6
|
+
method_option :email, :type => :string, :default => nil
|
7
|
+
method_option :password, :type => :string, :default => nil
|
8
|
+
method_option :ssh_key_file, :type => :string, :default => nil
|
9
|
+
method_option :app, :type => :string, :default => nil
|
10
|
+
def heroku
|
11
|
+
say "To activate your heroku account, please visit"
|
12
|
+
say "https://ci.solanolabs.com/"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright (c) 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Tddium
|
6
|
+
class TddiumCli < Thor
|
7
|
+
desc "hg:mirror", "Construct local hg -> git mirror"
|
8
|
+
method_option :noop, :type => :boolean, :default => false
|
9
|
+
method_option :force, :type => :boolean, :default => false
|
10
|
+
define_method "hg:mirror" do |*args|
|
11
|
+
tddium_setup({:repo => true})
|
12
|
+
|
13
|
+
if @scm.scm_name != 'hg' then
|
14
|
+
exit_failure("Current repository does not appear to be using Mercurial")
|
15
|
+
end
|
16
|
+
|
17
|
+
if @scm.origin_url.nil? then
|
18
|
+
exit_failure("Missing default path; please set default path in hgrc")
|
19
|
+
end
|
20
|
+
|
21
|
+
if File.exists?(@scm.mirror_path) then
|
22
|
+
if !options[:force] then
|
23
|
+
exit_failure("Mirror already exists; use --force to recreate")
|
24
|
+
end
|
25
|
+
if options[:noop] then
|
26
|
+
exit_failure("Running in no-op mode; not removing existing mirror")
|
27
|
+
end
|
28
|
+
FileUtils.rm_rf(@scm.mirror_path)
|
29
|
+
end
|
30
|
+
|
31
|
+
FileUtils.mkdir_p(@scm.mirror_path)
|
32
|
+
|
33
|
+
Tddium::Scripts.prepend_script_path
|
34
|
+
|
35
|
+
clone_command = "git clone hg::#{@scm.root} #{@scm.mirror_path}"
|
36
|
+
# origin_command = "cd #{@scm.mirror_path} && git remote set-url origin #{@scm.origin_url}"
|
37
|
+
|
38
|
+
if options[:noop] then
|
39
|
+
puts "export PATH=#{ENV['PATH']}"
|
40
|
+
puts clone_command
|
41
|
+
# puts origin_command
|
42
|
+
else
|
43
|
+
Kernel.system(clone_command)
|
44
|
+
# Kernel.system(origin_command)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# Copyright (c) 2011, 2012, 2013, 2014 Solano Labs All Rights Reserved
|
2
|
+
|
3
|
+
module Tddium
|
4
|
+
class TddiumCli < Thor
|
5
|
+
desc "keys", "List SSH keys authorized for Solano CI"
|
6
|
+
def keys
|
7
|
+
user_details = tddium_setup({:scm => false})
|
8
|
+
|
9
|
+
begin
|
10
|
+
if user_details then
|
11
|
+
show_third_party_keys_details(user_details)
|
12
|
+
end
|
13
|
+
|
14
|
+
keys_details = @tddium_api.get_keys
|
15
|
+
show_keys_details(keys_details)
|
16
|
+
rescue TddiumClient::Error::API => e
|
17
|
+
exit_failure Text::Error::LIST_KEYS_ERROR
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "keys:add [NAME] [PATH]", "Authorize an existing keypair for Solano CI"
|
22
|
+
method_option :dir, :type=>:string, :default=>nil
|
23
|
+
define_method "keys:add" do |name, path|
|
24
|
+
tddium_setup({:scm => false})
|
25
|
+
|
26
|
+
path = File.expand_path(path)
|
27
|
+
|
28
|
+
output_dir = options[:dir] || ENV['TDDIUM_GEM_KEY_DIR']
|
29
|
+
output_dir ||= Default::SSH_OUTPUT_DIR
|
30
|
+
|
31
|
+
begin
|
32
|
+
keydata = Tddium::Ssh.validate_keys name, path, @tddium_api
|
33
|
+
say Text::Process::ADD_KEYS_ADD % name
|
34
|
+
result = @tddium_api.set_keys({:keys => [keydata]})
|
35
|
+
|
36
|
+
priv_path = path.sub(/[.]pub$/, '')
|
37
|
+
say Text::Process::ADD_KEYS_ADD_DONE % [name, priv_path, result["git_server"] || Default::GIT_SERVER, priv_path]
|
38
|
+
|
39
|
+
rescue TddiumClient::Error::API => e
|
40
|
+
exit_failure Text::Error::ADD_KEYS_ERROR % name
|
41
|
+
rescue TddiumError => e
|
42
|
+
exit_failure e.message
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
map "generate" => :gen
|
47
|
+
desc "keys:gen [NAME]", "Generate and authorize a keypair for Solano CI"
|
48
|
+
method_option :dir, :type=>:string, :default=>nil
|
49
|
+
define_method "keys:gen" do |name|
|
50
|
+
tddium_setup({:scm => false})
|
51
|
+
|
52
|
+
output_dir = options[:dir] || ENV['TDDIUM_GEM_KEY_DIR']
|
53
|
+
output_dir ||= Default::SSH_OUTPUT_DIR
|
54
|
+
|
55
|
+
begin
|
56
|
+
keydata = Tddium::Ssh.validate_keys name, output_dir, @tddium_api, true
|
57
|
+
say Text::Process::ADD_KEYS_GENERATE % name
|
58
|
+
|
59
|
+
result = @tddium_api.set_keys({:keys => [keydata]})
|
60
|
+
outfile = File.expand_path(File.join(output_dir, "identity.tddium.#{name}"))
|
61
|
+
say Text::Process::ADD_KEYS_GENERATE_DONE % [name, result["git_server"] || Default::GIT_SERVER, outfile]
|
62
|
+
|
63
|
+
rescue TddiumClient::Error::API => e
|
64
|
+
exit_failure Text::Error::ADD_KEYS_ERROR % name
|
65
|
+
rescue TddiumError => e
|
66
|
+
exit_failure e.message
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
desc "keys:remove [NAME]", "Remove a key that was authorized for Solano CI"
|
71
|
+
define_method "keys:remove" do |name|
|
72
|
+
tddium_setup({:scm => false})
|
73
|
+
|
74
|
+
begin
|
75
|
+
say Text::Process::REMOVE_KEYS % name
|
76
|
+
result = @tddium_api.delete_keys(name)
|
77
|
+
say Text::Process::REMOVE_KEYS_DONE % name
|
78
|
+
rescue TddiumClient::Error::API => e
|
79
|
+
exit_failure Text::Error::REMOVE_KEYS_ERROR % name
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|