summaryrefslogtreecommitdiff
path: root/lib/system_check/base_check.rb
blob: e06245294c4287c890522df94a3b2346e685cb2f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# frozen_string_literal: true

module SystemCheck
  # Base class for Checks. You must inherit from here
  # and implement the methods below when necessary
  class BaseCheck
    include ::SystemCheck::Helpers

    # Define a custom term for when check passed
    #
    # @param [String] term used when check passed (default: 'yes')
    def self.set_check_pass(term)
      @check_pass = term
    end

    # Define a custom term for when check failed
    #
    # @param [String] term used when check failed (default: 'no')
    def self.set_check_fail(term)
      @check_fail = term
    end

    # Define the name of the SystemCheck that will be displayed during execution
    #
    # @param [String] name of the check
    def self.set_name(name)
      @name = name
    end

    # Define the reason why we skipped the SystemCheck
    #
    # This is only used if subclass implements `#skip?`
    #
    # @param [String] reason to be displayed
    def self.set_skip_reason(reason)
      @skip_reason = reason
    end

    # Term to be displayed when check passed
    #
    # @return [String] term when check passed ('yes' if not re-defined in a subclass)
    def self.check_pass
      call_or_return(@check_pass) || 'yes'
    end

    ## Term to be displayed when check failed
    #
    # @return [String] term when check failed ('no' if not re-defined in a subclass)
    def self.check_fail
      call_or_return(@check_fail) || 'no'
    end

    # Name of the SystemCheck defined by the subclass
    #
    # @return [String] the name
    def self.display_name
      call_or_return(@name) || self.name
    end

    # Skip reason defined by the subclass
    #
    # @return [String] the reason
    def self.skip_reason
      call_or_return(@skip_reason) || 'skipped'
    end

    # Define a reason why we skipped the SystemCheck (during runtime)
    #
    # This is used when you need dynamic evaluation like when you have
    # multiple reasons why a check can fail
    #
    # @param [String] reason to be displayed
    def skip_reason=(reason)
      @skip_reason = reason
    end

    # Skip reason defined during runtime
    #
    # This value have precedence over the one defined in the subclass
    #
    # @return [String] the reason
    def skip_reason
      @skip_reason
    end

    # Does the check support automatically repair routine?
    #
    # @return [Boolean] whether check implemented `#repair!` method or not
    def can_repair?
      self.class.instance_methods(false).include?(:repair!)
    end

    def can_skip?
      self.class.instance_methods(false).include?(:skip?)
    end

    def multi_check?
      self.class.instance_methods(false).include?(:multi_check)
    end

    # Execute the check routine
    #
    # This is where you should implement the main logic that will return
    # a boolean at the end
    #
    # You should not print any output to STDOUT here, use the specific methods instead
    #
    # @return [Boolean] whether check passed or failed
    def check?
      raise NotImplementedError
    end

    # Execute a custom check that cover multiple unities
    #
    # When using multi_check you have to provide the output yourself
    def multi_check
      raise NotImplementedError
    end

    # Prints troubleshooting instructions
    #
    # This is where you should print detailed information for any error found during #check?
    #
    # You may use helper methods to help format the output:
    #
    # @see #try_fixing_it
    # @see #fix_and_rerun
    # @see #for_more_infromation
    def show_error
      raise NotImplementedError
    end

    # When implemented by a subclass, will attempt to fix the issue automatically
    def repair!
      raise NotImplementedError
    end

    # When implemented by a subclass, will evaluate whether check should be skipped or not
    #
    # @return [Boolean] whether or not this check should be skipped
    def skip?
      raise NotImplementedError
    end

    def self.call_or_return(input)
      input.respond_to?(:call) ? input.call : input
    end
    private_class_method :call_or_return
  end
end