tugboat 0.2.0 → 1.0.0

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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -4
  4. data/CHANGELOG.md +325 -102
  5. data/CHANGELOG_old.md +150 -0
  6. data/Gemfile +6 -0
  7. data/README.md +12 -6
  8. data/Rakefile +7 -3
  9. data/features/step_definitions/steps.rb +0 -0
  10. data/features/support/env.rb +9 -0
  11. data/features/vagrant-adam/config_current_directory.feature +27 -0
  12. data/lib/tugboat/cli.rb +31 -3
  13. data/lib/tugboat/config.rb +13 -5
  14. data/lib/tugboat/middleware.rb +8 -0
  15. data/lib/tugboat/middleware/ask_for_credentials.rb +5 -4
  16. data/lib/tugboat/middleware/authentication_middleware.rb +2 -2
  17. data/lib/tugboat/middleware/config.rb +29 -0
  18. data/lib/tugboat/middleware/custom_logger.rb +2 -2
  19. data/lib/tugboat/middleware/find_droplet.rb +4 -0
  20. data/lib/tugboat/middleware/info_droplet.rb +5 -0
  21. data/lib/tugboat/middleware/inject_client.rb +1 -1
  22. data/lib/tugboat/middleware/list_droplets.rb +5 -1
  23. data/lib/tugboat/middleware/list_regions.rb +2 -2
  24. data/lib/tugboat/middleware/ssh_droplet.rb +17 -2
  25. data/lib/tugboat/version.rb +1 -1
  26. data/spec/cli/add_key_spec.rb +9 -9
  27. data/spec/cli/authorize_cli_spec.rb +76 -52
  28. data/spec/cli/create_cli_spec.rb +39 -4
  29. data/spec/cli/debug_cli_spec.rb +44 -0
  30. data/spec/cli/destroy_cli_spec.rb +30 -11
  31. data/spec/cli/destroy_image_cli_spec.rb +11 -11
  32. data/spec/cli/droplets_cli_spec.rb +6 -6
  33. data/spec/cli/halt_cli_spec.rb +9 -9
  34. data/spec/cli/images_cli_spec.rb +6 -6
  35. data/spec/cli/info_cli_spec.rb +42 -7
  36. data/spec/cli/info_image_cli_spec.rb +6 -6
  37. data/spec/cli/keys_cli_spec.rb +1 -1
  38. data/spec/cli/password_reset_cli_spec.rb +8 -8
  39. data/spec/cli/rebuild_cli_spec.rb +49 -49
  40. data/spec/cli/regions_cli_spec.rb +4 -4
  41. data/spec/cli/resize_cli_spec.rb +8 -8
  42. data/spec/cli/restart_cli_spec.rb +8 -8
  43. data/spec/cli/sizes_cli_spec.rb +1 -1
  44. data/spec/cli/snapshot_cli_spec.rb +7 -7
  45. data/spec/cli/ssh_cli_spec.rb +4 -4
  46. data/spec/cli/start_cli_spec.rb +7 -7
  47. data/spec/cli/verify_cli_spec.rb +10 -2
  48. data/spec/cli/wait_cli_spec.rb +6 -6
  49. data/spec/fixtures/500.html +68 -0
  50. data/spec/fixtures/show_droplet.json +1 -0
  51. data/spec/fixtures/show_droplet_fuzzy.json +13 -0
  52. data/spec/fixtures/show_droplet_inactive.json +1 -0
  53. data/spec/fixtures/show_droplets.json +2 -0
  54. data/spec/fixtures/show_droplets_fuzzy.json +35 -0
  55. data/spec/fixtures/show_droplets_inactive.json +2 -0
  56. data/spec/fixtures/show_regions.json +9 -6
  57. data/spec/middleware/base_spec.rb +1 -1
  58. data/spec/middleware/check_credentials_spec.rb +1 -1
  59. data/spec/middleware/inject_client_spec.rb +29 -0
  60. data/spec/middleware/inject_configuration_spec.rb +1 -1
  61. data/spec/middleware/ssh_droplet_spec.rb +30 -7
  62. data/spec/shared/environment.rb +1 -0
  63. data/spec/spec_helper.rb +11 -4
  64. data/tugboat.gemspec +9 -7
  65. metadata +64 -33
data/CHANGELOG_old.md ADDED
@@ -0,0 +1,150 @@
1
+ ## 0.2.1 (UNRELEASED)
2
+
3
+
4
+ ## 0.2.0 (Feburary 15, 2014)
5
+
6
+ FEATURES:
7
+
8
+ - [Pierre](https://github.com/spearway) added an `info-image` and `destroy-image`
9
+ command, letting you deal with your images from Tugboat. It's great. [GH-91]
10
+ - [Pierre](https://github.com/spearway) also added a `rebuild` command,
11
+ letting you take an existing droplet and recreate it from scratch. [GH-90]
12
+
13
+ IMPROVEMENTS:
14
+
15
+ - [Dale](https://github.com/Vel0x) made it so fuzzy name searching
16
+ is case insensitive. We wonder why we didn't do this earlier, really. [GH-88]
17
+ - There is now a `--quiet/-q` flag, which makes Tugboat be silent, as it
18
+ can get a little obnoxious. [GH-87]
19
+ - [Andrew](https://github.com/4n3w) hooked up a `backups_enabled` option
20
+ for creating droplets. [GH-82]
21
+
22
+
23
+ ## 0.0.9 (December 24, 2013)
24
+
25
+ FEATURES:
26
+
27
+ - [Pete](https://github.com/petems) added the ability to add an
28
+ ssh key to your account. [GH-64]
29
+ - [Caleb](https://github.com/calebreach) gave us an easy way
30
+ to pass a command through to a machine with the `-c` command. [GH-73]
31
+
32
+ IMPROVEMENTS:
33
+
34
+ - [Andrew](https://github.com/4n3w) added a private networking option. [GH-75]
35
+
36
+ BUG FIXES:
37
+
38
+ - [Zo](https://github.com/obradovic) made our default image 13.04 [GH-76]
39
+ - Issues with the JSON dependency in 2.0.0 were resolved. [GH-80]
40
+
41
+
42
+ ## 0.0.8 (September 7, 2013)
43
+
44
+ FEATURES:
45
+
46
+ - [Pete](https://github.com/petems) added configuration defaults
47
+ that you can set. [GH-61]
48
+ - [Pete](https://github.com/petems) added log filtering to debug output.
49
+ `DEBUG=1` now gives you filtered logs, `DEBUG=2`, raw. [GH-58]
50
+
51
+ IMPROVEMENTS:
52
+
53
+ - Error messages are now caught at the Faraday level and displayed
54
+ back to the user.
55
+
56
+ BUG FIXES:
57
+
58
+ - [Ørjan](https://github.com/blom) added a color reset on the `list`
59
+ command. [GH-57]
60
+
61
+ ## 0.0.7 (August 2, 2013)
62
+
63
+ IMPROVEMENTS:
64
+
65
+ - [Pete](https://github.com/petems) made it clearer to the user
66
+ if they don't have any droplets or images. [GH-48], [GH-49]
67
+
68
+ BUG FIXES:
69
+
70
+ - Fix the initial check for authorization after `authorize` [GH-41]
71
+
72
+ ## 0.0.6 (June 25, 2013)
73
+
74
+ FEATURES:
75
+
76
+ - [Ørjan](https://github.com/blom) added a `start` command, which
77
+ let's you start a droplet. [GH-30]
78
+ - [Ørjan](https://github.com/blom) added a `resize` command, which
79
+ let's you resize a droplet. [GH-40]
80
+ - [Ørjan](https://github.com/blom) added a `password-reset` command
81
+ [GH-45]
82
+ - Added a the `wait` command, allowing you to "wait" for a droplet
83
+ to enter a state. [GH-46]
84
+
85
+ IMPROVEMENTS:
86
+
87
+ - [Ørjan](https://github.com/blom) added an `--ssh-opts` flag, for the
88
+ `ssh` command. [GH-38]
89
+ - Droplet state is checked for some commands. For example, a droplet
90
+ can't be started if it's active. [GH-31]
91
+
92
+ BUG FIXES:
93
+
94
+ - DigitalOcean changed their `image_id`'s, so the defaults for `create`
95
+ were updated. [GH-39]
96
+
97
+ ## 0.0.5 (May 4, 2013)
98
+
99
+ FEATURES:
100
+
101
+ - [Ørjan](https://github.com/blom) added a `regions` command, which
102
+ returns a list of available DigitalOcean regions. You can specify
103
+ which region to use while creating: `tugboat create foobar -r 2`. [GH-18]
104
+ - [Ørjan](https://github.com/blom) added an ssh_user option to the
105
+ `ssh` command. This lets you specify the user to connect as on
106
+ a per-command basis, as well as in your `.tugboat`.
107
+ - [Ørjan](https://github.com/blom) added a `sizes` command, which
108
+ returns a list of available sizes. You can specify which size to
109
+ use while creating: `tugboat create foobar -s 66` [GH-19]
110
+ - [Ørjan](https://github.com/blom) added a `hard` flag to
111
+ `halt` and `restart`. This cycles the Droplet's power. `tugboat restart --hard` [GH-27]
112
+
113
+ IMPROVEMENTS:
114
+
115
+ - Tugboat now returns proper status codes for successes and failures.
116
+ [GH-21]
117
+ - Support for MRI 1.8.7
118
+ - CTRL+C's, SIG-INT's are now caught and quietly kill Tugboat without
119
+ a stacktrace.
120
+
121
+ ## 0.0.4 (April 23, 2013)
122
+
123
+ BUG FIXES:
124
+
125
+ - Fix a syntax error caused by the order of arguments on `snapshot`.
126
+ This changes the argument order and is a breaking change [GH-10].
127
+ - Fix an issue with looking up a droplet by it's `--name`. A variable
128
+ was changed, and because it was shadowed passed inspection.
129
+
130
+ IMPROVEMENTS:
131
+
132
+ - Added a warning for snapshotting a droplet in a non-powered off
133
+ state. DigitalOcean currently doesn't return an error from their API.
134
+ - Added a `--confirm` or `-c` to confirmed actions, like destroy. [GH-7]
135
+ - [Ørjan](https://github.com/blom) added a `--version` command to see
136
+ what version of Tugboat you're using.
137
+ - Substantially more test coverage - all of the commands (except `ssh` are
138
+ now integration tested. [GH-15]
139
+
140
+ FEATURES:
141
+
142
+ - Optionally add a list of ssh_key_ids when creating a droplet. These
143
+ SSH keys will automatically be added to your droplet.
144
+ - Show a list of SSH keys on your account with `tugboat keys`
145
+ - [Phil](https://github.com/PhilETaylor) added the ability to specify
146
+ an `--ssh-port` on `tugboat ssh`, as well as set a default in your `.tugboat` [GH-13]
147
+
148
+ ## 0.0.3 (April 15, 2013)
149
+
150
+ Initial release.
data/Gemfile CHANGED
@@ -2,3 +2,9 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in tugboat.gemspec
4
4
  gemspec
5
+
6
+ group :development do
7
+ # Random order is not in the Aruba Cucumber yet...
8
+ gem 'cucumber', git: 'https://github.com/cucumber/cucumber.git', tag: 'v2.0.0.beta.2'
9
+ gem 'cucumber-core', git: 'https://github.com/cucumber/cucumber-core.git', tag: 'v1.0.0.beta.2'
10
+ end
data/README.md CHANGED
@@ -8,10 +8,12 @@ A command line tool for interacting with your [DigitalOcean](https://www.digital
8
8
 
9
9
  gem install tugboat
10
10
 
11
+ Please note that Tugboat version 0.2.0 and up requires Ruby 1.9 or higher.
12
+
11
13
  ## Configuration
12
14
 
13
15
  Run the configuration utility, `tugboat authorize`. You can grab your keys
14
- [here](https://www.digitalocean.com/api_access).
16
+ [here](https://cloud.digitalocean.com/api_access).
15
17
 
16
18
  $ tugboat authorize
17
19
  Enter your client key: foo
@@ -30,6 +32,10 @@ Run the configuration utility, `tugboat authorize`. You can grab your keys
30
32
 
31
33
  Authentication with DigitalOcean was successful!
32
34
 
35
+ This will create a .tugboat file in your home folder (eg. ~/.tugboat).
36
+
37
+ Tugboat will look for a .tugboat config file first in the current directory you're running it in, then will look for one in the home directory.
38
+
33
39
  ## Usage
34
40
 
35
41
  ### Retrieve a list of your droplets
@@ -153,9 +159,9 @@ Optionally, list images provided by DigitalOcean as well.
153
159
 
154
160
  $ tugboat regions
155
161
  Regions:
156
- New York 1 (id: 1)
157
- Amsterdam 1 (id: 2)
158
- San Francisco 1 (id: 3)
162
+ New York 1 (id: 1) (slug: nyc1)
163
+ Amsterdam 1 (id: 2) (slug: ams1)
164
+ San Francisco 1 (id: 3) (slug: sfo1)
159
165
 
160
166
  ### List SSH Keys
161
167
 
@@ -188,9 +194,9 @@ ask tugboat about it.
188
194
  For a complete overview of all of the available commands, run:
189
195
 
190
196
  $ tugboat help
191
-
192
197
 
193
- Depending on your local configuration, you may need to install a CA bundle (OS X only) using [homebrew](http://brew.sh/) to commmunicate with DigitalOcean through SSL/TLS:
198
+
199
+ Depending on your local configuration, you may need to install a CA bundle (OS X only) using [homebrew](http://brew.sh/) to communicate with DigitalOcean through SSL/TLS:
194
200
 
195
201
  $ brew install curl-ca-bundle
196
202
 
data/Rakefile CHANGED
@@ -1,7 +1,11 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
2
  require 'rspec/core/rake_task'
3
-
3
+ require 'cucumber/rake/task'
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- task :default => :spec
7
+ Cucumber::Rake::Task.new(:features) do |t|
8
+ t.cucumber_opts = %w(--format pretty --order random)
9
+ end
10
+
11
+ task :default => [:spec, :features]
File without changes
@@ -0,0 +1,9 @@
1
+ require 'aruba/cucumber'
2
+
3
+ Before do
4
+
5
+ end
6
+
7
+ After do
8
+
9
+ end
@@ -0,0 +1,27 @@
1
+ Feature: config
2
+ In order to easily load DigitalOcean config
3
+ As a user
4
+ I should be able to load tugboat config from a .tugboat in the current directory
5
+
6
+ Scenario:
7
+ Given a file named ".tugboat" with:
8
+ """
9
+ ---
10
+ authentication:
11
+ client_key: FOO
12
+ api_key: BAR
13
+ ssh:
14
+ ssh_user: janedoe
15
+ ssh_key_path: "/Users/janedoe/.ssh/id_rsa"
16
+ ssh_port: '22'
17
+ defaults:
18
+ region: '8'
19
+ image: '9801950'
20
+ size: '66'
21
+ ssh_key: ''
22
+ private_networking: 'false'
23
+ backups_enabled: 'false'
24
+ """
25
+ When I run `tugboat config`
26
+ Then the exit status should not be 1
27
+ And the output should contain "ssh_user: janedoe"
data/lib/tugboat/cli.rb CHANGED
@@ -28,7 +28,7 @@ module Tugboat
28
28
  details to tugboat. First, you are asked for your API and Client keys,
29
29
  which are stored in ~/.tugboat.
30
30
 
31
- You can retrieve your credentials from digitalocean.com/api_access.
31
+ You can retrieve your credentials from https://cloud.digitalocean.com/api_access
32
32
 
33
33
  Optionally, you can configure the default SSH key path and username
34
34
  used for `tugboat ssh`. These default to '~/.ssh/id_rsa' and the
@@ -40,6 +40,21 @@ module Tugboat
40
40
  })
41
41
  end
42
42
 
43
+ desc "config", "Show your current config information"
44
+ long_desc "This shows the current information in the .tugboat config
45
+ being used by the app
46
+ "
47
+ method_option "hide",
48
+ :type => :boolean,
49
+ :default => true,
50
+ :aliases => "-h",
51
+ :desc => "Hide your API keys"
52
+ def config
53
+ Middleware.sequence_config.call({
54
+ "user_hide_keys" => options[:hide],
55
+ })
56
+ end
57
+
43
58
  desc "verify", "Check your DigitalOcean credentials"
44
59
  long_desc "This tests that your credentials created by the \`authorize\`
45
60
  command that are stored in ~/.tugboat are correct and allow you to connect
@@ -58,7 +73,7 @@ module Tugboat
58
73
  })
59
74
  end
60
75
 
61
- desc "images", "Retrieve a list of your images"
76
+ desc "images [OPTIONS]", "Retrieve a list of your images"
62
77
  method_option "global",
63
78
  :type => :boolean,
64
79
  :default => false,
@@ -84,6 +99,10 @@ module Tugboat
84
99
  :type => :string,
85
100
  :aliases => "-p",
86
101
  :desc => "The custom SSH Port to connect to"
102
+ method_option "use_public_ip",
103
+ :type => :boolean,
104
+ :aliases => "-e",
105
+ :desc => "Use public IP while private IP is present"
87
106
  method_option "ssh_user",
88
107
  :type => :string,
89
108
  :aliases => "-u",
@@ -103,6 +122,7 @@ module Tugboat
103
122
  "user_droplet_fuzzy_name" => name,
104
123
  "user_droplet_ssh_port" => options[:ssh_port],
105
124
  "user_droplet_ssh_user" => options[:ssh_user],
125
+ "user_droplet_use_public_ip" => options[:use_public_ip],
106
126
  "user_droplet_ssh_opts" => options[:ssh_opts],
107
127
  "user_droplet_ssh_command" => options[:ssh_command],
108
128
  "user_quiet" => options[:quiet]
@@ -136,6 +156,11 @@ module Tugboat
136
156
  :desc => "Enable backups on the droplet"
137
157
 
138
158
  def create(name)
159
+ if name =~ /^(-{0,2}help|-{1,2}h)/
160
+ help('create')
161
+ return
162
+ end
163
+
139
164
  Middleware.sequence_create_droplet.call({
140
165
  "create_droplet_size_id" => options[:size],
141
166
  "create_droplet_image_id" => options[:image],
@@ -334,7 +359,10 @@ module Tugboat
334
359
  Middleware.sequence_ssh_keys.call({})
335
360
  end
336
361
 
337
- desc "add-key NAME", "Upload an ssh public key."
362
+ desc "add-key KEY-NAME", "Upload an ssh public key to DigitalOcean, to be assigned to a droplet later"
363
+ long_desc "This uploads a ssh-key to DigitalOcean, which you can then assign to a droplet at
364
+ creation time so you can connect to it with the key rather than a password.
365
+ "
338
366
  method_option "key",
339
367
  :type => :string,
340
368
  :aliases => "-k",
@@ -12,15 +12,19 @@ module Tugboat
12
12
  FILE_NAME = '.tugboat'
13
13
  DEFAULT_SSH_KEY_PATH = '.ssh/id_rsa'
14
14
  DEFAULT_SSH_PORT = '22'
15
- DEFAULT_REGION = '1'
16
- DEFAULT_IMAGE = '350076'
15
+ DEFAULT_REGION = '8'
16
+ DEFAULT_IMAGE = '9801950'
17
17
  DEFAULT_SIZE = '66'
18
18
  DEFAULT_SSH_KEY = ''
19
19
  DEFAULT_PRIVATE_NETWORKING = 'false'
20
20
  DEFAULT_BACKUPS_ENABLED = 'false'
21
21
 
22
+ # Load config file from current directory, if not exit load from user's home directory
22
23
  def initialize
23
- @path = ENV["TUGBOAT_CONFIG_PATH"] || File.join(File.expand_path("~"), FILE_NAME)
24
+ @path = File.join(File.expand_path("."), FILE_NAME)
25
+ unless File.exists?(@path)
26
+ @path = ( ENV["TUGBOAT_CONFIG_PATH"] || File.join(File.expand_path("~"), FILE_NAME) )
27
+ end
24
28
  @data = self.load_config_file
25
29
  end
26
30
 
@@ -53,6 +57,10 @@ module Tugboat
53
57
  @data['ssh']['ssh_port']
54
58
  end
55
59
 
60
+ def use_public_ip
61
+ @data['use_public_ip']
62
+ end
63
+
56
64
  def default_region
57
65
  @data['defaults'].nil? ? DEFAULT_REGION : @data['defaults']['region']
58
66
  end
@@ -91,11 +99,11 @@ module Tugboat
91
99
  def create_config_file(client, api, ssh_key_path, ssh_user, ssh_port, region, image, size, ssh_key, private_networking, backups_enabled)
92
100
  # Default SSH Key path
93
101
  if ssh_key_path.empty?
94
- ssh_key_path = File.join(File.expand_path("~"), DEFAULT_SSH_KEY_PATH)
102
+ ssh_key_path = File.join("~", DEFAULT_SSH_KEY_PATH)
95
103
  end
96
104
 
97
105
  if ssh_user.empty?
98
- ssh_user = ENV['USER']
106
+ ssh_user = 'root'
99
107
  end
100
108
 
101
109
  if ssh_port.empty?
@@ -9,6 +9,7 @@ module Tugboat
9
9
  autoload :CheckCredentials, "tugboat/middleware/check_credentials"
10
10
  autoload :CheckDropletActive, "tugboat/middleware/check_droplet_active"
11
11
  autoload :CheckDropletInactive, "tugboat/middleware/check_droplet_inactive"
12
+ autoload :Config, "tugboat/middleware/config"
12
13
  autoload :ConfirmAction, "tugboat/middleware/confirm_action"
13
14
  autoload :CreateDroplet, "tugboat/middleware/create_droplet"
14
15
  autoload :RebuildDroplet, "tugboat/middleware/rebuild_droplet"
@@ -267,6 +268,13 @@ module Tugboat
267
268
  end
268
269
  end
269
270
 
271
+ # Returns current used config
272
+ def self.sequence_config
273
+ ::Middleware::Builder.new do
274
+ use Config
275
+ end
276
+ end
277
+
270
278
  # Wait for a droplet to enter a desired state
271
279
  def self.sequence_wait
272
280
  ::Middleware::Builder.new do
@@ -3,19 +3,20 @@ module Tugboat
3
3
  # Ask for user credentials from the command line, then write them out.
4
4
  class AskForCredentials < Base
5
5
  def call(env)
6
- say "Note: You can get this information from digitalocean.com/api_access", :yellow
6
+ say "Note: You can get this information from https://cloud.digitalocean.com/api_access", :yellow
7
+ say "Also Note: Tugboat is setup to work with v1 of the Digital Ocean API (https://developers.digitalocean.com/v1/)", :yellow
7
8
  say
8
9
  client_key = ask "Enter your client key:"
9
10
  api_key = ask "Enter your API key:"
10
11
  ssh_key_path = ask "Enter your SSH key path (optional, defaults to ~/.ssh/id_rsa):"
11
- ssh_user = ask "Enter your SSH user (optional, defaults to #{ENV['USER']}):"
12
+ ssh_user = ask "Enter your SSH user (optional, defaults to root):"
12
13
  ssh_port = ask "Enter your SSH port number (optional, defaults to 22):"
13
14
  say
14
15
  say "To retrieve region, image, size and key ID's, you can use the corresponding tugboat command, such as `tugboat images`."
15
16
  say "Defaults can be changed at any time in your ~/.tugboat configuration file."
16
17
  say
17
- region = ask "Enter your default region ID (optional, defaults to 1 (New York)):"
18
- image = ask "Enter your default image ID (optional, defaults to 350076 (Ubuntu 13.04 x64)):"
18
+ region = ask "Enter your default region ID (optional, defaults to 8 (New York 3)):"
19
+ image = ask "Enter your default image ID (optional, defaults to 9801950 (Ubuntu 14.04 x64)):"
19
20
  size = ask "Enter your default size ID (optional, defaults to 66 (512MB)):"
20
21
  ssh_key = ask "Enter your default ssh key ID (optional, defaults to none):"
21
22
  private_networking = ask "Enter your default for private networking (optional, defaults to false):"
@@ -21,10 +21,10 @@ module Tugboat
21
21
  @app.call(env)
22
22
  rescue Faraday::Error::ClientError => e
23
23
  puts "#{RED}#{e}!#{CLEAR}\n"
24
- if env[:body].status == "ERROR"
24
+ if env[:body].is_a?(Hashie::Rash)
25
25
  puts "\n#{RED}#{env[:body].error_message}#{CLEAR}\n\n"
26
26
  end
27
- puts "Double-check your parameters and configuration (in your ~/.tugboat file)"
27
+ puts "Double-check your parameters and configuration (in your ~/.tugboat file)" if env[:status] == 401
28
28
  exit 1
29
29
  end
30
30
  end