rocket_fuel 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +1 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +31 -0
  7. data/Rakefile +7 -0
  8. data/bin/rocket_fuel +8 -0
  9. data/lib/rocket_fuel/command_line_interface.rb +40 -0
  10. data/lib/rocket_fuel/fix/abstract_fix.rb +30 -0
  11. data/lib/rocket_fuel/fix/command_line_tool_fix.rb +61 -0
  12. data/lib/rocket_fuel/fix/command_line_tools/dmg_metadata.rb +46 -0
  13. data/lib/rocket_fuel/fix/command_line_tools/download.rb +30 -0
  14. data/lib/rocket_fuel/fix/command_line_tools/download_routine.rb +76 -0
  15. data/lib/rocket_fuel/fix/command_line_tools/install.applescript +58 -0
  16. data/lib/rocket_fuel/fix/command_line_tools/install.rb +31 -0
  17. data/lib/rocket_fuel/fix/file_sanitizer_fix.rb +25 -0
  18. data/lib/rocket_fuel/fix/macports_fix.rb +36 -0
  19. data/lib/rocket_fuel/fix/rbenv_fix.rb +24 -0
  20. data/lib/rocket_fuel/fix/rvm_fix.rb +24 -0
  21. data/lib/rocket_fuel/fix.rb +10 -0
  22. data/lib/rocket_fuel/operating_system.rb +53 -0
  23. data/lib/rocket_fuel/precheck/check.rb +52 -0
  24. data/lib/rocket_fuel/precheck/check_result.rb +17 -0
  25. data/lib/rocket_fuel/precheck/command_line_result_presenter.rb +28 -0
  26. data/lib/rocket_fuel/precheck/command_line_tool_check.rb +43 -0
  27. data/lib/rocket_fuel/precheck/macports_check.rb +48 -0
  28. data/lib/rocket_fuel/precheck/rbenv_check.rb +42 -0
  29. data/lib/rocket_fuel/precheck/run.rb +57 -0
  30. data/lib/rocket_fuel/precheck/rvm_check.rb +41 -0
  31. data/lib/rocket_fuel/precheck.rb +26 -0
  32. data/lib/rocket_fuel/system_details.rb +21 -0
  33. data/lib/rocket_fuel/version.rb +3 -0
  34. data/lib/rocket_fuel.rb +10 -0
  35. data/rocket_fuel.gemspec +28 -0
  36. data/spec/rocket_fuel/fix/command_line_tools/dmg_metadata_spec.rb +19 -0
  37. data/spec/rocket_fuel/fix/command_line_tools/download_spec.rb +12 -0
  38. data/spec/rocket_fuel/fix/macports_fix_spec.rb +23 -0
  39. data/spec/rocket_fuel/fix/rbenv_fix_spec.rb +29 -0
  40. data/spec/rocket_fuel/fix/rvm_fix_spec.rb +29 -0
  41. data/spec/rocket_fuel/operating_system_spec.rb +29 -0
  42. data/spec/rocket_fuel/precheck/check_result_spec.rb +23 -0
  43. data/spec/rocket_fuel/precheck/check_spec.rb +19 -0
  44. data/spec/rocket_fuel/precheck/command_line_result_presenter_spec.rb +32 -0
  45. data/spec/rocket_fuel/precheck/command_line_tool_check_spec.rb +71 -0
  46. data/spec/rocket_fuel/precheck/macports_check_spec.rb +34 -0
  47. data/spec/rocket_fuel/precheck/rbenv_check_spec.rb +35 -0
  48. data/spec/rocket_fuel/precheck/run_spec.rb +10 -0
  49. data/spec/rocket_fuel/precheck/rvm_check_spec.rb +38 -0
  50. data/spec/rocket_fuel/precheck_spec.rb +10 -0
  51. data/spec/spec_helper.rb +34 -0
  52. metadata +195 -0
@@ -0,0 +1,52 @@
1
+ require 'rocket_fuel/precheck'
2
+ require 'rocket_fuel/precheck/check_result'
3
+
4
+ module RocketFuel
5
+ module Precheck
6
+ class Check
7
+ def ok?
8
+ virtual_method(:ok?)
9
+ end
10
+
11
+ def run
12
+ CheckResult.new(ok?, message, self.class.check_name_value)
13
+ end
14
+
15
+ def check?
16
+ true
17
+ end
18
+
19
+ def message
20
+ ok? ? success_message : failure_message
21
+ end
22
+
23
+ class << self
24
+ def check_name(sym)
25
+ @check_name = sym
26
+ end
27
+
28
+ def check_name_value
29
+ @check_name
30
+ end
31
+
32
+ def register!
33
+ RocketFuel::Precheck.register_check(self)
34
+ end
35
+ end
36
+
37
+ protected
38
+ def success_message
39
+ virtual_method(:success_message)
40
+ end
41
+
42
+ def failure_message
43
+ virtual_method(:failure_message)
44
+ end
45
+
46
+ def virtual_method(method_name)
47
+ raise RocketFuel::NotImplementedError,
48
+ "you must override the `#{method_name}` in your check"
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,17 @@
1
+ module RocketFuel
2
+ module Precheck
3
+ class CheckResult
4
+ attr_reader :result
5
+ attr_reader :message
6
+ attr_reader :check_name
7
+
8
+ def initialize(result, message, check_name)
9
+ @result, @message, @check_name = result, message, check_name
10
+ end
11
+
12
+ def ok?
13
+ result
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,28 @@
1
+ module RocketFuel
2
+ module Precheck
3
+ class CommandLineResultPresenter
4
+ include Thor::Base
5
+
6
+ SUCCESS_ICON = "\u2713".encode('utf-8')
7
+ FAILURE_ICON = "\u00D7".encode('utf-8')
8
+
9
+ def initialize(result)
10
+ @result = result
11
+ end
12
+
13
+ def present
14
+ print_wrapped(set_color([icon, @result.message].join(" "), color),
15
+ :indent => 2)
16
+ end
17
+
18
+ protected
19
+ def icon
20
+ @result.ok? ? SUCCESS_ICON : FAILURE_ICON
21
+ end
22
+
23
+ def color
24
+ @result.ok? ? :green : :red
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,43 @@
1
+ require 'rocket_fuel/precheck/check'
2
+
3
+ module RocketFuel
4
+ module Precheck
5
+ class CommandLineToolCheck < Check
6
+ check_name :command_line_tools
7
+ register!
8
+
9
+ TEN_NINE_RECEIPT_PATH = '/var/db/receipts/com.apple.pkg.CLTools_Executables.bom'
10
+ DEFAULT_RECEIPT_PATH = '/var/db/receipts/com.apple.pkg.DeveloperToolsCLI.bom'
11
+
12
+ def ok?
13
+ installed?
14
+ end
15
+
16
+ def check?
17
+ RocketFuel::SystemDetails.platform_family?(:mac)
18
+ end
19
+
20
+ protected
21
+
22
+ def failure_message
23
+ 'Command Line Tools NOT found.'
24
+ end
25
+
26
+ def success_message
27
+ 'Command Line Tools found.'
28
+ end
29
+
30
+ def installed?
31
+ FileTest.exist?(receipt_file)
32
+ end
33
+
34
+ def receipt_file
35
+ if RocketFuel::SystemDetails.os.minor_version =~ /\A10.(9|(10))/
36
+ TEN_NINE_RECEIPT_PATH
37
+ else
38
+ DEFAULT_RECEIPT_PATH
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,48 @@
1
+ require 'rocket_fuel/precheck/check'
2
+
3
+ module RocketFuel
4
+ module Precheck
5
+ class MacportsCheck < Check
6
+ check_name :macports
7
+ register!
8
+
9
+ def ok?
10
+ !blacklisted_files_not_found?
11
+ end
12
+
13
+ def check?
14
+ RocketFuel::SystemDetails.platform_family?(:mac)
15
+ end
16
+
17
+ class << self
18
+ def bin_path
19
+ '/opt/local/bin/port'
20
+ end
21
+ end
22
+
23
+ protected
24
+ def blacklisted_files_not_found?
25
+ blacklisted_files.each do |file|
26
+ return true if FileTest.exist?(file)
27
+ end
28
+
29
+ return false
30
+ end
31
+
32
+ #TODO: this abstraction can be applied in many places (rbenv, rvm)
33
+ def blacklisted_files
34
+ [
35
+ self.class.bin_path
36
+ ]
37
+ end
38
+
39
+ def success_message
40
+ "MacPorts NOT found."
41
+ end
42
+
43
+ def failure_message
44
+ "MacPorts found!"
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,42 @@
1
+ require 'rocket_fuel/precheck/check'
2
+
3
+ module RocketFuel
4
+ module Precheck
5
+ class RbenvCheck < Check
6
+ check_name :rbenv
7
+ register!
8
+
9
+ def ok?
10
+ !home_path_exists? && !global_path_exists?
11
+ end
12
+
13
+ class << self
14
+ def home_path
15
+ File.join(ENV['HOME'], '.rbenv')
16
+ end
17
+
18
+ #homebrew recommended, alternative path
19
+ def global_path
20
+ '/usr/local/var/rbenv'
21
+ end
22
+ end
23
+
24
+ protected
25
+ def success_message
26
+ "rbenv NOT found."
27
+ end
28
+
29
+ def failure_message
30
+ "rbenv found!"
31
+ end
32
+
33
+ def home_path_exists?
34
+ FileTest.exist?(self.class.home_path)
35
+ end
36
+
37
+ def global_path_exists?
38
+ FileTest.exist?(self.class.global_path)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,57 @@
1
+ require 'thor'
2
+
3
+ require 'rocket_fuel/precheck/command_line_result_presenter'
4
+
5
+ require 'rocket_fuel/precheck/command_line_tool_check'
6
+ require 'rocket_fuel/precheck/rvm_check'
7
+ require 'rocket_fuel/precheck/rbenv_check'
8
+ require 'rocket_fuel/precheck/macports_check'
9
+
10
+ require 'rocket_fuel/fix'
11
+
12
+ module RocketFuel
13
+ module Precheck
14
+ class Run
15
+ include Thor::Base
16
+ def results
17
+ failed_checks = []
18
+ RocketFuel::Precheck.checks.each do |key, klass|
19
+ check = klass.new
20
+ if check.check?
21
+ CommandLineResultPresenter.new(check).present
22
+ if !check.ok?
23
+ failed_checks << key
24
+ end
25
+ end
26
+ end
27
+
28
+ say('')
29
+ say('========================')
30
+ say('')
31
+
32
+ if !failed_checks.empty?
33
+ say('***YOU ARE NOT CLEARED FOR INSTALLATION***', :red)
34
+ say('')
35
+
36
+ failed_checks.each do |sym|
37
+ if RocketFuel::Precheck.fixes[sym]
38
+ fix = RocketFuel::Precheck.fixes[sym].new
39
+ say("#{fix.title}", :red)
40
+ say('')
41
+ print_wrapped(fix.message, :indent => 2)
42
+
43
+ say('')
44
+ print_wrapped("Rocket Fuel can tackle this for you. " +
45
+ "Invoke `rocket_fuel fix #{sym}` to resolve this issue.",
46
+ :indent => 2)
47
+ end
48
+ end
49
+ else
50
+ say('***Congratulations! You\'re cleared to install with Rocket Fuel***', :green)
51
+ say('')
52
+ say('Run `rocket_fuel install` to proceed.')
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,41 @@
1
+ require 'rocket_fuel/precheck/check'
2
+
3
+ module RocketFuel
4
+ module Precheck
5
+ class RvmCheck < Check
6
+ check_name :rvm
7
+ register!
8
+
9
+ def ok?
10
+ !home_path_exists? && !global_path_exists?
11
+ end
12
+
13
+ class << self
14
+ def home_path
15
+ File.join(ENV['HOME'], '.rvm')
16
+ end
17
+
18
+ def global_path
19
+ '/usr/local/rvm'
20
+ end
21
+ end
22
+
23
+ protected
24
+ def success_message
25
+ "RVM NOT found."
26
+ end
27
+
28
+ def failure_message
29
+ "RVM found!"
30
+ end
31
+
32
+ def home_path_exists?
33
+ FileTest.exist?(self.class.home_path)
34
+ end
35
+
36
+ def global_path_exists?
37
+ FileTest.exist?(self.class.global_path)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,26 @@
1
+ module RocketFuel
2
+ module Precheck
3
+ def self.checks
4
+ @checks
5
+ end
6
+
7
+ def self.register_check(check)
8
+ @checks ||= {}
9
+ @checks[check.check_name_value] = check
10
+ end
11
+
12
+ def self.fixes
13
+ @fixes
14
+ end
15
+
16
+ def self.register_fix(fix)
17
+ @fixes ||= {}
18
+ @fixes[fix.fix_name_value] = fix
19
+ end
20
+ end
21
+ end
22
+
23
+ require 'rocket_fuel/precheck/check_result'
24
+
25
+ require 'rocket_fuel/precheck/run'
26
+ require 'rocket_fuel/fix'
@@ -0,0 +1,21 @@
1
+ require 'rocket_fuel/operating_system'
2
+
3
+ module RocketFuel
4
+ module SystemDetails
5
+ SUPPORTED_OSX_MINORS = ['10.10', '10.9', '10.8', '10.7']
6
+
7
+ class << self
8
+ def os_version
9
+ os.version
10
+ end
11
+
12
+ def os
13
+ @os ||= RocketFuel::OperatingSystem.new
14
+ end
15
+
16
+ def platform_family?(platform)
17
+ os.platform_family?(platform)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,3 @@
1
+ module RocketFuel
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'thor'
2
+
3
+ require 'rocket_fuel/version'
4
+ require 'rocket_fuel/system_details'
5
+
6
+ module RocketFuel
7
+ # Your code goes here...
8
+
9
+ class NotImplementedError < StandardError; end;
10
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rocket_fuel/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'rocket_fuel'
8
+ spec.version = RocketFuel::VERSION
9
+ spec.authors = ['Dan Pickett']
10
+ spec.email = ['dan.pickett@launchacademy.com']
11
+ spec.summary = %q{A ruby client for installing rocket fuel}
12
+ spec.description = %q{A ruby client for installing rocket fuel.}
13
+ spec.homepage = ""
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'thor'
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.7'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ spec.add_development_dependency 'mocha'
27
+ spec.add_development_dependency 'fakefs'
28
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ require'rocket_fuel/fix'
4
+
5
+ describe RocketFuel::Fix::CommandLineTools::DmgMetadata do
6
+ RocketFuel::SystemDetails::SUPPORTED_OSX_MINORS.each do |version|
7
+ let(:dmg_metadata) { RocketFuel::Fix::CommandLineTools::DmgMetadata.new('') }
8
+
9
+ it "has a volume dir for #{version}" do
10
+ RocketFuel::SystemDetails.os.stubs(:minor_version).returns(version)
11
+ expect(dmg_metadata.volume_dir).to_not be_nil
12
+ end
13
+
14
+ it "has a pkg_name for #{version}" do
15
+ RocketFuel::SystemDetails.os.stubs(:minor_version).returns(version)
16
+ expect(dmg_metadata.pkg_name).to_not be_nil
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ require'rocket_fuel/fix'
4
+
5
+ describe RocketFuel::Fix::CommandLineTools::Download do
6
+ RocketFuel::SystemDetails::SUPPORTED_OSX_MINORS.each do |version|
7
+ let(:download) { RocketFuel::Fix::CommandLineTools::Download.new }
8
+ it "has a url for #{version}" do
9
+ expect(download.url).to_not be_nil
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rocket_fuel/fix'
4
+ require 'fakefs/spec_helpers'
5
+
6
+ require 'fileutils'
7
+
8
+ describe RocketFuel::Fix::MacportsFix do
9
+ include FakeFS::SpecHelpers
10
+ let(:fix) { RocketFuel::Fix::MacportsFix.new }
11
+
12
+ it 'has a title' do
13
+ expect(fix.title).to match(/Macports/i)
14
+ end
15
+
16
+ it 'removes relevant files' do
17
+ fix.class.files_to_remove.each do |path|
18
+ FileUtils.mkdir_p(path)
19
+ fix.run
20
+ expect(FileTest.exist?(path)).to be(false)
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rocket_fuel/fix'
4
+ require 'fakefs/spec_helpers'
5
+
6
+ require 'fileutils'
7
+
8
+ describe RocketFuel::Fix::RbenvFix do
9
+ include FakeFS::SpecHelpers
10
+ let(:fix) { RocketFuel::Fix::RbenvFix.new }
11
+
12
+ it 'has a title' do
13
+ expect(fix.title).to match(/rbenv/i)
14
+ end
15
+
16
+ it 'removes files in the home directory' do
17
+ path = RocketFuel::Precheck::RbenvCheck.home_path
18
+ FileUtils.mkdir_p(path)
19
+ fix.run
20
+ expect(FileTest.exist?(path)).to be(false)
21
+ end
22
+
23
+ it 'removes files in the global directory' do
24
+ path = RocketFuel::Precheck::RbenvCheck.global_path
25
+ FileUtils.mkdir_p(path)
26
+ fix.run
27
+ expect(FileTest.exist?(path)).to be(false)
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rocket_fuel/fix'
4
+ require 'fakefs/spec_helpers'
5
+
6
+ require 'fileutils'
7
+
8
+ describe RocketFuel::Fix::RvmFix do
9
+ include FakeFS::SpecHelpers
10
+ let(:fix) { RocketFuel::Fix::RvmFix.new }
11
+
12
+ it 'has a title' do
13
+ expect(fix.title).to match(/rvm/i)
14
+ end
15
+
16
+ it 'removes files in the home directory' do
17
+ path = RocketFuel::Precheck::RvmCheck.home_path
18
+ FileUtils.mkdir_p(path)
19
+ fix.run
20
+ expect(FileTest.exist?(path)).to be(false)
21
+ end
22
+
23
+ it 'removes files in the global directory' do
24
+ path = RocketFuel::Precheck::RvmCheck.global_path
25
+ FileUtils.mkdir_p(path)
26
+ fix.run
27
+ expect(FileTest.exist?(path)).to be(false)
28
+ end
29
+ end
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ describe RocketFuel::OperatingSystem do
4
+ context '10.10' do
5
+ let(:minor) { '10.10' }
6
+ let(:os) { RocketFuel::OperatingSystem.new('darwin', minor) }
7
+
8
+ it 'has a name' do
9
+ expect(os.name).to eq(:mac)
10
+ end
11
+
12
+ it 'has a version' do
13
+ expect(os.version).to eq(minor)
14
+ end
15
+
16
+ it 'has a minor version' do
17
+ expect(os.minor_version).to eq(minor)
18
+ end
19
+ end
20
+
21
+ context '10.9' do
22
+ let(:minor) { '10.9' }
23
+ let(:os) { RocketFuel::OperatingSystem.new('darwin', minor + '.4') }
24
+
25
+ it 'has a minor version' do
26
+ expect(os.minor_version).to eq(minor)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rocket_fuel/precheck/check_result'
4
+
5
+ describe RocketFuel::Precheck::CheckResult do
6
+ it 'has a boolean result' do
7
+ bool = true
8
+ check_result = RocketFuel::Precheck::CheckResult.new(bool, '', :something)
9
+ expect(check_result.result).to eq(bool)
10
+ end
11
+
12
+ it 'has a message' do
13
+ msg = 'Message'
14
+ result = RocketFuel::Precheck::CheckResult.new(true, msg, :something)
15
+ expect(result.message).to eq(msg)
16
+ end
17
+
18
+ it 'has a check_name'do
19
+ check_name = :something
20
+ result = RocketFuel::Precheck::CheckResult.new(true, 'a msg', :something)
21
+ expect(result.check_name).to eq(check_name)
22
+ end
23
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rocket_fuel/precheck'
4
+
5
+ describe RocketFuel::Precheck::Check do
6
+ let(:check) { RocketFuel::Precheck::Check.new }
7
+ let(:error_klass) { RocketFuel::NotImplementedError }
8
+ it 'has a virtual method ok?' do
9
+ expect(lambda { check.ok? }).to raise_error(error_klass)
10
+ end
11
+
12
+ it 'has a virtual method success_message' do
13
+ expect(lambda { check.send(:success_message) }).to raise_error(error_klass)
14
+ end
15
+
16
+ it 'has a virtual method failure_message' do
17
+ expect(lambda { check.send(:failure_message) }).to raise_error(error_klass)
18
+ end
19
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ require 'rocket_fuel/precheck/command_line_result_presenter'
4
+
5
+ describe RocketFuel::Precheck::CommandLineResultPresenter do
6
+ let(:success_icon) do
7
+ RocketFuel::Precheck::CommandLineResultPresenter::SUCCESS_ICON
8
+ end
9
+
10
+ let(:failure_icon) do
11
+ RocketFuel::Precheck::CommandLineResultPresenter::FAILURE_ICON
12
+ end
13
+
14
+ it 'includes the message' do
15
+ message = 'clearance granted.'
16
+ result = RocketFuel::Precheck::CheckResult.new(true, message, :something)
17
+ presented_result = RocketFuel::Precheck::CommandLineResultPresenter.new(result)
18
+ expect(capture(:stdout) { presented_result.present }).to include(message)
19
+ end
20
+
21
+ it 'starts with a success icon if the result is successful' do
22
+ result = RocketFuel::Precheck::CheckResult.new(true, 'clearance granted.', :something)
23
+ presented_result = RocketFuel::Precheck::CommandLineResultPresenter.new(result)
24
+ expect(capture(:stdout) { presented_result.present }).to include(success_icon)
25
+ end
26
+
27
+ it 'starts with a failure icon if the result is not successful' do
28
+ result = RocketFuel::Precheck::CheckResult.new(false, 'clearance granted.', :something)
29
+ presented_result = RocketFuel::Precheck::CommandLineResultPresenter.new(result)
30
+ expect(capture(:stdout) { presented_result.present }).to include(failure_icon)
31
+ end
32
+ end