nimbu 0.4 → 0.5.1
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.
- 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)
|