toolshed 1.0.2 → 1.0.3
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 +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +11 -0
- data/.toolshedrc.sample +32 -0
- data/README.md +159 -2
- data/Rakefile +3 -3
- data/bin/toolshed +6 -1
- data/lib/toolshed.rb +38 -28
- data/lib/toolshed/base.rb +33 -11
- data/lib/toolshed/cli.rb +30 -38
- data/lib/toolshed/client.rb +87 -293
- data/lib/toolshed/commands/base.rb +65 -23
- data/lib/toolshed/commands/checkout_branch.rb +15 -2
- data/lib/toolshed/commands/create_branch.rb +34 -29
- data/lib/toolshed/commands/create_pivotal_tracker_note.rb +9 -3
- data/lib/toolshed/commands/create_pull_request.rb +115 -68
- data/lib/toolshed/commands/create_ticket_comment.rb +17 -1
- data/lib/toolshed/commands/delete_branch.rb +34 -3
- data/lib/toolshed/commands/get_daily_time_update.rb +20 -3
- data/lib/toolshed/commands/list_branches.rb +16 -5
- data/lib/toolshed/commands/push_branch.rb +28 -9
- data/lib/toolshed/commands/rename_branch.rb +29 -0
- data/lib/toolshed/commands/ssh.rb +44 -3
- data/lib/toolshed/commands/ticket_information.rb +30 -4
- data/lib/toolshed/commands/update_pivotal_tracker_story_status.rb +9 -3
- data/lib/toolshed/commands/update_ticket_status.rb +8 -2
- data/lib/toolshed/entry_point.rb +89 -0
- data/lib/toolshed/git.rb +59 -0
- data/lib/toolshed/git/branch.rb +224 -0
- data/lib/toolshed/git/github.rb +45 -57
- data/lib/toolshed/git/validator.rb +14 -0
- data/lib/toolshed/logger.rb +46 -0
- data/lib/toolshed/password.rb +11 -6
- data/lib/toolshed/server_administration/ssh.rb +4 -2
- data/lib/toolshed/ticket_tracking/jira.rb +8 -6
- data/lib/toolshed/ticket_tracking/pivotal_tracker.rb +8 -6
- data/lib/toolshed/time_tracking/harvest.rb +8 -14
- data/lib/toolshed/version.rb +25 -1
- data/test/commands/checkout_branch_test.rb +11 -7
- data/test/commands/create_branch_test.rb +29 -24
- data/test/commands/create_pull_request_test.rb +39 -31
- data/test/commands/delete_branch_test.rb +35 -25
- data/test/commands/get_daily_time_update_test.rb +8 -8
- data/test/commands/push_branch_test.rb +27 -15
- data/test/commands/rename_branch_test.rb +59 -0
- data/test/git/git_helper.rb +5 -5
- data/test/git/git_test.rb +36 -31
- data/test/git/github_test.rb +9 -46
- data/test/helper.rb +11 -11
- data/test/server_administration/ssh_test.rb +1 -0
- data/test/ticket_tracking/jira_test.rb +18 -16
- data/test/time_tracking/harvest_test.rb +8 -6
- data/toolshed.gemspec +23 -20
- metadata +95 -46
- data/bin/toolshed.rb +0 -261
- data/lib/toolshed/git/git.rb +0 -119
@@ -0,0 +1,224 @@
|
|
1
|
+
require 'toolshed/git'
|
2
|
+
|
3
|
+
module Toolshed
|
4
|
+
class Git
|
5
|
+
class Branch < Toolshed::Git
|
6
|
+
def initialize(options = {})
|
7
|
+
super(options)
|
8
|
+
end
|
9
|
+
|
10
|
+
# class methods
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def ask_which_branch(branch_names)
|
14
|
+
selected_branch_name = ''
|
15
|
+
choose do |menu|
|
16
|
+
menu.prompt = "Multiple branches matched input branch name. Which branch are you looking for? "
|
17
|
+
|
18
|
+
branch_names.each do |branch_name|
|
19
|
+
menu.choice(branch_name.to_sym, branch_name) do |branch_name|
|
20
|
+
selected_branch_name = branch_name
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
selected_branch_name.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
def from
|
28
|
+
`git rev-parse --abbrev-ref --symbolic-full-name @{u}`.split('/')[-1].strip
|
29
|
+
end
|
30
|
+
|
31
|
+
def checkout(checkout_branch_name)
|
32
|
+
Toolshed.logger.info ''
|
33
|
+
Toolshed.logger.info "Looking for branch #{checkout_branch_name}"
|
34
|
+
actual_branch_name = Toolshed::Git::Branch.name_from_substring(checkout_branch_name)
|
35
|
+
Toolshed.logger.info "Switching to branch #{actual_branch_name}"
|
36
|
+
result = Toolshed::Base.wait_for_command("git checkout #{actual_branch_name} #{Toolshed::Client.instance.git_quiet}")
|
37
|
+
if /.*Your local changes to the following files would be overwritten by checkout.*/.match(result[:stderr][0])
|
38
|
+
Toolshed.logger.fatal "Unable to checkout branch due to the following error(s) #{result[:all].join(', ')}"
|
39
|
+
Toolshed.die
|
40
|
+
end
|
41
|
+
Toolshed::Base.wait_for_command(Toolshed::Git.git_submodule_command) unless Toolshed::Git.git_submodule_command.empty?
|
42
|
+
Toolshed.logger.info "Switched to branch #{actual_branch_name}"
|
43
|
+
actual_branch_name
|
44
|
+
end
|
45
|
+
|
46
|
+
def name
|
47
|
+
branch = Toolshed::Git::Branch.new
|
48
|
+
branch.name
|
49
|
+
end
|
50
|
+
|
51
|
+
def name_from_substring(substring)
|
52
|
+
branches = Toolshed::Base.wait_for_command("git branch | grep \"#{substring}\"")
|
53
|
+
branch_names = branches[:all].map { |branch_name| branch_name.gsub('*', '').strip }
|
54
|
+
|
55
|
+
return substring if branch_names.length == 0
|
56
|
+
return branch_names.first if branch_names.length == 1
|
57
|
+
Toolshed::Git::Branch.ask_which_branch(branch_names)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# instance methods
|
62
|
+
|
63
|
+
def create
|
64
|
+
validator.validate!(self)
|
65
|
+
Toolshed.logger.info ''
|
66
|
+
|
67
|
+
new_branch_name = Toolshed::Git.clean_branch_name(to_remote_branch_name)
|
68
|
+
Toolshed.logger.info "Creating branch #{new_branch_name} from #{from_remote_name}/#{from_remote_branch_name}"
|
69
|
+
|
70
|
+
remote_update
|
71
|
+
results = Toolshed::Base.wait_for_command("git checkout -b #{new_branch_name} #{from_remote_name}/#{from_remote_branch_name} #{Toolshed::Client.instance.git_quiet}")
|
72
|
+
results[:all].each do |out|
|
73
|
+
if out.match(/.*fatal.*/)
|
74
|
+
Toolshed.logger.fatal out
|
75
|
+
Toolshed.die
|
76
|
+
else
|
77
|
+
Toolshed.logger.info out
|
78
|
+
end
|
79
|
+
end
|
80
|
+
Toolshed::Base.wait_for_command(Toolshed::Git.git_submodule_command) unless Toolshed::Git.git_submodule_command.empty?
|
81
|
+
|
82
|
+
Toolshed.logger.info ''
|
83
|
+
Toolshed.logger.info "Pushing branch #{new_branch_name} to #{from_remote_name}/#{from_remote_branch_name}."
|
84
|
+
self.passed_branch_name = new_branch_name
|
85
|
+
push
|
86
|
+
|
87
|
+
Toolshed.logger.info ''
|
88
|
+
Toolshed.logger.info "Branch #{new_branch_name} has been created from #{from_remote_name}/#{from_remote_branch_name}."
|
89
|
+
end
|
90
|
+
|
91
|
+
def delete(delete_branch_name)
|
92
|
+
actual_branch_name = Toolshed::Git::Branch.name_from_substring(delete_branch_name)
|
93
|
+
Toolshed.logger.info ''
|
94
|
+
Toolshed.logger.info "Deleting branch '#{actual_branch_name}'"
|
95
|
+
if actual_branch_name == name
|
96
|
+
Toolshed.logger.info 'Checking out master branch'
|
97
|
+
Toolshed.logger.info ''
|
98
|
+
Toolshed::Git::Branch.checkout('master')
|
99
|
+
end
|
100
|
+
|
101
|
+
delete_local(actual_branch_name)
|
102
|
+
delete_remote(actual_branch_name)
|
103
|
+
Toolshed.logger.info ''
|
104
|
+
Toolshed.logger.info "Deleted branch #{actual_branch_name}"
|
105
|
+
end
|
106
|
+
|
107
|
+
def delete_local(local_branch_name)
|
108
|
+
unless local.map { |local_branch| local_branch[:branch_name] }.include?(local_branch_name)
|
109
|
+
Toolshed.logger.warn "Unable to delete '#{local_branch_name}' from local as it does not exist skipping"
|
110
|
+
return
|
111
|
+
end
|
112
|
+
|
113
|
+
results = Toolshed::Base.wait_for_command("git branch -D #{local_branch_name}")
|
114
|
+
results[:all].each do |result|
|
115
|
+
Toolshed.logger.info result.rstrip
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def delete_remote(remote_branch_name)
|
120
|
+
unless remote.include?(remote_branch_name)
|
121
|
+
Toolshed.logger.warn "Unable to delete '#{remote_branch_name}' from remote as it does not exist skipping"
|
122
|
+
return
|
123
|
+
end
|
124
|
+
|
125
|
+
Toolshed.logger.info "Deleting #{remote_branch_name} from remote"
|
126
|
+
results = Toolshed::Base.wait_for_command("git push #{Toolshed::Client.instance.push_to_remote_name} --delete #{remote_branch_name}")
|
127
|
+
results[:all].each do |result|
|
128
|
+
Toolshed.logger.info result.rstrip
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def list
|
133
|
+
remote_update
|
134
|
+
list_local
|
135
|
+
list_remote
|
136
|
+
end
|
137
|
+
|
138
|
+
def list_local
|
139
|
+
Toolshed.logger.info ''
|
140
|
+
Toolshed.logger.info 'Local Branches'
|
141
|
+
Toolshed.logger.info ''
|
142
|
+
current_branch_name = name
|
143
|
+
local.each do |local_branch|
|
144
|
+
Toolshed.logger.info "#{local_branch[:branch_name]} #{local_branch[:branch_info]}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def list_remote
|
149
|
+
Toolshed.logger.info ''
|
150
|
+
Toolshed.logger.info 'Remote Branches'
|
151
|
+
Toolshed.logger.info ''
|
152
|
+
remote.each do |remote_branch|
|
153
|
+
Toolshed.logger.info remote_branch
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def local
|
158
|
+
@local ||= begin
|
159
|
+
local_branches = []
|
160
|
+
results = Toolshed::Base.wait_for_command('git branch -avv')
|
161
|
+
results[:stdout].each do |stdout|
|
162
|
+
next if /remotes.*/.match(stdout) || /HEAD.*/.match(stdout)
|
163
|
+
branch_name = /.*\s{3,}/.match(stdout)[0]
|
164
|
+
branch_name = branch_name.gsub('*', '')
|
165
|
+
branch_info_match = /\[[a-z].*\]/.match(stdout)
|
166
|
+
branch_info = ''
|
167
|
+
branch_info = branch_info_match[0] unless branch_info_match.nil?
|
168
|
+
local_branches << { branch_name: branch_name.lstrip.rstrip, branch_info: branch_info.lstrip.rstrip }
|
169
|
+
end
|
170
|
+
local_branches
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def name
|
175
|
+
(passed_branch_name.nil? || passed_branch_name.empty?) ? `git rev-parse --abbrev-ref HEAD`.strip : Toolshed::Git::Branch.name_from_substring(passed_branch_name) # rubocop:disable Metrics/LineLength
|
176
|
+
end
|
177
|
+
|
178
|
+
def push
|
179
|
+
Toolshed.logger.info "Pushing #{name}"
|
180
|
+
if (name.nil? || name.empty?) && (!passed_branch_name.nil? && !passed_branch_name.empty?)
|
181
|
+
Toolshed.logger.fatal "Branch #{passed_branch_name} was not found. Unable to push branch."
|
182
|
+
Toolshed.die
|
183
|
+
end
|
184
|
+
result = Toolshed::Base.wait_for_command("git push #{to_remote_name} #{name} #{force} #{Toolshed::Client.instance.git_quiet}")
|
185
|
+
result[:all].each do |stdout|
|
186
|
+
Toolshed.logger.info stdout
|
187
|
+
end
|
188
|
+
Toolshed.logger.info 'Everything up-to-date' if result[:stdout].empty? && result[:stderr].empty?
|
189
|
+
Toolshed.logger.info "#{name} has been pushed"
|
190
|
+
end
|
191
|
+
|
192
|
+
def remote
|
193
|
+
remote_branches = []
|
194
|
+
results = Toolshed::Base.wait_for_command('git branch -avv')
|
195
|
+
results[:stdout].each do |stdout|
|
196
|
+
next unless /remotes\/#{from_remote_name}.*/.match(stdout)
|
197
|
+
next if /.*HEAD.*/.match(stdout)
|
198
|
+
matches = /([^\s]+)/.match(stdout)
|
199
|
+
remote_branches << matches[0].gsub("remotes/#{from_remote_name}/", '')
|
200
|
+
end
|
201
|
+
remote_branches
|
202
|
+
end
|
203
|
+
|
204
|
+
def rename(new_branch_name)
|
205
|
+
current_branch_name = passed_branch_name
|
206
|
+
results = Toolshed::Base.wait_for_command("git branch -m #{passed_branch_name} #{new_branch_name}")
|
207
|
+
results[:all].each do |out|
|
208
|
+
matches = /(error.*|fatal.*)/.match(out)
|
209
|
+
if matches.length > 0
|
210
|
+
Toolshed.logger.fatal out
|
211
|
+
Toolshed.die("Unable to proceed supplied branch '#{current_branch_name}' does not exist in local repository.")
|
212
|
+
else
|
213
|
+
Toolshed.logger.info out
|
214
|
+
end
|
215
|
+
end
|
216
|
+
self.passed_branch_name = new_branch_name
|
217
|
+
push
|
218
|
+
delete_remote(current_branch_name)
|
219
|
+
Toolshed.logger.info ''
|
220
|
+
Toolshed.logger.info "Deleted branch #{current_branch_name}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
data/lib/toolshed/git/github.rb
CHANGED
@@ -1,98 +1,86 @@
|
|
1
|
+
require 'toolshed/git/branch'
|
2
|
+
require 'toolshed/git'
|
3
|
+
|
1
4
|
module Toolshed
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
+
class Git
|
6
|
+
# Class created to handle specific git tasks related to github
|
7
|
+
class Github < Toolshed::Git
|
5
8
|
include HTTParty
|
6
9
|
|
7
10
|
attr_accessor :default_options
|
8
11
|
|
9
|
-
def initialize(options={})
|
12
|
+
def initialize(options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
10
13
|
super(options)
|
11
14
|
|
12
|
-
username = Toolshed::Client
|
13
|
-
password = Toolshed::Client
|
14
|
-
token = Toolshed::Client
|
15
|
-
|
16
|
-
unless (options[:username].nil?)
|
17
|
-
username = options[:username]
|
18
|
-
end
|
15
|
+
username = Toolshed::Client.instance.github_username
|
16
|
+
password = Toolshed::Client.instance.github_password
|
17
|
+
token = Toolshed::Client.instance.github_token
|
19
18
|
|
20
|
-
unless
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
unless (token.nil?)
|
19
|
+
username = options[:username] unless options[:username].nil?
|
20
|
+
password = options[:password] unless options[:password].nil?
|
21
|
+
unless token.nil?
|
25
22
|
username = token
|
26
23
|
password = nil
|
27
24
|
end
|
28
25
|
|
29
|
-
unless
|
26
|
+
unless options[:token].nil?
|
30
27
|
username = options[:token]
|
31
28
|
password = nil
|
32
29
|
end
|
33
30
|
|
34
31
|
@auth = { username: username, password: password }
|
35
32
|
self.default_options = {
|
36
|
-
:
|
37
|
-
|
33
|
+
headers: {
|
34
|
+
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1309.0 Safari/537.17' # rubocop:disable Metrics/LineLength
|
38
35
|
},
|
39
|
-
basic_auth: @auth
|
36
|
+
basic_auth: @auth
|
40
37
|
}
|
41
38
|
end
|
42
39
|
|
43
|
-
def create_pull_request(title, body, options={})
|
44
|
-
options.merge!(
|
45
|
-
options.merge!(
|
46
|
-
body:
|
40
|
+
def create_pull_request(title, body, options = {}) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/LineLength
|
41
|
+
options.merge!(default_options)
|
42
|
+
options.merge!(
|
43
|
+
body:
|
44
|
+
{
|
47
45
|
title: title,
|
48
|
-
|
49
|
-
|
50
|
-
|
46
|
+
body: body,
|
47
|
+
head: "#{Toolshed::Client.instance.github_username}:#{Toolshed::Git::Branch.name}", # rubocop:disable Metrics/LineLength
|
48
|
+
base: Toolshed::Git::Branch.from
|
51
49
|
}.to_json
|
52
|
-
|
53
|
-
|
54
|
-
|
50
|
+
)
|
51
|
+
display_options = Marshal.load(Marshal.dump(options))
|
52
|
+
display_options[:basic_auth][:password] = '********'
|
53
|
+
Toolshed.logger.info "Creating pull request with the following options: #{display_options.inspect}" # rubocop:disable Metrics/LineLength
|
54
|
+
response = HTTParty.post("#{Toolshed::Client::GITHUB_BASE_API_URL}repos/#{Toolshed::Client.instance.pull_from_repository_user}/#{Toolshed::Client.instance.pull_from_repository_name}/pulls", options).response # rubocop:disable Metrics/LineLength
|
55
55
|
response = JSON.parse(response.body)
|
56
|
-
if
|
56
|
+
if response['errors'].nil?
|
57
57
|
response
|
58
58
|
else
|
59
|
-
|
59
|
+
fail "Validation errors #{response.inspect}"
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def list_branches(options={})
|
64
|
-
options.merge!(self.default_options)
|
65
|
-
|
66
|
-
response = HTTParty.get("#{Toolshed::Client::GITHUB_BASE_API_URL}repos/#{Toolshed::Client.github_username}/#{Toolshed::Client.pull_from_repository_name}/branches", options).response
|
67
|
-
response = JSON.parse(response.body)
|
68
|
-
end
|
69
|
-
|
70
63
|
def self.username
|
71
|
-
username = Toolshed::Client
|
72
|
-
|
73
|
-
# prompt to ask for username
|
74
|
-
puts "Github username? "
|
75
|
-
username = $stdin.gets.chomp.strip
|
76
|
-
end
|
64
|
+
username = Toolshed::Client.instance.github_username
|
65
|
+
return username unless username.nil?
|
77
66
|
|
78
|
-
|
67
|
+
puts 'Github username? '
|
68
|
+
$stdin.gets.chomp.strip
|
79
69
|
end
|
80
70
|
|
81
71
|
def self.password
|
82
|
-
password = Toolshed::Client
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
return password
|
72
|
+
password = Toolshed::Client.instance.github_password
|
73
|
+
return password unless password.nil?
|
74
|
+
|
75
|
+
system 'stty -echo'
|
76
|
+
puts 'Github password? '
|
77
|
+
password = $stdin.gets.chomp.strip
|
78
|
+
system 'stty echo'
|
79
|
+
password
|
92
80
|
end
|
93
81
|
|
94
82
|
def self.create_instance
|
95
|
-
Toolshed::Git::Github.new(
|
83
|
+
Toolshed::Git::Github.new(username: Toolshed::Git::Github.username, password: Toolshed::Git::Github.password) # rubocop:disable Metrics/LineLength
|
96
84
|
end
|
97
85
|
end
|
98
86
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'veto'
|
2
|
+
|
3
|
+
module Toolshed
|
4
|
+
class Git
|
5
|
+
class Validator
|
6
|
+
include Veto.validator
|
7
|
+
|
8
|
+
validates :from_remote_name, :presence => true
|
9
|
+
validates :from_remote_branch_name, :presence => true
|
10
|
+
validates :to_remote_name, :presence => true
|
11
|
+
validates :to_remote_branch_name, :presence => true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'term/ansicolor'
|
3
|
+
require 'logger'
|
4
|
+
|
5
|
+
class Toolshed::Logger
|
6
|
+
include Singleton
|
7
|
+
include Term::ANSIColor
|
8
|
+
|
9
|
+
attr_accessor :loggers
|
10
|
+
|
11
|
+
def self.create(options = {})
|
12
|
+
instance.loggers = []
|
13
|
+
log_sources = options[:log_sources] || [STDOUT]
|
14
|
+
log_sources.each do |log_source|
|
15
|
+
instance.loggers << Logger.new(log_source)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_log_source(source)
|
20
|
+
loggers << Logger.new(source)
|
21
|
+
end
|
22
|
+
|
23
|
+
def debug(message)
|
24
|
+
loggers.each do |logger|
|
25
|
+
logger.debug(message)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def fatal(message)
|
30
|
+
loggers.each do |logger|
|
31
|
+
logger.info(red(message))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def info(message)
|
36
|
+
loggers.each do |logger|
|
37
|
+
logger.info(green(message))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def warn(message)
|
42
|
+
loggers.each do |logger|
|
43
|
+
logger.warn(yellow(message))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/toolshed/password.rb
CHANGED
@@ -8,7 +8,8 @@ module Toolshed
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def read_user_input_password(type, prompt_message='Password:')
|
11
|
-
|
11
|
+
value = self.send(type)
|
12
|
+
unless value.nil? || value.empty?
|
12
13
|
read_password_from_configuration(type)
|
13
14
|
else
|
14
15
|
prompt_user_to_input_password(prompt_message)
|
@@ -31,11 +32,15 @@ module Toolshed
|
|
31
32
|
end
|
32
33
|
|
33
34
|
def read_password_from_configuration(type)
|
34
|
-
|
35
|
-
|
36
|
-
credentials[self.send(type)]
|
37
|
-
|
38
|
-
|
35
|
+
begin
|
36
|
+
credentials = Toolshed::Client.read_credenials
|
37
|
+
if credentials[self.send(type)]
|
38
|
+
credentials[self.send(type)]
|
39
|
+
else
|
40
|
+
self.send(type)
|
41
|
+
end
|
42
|
+
rescue => e
|
43
|
+
puts e.inspect
|
39
44
|
end
|
40
45
|
end
|
41
46
|
end
|