tugboat 2.2.2 → 2.2.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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +520 -0
  3. data/CHANGELOG.md +9 -0
  4. data/Gemfile +0 -6
  5. data/README.md +34 -2
  6. data/Rakefile +6 -1
  7. data/bin/tugboat +2 -2
  8. data/features/cassettes/config/Array_of_SSH_Keys_in_Config.yml +1 -1
  9. data/features/cassettes/config/Single_SSH_key_as_number_in_config.yml +1 -1
  10. data/features/step_definitions/steps.rb +1 -1
  11. data/features/support/env.rb +7 -3
  12. data/lib/tugboat.rb +2 -2
  13. data/lib/tugboat/cli.rb +394 -444
  14. data/lib/tugboat/config.rb +43 -61
  15. data/lib/tugboat/middleware.rb +33 -33
  16. data/lib/tugboat/middleware/add_key.rb +12 -13
  17. data/lib/tugboat/middleware/ask_for_credentials.rb +12 -13
  18. data/lib/tugboat/middleware/base.rb +25 -20
  19. data/lib/tugboat/middleware/check_configuration.rb +3 -6
  20. data/lib/tugboat/middleware/check_credentials.rb +0 -1
  21. data/lib/tugboat/middleware/check_droplet_active.rb +2 -4
  22. data/lib/tugboat/middleware/check_droplet_inactive.rb +2 -4
  23. data/lib/tugboat/middleware/config.rb +3 -5
  24. data/lib/tugboat/middleware/confirm_action.rb +4 -6
  25. data/lib/tugboat/middleware/create_droplet.rb +27 -44
  26. data/lib/tugboat/middleware/custom_logger.rb +52 -54
  27. data/lib/tugboat/middleware/destroy_droplet.rb +5 -6
  28. data/lib/tugboat/middleware/destroy_image.rb +5 -6
  29. data/lib/tugboat/middleware/find_droplet.rb +43 -47
  30. data/lib/tugboat/middleware/find_image.rb +23 -29
  31. data/lib/tugboat/middleware/halt_droplet.rb +9 -10
  32. data/lib/tugboat/middleware/info_droplet.rb +30 -33
  33. data/lib/tugboat/middleware/info_image.rb +1 -1
  34. data/lib/tugboat/middleware/inject_client.rb +8 -10
  35. data/lib/tugboat/middleware/inject_configuration.rb +1 -2
  36. data/lib/tugboat/middleware/list_droplets.rb +9 -10
  37. data/lib/tugboat/middleware/list_images.rb +9 -9
  38. data/lib/tugboat/middleware/list_regions.rb +1 -1
  39. data/lib/tugboat/middleware/list_sizes.rb +1 -1
  40. data/lib/tugboat/middleware/list_ssh_keys.rb +1 -3
  41. data/lib/tugboat/middleware/password_reset.rb +6 -7
  42. data/lib/tugboat/middleware/rebuild_droplet.rb +7 -7
  43. data/lib/tugboat/middleware/resize_droplet.rb +6 -7
  44. data/lib/tugboat/middleware/restart_droplet.rb +4 -11
  45. data/lib/tugboat/middleware/snapshot_droplet.rb +7 -8
  46. data/lib/tugboat/middleware/ssh_droplet.rb +30 -31
  47. data/lib/tugboat/middleware/start_droplet.rb +5 -5
  48. data/lib/tugboat/middleware/wait_for_state.rb +2 -3
  49. data/lib/tugboat/version.rb +1 -1
  50. data/spec/cli/add_key_spec.rb +25 -28
  51. data/spec/cli/authorize_cli_spec.rb +57 -60
  52. data/spec/cli/config_cli_spec.rb +8 -11
  53. data/spec/cli/create_cli_spec.rb +40 -46
  54. data/spec/cli/debug_cli_spec.rb +29 -29
  55. data/spec/cli/destroy_cli_spec.rb +58 -60
  56. data/spec/cli/destroy_image_cli_spec.rb +42 -45
  57. data/spec/cli/droplets_cli_spec.rb +62 -64
  58. data/spec/cli/env_variable_spec.rb +14 -15
  59. data/spec/cli/halt_cli_spec.rb +65 -69
  60. data/spec/cli/help_cli_spec.rb +8 -8
  61. data/spec/cli/images_cli_spec.rb +28 -30
  62. data/spec/cli/info_cli_spec.rb +144 -147
  63. data/spec/cli/info_image_cli_spec.rb +57 -60
  64. data/spec/cli/keys_cli_spec.rb +8 -10
  65. data/spec/cli/password_reset_cli_spec.rb +56 -56
  66. data/spec/cli/rebuild_cli_spec.rb +194 -198
  67. data/spec/cli/regions_cli_spec.rb +8 -8
  68. data/spec/cli/resize_cli_spec.rb +54 -56
  69. data/spec/cli/restart_cli_spec.rb +53 -57
  70. data/spec/cli/sizes_cli_spec.rb +7 -8
  71. data/spec/cli/snapshot_cli_spec.rb +50 -53
  72. data/spec/cli/ssh_cli_spec.rb +41 -42
  73. data/spec/cli/start_cli_spec.rb +48 -52
  74. data/spec/cli/verify_cli_spec.rb +22 -25
  75. data/spec/cli/version_cli_spec.rb +6 -8
  76. data/spec/cli/wait_cli_spec.rb +50 -52
  77. data/spec/config_spec.rb +56 -57
  78. data/spec/middleware/base_spec.rb +5 -6
  79. data/spec/middleware/check_configuration_spec.rb +5 -7
  80. data/spec/middleware/check_credentials_spec.rb +9 -10
  81. data/spec/middleware/check_droplet_active_spec.rb +5 -7
  82. data/spec/middleware/check_droplet_inactive_spec.rb +5 -7
  83. data/spec/middleware/find_droplet_spec.rb +4 -5
  84. data/spec/middleware/find_image_spec.rb +4 -5
  85. data/spec/middleware/inject_client_spec.rb +9 -12
  86. data/spec/middleware/inject_configuration_spec.rb +4 -7
  87. data/spec/middleware/ssh_droplet_spec.rb +70 -73
  88. data/spec/shared/environment.rb +18 -20
  89. data/spec/spec_helper.rb +4 -4
  90. data/tugboat.gemspec +10 -6
  91. metadata +88 -17
@@ -11,7 +11,7 @@ module Tugboat
11
11
  # First, if nothing is provided to us, we should quit and
12
12
  # let the user know.
13
13
  if !user_fuzzy_name && !user_image_name && !user_image_id
14
- say "Tugboat attempted to find an image with no arguments.", :red
14
+ say 'Tugboat attempted to find an image with no arguments.', :red
15
15
  say "Try running `tugboat #{env['tugboat_action']} imagename`", :green
16
16
  say "For more help run: `tugboat help #{env['tugboat_action']}`", :blue
17
17
  exit 1
@@ -24,7 +24,7 @@ module Tugboat
24
24
 
25
25
  # Easy for us if they provide an id. Just set it to the image_id
26
26
  if user_image_id
27
- say "Image id provided. Finding Image...", nil, false
27
+ say 'Image id provided. Finding Image...', nil, false
28
28
  response = ocean.image.show user_image_id
29
29
 
30
30
  unless response.success?
@@ -32,26 +32,26 @@ module Tugboat
32
32
  exit 1
33
33
  end
34
34
 
35
- env["image_id"] = response.image.id
36
- env["image_name"] = "(#{response.image.name})"
35
+ env['image_id'] = response.image.id
36
+ env['image_name'] = "(#{response.image.name})"
37
37
  end
38
38
 
39
39
  # If they provide a name, we need to get the ID for it.
40
40
  # This requires a lookup.
41
- if user_image_name && !env["image_id"]
42
- say "Image name provided. Finding Image...", nil, false
41
+ if user_image_name && !env['image_id']
42
+ say 'Image name provided. Finding Image...', nil, false
43
43
 
44
44
  # Look for the image by an exact name match.
45
45
  ocean.image.all['images'].each do |d|
46
46
  if d.name == user_image_name
47
- env["image_id"] = d.id
48
- env["image_name"] = "(#{d.name})"
47
+ env['image_id'] = d.id
48
+ env['image_name'] = "(#{d.name})"
49
49
  end
50
50
  end
51
51
 
52
52
  # If we coulnd't find it, tell the user and drop out of the
53
53
  # sequence.
54
- if !env["image_id"]
54
+ unless env['image_id']
55
55
  say "error\nUnable to find an image named '#{user_image_name}'.", :red
56
56
  exit 1
57
57
  end
@@ -62,61 +62,55 @@ module Tugboat
62
62
  # with a flag.
63
63
  #
64
64
  # This requires a lookup.
65
- if user_fuzzy_name && !env["image_id"]
66
- say "Image fuzzy name provided. Finding image ID...", nil, false
65
+ if user_fuzzy_name && !env['image_id']
66
+ say 'Image fuzzy name provided. Finding image ID...', nil, false
67
67
 
68
68
  found_images = []
69
69
  choices = []
70
70
 
71
- ocean.image.all['images'].each_with_index do |d, i|
72
-
71
+ ocean.image.all['images'].each_with_index do |d, _i|
73
72
  # Check to see if one of the image names have the fuzzy string.
74
- if d.name.upcase.include? user_fuzzy_name.upcase
75
- found_images << d
76
- end
73
+ found_images << d if d.name.upcase.include? user_fuzzy_name.upcase
77
74
 
78
75
  unless d.slug.nil?
79
- if d.slug.upcase.include? user_fuzzy_name.upcase
80
- found_images << d
81
- end
76
+ found_images << d if d.slug.upcase.include? user_fuzzy_name.upcase
82
77
  end
83
78
  end
84
79
 
85
80
  # Check to see if we have more then one image, and prompt
86
81
  # a user to choose otherwise.
87
82
  if found_images.length == 1
88
- env["image_id"] = found_images.first.id
89
- env["image_name"] = "(#{found_images.first.name})"
83
+ env['image_id'] = found_images.first.id
84
+ env['image_name'] = "(#{found_images.first.name})"
90
85
  elsif found_images.length > 1
91
86
  # Did we run the multiple questionairre?
92
87
  did_run_multiple = true
93
88
 
94
- say "Multiple images found."
89
+ say 'Multiple images found.'
95
90
  say
96
91
  found_images.each_with_index do |d, i|
97
92
  say "#{i}) #{d.name} (#{d.id})"
98
93
  choices << i.to_s
99
94
  end
100
95
  say
101
- choice = ask "Please choose a image:", :limited_to => choices
102
- env["image_id"] = found_images[choice.to_i].id
103
- env["image_name"] = found_images[choice.to_i].name
96
+ choice = ask 'Please choose a image:', limited_to: choices
97
+ env['image_id'] = found_images[choice.to_i].id
98
+ env['image_name'] = found_images[choice.to_i].name
104
99
  end
105
100
 
106
101
  # If we coulnd't find it, tell the user and drop out of the
107
102
  # sequence.
108
- if !env["image_id"]
103
+ unless env['image_id']
109
104
  say "error\nUnable to find an image named '#{user_fuzzy_name}'.", :red
110
105
  exit 1
111
106
  end
112
107
  end
113
108
 
114
- if !did_run_multiple
115
- say "done#{CLEAR}, #{env["image_id"]} #{env["image_name"]}", :green
109
+ unless did_run_multiple
110
+ say "done#{CLEAR}, #{env['image_id']} #{env['image_name']}", :green
116
111
  end
117
112
  @app.call(env)
118
113
  end
119
114
  end
120
115
  end
121
116
  end
122
-
@@ -4,19 +4,19 @@ module Tugboat
4
4
  def call(env)
5
5
  ocean = env['barge']
6
6
 
7
- response = if env["user_droplet_hard"]
8
- say "Queuing hard shutdown for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
9
- ocean.droplet.power_off env["droplet_id"]
10
- else
11
- say "Queuing shutdown for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
12
- ocean.droplet.shutdown env["droplet_id"]
7
+ response = if env['user_droplet_hard']
8
+ say "Queuing hard shutdown for #{env['droplet_id']} #{env['droplet_name']}...", nil, false
9
+ ocean.droplet.power_off env['droplet_id']
10
+ else
11
+ say "Queuing shutdown for #{env['droplet_id']} #{env['droplet_name']}...", nil, false
12
+ ocean.droplet.shutdown env['droplet_id']
13
13
  end
14
14
 
15
- unless response.success?
15
+ if response.success?
16
+ say 'Halt successful!', :green
17
+ else
16
18
  say "Failed to halt on Droplet: #{response.message}", :red
17
19
  exit 1
18
- else
19
- say "Halt successful!", :green
20
20
  end
21
21
 
22
22
  @app.call(env)
@@ -24,4 +24,3 @@ module Tugboat
24
24
  end
25
25
  end
26
26
  end
27
-
@@ -4,7 +4,7 @@ module Tugboat
4
4
  def call(env)
5
5
  ocean = env['barge']
6
6
 
7
- response = ocean.droplet.show env["droplet_id"]
7
+ response = ocean.droplet.show env['droplet_id']
8
8
 
9
9
  check_response_success('get info for Droplet', response)
10
10
 
@@ -15,45 +15,45 @@ module Tugboat
15
15
  exit 1
16
16
  end
17
17
 
18
- if droplet.status == "active"
19
- status_color = GREEN
20
- else
21
- status_color = RED
22
- end
18
+ status_color = if droplet.status == 'active'
19
+ GREEN
20
+ else
21
+ RED
22
+ end
23
23
 
24
- attribute = env["user_attribute"]
24
+ attribute = env['user_attribute']
25
25
 
26
- droplet_ip4_public = droplet.networks.v4.detect { |address| address.type == 'public' }.ip_address
27
- droplet_ip6_public = droplet.networks.v6.detect { |address| address.type == 'public' }.ip_address unless droplet.networks.v6.empty?
28
- check_private_ip = droplet.networks.v4.detect { |address| address.type == 'private' }
26
+ droplet_ip4_public = droplet.networks.v4.find { |address| address.type == 'public' }.ip_address
27
+ droplet_ip6_public = droplet.networks.v6.find { |address| address.type == 'public' }.ip_address unless droplet.networks.v6.empty?
28
+ check_private_ip = droplet.networks.v4.find { |address| address.type == 'private' }
29
29
  droplet_private_ip = check_private_ip.ip_address if check_private_ip
30
30
 
31
31
  attributes_list = [
32
- ["name", droplet.name],
33
- ["id", droplet.id],
34
- ["status", droplet.status],
35
- ["ip4", droplet_ip4_public],
36
- ["ip6", droplet_ip6_public],
37
- ["private_ip", droplet_private_ip],
38
- ["region", droplet.region.slug],
39
- ["image", droplet.image.id],
40
- ["size", droplet.size_slug],
41
- ["backups_active", !droplet.backup_ids.empty?]
32
+ ['name', droplet.name],
33
+ ['id', droplet.id],
34
+ ['status', droplet.status],
35
+ ['ip4', droplet_ip4_public],
36
+ ['ip6', droplet_ip6_public],
37
+ ['private_ip', droplet_private_ip],
38
+ ['region', droplet.region.slug],
39
+ ['image', droplet.image.id],
40
+ ['size', droplet.size_slug],
41
+ ['backups_active', !droplet.backup_ids.empty?]
42
42
  ]
43
43
  attributes = Hash[*attributes_list.flatten(1)]
44
44
 
45
45
  if attribute
46
- if attributes.has_key? attribute
46
+ if attributes.key? attribute
47
47
  say attributes[attribute]
48
48
  else
49
49
  say "Invalid attribute \"#{attribute}\"", :red
50
- say "Provide one of the following:", :red
50
+ say 'Provide one of the following:', :red
51
51
  attributes_list.each { |a| say " #{a[0]}", :red }
52
52
  exit 1
53
53
  end
54
54
  else
55
- if env["user_porcelain"]
56
- attributes_list.select{ |a| a[1] != nil }.each{ |a| say "#{a[0]} #{a[1]}"}
55
+ if env['user_porcelain']
56
+ attributes_list.select { |a| !a[1].nil? }.each { |a| say "#{a[0]} #{a[1]}" }
57
57
  else
58
58
  say
59
59
  say "Name: #{droplet.name}"
@@ -62,15 +62,13 @@ module Tugboat
62
62
  say "IP4: #{droplet_ip4_public}"
63
63
  say "IP6: #{droplet_ip6_public}" unless droplet.networks.v6.empty?
64
64
 
65
- if droplet_private_ip
66
- say "Private IP: #{droplet_private_ip}"
67
- end
65
+ say "Private IP: #{droplet_private_ip}" if droplet_private_ip
68
66
 
69
- if droplet.image.slug.nil?
70
- image_description = droplet.image.name
71
- else
72
- image_description = droplet.image.slug
73
- end
67
+ image_description = if droplet.image.slug.nil?
68
+ droplet.image.name
69
+ else
70
+ droplet.image.slug
71
+ end
74
72
 
75
73
  say "Region: #{droplet.region.name} - #{droplet.region.slug}"
76
74
  say "Image: #{droplet.image.id} - #{image_description}"
@@ -84,4 +82,3 @@ module Tugboat
84
82
  end
85
83
  end
86
84
  end
87
-
@@ -4,7 +4,7 @@ module Tugboat
4
4
  def call(env)
5
5
  ocean = env['barge']
6
6
 
7
- response = ocean.image.show env["image_id"]
7
+ response = ocean.image.show env['image_id']
8
8
 
9
9
  unless response.success?
10
10
  say "Failed to get info for Image: #{response.message}", :red
@@ -5,19 +5,17 @@ module Tugboat
5
5
  module Middleware
6
6
  # Inject the digital ocean client into the environment
7
7
  class InjectClient < Base
8
+ def call(env)
9
+ # Sets the digital ocean client into the environment for use
10
+ # later.
11
+ @access_token = env['config'].access_token
8
12
 
9
- def call(env)
10
- # Sets the digital ocean client into the environment for use
11
- # later.
12
- @access_token = env["config"].access_token
13
+ env['barge'] = Barge::Client.new(access_token: @access_token)
13
14
 
14
- env['barge'] = Barge::Client.new(:access_token => @access_token)
15
+ env['barge'].faraday.use CustomLogger if ENV['DEBUG']
15
16
 
16
- env['barge'].faraday.use CustomLogger if ENV['DEBUG']
17
-
18
- @app.call(env)
19
- end
17
+ @app.call(env)
18
+ end
20
19
  end
21
20
  end
22
21
  end
23
-
@@ -5,11 +5,10 @@ module Tugboat
5
5
  def call(env)
6
6
  config = Tugboat::Configuration.instance
7
7
 
8
- env["config"] = config
8
+ env['config'] = config
9
9
 
10
10
  @app.call(env)
11
11
  end
12
12
  end
13
13
  end
14
14
  end
15
-
@@ -13,22 +13,22 @@ module Tugboat
13
13
  droplet_list.each do |droplet|
14
14
  has_one = true
15
15
 
16
- private_addr = droplet.networks.v4.detect { |address| address.type == 'private' }
16
+ private_addr = droplet.networks.v4.find { |address| address.type == 'private' }
17
17
  if private_addr
18
18
  private_ip = ", private_ip: #{private_addr.ip_address}"
19
19
  end
20
20
 
21
- if droplet.status == "active"
22
- status_color = GREEN
23
- else
24
- status_color = RED
25
- end
21
+ status_color = if droplet.status == 'active'
22
+ GREEN
23
+ else
24
+ RED
25
+ end
26
26
 
27
- public_addr = droplet.networks.v4.detect { |address| address.type == 'public' }
28
- say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, id: #{droplet.id}#{env["include_urls"] ? droplet_id_to_url(droplet.id) : '' })"
27
+ public_addr = droplet.networks.v4.find { |address| address.type == 'public' }
28
+ say "#{droplet.name} (ip: #{public_addr.ip_address}#{private_ip}, status: #{status_color}#{droplet.status}#{CLEAR}, region: #{droplet.region.slug}, id: #{droplet.id}#{env['include_urls'] ? droplet_id_to_url(droplet.id) : ''})"
29
29
  end
30
30
 
31
- if not has_one
31
+ unless has_one
32
32
  say "You don't appear to have any droplets.", :red
33
33
  say "Try creating one with #{GREEN}\`tugboat create\`#{CLEAR}"
34
34
  end
@@ -44,4 +44,3 @@ module Tugboat
44
44
  end
45
45
  end
46
46
  end
47
-
@@ -3,33 +3,33 @@ module Tugboat
3
3
  class ListImages < Base
4
4
  def call(env)
5
5
  ocean = env['barge']
6
- my_images = ocean.image.all(:private => true)
6
+ my_images = ocean.image.all(private: true)
7
7
  public_images = ocean.image.all.images - my_images.images
8
8
 
9
9
  if env['user_show_just_private_images']
10
- say "Showing just private images", :green
11
- say "Private Images:", :blue
10
+ say 'Showing just private images', :green
11
+ say 'Private Images:', :blue
12
12
  my_images_list = my_images.images
13
13
  if my_images_list.nil? || my_images_list.empty?
14
- say "No private images found"
14
+ say 'No private images found'
15
15
  else
16
16
  my_images_list.each do |image|
17
17
  say "#{image.name} (id: #{image.id}, distro: #{image.distribution})"
18
18
  end
19
19
  end
20
20
  else
21
- say "Showing both private and public images"
22
- say "Private Images:", :blue
21
+ say 'Showing both private and public images'
22
+ say 'Private Images:', :blue
23
23
  my_images_list = my_images.images
24
24
  if my_images_list.nil? || my_images_list.empty?
25
- say "No private images found"
25
+ say 'No private images found'
26
26
  else
27
27
  my_images_list.each do |image|
28
28
  say "#{image.name} (id: #{image.id}, distro: #{image.distribution})"
29
29
  end
30
30
  end
31
31
  say ''
32
- say "Public Images:", :blue
32
+ say 'Public Images:', :blue
33
33
  public_images.each do |image|
34
34
  say "#{image.name} (slug: #{image.slug}, id: #{image.id}, distro: #{image.distribution})"
35
35
  end
@@ -39,4 +39,4 @@ module Tugboat
39
39
  end
40
40
  end
41
41
  end
42
- end
42
+ end
@@ -5,7 +5,7 @@ module Tugboat
5
5
  ocean = env['barge']
6
6
  regions = ocean.region.all.regions.sort_by(&:name)
7
7
 
8
- say "Regions:"
8
+ say 'Regions:'
9
9
  regions.each do |region|
10
10
  say "#{region.name} (slug: #{region.slug})"
11
11
  end
@@ -5,7 +5,7 @@ module Tugboat
5
5
  ocean = env['barge']
6
6
  sizes = ocean.size.all.sizes
7
7
 
8
- say "Sizes:"
8
+ say 'Sizes:'
9
9
  sizes.each do |size|
10
10
  say "Disk: #{size.disk}GB, Memory: #{size.memory.round}MB (slug: #{size.slug})"
11
11
  end
@@ -2,11 +2,10 @@ module Tugboat
2
2
  module Middleware
3
3
  class ListSSHKeys < Base
4
4
  def call(env)
5
-
6
5
  ocean = env['barge']
7
6
  ssh_keys = ocean.key.all.ssh_keys
8
7
 
9
- say "SSH Keys:"
8
+ say 'SSH Keys:'
10
9
  ssh_keys.each do |key|
11
10
  say "Name: #{key.name}, (id: #{key.id}), fingerprint: #{key.fingerprint}"
12
11
  end
@@ -16,4 +15,3 @@ module Tugboat
16
15
  end
17
16
  end
18
17
  end
19
-
@@ -4,15 +4,15 @@ module Tugboat
4
4
  def call(env)
5
5
  ocean = env['barge']
6
6
 
7
- say "Queuing password reset for #{env["droplet_id"]} #{env["droplet_name"]}...", nil, false
8
- response = ocean.droplet.password_reset env["droplet_id"]
7
+ say "Queuing password reset for #{env['droplet_id']} #{env['droplet_name']}...", nil, false
8
+ response = ocean.droplet.password_reset env['droplet_id']
9
9
 
10
- unless response.success?
10
+ if response.success?
11
+ say 'Password reset successful!', :green
12
+ say 'Your new root password will be emailed to you', :green
13
+ else
11
14
  say "Failed to reset password on Droplet: #{response.message}", :red
12
15
  exit 1
13
- else
14
- say "Password reset successful!", :green
15
- say "Your new root password will be emailed to you", :green
16
16
  end
17
17
 
18
18
  @app.call(env)
@@ -20,4 +20,3 @@ module Tugboat
20
20
  end
21
21
  end
22
22
  end
23
-