hospital 0.5.0 → 0.7.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.
- checksums.yaml +4 -4
- data/lib/hospital/checkup.rb +43 -0
- data/lib/hospital/checkup_group.rb +55 -0
- data/lib/hospital/diagnosis.rb +35 -8
- data/lib/hospital/formatter/base.rb +11 -0
- data/lib/hospital/formatter/pre.rb +31 -0
- data/lib/hospital/formatter/shell.rb +31 -0
- data/lib/hospital/string_formatter.rb +31 -0
- data/lib/hospital/tasks/checkup.rake +6 -11
- data/lib/hospital/version.rb +1 -1
- data/lib/hospital.rb +61 -71
- metadata +37 -4
- data/lib/hospital/formatter.rb +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c474d0a653f97f57a2e281a594c0e9b45d3e03bd17bd0b4ea80140e79b8d6572
|
4
|
+
data.tar.gz: 24c2232ea33222d4c470c2c736a6bf93745049d332fa07c44970c4f654bcc5eb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 05540eb19dbdd3277ef4d76bca4f8692e69c6eba340e0a8f91a8c554dd81bf654fa478c7f9396925eed5e2deca3ac28d75b872cec652b38128b84291a65d3b02
|
7
|
+
data.tar.gz: 0eb85a41d00fe122217b07eef2d6a69f5d8f6dadbbfcd95b21991d0e055c2be35e2aeec4c9d4f4a86d133d50b960f7697746a26cb08e7fb584389905491d5fb3
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hospital
|
4
|
+
class Checkup
|
5
|
+
attr_reader :code, :condition, :diagnosis, :group, :skipped, :klass, :precondition
|
6
|
+
|
7
|
+
def initialize klass, code, title: nil, condition: -> { true }, precondition: false
|
8
|
+
@klass = klass
|
9
|
+
@code = code
|
10
|
+
@condition = condition
|
11
|
+
@diagnosis = Hospital::Diagnosis.new([klass.to_s, title].compact.join(' - '))
|
12
|
+
@precondition = precondition
|
13
|
+
@group = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset_diagnosis
|
17
|
+
diagnosis.reset
|
18
|
+
end
|
19
|
+
|
20
|
+
def check verbose: false
|
21
|
+
diagnosis.reset
|
22
|
+
|
23
|
+
if condition.nil? || condition.call
|
24
|
+
@skipped = false
|
25
|
+
code.call(diagnosis)
|
26
|
+
diagnosis
|
27
|
+
else
|
28
|
+
@skipped = true
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
rescue StandardError => e
|
32
|
+
diagnosis.add_error "Unrescued exception in #{klass}.checkup:\n#{e.full_message}.\nThis is a bug inside the checkup method that should be fixed!"
|
33
|
+
end
|
34
|
+
|
35
|
+
def success?
|
36
|
+
diagnosis.success?
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_group group
|
40
|
+
@group = group
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require_relative "string_formatter"
|
2
|
+
|
3
|
+
using StringFormatter
|
4
|
+
|
5
|
+
module Hospital
|
6
|
+
class CheckupGroup
|
7
|
+
attr_reader :name, :checkups, :precondition_checkups, :skipped
|
8
|
+
|
9
|
+
def initialize name
|
10
|
+
@name = name
|
11
|
+
@precondition_checkups = []
|
12
|
+
@checkups = []
|
13
|
+
@skipped = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_checkups
|
17
|
+
@precondition_checkups + @checkups
|
18
|
+
end
|
19
|
+
|
20
|
+
def header
|
21
|
+
"#{name.to_s.capitalize.gsub(/_/, ' ')} checks"
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_checkup checkup
|
25
|
+
checkup.set_group self
|
26
|
+
|
27
|
+
if checkup.precondition
|
28
|
+
@precondition_checkups << checkup
|
29
|
+
else
|
30
|
+
@checkups << checkup
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def run_checkups verbose: false
|
35
|
+
run_precondition_checkups verbose: verbose
|
36
|
+
|
37
|
+
unless @skipped
|
38
|
+
run_dependent_checkups verbose: verbose
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def run_precondition_checkups verbose: false
|
43
|
+
@precondition_checkups.each do |checkup|
|
44
|
+
checkup.check verbose: verbose
|
45
|
+
@skipped = true unless checkup.success?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def run_dependent_checkups verbose: false
|
50
|
+
@checkups.each do |checkup|
|
51
|
+
checkup.check verbose: verbose
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
data/lib/hospital/diagnosis.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require_relative "string_formatter"
|
2
|
+
|
3
|
+
using StringFormatter
|
4
|
+
|
5
|
+
class Hospital::Diagnosis
|
6
|
+
attr_reader :infos, :warnings, :skips, :errors, :name, :results
|
3
7
|
|
4
8
|
def initialize name
|
5
9
|
@name = name.to_s
|
@@ -9,6 +13,7 @@ class Hospital::Diagnosis
|
|
9
13
|
def reset
|
10
14
|
@infos = []
|
11
15
|
@warnings = []
|
16
|
+
@skips = []
|
12
17
|
@errors = []
|
13
18
|
@results = []
|
14
19
|
end
|
@@ -44,8 +49,8 @@ class Hospital::Diagnosis
|
|
44
49
|
"#{prefix} #{message.gsub(/\n\z/, '').gsub(/\n/, prefix ? "\n " : "\n")}"
|
45
50
|
end
|
46
51
|
|
47
|
-
def put
|
48
|
-
|
52
|
+
def put out
|
53
|
+
out.put_diagnosis_result output
|
49
54
|
end
|
50
55
|
end
|
51
56
|
|
@@ -54,11 +59,15 @@ class Hospital::Diagnosis
|
|
54
59
|
end
|
55
60
|
|
56
61
|
class Warning < Result
|
57
|
-
def prefix; '🟠'
|
62
|
+
def prefix; '🟠' end
|
63
|
+
end
|
64
|
+
|
65
|
+
class Skip < Result
|
66
|
+
def prefix; '🟠' end
|
58
67
|
end
|
59
68
|
|
60
69
|
class Error < Result
|
61
|
-
def prefix; '🔴'
|
70
|
+
def prefix; '🔴' end
|
62
71
|
end
|
63
72
|
|
64
73
|
def add_info message
|
@@ -73,13 +82,31 @@ class Hospital::Diagnosis
|
|
73
82
|
@results << warning
|
74
83
|
end
|
75
84
|
|
85
|
+
def add_skip message
|
86
|
+
skip = Skip.new message
|
87
|
+
@skips << skip
|
88
|
+
@results << skip
|
89
|
+
end
|
90
|
+
|
76
91
|
def add_error message
|
77
92
|
error = Error.new message
|
78
93
|
@errors << error
|
79
94
|
@results << error
|
80
95
|
end
|
81
96
|
|
82
|
-
def put_results
|
83
|
-
results.each
|
97
|
+
def put_results out
|
98
|
+
results.each do |result|
|
99
|
+
result.put out
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def success?
|
104
|
+
errors.count == 0 && skips.count == 0
|
105
|
+
end
|
106
|
+
|
107
|
+
def on_success_message message
|
108
|
+
if success?
|
109
|
+
add_info message
|
110
|
+
end
|
84
111
|
end
|
85
112
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
using StringFormatter
|
4
|
+
|
5
|
+
module Hospital
|
6
|
+
module Formatter
|
7
|
+
class Pre < Base
|
8
|
+
def put_group_header text
|
9
|
+
@buffer << "\n\n### #{text}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def put_diagnosis_header text
|
13
|
+
@buffer << "\n\n## #{text}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def put_summary errors_count, warnings_count
|
17
|
+
@buffer << <<~END
|
18
|
+
\n\n
|
19
|
+
#### Summary:
|
20
|
+
Errors: #{errors_count}
|
21
|
+
Warnings: #{warnings_count}
|
22
|
+
END
|
23
|
+
end
|
24
|
+
|
25
|
+
def put_diagnosis_result text
|
26
|
+
@buffer << "\n#{text}"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require_relative "base"
|
2
|
+
|
3
|
+
using StringFormatter
|
4
|
+
|
5
|
+
module Hospital
|
6
|
+
module Formatter
|
7
|
+
class Shell < Base
|
8
|
+
def put_group_header text
|
9
|
+
@buffer << "\n### #{text}".h1
|
10
|
+
end
|
11
|
+
|
12
|
+
def put_diagnosis_header text
|
13
|
+
@buffer << "\n#{text.h2.indented}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def put_summary errors_count, warnings_count
|
17
|
+
@buffer << <<~END
|
18
|
+
|
19
|
+
#{"Summary:".h1}
|
20
|
+
#{"Errors: #{errors_count}".red}
|
21
|
+
#{"Warnings: #{warnings_count}".yellow}
|
22
|
+
END
|
23
|
+
end
|
24
|
+
|
25
|
+
def put_diagnosis_result text
|
26
|
+
@buffer << "\n#{text.indented}"
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module StringFormatter
|
2
|
+
refine String do
|
3
|
+
def bold
|
4
|
+
"\e[1m#{self}\e[0m"
|
5
|
+
end
|
6
|
+
|
7
|
+
def underline
|
8
|
+
"\e[4m#{self}\e[0m"
|
9
|
+
end
|
10
|
+
|
11
|
+
def h1
|
12
|
+
"\n#{self}".underline.bold
|
13
|
+
end
|
14
|
+
|
15
|
+
def h2
|
16
|
+
"\n#{self}".underline
|
17
|
+
end
|
18
|
+
|
19
|
+
def red
|
20
|
+
"\e[31m#{self}\e[0m"
|
21
|
+
end
|
22
|
+
|
23
|
+
def yellow
|
24
|
+
"\e[33m#{self}\e[0m"
|
25
|
+
end
|
26
|
+
|
27
|
+
def indented
|
28
|
+
"#{self}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -2,17 +2,12 @@
|
|
2
2
|
|
3
3
|
require_relative '../../hospital'
|
4
4
|
|
5
|
+
# usage:
|
6
|
+
# rake doctor
|
7
|
+
# rake doctor[true]
|
8
|
+
|
5
9
|
desc 'Check system setup sanity.'
|
6
10
|
task :doctor, [:verbose] => :environment do |t, args|
|
7
|
-
# at_exit { Rake::Task['doctor:summary'].invoke if $!.nil? }
|
8
|
-
|
9
|
-
ActiveRecord::Base.connection_pool.disconnect!
|
10
|
-
ActiveSupport.on_load(:active_record) do
|
11
|
-
config = ActiveRecord::Base.configurations[Rails.env]
|
12
|
-
config['pool'] = 100
|
13
|
-
ActiveRecord::Base.establish_connection(config)
|
14
|
-
end
|
15
|
-
|
16
11
|
verbose = args[:verbose] == "true"
|
17
12
|
|
18
13
|
# silence warnings about double constant definitions
|
@@ -20,7 +15,7 @@ task :doctor, [:verbose] => :environment do |t, args|
|
|
20
15
|
p "eager load all classes" if verbose
|
21
16
|
Rails.application.eager_load!
|
22
17
|
end
|
23
|
-
|
18
|
+
|
24
19
|
p "start checkup" if verbose
|
25
|
-
Hospital.
|
20
|
+
puts Hospital::Runner.new(verbose: verbose).do_checkup_all
|
26
21
|
end
|
data/lib/hospital/version.rb
CHANGED
data/lib/hospital.rb
CHANGED
@@ -1,114 +1,104 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "byebug"
|
4
|
+
require 'require_all'
|
3
5
|
require_relative "hospital/version"
|
6
|
+
require_relative "hospital/checkup"
|
7
|
+
require_relative "hospital/checkup_group"
|
4
8
|
require_relative "hospital/diagnosis"
|
5
|
-
require_relative "hospital/
|
9
|
+
require_relative "hospital/string_formatter"
|
10
|
+
require_relative "hospital/formatter/shell"
|
11
|
+
require_relative "hospital/formatter/pre"
|
6
12
|
|
7
|
-
using
|
13
|
+
using StringFormatter
|
8
14
|
|
9
15
|
module Hospital
|
10
16
|
require_relative 'railtie' if defined?(Rails)
|
11
17
|
|
12
18
|
class Error < StandardError; end
|
13
19
|
|
14
|
-
|
15
|
-
attr_reader :code, :condition, :diagnosis, :group, :skipped, :klass
|
20
|
+
@@groups = []
|
16
21
|
|
17
|
-
|
18
|
-
@klass = klass
|
19
|
-
@code = code
|
20
|
-
@group = group
|
21
|
-
@condition = condition
|
22
|
-
@diagnosis = Hospital::Diagnosis.new([klass.to_s, title].compact.join(' - '))
|
23
|
-
end
|
22
|
+
class << self
|
24
23
|
|
25
|
-
def
|
26
|
-
|
24
|
+
def included(klass)
|
25
|
+
raise Hospital::Error.new("Cannot include Hospital, please extend instead.")
|
27
26
|
end
|
28
27
|
|
29
|
-
|
30
|
-
|
28
|
+
# used to call the checkup for a specific class directly (in specs)
|
29
|
+
def do_checkup(klass, verbose: false)
|
30
|
+
@@groups.map(&:all_checkups).flatten.select{|cu| cu.klass == klass }.map do |cu|
|
31
|
+
cu.check verbose: verbose
|
32
|
+
end
|
33
|
+
end
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
else
|
37
|
-
@skipped = true
|
38
|
-
nil
|
35
|
+
def find_or_create_checkup_group name
|
36
|
+
unless checkup_group = @@groups.detect{|g| g.name == name }
|
37
|
+
checkup_group = CheckupGroup.new name
|
38
|
+
@@groups << checkup_group
|
39
39
|
end
|
40
|
-
|
41
|
-
|
40
|
+
checkup_group
|
41
|
+
end
|
42
|
+
|
43
|
+
def groups
|
44
|
+
@@groups
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
|
-
|
48
|
+
def checkup if: -> { true }, group: :general, title: nil, precondition: false, &code
|
49
|
+
checkup_group = Hospital.find_or_create_checkup_group group
|
50
|
+
checkup = Checkup.new(
|
51
|
+
self,
|
52
|
+
code,
|
53
|
+
title: title,
|
54
|
+
condition: binding.local_variable_get('if'),
|
55
|
+
precondition: precondition
|
56
|
+
)
|
57
|
+
|
58
|
+
# p "adding #{checkup.inspect} to #{group_name}"
|
59
|
+
checkup_group.add_checkup checkup
|
60
|
+
end
|
46
61
|
|
47
|
-
class
|
62
|
+
class Runner
|
63
|
+
attr_reader :verbose
|
48
64
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
65
|
+
def initialize verbose: false, formatter: :shell
|
66
|
+
@verbose = verbose
|
67
|
+
@formatter = case formatter
|
68
|
+
when :pre then Formatter::Pre
|
69
|
+
else Formatter::Shell
|
70
|
+
end
|
52
71
|
|
53
|
-
|
54
|
-
#
|
55
|
-
@@checkups[klass] = Checkup.new klass, -> (diagnosis) do
|
56
|
-
diagnosis.add_warning("#{klass}: No checks defined! Please call checkup with a lambda.")
|
57
|
-
end, group: :general
|
72
|
+
@out = @formatter.new
|
73
|
+
# @out.put_group_header "using formatter #{@formatter}"
|
58
74
|
end
|
59
75
|
|
60
|
-
def do_checkup_all
|
76
|
+
def do_checkup_all
|
61
77
|
errcount = 0
|
62
78
|
warcount = 0
|
63
79
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
checkup.check(verbose: verbose)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
threads.each &:join
|
80
|
+
Hospital.groups.each do |group|
|
81
|
+
@out.put_group_header group.header
|
82
|
+
group.run_checkups verbose: verbose
|
72
83
|
|
73
|
-
|
74
|
-
puts group_header(group)
|
75
|
-
first = false
|
76
|
-
|
77
|
-
checkups.each do |klass, checkup|
|
84
|
+
group.all_checkups.each do |checkup|
|
78
85
|
if diagnosis = checkup.diagnosis
|
79
86
|
errcount += diagnosis.errors.count
|
80
87
|
warcount += diagnosis.warnings.count
|
81
88
|
|
82
|
-
if !checkup.skipped
|
83
|
-
|
84
|
-
diagnosis.put_results
|
89
|
+
if !checkup.skipped && (!checkup.group.skipped || checkup.precondition)
|
90
|
+
@out.put_diagnosis_header "Checking #{diagnosis.name}:"
|
91
|
+
diagnosis.put_results @out
|
85
92
|
elsif verbose
|
86
|
-
|
93
|
+
@out.put_diagnosis_header "Skipped #{diagnosis.name}."
|
87
94
|
end
|
88
95
|
end
|
89
96
|
end
|
90
97
|
end
|
91
98
|
|
92
|
-
|
99
|
+
@out.put_summary errcount, warcount
|
93
100
|
|
94
|
-
|
95
|
-
#{"Errors: #{errcount}".red}
|
96
|
-
#{"Warnings: #{warcount}".yellow}
|
97
|
-
END
|
98
|
-
end
|
99
|
-
|
100
|
-
# used to call the checkup for a specific class directly (in specs)
|
101
|
-
def do_checkup(klass)
|
102
|
-
@@checkups[klass].check
|
103
|
-
end
|
104
|
-
|
105
|
-
def group_header group
|
106
|
-
"### #{group.to_s.capitalize.gsub(/_/, ' ')} checks".h1
|
101
|
+
@out.buffer
|
107
102
|
end
|
108
103
|
end
|
109
|
-
|
110
|
-
def checkup if: -> { true }, group: :general, title: nil, &code
|
111
|
-
@@checkups[self] = Checkup.new self, code, group: group, title: title, condition: binding.local_variable_get('if')
|
112
|
-
end
|
113
|
-
|
114
104
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hospital
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2024-03-26 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: byebug
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: require_all
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
13
41
|
description: Imagine a team of little doctors creating diagnoses and creating a useful
|
14
42
|
report.
|
15
43
|
email:
|
@@ -21,8 +49,13 @@ files:
|
|
21
49
|
- LICENSE.txt
|
22
50
|
- README.md
|
23
51
|
- lib/hospital.rb
|
52
|
+
- lib/hospital/checkup.rb
|
53
|
+
- lib/hospital/checkup_group.rb
|
24
54
|
- lib/hospital/diagnosis.rb
|
25
|
-
- lib/hospital/formatter.rb
|
55
|
+
- lib/hospital/formatter/base.rb
|
56
|
+
- lib/hospital/formatter/pre.rb
|
57
|
+
- lib/hospital/formatter/shell.rb
|
58
|
+
- lib/hospital/string_formatter.rb
|
26
59
|
- lib/hospital/tasks/checkup.rake
|
27
60
|
- lib/hospital/version.rb
|
28
61
|
- lib/railtie.rb
|
data/lib/hospital/formatter.rb
DELETED