nimbu 0.4 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/nimbu.rb +3 -19
- data/lib/nimbu/auth.rb +106 -95
- data/lib/nimbu/cli.rb +20 -3
- data/lib/nimbu/command.rb +138 -68
- data/lib/nimbu/command/auth.rb +21 -3
- data/lib/nimbu/command/base.rb +38 -75
- data/lib/nimbu/command/browse.rb +63 -0
- data/lib/nimbu/command/help.rb +1 -1
- data/lib/nimbu/command/helpers.rb +6 -4
- data/lib/nimbu/command/init.rb +5 -6
- data/lib/nimbu/command/server.rb +119 -55
- data/lib/nimbu/command/sites.rb +32 -0
- data/lib/nimbu/command/themes.rb +29 -52
- data/lib/nimbu/helpers.rb +268 -89
- data/lib/nimbu/server/base.rb +56 -41
- data/lib/nimbu/ssh.rb +54 -0
- data/lib/nimbu/version.rb +1 -1
- metadata +128 -42
- data/lib/nimbu/client.rb +0 -289
- data/lib/nimbu/client/rendezvous.rb +0 -76
- data/lib/nimbu/server/views/index.haml +0 -1
data/lib/nimbu.rb
CHANGED
@@ -1,28 +1,12 @@
|
|
1
1
|
require "nimbu/version"
|
2
|
-
require "nimbu
|
2
|
+
require "nimbu-api"
|
3
3
|
|
4
4
|
module Nimbu
|
5
5
|
def self.debug=(value)
|
6
|
-
|
6
|
+
@debug = value
|
7
7
|
end
|
8
8
|
|
9
9
|
def self.debug
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.development=(value)
|
14
|
-
@@development = value
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.development
|
18
|
-
@@development
|
19
|
-
end
|
20
|
-
|
21
|
-
def self.v2=(value)
|
22
|
-
@@v2 = value
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.v2
|
26
|
-
@@v2
|
10
|
+
@debug || false
|
27
11
|
end
|
28
12
|
end
|
data/lib/nimbu/auth.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require "yaml"
|
2
2
|
require "nimbu"
|
3
|
-
require "nimbu/client"
|
4
3
|
require "nimbu/helpers"
|
5
4
|
|
6
5
|
class Nimbu::Auth
|
@@ -12,9 +11,7 @@ class Nimbu::Auth
|
|
12
11
|
|
13
12
|
def client
|
14
13
|
@client ||= begin
|
15
|
-
|
16
|
-
client.on_warning { |msg| self.display("\n#{msg}\n\n") }
|
17
|
-
client
|
14
|
+
Nimbu::Client.new(:oauth_token => token, :endpoint => host)
|
18
15
|
end
|
19
16
|
end
|
20
17
|
|
@@ -29,34 +26,38 @@ class Nimbu::Auth
|
|
29
26
|
|
30
27
|
# just a stub; will raise if not authenticated
|
31
28
|
def check
|
32
|
-
client.list
|
29
|
+
client.sites.list
|
30
|
+
end
|
31
|
+
|
32
|
+
def host
|
33
|
+
ENV['NIMBU_HOST'] || "https://api.nimbu.io"
|
33
34
|
end
|
34
35
|
|
35
36
|
def default_host
|
36
|
-
"
|
37
|
+
"https://api.nimbu.io"
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
-
@
|
40
|
+
def admin_host
|
41
|
+
@admin_host ||= host.gsub(/https?\:\/\/api\./,'')
|
42
|
+
end
|
43
|
+
|
44
|
+
def site
|
45
|
+
@site ||= ENV['NIMBU_SITE'] || get_nimbu_site
|
41
46
|
end
|
42
47
|
|
43
48
|
def theme
|
44
49
|
@theme ||= ENV['NIMBU_THEME'] || get_nimbu_theme
|
45
50
|
end
|
46
51
|
|
47
|
-
def
|
48
|
-
|
49
|
-
get_configuration[:development]
|
50
|
-
else
|
51
|
-
get_configuration[:hostname]
|
52
|
-
end
|
52
|
+
def get_nimbu_site
|
53
|
+
get_configuration["site"]
|
53
54
|
end
|
54
55
|
|
55
56
|
def get_nimbu_theme
|
56
|
-
get_configuration[
|
57
|
+
get_configuration["theme"] || "default-theme"
|
57
58
|
end
|
58
59
|
|
59
|
-
def get_configuration
|
60
|
+
def get_configuration
|
60
61
|
@configuration ||= (read_configuration || ask_for_and_save_configuration)
|
61
62
|
end
|
62
63
|
|
@@ -75,20 +76,75 @@ class Nimbu::Auth
|
|
75
76
|
@host = nil
|
76
77
|
end
|
77
78
|
|
78
|
-
|
79
|
-
puts "What is the hostname for this Nimbu site?"
|
80
|
-
print "Hostname: "
|
81
|
-
hostname = ask
|
79
|
+
def ask_for_configuration
|
82
80
|
|
83
|
-
|
84
|
-
|
85
|
-
theme = ask
|
81
|
+
subdomain = nil
|
82
|
+
sites = client.sites.list
|
86
83
|
|
87
|
-
|
84
|
+
unless sites.respond_to?(:any?) && sites.any?
|
85
|
+
display "You don't have access to any Nimbu sites you can edit yet..."
|
86
|
+
display ""
|
87
|
+
display "Please visit http://nimbu.io, start your 30-day trial and discover our amazing platform!"
|
88
|
+
exit(1)
|
89
|
+
else
|
90
|
+
print_separator
|
91
|
+
display "\nLet's first setup the configuration for this directory..."
|
92
|
+
display "\nYou have access to following sites:\n"
|
93
|
+
sites.each_with_index do |site,i|
|
94
|
+
display " #{i+1}) #{site.name.white.bold} => http://#{site.domain}"
|
95
|
+
end
|
96
|
+
site_number = 0
|
97
|
+
retry_site = false
|
98
|
+
while site_number < 1 || site_number > sites.length
|
99
|
+
unless retry_site
|
100
|
+
print "\nOn which site would you like to work? "
|
101
|
+
else
|
102
|
+
print "\nPlease enter the number of your site (between 1-#{sites.length}): "
|
103
|
+
end
|
104
|
+
site_number_string = ask
|
105
|
+
site_number = site_number_string.to_i rescue 0
|
106
|
+
retry_site = true
|
107
|
+
end
|
108
|
+
puts ""
|
109
|
+
site = sites[site_number-1]
|
110
|
+
display "Site chosen => #{site.name.white.bold} (http://#{site.domain})"
|
111
|
+
subdomain = site.subdomain
|
112
|
+
@site = subdomain
|
113
|
+
end
|
114
|
+
|
115
|
+
themes = client.themes(:subdomain => subdomain).list
|
116
|
+
current_theme = if themes.length > 1
|
117
|
+
theme_number = 0
|
118
|
+
retry_theme = false
|
119
|
+
while theme_number < 1 || theme_number > themes.length
|
120
|
+
unless retry_theme
|
121
|
+
print "\nOn which theme would you like to work in this directory? "
|
122
|
+
else
|
123
|
+
print "\nPlease enter the number of your theme (between 1-#{themes.length}): "
|
124
|
+
end
|
125
|
+
theme_number_string = ask
|
126
|
+
theme_number = theme_number_string.to_i rescue 0
|
127
|
+
retry_theme = true
|
128
|
+
end
|
129
|
+
puts ""
|
130
|
+
display "Theme chosen => #{themes[theme_number-1].name}"
|
131
|
+
themes[theme_number-1]
|
132
|
+
else
|
133
|
+
themes.first
|
134
|
+
end
|
135
|
+
@theme = current_theme.short
|
136
|
+
print_separator
|
137
|
+
|
138
|
+
{ "site" => subdomain, "theme" => current_theme.short }
|
88
139
|
end
|
89
140
|
|
90
141
|
def read_configuration
|
91
|
-
|
142
|
+
existing_config = YAML::load(File.open( configuration_file )) if File.exists?(configuration_file)
|
143
|
+
if existing_config && ! existing_config["site"].nil?
|
144
|
+
existing_config
|
145
|
+
else
|
146
|
+
nil
|
147
|
+
end
|
92
148
|
end
|
93
149
|
|
94
150
|
def write_configuration
|
@@ -102,23 +158,15 @@ class Nimbu::Auth
|
|
102
158
|
@credentials = ask_for_and_save_credentials
|
103
159
|
end
|
104
160
|
|
105
|
-
def
|
106
|
-
get_credentials
|
107
|
-
end
|
108
|
-
|
109
|
-
def password # :nodoc:
|
110
|
-
get_credentials[1]
|
111
|
-
end
|
112
|
-
|
113
|
-
def api_key
|
114
|
-
Nimbu::Client.auth(user, password)["api_key"]
|
161
|
+
def token # :nodoc:
|
162
|
+
get_credentials
|
115
163
|
end
|
116
164
|
|
117
165
|
def credentials_file
|
118
166
|
if host == default_host
|
119
167
|
"#{home_directory}/.nimbu/credentials"
|
120
168
|
else
|
121
|
-
"#{home_directory}/.nimbu/credentials.#{CGI.escape(host)}"
|
169
|
+
"#{home_directory}/.nimbu/credentials.#{CGI.escape(host.gsub(/https?\:\/\//,''))}"
|
122
170
|
end
|
123
171
|
end
|
124
172
|
|
@@ -132,16 +180,17 @@ class Nimbu::Auth
|
|
132
180
|
end
|
133
181
|
|
134
182
|
def read_credentials
|
135
|
-
if
|
136
|
-
|
183
|
+
credentials = File.read(credentials_file) if File.exists?(credentials_file)
|
184
|
+
if credentials && credentials =~ /^(bearer|oauth2|token) ([\w]+)$/i
|
185
|
+
$2
|
137
186
|
else
|
138
|
-
|
187
|
+
nil
|
139
188
|
end
|
140
189
|
end
|
141
190
|
|
142
191
|
def write_credentials
|
143
192
|
FileUtils.mkdir_p(File.dirname(credentials_file))
|
144
|
-
File.open(credentials_file, 'w') {|credentials| credentials.
|
193
|
+
File.open(credentials_file, 'w') {|credentials| credentials.print("token #{self.credentials}")}
|
145
194
|
FileUtils.chmod(0700, File.dirname(credentials_file))
|
146
195
|
FileUtils.chmod(0600, credentials_file)
|
147
196
|
end
|
@@ -159,16 +208,21 @@ class Nimbu::Auth
|
|
159
208
|
end
|
160
209
|
|
161
210
|
def ask_for_credentials
|
162
|
-
|
163
|
-
|
164
|
-
print "Email: "
|
211
|
+
print "Login: "
|
165
212
|
user = ask
|
166
213
|
|
167
214
|
print "Password: "
|
168
215
|
password = running_on_windows? ? ask_for_password_on_windows : ask_for_password
|
169
|
-
api_key = Nimbu::Client.auth(user, password)['api_key']
|
170
216
|
|
171
|
-
|
217
|
+
begin
|
218
|
+
oauth = Nimbu::Client.new(:basic_auth => "#{user}:#{password}", :endpoint => host).authenticate
|
219
|
+
oauth.token
|
220
|
+
rescue Exception => e
|
221
|
+
if e.respond_to?(:http_status_code) && e.http_status_code == 401
|
222
|
+
display " => could not login... please check your username and/or password!\n\n"
|
223
|
+
end
|
224
|
+
nil
|
225
|
+
end
|
172
226
|
end
|
173
227
|
|
174
228
|
def ask_for_password_on_windows
|
@@ -202,15 +256,11 @@ class Nimbu::Auth
|
|
202
256
|
end
|
203
257
|
|
204
258
|
def ask_for_and_save_credentials
|
259
|
+
display "Please authenticate with Nimbu.io:"
|
205
260
|
begin
|
206
261
|
@credentials = ask_for_credentials
|
207
262
|
write_credentials
|
208
263
|
check
|
209
|
-
rescue ::RestClient::Unauthorized, ::RestClient::ResourceNotFound => e
|
210
|
-
delete_credentials
|
211
|
-
display "Authentication failed."
|
212
|
-
retry if retry_login?
|
213
|
-
exit 1
|
214
264
|
rescue Exception => e
|
215
265
|
delete_credentials
|
216
266
|
raise e
|
@@ -218,55 +268,16 @@ class Nimbu::Auth
|
|
218
268
|
@credentials
|
219
269
|
end
|
220
270
|
|
221
|
-
def check_for_associated_ssh_key
|
222
|
-
return unless client.keys.empty?
|
223
|
-
associate_or_generate_ssh_key
|
224
|
-
end
|
225
|
-
|
226
|
-
def associate_or_generate_ssh_key
|
227
|
-
public_keys = Dir.glob("#{home_directory}/.ssh/*.pub").sort
|
228
|
-
|
229
|
-
case public_keys.length
|
230
|
-
when 0 then
|
231
|
-
display "Could not find an existing public key."
|
232
|
-
display "Would you like to generate one? [Yn] ", false
|
233
|
-
unless ask.strip.downcase == "n"
|
234
|
-
display "Generating new SSH public key."
|
235
|
-
generate_ssh_key("id_rsa")
|
236
|
-
associate_key("#{home_directory}/.ssh/id_rsa.pub")
|
237
|
-
end
|
238
|
-
when 1 then
|
239
|
-
display "Found existing public key: #{public_keys.first}"
|
240
|
-
associate_key(public_keys.first)
|
241
|
-
else
|
242
|
-
display "Found the following SSH public keys:"
|
243
|
-
public_keys.each_with_index do |key, index|
|
244
|
-
display "#{index+1}) #{File.basename(key)}"
|
245
|
-
end
|
246
|
-
display "Which would you like to use with your Nimbu account? ", false
|
247
|
-
chosen = public_keys[ask.to_i-1] rescue error("Invalid choice")
|
248
|
-
associate_key(chosen)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
def generate_ssh_key(keyfile)
|
253
|
-
ssh_dir = File.join(home_directory, ".ssh")
|
254
|
-
unless File.exists?(ssh_dir)
|
255
|
-
FileUtils.mkdir_p ssh_dir
|
256
|
-
File.chmod(0700, ssh_dir)
|
257
|
-
end
|
258
|
-
`ssh-keygen -t rsa -N "" -f \"#{home_directory}/.ssh/#{keyfile}\" 2>&1`
|
259
|
-
end
|
260
|
-
|
261
|
-
def associate_key(key)
|
262
|
-
display "Uploading SSH public key #{key}"
|
263
|
-
client.add_key(File.read(key))
|
264
|
-
end
|
265
|
-
|
266
271
|
def retry_login?
|
267
272
|
@login_attempts ||= 0
|
268
273
|
@login_attempts += 1
|
269
274
|
@login_attempts < 3
|
270
275
|
end
|
276
|
+
|
277
|
+
def print_separator
|
278
|
+
print "\n"
|
279
|
+
60.times { print "#"}
|
280
|
+
print "\n"
|
281
|
+
end
|
271
282
|
end
|
272
283
|
end
|
data/lib/nimbu/cli.rb
CHANGED
@@ -1,12 +1,29 @@
|
|
1
1
|
require "nimbu"
|
2
2
|
require "nimbu/command"
|
3
|
+
require "nimbu/helpers"
|
3
4
|
|
4
5
|
class Nimbu::CLI
|
5
6
|
|
7
|
+
extend Nimbu::Helpers
|
8
|
+
|
6
9
|
def self.start(*args)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
+
begin
|
11
|
+
if $stdin.isatty
|
12
|
+
$stdin.sync = true
|
13
|
+
end
|
14
|
+
if $stdout.isatty
|
15
|
+
$stdout.sync = true
|
16
|
+
end
|
17
|
+
command = args.shift.strip rescue "help"
|
18
|
+
Nimbu::Command.load
|
19
|
+
Nimbu::Command.run(command, args)
|
20
|
+
rescue Interrupt
|
21
|
+
`stty icanon echo`
|
22
|
+
error("Command cancelled.")
|
23
|
+
rescue => error
|
24
|
+
styled_error(error)
|
25
|
+
exit(1)
|
26
|
+
end
|
10
27
|
end
|
11
28
|
|
12
29
|
end
|
data/lib/nimbu/command.rb
CHANGED
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'nimbu/helpers'
|
2
2
|
require 'nimbu/version'
|
3
|
+
require 'term/ansicolor'
|
3
4
|
require "optparse"
|
4
5
|
|
6
|
+
class String
|
7
|
+
include Term::ANSIColor
|
8
|
+
end
|
9
|
+
|
5
10
|
module Nimbu
|
6
11
|
module Command
|
7
12
|
class CommandFailed < RuntimeError; end
|
@@ -22,6 +27,10 @@ module Nimbu
|
|
22
27
|
@@command_aliases ||= {}
|
23
28
|
end
|
24
29
|
|
30
|
+
def self.files
|
31
|
+
@@files ||= Hash.new {|hash,key| hash[key] = File.readlines(key).map {|line| line.strip}}
|
32
|
+
end
|
33
|
+
|
25
34
|
def self.namespaces
|
26
35
|
@@namespaces ||= {}
|
27
36
|
end
|
@@ -38,72 +47,70 @@ module Nimbu
|
|
38
47
|
@current_command
|
39
48
|
end
|
40
49
|
|
50
|
+
def self.current_command=(new_current_command)
|
51
|
+
@current_command = new_current_command
|
52
|
+
end
|
53
|
+
|
41
54
|
def self.current_args
|
42
55
|
@current_args
|
43
56
|
end
|
44
57
|
|
45
58
|
def self.current_options
|
46
|
-
@current_options
|
59
|
+
@current_options ||= {}
|
47
60
|
end
|
48
61
|
|
49
62
|
def self.global_options
|
50
63
|
@global_options ||= []
|
51
64
|
end
|
52
65
|
|
53
|
-
def self.global_option(name, *args)
|
54
|
-
global_options << { :name => name, :args => args }
|
66
|
+
def self.global_option(name, *args, &blk)
|
67
|
+
global_options << { :name => name.to_s, :args => args.sort.reverse, :proc => blk }
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.warnings
|
71
|
+
@warnings ||= []
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.display_warnings
|
75
|
+
unless warnings.empty?
|
76
|
+
$stderr.puts(warnings.map {|warning| " ! #{warning}"}.join("\n"))
|
77
|
+
end
|
55
78
|
end
|
56
79
|
|
57
|
-
global_option :app, "--app APP", "-a"
|
58
|
-
global_option :confirm, "--confirm APP"
|
59
80
|
global_option :help, "--help", "-h"
|
60
|
-
global_option :
|
81
|
+
global_option :debug, "--debug"
|
61
82
|
|
62
83
|
def self.prepare_run(cmd, args=[])
|
63
84
|
command = parse(cmd)
|
64
85
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
output_with_bang("`#{cmd}` is not a nimbu command.")
|
72
|
-
|
73
|
-
distances = {}
|
74
|
-
(commands.keys + command_aliases.keys).each do |suggestion|
|
75
|
-
distance = string_distance(cmd, suggestion)
|
76
|
-
distances[distance] ||= []
|
77
|
-
distances[distance] << suggestion
|
78
|
-
end
|
79
|
-
|
80
|
-
if distances.keys.min < 4
|
81
|
-
suggestions = distances[distances.keys.min].sort
|
82
|
-
if suggestions.length == 1
|
83
|
-
output_with_bang("Perhaps you meant `#{suggestions.first}`.")
|
84
|
-
else
|
85
|
-
output_with_bang("Perhaps you meant #{suggestions[0...-1].map {|suggestion| "`#{suggestion}`"}.join(', ')} or `#{suggestions.last}`.")
|
86
|
-
end
|
87
|
-
end
|
86
|
+
if args.include?('-h') || args.include?('--help')
|
87
|
+
args.unshift(cmd) unless cmd =~ /^-.*/
|
88
|
+
cmd = 'help'
|
89
|
+
command = parse(cmd)
|
90
|
+
end
|
88
91
|
|
89
|
-
|
90
|
-
|
92
|
+
if cmd == '--version'
|
93
|
+
cmd = 'version'
|
94
|
+
command = parse(cmd)
|
91
95
|
end
|
92
96
|
|
93
97
|
@current_command = cmd
|
98
|
+
@anonymized_args, @normalized_args = [], []
|
94
99
|
|
95
100
|
opts = {}
|
96
101
|
invalid_options = []
|
97
102
|
|
98
103
|
parser = OptionParser.new do |parser|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
104
|
+
parser.base.long.delete('version')
|
105
|
+
(global_options + (command && command[:options] || [])).each do |option|
|
106
|
+
parser.on(*option[:args]) do |value|
|
107
|
+
if option[:proc]
|
108
|
+
option[:proc].call(value)
|
109
|
+
end
|
110
|
+
opts[option[:name].gsub('-', '_').to_sym] = value
|
111
|
+
ARGV.join(' ') =~ /(#{option[:args].map {|arg| arg.split(' ', 2).first}.join('|')})/
|
112
|
+
@anonymized_args << "#{$1} _"
|
113
|
+
@normalized_args << "#{option[:args].last.split(' ', 2).first} _"
|
107
114
|
end
|
108
115
|
end
|
109
116
|
end
|
@@ -111,53 +118,116 @@ module Nimbu
|
|
111
118
|
begin
|
112
119
|
parser.order!(args) do |nonopt|
|
113
120
|
invalid_options << nonopt
|
121
|
+
@anonymized_args << '!'
|
122
|
+
@normalized_args << '!'
|
114
123
|
end
|
115
124
|
rescue OptionParser::InvalidOption => ex
|
116
125
|
invalid_options << ex.args.first
|
126
|
+
@anonymized_args << '!'
|
127
|
+
@normalized_args << '!'
|
117
128
|
retry
|
118
129
|
end
|
119
130
|
|
120
|
-
raise OptionParser::ParseError if opts[:help]
|
121
|
-
|
122
131
|
args.concat(invalid_options)
|
123
132
|
|
124
133
|
@current_args = args
|
125
134
|
@current_options = opts
|
135
|
+
@invalid_arguments = invalid_options
|
136
|
+
|
137
|
+
if opts[:debug]
|
138
|
+
Nimbu.debug = true
|
139
|
+
end
|
140
|
+
|
141
|
+
@anonymous_command = [ARGV.first, *@anonymized_args].join(' ')
|
142
|
+
begin
|
143
|
+
usage_directory = "#{home_directory}/.nimbu/usage"
|
144
|
+
FileUtils.mkdir_p(usage_directory)
|
145
|
+
usage_file = usage_directory << "/#{Nimbu::VERSION}"
|
146
|
+
usage = if File.exists?(usage_file)
|
147
|
+
json_decode(File.read(usage_file))
|
148
|
+
else
|
149
|
+
{}
|
150
|
+
end
|
151
|
+
usage[@anonymous_command] ||= 0
|
152
|
+
usage[@anonymous_command] += 1
|
153
|
+
File.write(usage_file, json_encode(usage) + "\n")
|
154
|
+
rescue
|
155
|
+
# usage writing is not important, allow failures
|
156
|
+
end
|
157
|
+
|
158
|
+
if command
|
159
|
+
command_instance = command[:klass].new(args.dup, opts.dup)
|
126
160
|
|
127
|
-
|
161
|
+
if !@normalized_args.include?('--app _') && (implied_app = command_instance.app rescue nil)
|
162
|
+
@normalized_args << '--app _'
|
163
|
+
end
|
164
|
+
@normalized_command = [ARGV.first, @normalized_args.sort_by {|arg| arg.gsub('-', '')}].join(' ')
|
165
|
+
|
166
|
+
[ command_instance, command[:method] ]
|
167
|
+
else
|
168
|
+
error([
|
169
|
+
"`#{cmd}` is not a Nimbu command.",
|
170
|
+
suggestion(cmd, commands.keys + command_aliases.keys),
|
171
|
+
"See `Nimbu help` for a list of available commands."
|
172
|
+
].compact.join("\n"))
|
173
|
+
end
|
128
174
|
end
|
129
175
|
|
130
176
|
def self.run(cmd, arguments=[])
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
139
|
-
rescue RestClient::PaymentRequired => e
|
140
|
-
retry if run('account:confirm_billing', arguments.dup)
|
141
|
-
rescue RestClient::ResourceNotFound => e
|
142
|
-
error extract_error(e.http_body) {
|
143
|
-
e.http_body =~ /^[\w\s]+ not found$/ ? e.http_body : "Resource not found"
|
144
|
-
}
|
145
|
-
rescue RestClient::Locked => e
|
146
|
-
app = e.response.headers[:x_confirmation_required]
|
147
|
-
if confirm_command(app, extract_error(e.response.body))
|
148
|
-
arguments << '--confirm' << app
|
149
|
-
retry
|
177
|
+
begin
|
178
|
+
object, method = prepare_run(cmd, arguments.dup)
|
179
|
+
object.send(method)
|
180
|
+
rescue Interrupt, StandardError, SystemExit => error
|
181
|
+
# load likely error classes, as they may not be loaded yet due to defered loads
|
182
|
+
require 'rest_client'
|
183
|
+
raise(error)
|
150
184
|
end
|
151
|
-
rescue RestClient::
|
152
|
-
|
153
|
-
|
154
|
-
|
185
|
+
# rescue Nimbu::API::Errors::Unauthorized, RestClient::Unauthorized
|
186
|
+
# puts "Authentication failure"
|
187
|
+
# unless ENV['Nimbu_API_KEY']
|
188
|
+
# run "login"
|
189
|
+
# retry
|
190
|
+
# end
|
191
|
+
# rescue Nimbu::API::Errors::VerificationRequired, RestClient::PaymentRequired => e
|
192
|
+
# retry if Nimbu::Helpers.confirm_billing
|
193
|
+
# rescue Nimbu::API::Errors::NotFound => e
|
194
|
+
# error extract_error(e.response.body) {
|
195
|
+
# e.response.body =~ /^([\w\s]+ not found).?$/ ? $1 : "Resource not found"
|
196
|
+
# }
|
197
|
+
# rescue RestClient::ResourceNotFound => e
|
198
|
+
# error extract_error(e.http_body) {
|
199
|
+
# e.http_body =~ /^([\w\s]+ not found).?$/ ? $1 : "Resource not found"
|
200
|
+
# }
|
201
|
+
# rescue Nimbu::API::Errors::Locked => e
|
202
|
+
# app = e.response.headers[:x_confirmation_required]
|
203
|
+
# if confirm_command(app, extract_error(e.response.body))
|
204
|
+
# arguments << '--confirm' << app
|
205
|
+
# retry
|
206
|
+
# end
|
207
|
+
# rescue RestClient::Locked => e
|
208
|
+
# app = e.response.headers[:x_confirmation_required]
|
209
|
+
# if confirm_command(app, extract_error(e.http_body))
|
210
|
+
# arguments << '--confirm' << app
|
211
|
+
# retry
|
212
|
+
# end
|
213
|
+
# rescue Nimbu::API::Errors::Timeout, RestClient::RequestTimeout
|
214
|
+
# error "API request timed out. Please try again, or contact support@Nimbu.com if this issue persists."
|
215
|
+
# rescue Nimbu::API::Errors::ErrorWithResponse => e
|
216
|
+
# error extract_error(e.response.body)
|
217
|
+
# rescue RestClient::RequestFailed => e
|
218
|
+
# error extract_error(e.http_body)
|
155
219
|
rescue CommandFailed => e
|
156
220
|
error e.message
|
157
|
-
rescue OptionParser::ParseError
|
221
|
+
rescue OptionParser::ParseError
|
158
222
|
commands[cmd] ? run("help", [cmd]) : run("help")
|
159
|
-
rescue
|
160
|
-
|
223
|
+
rescue Excon::Errors::SocketError => e
|
224
|
+
if e.message == 'getaddrinfo: nodename nor servname provided, or not known (SocketError)'
|
225
|
+
error("Unable to connect to Nimbu API, please check internet connectivity and try again.")
|
226
|
+
else
|
227
|
+
raise(e)
|
228
|
+
end
|
229
|
+
ensure
|
230
|
+
display_warnings
|
161
231
|
end
|
162
232
|
|
163
233
|
def self.parse(cmd)
|