blufin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. checksums.yaml +7 -0
  2. data/bin/bf +5 -0
  3. data/bin/blufin +5 -0
  4. data/lib/blufin.rb +245 -0
  5. data/lib/core/code_scanners/common/scanner_common.rb +83 -0
  6. data/lib/core/code_scanners/common/scanner_java.rb +106 -0
  7. data/lib/core/code_scanners/scanner_java_embedded_objects.rb +386 -0
  8. data/lib/core/code_scanners/scanner_java_enums.rb +125 -0
  9. data/lib/core/code_scanners/scanner_java_source.rb +29 -0
  10. data/lib/core/code_scanners/scanner_java_tests.rb +157 -0
  11. data/lib/core/error_handling/schema_error.rb +9 -0
  12. data/lib/core/error_handling/sql_error.rb +21 -0
  13. data/lib/core/error_handling/sql_error_handler.rb +149 -0
  14. data/lib/core/error_handling/yml_error.rb +21 -0
  15. data/lib/core/error_handling/yml_error_handler.rb +437 -0
  16. data/lib/core/mysql.rb +347 -0
  17. data/lib/core/opt.rb +21 -0
  18. data/lib/core/site/site.rb +26 -0
  19. data/lib/core/site/site_auth.rb +88 -0
  20. data/lib/core/site/site_embedded.rb +27 -0
  21. data/lib/core/site/site_ports.rb +9 -0
  22. data/lib/core/site/site_resolver.rb +276 -0
  23. data/lib/core/site/site_services.rb +162 -0
  24. data/lib/core/site/site_ui.rb +16 -0
  25. data/lib/core/yml/config/yml_config_validator.rb +219 -0
  26. data/lib/core/yml/maven/yml_maven_validator.rb +1132 -0
  27. data/lib/core/yml/resource/yml_resource_validator.rb +154 -0
  28. data/lib/core/yml/schema/yml_schema_flags.rb +9 -0
  29. data/lib/core/yml/schema/yml_schema_validator.rb +1850 -0
  30. data/lib/core/yml/yml_cache_handler.rb +115 -0
  31. data/lib/core/yml/yml_common.rb +487 -0
  32. data/lib/core/yml/yml_meta_writer_base.rb +300 -0
  33. data/lib/core/yml/yml_outputter.rb +307 -0
  34. data/lib/core/yml/yml_validator_base.rb +630 -0
  35. data/lib/core/yml_writers/yml_configuration_writer.rb +40 -0
  36. data/lib/core/yml_writers/yml_java_api_resource_writer.rb +348 -0
  37. data/lib/core/yml_writers/yml_java_cron_type_writer.rb +113 -0
  38. data/lib/core/yml_writers/yml_java_css_dependency_writer.rb +59 -0
  39. data/lib/core/yml_writers/yml_java_dao_writer.rb +364 -0
  40. data/lib/core/yml_writers/yml_java_dto_writer.rb +251 -0
  41. data/lib/core/yml_writers/yml_java_embedded_object_writer.rb +968 -0
  42. data/lib/core/yml_writers/yml_java_enum_writer.rb +161 -0
  43. data/lib/core/yml_writers/yml_java_js_dependency_writer.rb +59 -0
  44. data/lib/core/yml_writers/yml_java_message_type_writer.rb +106 -0
  45. data/lib/core/yml_writers/yml_java_meta_writer.rb +173 -0
  46. data/lib/core/yml_writers/yml_java_model_writer.rb +510 -0
  47. data/lib/core/yml_writers/yml_java_pom_writer.rb +1050 -0
  48. data/lib/core/yml_writers/yml_java_resource_data_writer.rb +251 -0
  49. data/lib/core/yml_writers/yml_java_sdk_writer.rb +732 -0
  50. data/lib/core/yml_writers/yml_java_validator_writer.rb +280 -0
  51. data/lib/core/yml_writers/yml_java_worker_writer.rb +81 -0
  52. data/lib/core/yml_writers/yml_sql_structure_writer.rb +307 -0
  53. data/lib/core/yml_writers/yml_sql_template_writer.rb +243 -0
  54. data/lib/core/yml_writers/yml_vue_service_writer.rb +170 -0
  55. data/lib/core/yml_writers/yml_writer_base.rb +114 -0
  56. data/lib/routes/api_list.rb +35 -0
  57. data/lib/routes/api_meta.rb +59 -0
  58. data/lib/routes/build.rb +46 -0
  59. data/lib/routes/create/create_api.rb +35 -0
  60. data/lib/routes/create/create_ui.rb +84 -0
  61. data/lib/routes/export.rb +56 -0
  62. data/lib/routes/generate/generate_api.rb +225 -0
  63. data/lib/routes/generate/generate_img_favicon.rb +56 -0
  64. data/lib/routes/generate/generate_img_landing.rb +94 -0
  65. data/lib/routes/generate/generate_lambda.rb +43 -0
  66. data/lib/routes/lint.rb +35 -0
  67. data/lib/routes/mysql_reset.rb +43 -0
  68. data/lib/routes/release_blufin.rb +351 -0
  69. data/lib/routes/run.rb +35 -0
  70. data/lib/version.rb +1 -0
  71. data/opt/README.MD +2 -0
  72. data/opt/config/schema.yml +73 -0
  73. data/opt/config/template.yml +25 -0
  74. data/opt/sql/data/config/data-client.sql +7 -0
  75. data/opt/sql/data/config/data-db-configuration-property.sql +47 -0
  76. data/opt/sql/data/config/data-db-configuration.sql +9 -0
  77. data/opt/sql/data/config/data-db.sql +175 -0
  78. data/opt/sql/data/config/data-profile-api.sql +47 -0
  79. data/opt/sql/data/config/data-profile-cron.sql +0 -0
  80. data/opt/sql/data/config/data-profile-worker.sql +0 -0
  81. data/opt/sql/data/config/data-profile.sql +87 -0
  82. data/opt/sql/data/config/data-project.sql +95 -0
  83. data/opt/sql/structure/blufin-master-structure-fks.sql +65 -0
  84. data/opt/sql/structure/blufin-master-structure.sql +97 -0
  85. data/opt/sql/structure/blufin-mock-structure-fks.sql +38 -0
  86. data/opt/sql/structure/blufin-mock-structure.sql +98 -0
  87. data/opt/sql/templates/config/template-client.sql +7 -0
  88. data/opt/sql/templates/config/template-db-configuration-property.sql +11 -0
  89. data/opt/sql/templates/config/template-db-configuration.sql +9 -0
  90. data/opt/sql/templates/config/template-db.sql +21 -0
  91. data/opt/sql/templates/config/template-profile-api.sql +11 -0
  92. data/opt/sql/templates/config/template-profile-cron.sql +7 -0
  93. data/opt/sql/templates/config/template-profile-worker.sql +7 -0
  94. data/opt/sql/templates/config/template-profile.sql +21 -0
  95. data/opt/sql/templates/config/template-project.sql +23 -0
  96. data/opt/yml/api/schema/config/client.yml +14 -0
  97. data/opt/yml/api/schema/config/db.yml +45 -0
  98. data/opt/yml/api/schema/config/db_configuration.yml +22 -0
  99. data/opt/yml/api/schema/config/db_configuration_property.yml +22 -0
  100. data/opt/yml/api/schema/config/profile.yml +53 -0
  101. data/opt/yml/api/schema/config/profile_api.yml +22 -0
  102. data/opt/yml/api/schema/config/profile_cron.yml +14 -0
  103. data/opt/yml/api/schema/config/profile_worker.yml +14 -0
  104. data/opt/yml/api/schema/config/project.yml +48 -0
  105. data/opt/yml/api/schema/mock/mock.yml +99 -0
  106. data/opt/yml/api/schema/mock/mock_nested_if_enum.yml +16 -0
  107. data/opt/yml/api/schema/mock/mock_nested_if_enum_system.yml +16 -0
  108. data/opt/yml/api/schema/mock/mock_nested_linked.yml +43 -0
  109. data/opt/yml/api/schema/mock/mock_nested_multiple.yml +61 -0
  110. data/opt/yml/api/schema/mock/mock_nested_single.yml +67 -0
  111. data/opt/yml/api/schema/mock/mock_nested_single_super_deep.yml +32 -0
  112. data/opt/yml/api/schema/mock/mock_nested_single_super_super_deep.yml +17 -0
  113. metadata +240 -0
@@ -0,0 +1,29 @@
1
+ module Blufin
2
+
3
+ # This class scans ALL Java classes and does general validation.
4
+ # Anything that doesn't fit into a sub-class will go in here.
5
+ class ScannerJavaSource
6
+
7
+ # @return void
8
+ def initialize(site, error_handler)
9
+
10
+ @site = Blufin::SiteResolver::validate_site(site)
11
+ @site_name = Blufin::SiteResolver::get_site_name(@site)
12
+ @site_path = Blufin::SiteResolver::get_site_location(@site)
13
+ @site_domain = Blufin::SiteResolver::get_site_domain(@site)
14
+
15
+ @error_handler = error_handler
16
+
17
+ # @all_files = Blufin::ScannerCommon::get_non_ignored_files(@site_path, ['java'], @error_handler, Blufin::Site::PATH_APP_INFRASTRUCTURE)
18
+ # @all_files.each do |file|
19
+ #
20
+ # class_info = Blufin::ScannerJava::scan(file, @site)
21
+ # puts class_info.inspect
22
+ #
23
+ # end
24
+
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,157 @@
1
+ module Blufin
2
+
3
+ # This class scans ALL Java classes and generates blank tests for every class which doesn't have a test.
4
+ # Also throws errors if 'rogue' tests exist and/or tests are named/placed incorrectly.
5
+ class ScannerJavaTests < Blufin::YmlWriterBase
6
+
7
+ TEMPLATE = <<TEMPLATE
8
+ package #{PLACEHOLDER_PACKAGE};
9
+
10
+ import org.junit.Before;
11
+ import org.junit.Test;
12
+ import org.junit.runner.RunWith;
13
+ import org.mockito.runners.MockitoJUnitRunner;
14
+
15
+ import static org.hamcrest.CoreMatchers.is;
16
+ import static org.hamcrest.MatcherAssert.assertThat;
17
+
18
+ @RunWith(MockitoJUnitRunner.class)
19
+ public class #{PLACEHOLDER_CLASS} {
20
+
21
+ @Before
22
+ public void setUp() {}
23
+
24
+ @Test
25
+ public void testSomething() {
26
+
27
+ assertThat(true, is(true));
28
+ }
29
+ }
30
+ TEMPLATE
31
+
32
+ # @return void
33
+ def initialize(site, error_handler)
34
+
35
+ @site = Blufin::SiteResolver::validate_site(site)
36
+ @site_name = Blufin::SiteResolver::get_site_name(@site)
37
+ @site_name_camel_cased = Blufin::SiteResolver::get_site_name_camel_cased(@site)
38
+ @site_path = Blufin::SiteResolver::get_site_location(@site)
39
+ @site_domain = Blufin::SiteResolver::get_site_domain(@site)
40
+
41
+ @error_handler = error_handler
42
+
43
+ @infrastructure_classes = {}
44
+ @infrastructure_tests = {}
45
+
46
+ scan_blufin
47
+ scan_app_infrastructure
48
+
49
+ tests_create_and_validate
50
+ tests_rogue_check
51
+
52
+ end
53
+
54
+ private
55
+
56
+ # Scans the /blufin parent java library files.
57
+ # @return void
58
+ def scan_blufin
59
+
60
+ all_files = Blufin::ScannerCommon::get_non_ignored_files(Blufin::Config::get_path('Paths', 'BlufinJava'), ['java'], @error_handler)
61
+ all_files.each do |file|
62
+
63
+ # TODO - SCAN BLUFIN-JAVA FILES
64
+
65
+ # output_classes = []
66
+ # output_tests = []
67
+ # @infrastructure_classes.each do |key, data|
68
+ # flags = []
69
+ # flags << (data[Blufin::ScannerJava::TEST_REQUIRED] ? 'Test Required' : nil)
70
+ # output_classes << "\x1B[38;5;154m#{key} \x1B[38;5;240m\xe2\x80\x94 #{flags.join('|')}"
71
+ # end
72
+ # @infrastructure_tests.each do |key, data|
73
+ # output_tests << "\x1B[38;5;196m#{key}\x1B[0m"
74
+ # end
75
+ # Blufin::Terminal::info('Classes', output_classes)
76
+ # Blufin::Terminal::info('Tests', output_tests)
77
+ end
78
+
79
+ end
80
+
81
+ # Scans the /app-infrastructure directory.
82
+ # @return void
83
+ def scan_app_infrastructure
84
+ base_path = "#{@site_name.gsub('-', '/')}\\/(#{Blufin::SiteServices::REGEX_SERVICES})"
85
+ all_files = Blufin::ScannerCommon::get_non_ignored_files(@site_path, ['java'], @error_handler, Blufin::Site::PATH_APP_INFRASTRUCTURE)
86
+ all_files.each do |file|
87
+ next if file =~ /#{base_path}\/#{@site_name_camel_cased}(#{Blufin::SiteServices::REGEX_SERVICES_CAPITALIZED}).java\z/
88
+ next if file =~ /#{base_path}\/#{@site_name_camel_cased}(#{Blufin::SiteServices::REGEX_SERVICES_CAPITALIZED})Config.java\z/
89
+ next if file =~ /#{base_path}\/health\//
90
+ next if file =~ /#{base_path}\/tasks\//
91
+ class_info = Blufin::ScannerJava::scan(file, @site, @error_handler)
92
+ next unless class_info[Blufin::ScannerJava::TYPE] == Blufin::ScannerJava::TYPE_CLASS
93
+ file_path_split = Blufin::YmlCommon::split_to_path_file(file, @site_path)
94
+ if class_info[Blufin::ScannerJava::TEST]
95
+ @infrastructure_tests[file_path_split[1].gsub('.java', '')] = class_info
96
+ else
97
+ @infrastructure_classes[file_path_split[1].gsub('.java', '')] = class_info
98
+ end
99
+ end
100
+ end
101
+
102
+ # Checks that Tests are correct.
103
+ # Also creates Tests for classes which need them.
104
+ # @return void
105
+ def tests_create_and_validate
106
+
107
+ @infrastructure_classes.each do |clazz, clazz_info|
108
+
109
+ # TODO - TESTS SHOULD NOT HAVE @AutoGenerated + @TestNotSomething annotations... 21-02-2017
110
+
111
+ if clazz_info[Blufin::ScannerJava::TEST_REQUIRED]
112
+ test_name = "#{clazz}Test"
113
+ file = "#{@site_path}/#{clazz_info[Blufin::ScannerJava::PATH]}/#{test_name}.java"
114
+ file = Blufin::ScannerCommon::swap_classpath_for_testpath(@site, file)
115
+ contents = TEMPLATE
116
+ contents = contents.gsub(PLACEHOLDER_PACKAGE, get_package_from_file(@site, file))
117
+ contents = contents.gsub(PLACEHOLDER_CLASS, test_name)
118
+ contents_ignore = [
119
+ 'import org.junit.Before;',
120
+ 'import static org.hamcrest.MatcherAssert.assertThat;',
121
+ 'import static org.hamcrest.core.Is.is;',
122
+ 'import static org.hamcrest.CoreMatchers.is;',
123
+ 'import static org.hamcrest.MatcherAssert.assertThat;',
124
+ ' @Before',
125
+ ' public void setUp() {}',
126
+ ' public void testSomething() {',
127
+ ' assertThat(true, is(true));'
128
+ ]
129
+ Blufin::YmlCommon::validate_file_and_contents(@site, file, Blufin::YmlCommon::convert_string_to_line_array(contents), contents_ignore, @error_handler)
130
+ end
131
+
132
+ end
133
+
134
+ end
135
+
136
+ # Check for Rogue Tests?
137
+ # @return void
138
+ def tests_rogue_check
139
+
140
+ @infrastructure_tests.each do |clazz, test_info|
141
+
142
+ file = "#{test_info[Blufin::ScannerJava::PATH]}/#{clazz}"
143
+ class_info = @infrastructure_classes[clazz.gsub(/Test\z/, '')]
144
+
145
+ if class_info.nil?
146
+ @error_handler.add_error(Blufin::YmlErrorHandler::TEST_NOT_EXPECTED, file, nil, nil, clazz) unless test_info[Blufin::ScannerJava::TEST_NOT_RELATED_TO_CLASS]
147
+ else
148
+ @error_handler.add_error(Blufin::YmlErrorHandler::TEST_NOT_EXPECTED, file, nil, nil, clazz) unless class_info[Blufin::ScannerJava::TEST_REQUIRED]
149
+ end
150
+
151
+ end
152
+
153
+ end
154
+
155
+ end
156
+
157
+ end
@@ -0,0 +1,9 @@
1
+ module Blufin
2
+
3
+ class SchemaError
4
+
5
+ attr_accessor :schema_address, :file, :error_detail, :error_message, :multi_line_content, :section
6
+
7
+ end
8
+
9
+ end
@@ -0,0 +1,21 @@
1
+ module Blufin
2
+
3
+ class SqlError
4
+
5
+ attr_accessor :type, :file, :line, :multi_line_content
6
+
7
+ def initialize(type, file, line, multi_line_content)
8
+
9
+ raise RuntimeError, "multi_line_content must be either nil or Array, you passed: #{multi_line_content.class}" unless multi_line_content.nil? || multi_line_content.is_a?(Array)
10
+
11
+ @type = type
12
+ @file = file
13
+ @line = line
14
+
15
+ @multi_line_content = multi_line_content
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,149 @@
1
+ module Blufin
2
+
3
+ class SqlErrorHandler
4
+
5
+ ERROR_SQL_REGEX_MISMATCH = 100
6
+ ERROR_SQL_SCHEMA_MISMATCH = 101
7
+ ERROR_SQL_STATEMENT_NOT_EXPECTED = 102
8
+
9
+ # Returns a Hash of valid error types with titles/descriptions.
10
+ # Moved to top of file for easier programming.
11
+ # @return Hash
12
+ def error_type_meta
13
+ {
14
+ ERROR_SQL_REGEX_MISMATCH => ['SQL DATA - REGEX MISMATCH', "Line does not match expected pattern \xe2\x80\x94 please check your formatting."],
15
+ ERROR_SQL_SCHEMA_MISMATCH => ['SQL DATA - SCHEMA MISMATCH', "Field(s) within a SQL INSERT statement don't match the actual schema."],
16
+ ERROR_SQL_STATEMENT_NOT_EXPECTED => ['SQL DATA - STATEMENT NOT EXPECTED', 'Statement matches REGEX but was not expected in this part of the file.']
17
+ }
18
+ end
19
+
20
+ # Initializes the Error Handler.
21
+ # @return void
22
+ def initialize(site)
23
+
24
+ @site = Blufin::SiteResolver::validate_site(site)
25
+ @site_sql_path = Blufin::SiteResolver::path_to_sql(@site)
26
+
27
+ @errors = []
28
+
29
+ end
30
+
31
+ # Adds an error to the @error Array.
32
+ # @return void
33
+ def add_error(type, file, line, multi_line_content = nil)
34
+ raise RuntimeError, "Expected multi_line_content to be Array, instead got: #{multi_line_content.class}" unless multi_line_content.nil? || multi_line_content.is_a?(Array)
35
+ @errors << Blufin::SqlError.new(validate_error_type(type), validate_file(file), validate_line(line), multi_line_content)
36
+ end
37
+
38
+ # Displays errors (if any) and halts the script if so.
39
+ # @return Boolean
40
+ def display_errors_if_any(exit = false)
41
+
42
+ return false unless @errors.any?
43
+
44
+ puts
45
+
46
+ errors_types = []
47
+ errors_sorted_by_type = {}
48
+ errors_meta = error_type_meta
49
+ errors_output = []
50
+
51
+ column_path = []
52
+ column_file = []
53
+ column_line = []
54
+
55
+ @errors.each do |error|
56
+ path = ''
57
+ file = ''
58
+ if errors_sorted_by_type[error.type].nil?
59
+ errors_types << error.type
60
+ errors_sorted_by_type[error.type] = []
61
+ end
62
+ errors_sorted_by_type[error.type] << error
63
+ file_parts = error.file.dup.strip.gsub(@site_sql_path, '').gsub(/\A\//, '').split('/')
64
+ file_parts.each_with_index do |part, idx|
65
+ if idx < file_parts.length - 1
66
+ path << "#{part}/"
67
+ else
68
+ file << part
69
+ end
70
+ end
71
+ column_path << path
72
+ column_file << file
73
+ column_line << error.line
74
+ end
75
+
76
+ column_path_max = column_path.max_by(&:length).length
77
+ column_file_max = column_file.max_by(&:length).length
78
+ column_line_max = column_line.max_by(&:length).length
79
+
80
+ multi_line_padding = (column_path_max + column_file_max + column_line_max + 6).times.collect { ' ' }.join('')
81
+
82
+ errors_types.sort!
83
+ errors_types.each do |error_type|
84
+ errors_output << "#{''.ljust(column_path_max - 5, ' ')}\x1B[38;5;231m\x1B[48;5;238m ERROR \x1B[48;5;196m #{errors_meta[error_type][0]} \x1B[0m\x1B[38;5;240m \xe2\x86\x92 \x1B[0m\x1B[38;5;221m#{errors_meta[error_type][1]}\x1B[0m"
85
+ errors_output << ''
86
+ errors_sorted_by_type[error_type].each do |error|
87
+ path_and_file = split_to_path_file(error.file)
88
+ content = Blufin::Files::read_file(error.file, error.line.dup.to_i, error.line.dup.to_i)
89
+ errors_output << " \x1B[38;5;240m#{path_and_file[0].rjust(column_path_max, ' ')}\x1B[38;5;196m#{path_and_file[1].ljust(column_file_max, ' ')}\x1B[0m:\x1B[38;5;76m#{error.line.ljust(column_line_max, ' ')}\x1B[0m \x1B[38;5;246m\xe2\x80\x94 \x1B[0m\x1B[48;5;240m#{content[0].gsub("\n", '')}\x1B[0m"
90
+ if error.multi_line_content.is_a?(Array)
91
+ error.multi_line_content.each do |line|
92
+ errors_output << "#{multi_line_padding}#{line}"
93
+ end
94
+ end
95
+ end
96
+ errors_output << ''
97
+ end
98
+
99
+ errors_output.each { |line| puts line }
100
+
101
+ exit 1 if exit
102
+
103
+ true
104
+
105
+ end
106
+
107
+ private
108
+
109
+ # Validate the file.
110
+ # @return String
111
+ def validate_file(file)
112
+ raise RuntimeError, "File does not exist: #{Blufin::Terminal::format_flag(file)}" unless Blufin::Files::file_exists(file)
113
+ file
114
+ end
115
+
116
+ # Validate the line number.
117
+ # @return String
118
+ def validate_line(line)
119
+ line = line.to_s.strip
120
+ raise RuntimeError, "Expected integer, instead got: #{line}" unless line =~ /^\d+$/
121
+ line
122
+ end
123
+
124
+ # Validate the error type.
125
+ # @return String
126
+ def validate_error_type(type)
127
+ raise RuntimeError, "Invalid error type: #{type} \xe2\x80\x94 perhaps you forgot to add it to the valid type array in Blufin::SqlErrorHandler ?" unless error_type_meta.keys.include?(type)
128
+ type
129
+ end
130
+
131
+ # Removes the majority of the pathname to file.
132
+ # @return String
133
+ def split_to_path_file(path_and_file)
134
+ path = ''
135
+ file = ''
136
+ file_parts = path_and_file.strip.gsub(@site_sql_path, '').gsub(/\A\//, '').split('/')
137
+ file_parts.each_with_index do |part, idx|
138
+ if idx < file_parts.length - 1
139
+ path << "#{part}/"
140
+ else
141
+ file << part
142
+ end
143
+ end
144
+ [path, file]
145
+ end
146
+
147
+ end
148
+
149
+ end
@@ -0,0 +1,21 @@
1
+ module Blufin
2
+
3
+ class YmlError
4
+
5
+ attr_accessor :type, :file, :section, :field, :message
6
+
7
+ def initialize(type, file, section, field, message)
8
+
9
+ message = [message] if message.is_a?(String)
10
+
11
+ @type = type
12
+ @file = file
13
+ @section = section
14
+ @field = field
15
+ @message = message
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,437 @@
1
+ require 'columnist'
2
+
3
+ module Blufin
4
+
5
+ class YmlErrorHandler
6
+
7
+ extend Columnist
8
+
9
+ FILE_EMPTY = 1000
10
+ FILE_INVALID = 1005
11
+ FILE_NOT_FOUND = 1010
12
+ TEST_NOT_FOUND = 1011
13
+ FILE_NOT_FOUND_GITIGNORE = 1011
14
+ FILE_NOT_EXPECTED = 1020
15
+ TEST_NOT_EXPECTED = 1021
16
+ FILE_CONTENT_MISMATCH = 1030
17
+ DIRECTORY_NOT_FOUND = 1050
18
+ DIRECTORY_NOT_EXPECTED = 1060
19
+ SECTION_ORDER = 1100
20
+ SECTION_TITLE_REGEX = 1110
21
+ SECTION_VALUE_REGEX = 1111
22
+ SECTION_ALPHABETICAL = 1120
23
+ ARRAY_KEY_ROGUE = 1130
24
+ ARRAY_VALUE_REGEX = 1131
25
+ ARRAY_VALUE_BLANK = 1132
26
+ ARRAY_STRING_EXPECTED = 1133
27
+ ARRAY_HASHES_EXPECTED = 1134
28
+ ANNOTATIONS_ONE_OR_ANOTHER = 1150
29
+ ANNOTATIONS_NOT_EXPECTED = 1151
30
+ FIELD_MISSING_EMPTY = 1200
31
+ FIELD_BOOLEAN = 1210
32
+ FIELD_FILE = 1220
33
+ FIELD_TEXT_CAPITALIZED = 1230
34
+ FIELD_TEXT_REGEX = 1240
35
+ FIELD_TEXT_NOT_DEFINED = 1250
36
+ FIELD_ROGUE = 1260
37
+ FIELD_UNNECESSARY = 1270
38
+ FIELD_MISSING = 1279
39
+ FIELD_ORDER = 1280
40
+ FIELD_INVALID_VALUE = 1285
41
+ FIELD_INVALID_TYPE = 1286
42
+ FIELD_REQUIRES_SUB_FIELDS = 1287
43
+ FIELD_CANNOT_BE_BLANK = 1288
44
+ FIELD_NAME_TRANSIENT_CONFLICT = 1289
45
+ STYLE_MULTIPLE_BLANK_LINES = 1300
46
+ STYLE_TRAILING_BLANK_LINES = 1310
47
+ STYLE_UNRECOGNIZED_LINE = 1320
48
+ API_ENDPOINTS_MISSING = 2000
49
+ API_ENDPOINTS_NOT_ALLOWED = 2001
50
+ API_METHOD_INVALID_FOR_REQUIRED_OBJECT = 2003
51
+ CONFIG = 2100 # RESERVED
52
+ CRON = 2200 # RESERVED
53
+ EVENT = 2300 # RESERVED
54
+ SCHEMA = 2400 # RESERVED
55
+ WORKER_MESSAGE_TYPE_NOT_FOUND = 2500
56
+ DATA_NOT_ALPHABETICAL = 3000
57
+ MAVEN_MODULE_UNRECOGNIZED = 3100
58
+ MAVEN_MODULE_NOT_DEFINED = 3105
59
+ MAVEN_MODULE_NOT_REGISTERED = 3106
60
+ MAVEN_MODULE_DUPLICATE = 3110
61
+ MAVEN_MODULE_ORDER = 3115
62
+ MAVEN_MODULE_UNDEFINED_PARENT = 3116
63
+ MAVEN_MODULE_UNUSED_PARENT = 3117
64
+
65
+ # EVERYTHING IN THE 5000 (OR ABOVE) RANGE PRODUCES ERRORS WITHOUT SECTION/FIELD OUTPUT (AS THEY ARE GENERALLY FILE RELATED).
66
+ EMBEDDED_OBJECT_NOT_FOUND = 5000
67
+ EMBEDDED_OBJECT_NO_ANNOTATION = 5005
68
+ EMBEDDED_OBJECT_NO_TABLE = 5006
69
+ EMBEDDED_OBJECT_INVALID_SCHEMA = 5001
70
+ EMBEDDED_OBJECT_INVALID_NAME = 5010
71
+ EMBEDDED_OBJECT_INVALID_REF_REGEX = 5011
72
+ EMBEDDED_OBJECT_INVALID_REF_LENGTH = 5012
73
+ EMBEDDED_OBJECT_INVALID_ABSTRACTION = 5015
74
+ EMBEDDED_OBJECT_INVALID_EXTENSION = 5016
75
+ EMBEDDED_OBJECT_INVALID_LINE = 5018
76
+ EMBEDDED_OBJECT_INVALID_REGEX = 5019
77
+ EMBEDDED_OBJECT_DATA_NOT_FOUND = 5020
78
+ EMBEDDED_FIELD_MISSING = 5030
79
+ EMBEDDED_FIELD_WRONG_TYPE = 5031
80
+ EMBEDDED_ANNOTATION_MISSING = 5032
81
+ EMBEDDED_ANNOTATION_UNNECESSARY = 5033
82
+ EMBEDDED_EXTRA_VALUE_INVALID = 5034
83
+ EMBEDDED_DATA_TYPE_INVALID = 5035
84
+ EMBEDDED_FLAGS_INVALID = 5036
85
+ EMBEDDED_FKEY_INVALID = 5037
86
+ EMBEDDED_MUST_BE_ENCRYPTED = 5038
87
+ EMBEDDED_CONFIG_CANNOT_BE_ENCRYPTED = 5039
88
+ UNEXPECTED_EXCEPTION = 9999
89
+
90
+ COLOR_TITLE = 123
91
+ COLOR_ERROR_MESSAGE = 242
92
+
93
+ MDASH = "\xe2\x80\x94"
94
+
95
+ # Returns a Hash of valid error types with titles/descriptions.
96
+ # Moved to top of file for easier programming.
97
+ # @return Hash
98
+ def self.error_type_meta
99
+ {
100
+ FILE_EMPTY => ['EMPTY FILE', "The YML parser expected #{Blufin::Terminal::format_action('file(s)')} to contain data:"],
101
+ FILE_INVALID => ['INVALID FILE', "The YML parser was unable to parse the following #{Blufin::Terminal::format_action('file(s)')}:", 'Unable to parse: %s'],
102
+ FILE_NOT_FOUND => ['FILE NOT FOUND', "The YML parser expected #{Blufin::Terminal::format_action('file(s)')} to exist:", 'File not found: %s'],
103
+ TEST_NOT_FOUND => ['TEST NOT FOUND', "The YML parser expected #{Blufin::Terminal::format_action('tests(s)')} to exist (most likely due to missing #{Blufin::SiteServices::ANNOTATION_TEST_REQUIRED}):", 'Test not found: %s'],
104
+ FILE_NOT_FOUND_GITIGNORE => ['GITIGNORE NOT FOUND', "The YML parser expected #{Blufin::Terminal::format_action('.gitignore')} to exist:", 'File not found in: %s'],
105
+ FILE_NOT_EXPECTED => ['FILE NOT EXPECTED', "The YML parser did not expect certain #{Blufin::Terminal::format_action('file(s)')} to exist:", 'Rogue file: %s'],
106
+ TEST_NOT_EXPECTED => ['TEST NOT EXPECTED', "The YML parser did not expect certain #{Blufin::Terminal::format_action('test(s)')} to exist (most likely due to missing #{Blufin::SiteServices::ANNOTATION_TEST_NOT_RELATED_TO_CLASS}):", 'Rogue test: %s'],
107
+ FILE_CONTENT_MISMATCH => ['FILE CONTENT MISMATCH', "The YML parser expect file(s) to have certain #{Blufin::Terminal::format_action('content(s)')} but it wasn't found:"],
108
+ DIRECTORY_NOT_FOUND => ['DIRECTORY NOT FOUND', "The YML parser expected #{Blufin::Terminal::format_action('director(ies)')} to exist:", 'Directory not found: %s'],
109
+ DIRECTORY_NOT_EXPECTED => ['DIRECTORY NOT EXPECTED', "The YML parser did not expect certain #{Blufin::Terminal::format_action('director(ies)')} to exist:", 'Rogue directory: %s'],
110
+ SECTION_ORDER => ['SECTION ORDER MISMATCH', "The YML parser expected #{Blufin::Terminal::format_action('section(s)')} within a file to be in a certain order:"],
111
+ SECTION_TITLE_REGEX => ['SECTION TITLE REGEX MISMATCH', "The YML parser expected section title to match #{Blufin::Terminal::format_action('regex')}:", '%s does not match regex: %s'],
112
+ SECTION_VALUE_REGEX => ['SECTION VALUE REGEX MISMATCH', "The YML parser expected section value to match #{Blufin::Terminal::format_action('regex')}:", '%s does not match regex: %s'],
113
+ SECTION_ALPHABETICAL => ['SECTION NOT ALPHABETICAL', "The YML parser expected section keys to be in #{Blufin::Terminal::format_action('alphabetical')} order:", '%s is in the wrong position.'],
114
+ ARRAY_KEY_ROGUE => ['ROGUE KEY', "The YML parser did not recognize certain #{Blufin::Terminal::format_action('array key(s)')} to exist:", 'Rogue key: %s'],
115
+ ARRAY_VALUE_REGEX => ['ARRAY VALUE REGEX MISMATCH', "The YML parser expected section array value to match #{Blufin::Terminal::format_action('regex')}:", '%s does not match regex: %s'],
116
+ ARRAY_VALUE_BLANK => ['ARRAY VALUE BLANK', "#{Blufin::Terminal::format_action('Array value(s)')} cannot be blank:", 'Blank key: %s'],
117
+ ARRAY_STRING_EXPECTED => ['STRING ARRAY EXPECTED', "The YML parser expected an #{Blufin::Terminal::format_action('Array of Strings')}:", 'Got: %s'],
118
+ ARRAY_HASHES_EXPECTED => ['HASH ARRAY EXPECTED', "The YML parser expected an #{Blufin::Terminal::format_action('Array of Hashes')}:", 'Got: %s'],
119
+ ANNOTATIONS_ONE_OR_ANOTHER => ['ANNOTATIONS MISMATCH', "The YML parser expected either one #{Blufin::Terminal::format_action('annotation')} or another:", '%s cannot be used together.'],
120
+ ANNOTATIONS_NOT_EXPECTED => ['ANNOTATIONS NOT EXPECTED', "The YML parser did not expect certain #{Blufin::Terminal::format_action('annotation(s)')} to exist in file(s):", '%s cannot be used in this file.'],
121
+ FIELD_MISSING_EMPTY => ['MISSING/EMPTY FIELD', "The YML parser expected certain #{Blufin::Terminal::format_action('field(s)')} to exist and not be empty:"],
122
+ FIELD_BOOLEAN => ['INVALID VALUE - BOOLEAN', "Boolean fields must be #{Blufin::Terminal::format_action('TRUE')} or #{Blufin::Terminal::format_action('FALSE')}:"],
123
+ FIELD_FILE => ['INVALID VALUE - FILE NOT FOUND', "The YML parser expected certain #{Blufin::Terminal::format_action('file(s)')} to exist:", 'File not found: %s'],
124
+ FIELD_TEXT_CAPITALIZED => ['VALUE NOT CAPITALIZED', "The YML parser expected text in field(s) to be #{Blufin::Terminal::format_action('capitalized')}:"],
125
+ FIELD_TEXT_REGEX => ['VALUE REGEX MISMATCH', "The YML parser expected text in field(s) to match #{Blufin::Terminal::format_action('regex')}:", '%s does not match regex: %s'],
126
+ FIELD_TEXT_NOT_DEFINED => ['VALUE NOT DEFINED', "The YML parser expected text in field(s) to match pre-set #{Blufin::Terminal::format_action('values')}:"],
127
+ FIELD_ROGUE => ['ROGUE PROPERTY', "The YML parser did not recognize certain #{Blufin::Terminal::format_action('properties')} to exist:", 'Rogue property: %s'],
128
+ FIELD_UNNECESSARY => ['UNNECESSARY PROPERTY', "The following #{Blufin::Terminal::format_action('properties')} are unnecessary with the current configuration:", 'Unnecessary field: %s'],
129
+ FIELD_MISSING => ['PROPERTY MISSING', "The YML parser expected #{Blufin::Terminal::format_action('properties')} within a section to exist:"],
130
+ FIELD_ORDER => ['PROPERTY ORDER MISMATCH', "The YML parser expected #{Blufin::Terminal::format_action('properties')} within a section to be in a certain order:"],
131
+ FIELD_INVALID_VALUE => ['PROPERTY INVALID VALUE', "The YML parser expected properties to contain a certain #{Blufin::Terminal::format_action('value(s)')}:", 'Valid value(s): %s'],
132
+ FIELD_INVALID_TYPE => ['PROPERTY INVALID TYPE', "The YML parser expected properties to to be a certain #{Blufin::Terminal::format_action('type')}:"],
133
+ FIELD_REQUIRES_SUB_FIELDS => ['PROPERTY REQUIRES SUB-FIELDS', "The YML parser expected properties to contain #{Blufin::Terminal::format_action('sub-properties')}:"],
134
+ FIELD_CANNOT_BE_BLANK => ['PROPERTY CANNOT BE BLANK', "Optional properties -- if present -- #{Blufin::Terminal::format_action('cannot be empty')}:", 'Empty properties: %s'],
135
+ FIELD_NAME_TRANSIENT_CONFLICT => ['PROPERTY NAME TRANSIENT CONFLICT', "Property name conflicts with an auto-generated #{Blufin::Terminal::format_action('transient property')}:", 'Conflicting property: %s'],
136
+ STYLE_MULTIPLE_BLANK_LINES => ['UNNECESSARY BLANK LINE', "Unnecessary #{Blufin::Terminal::format_action('blank line(s)')} found in YML file(s):", 'Line: %s'],
137
+ STYLE_TRAILING_BLANK_LINES => ['TRAILING BLANK LINE(S)', "#{Blufin::Terminal::format_action('Trailing blank line(s)')} are not allowed in YML files:", 'Line: %s'],
138
+ STYLE_UNRECOGNIZED_LINE => ['UNRECOGNIZED LINE', "Something is wrong with this #{Blufin::Terminal::format_action('line')}. Perhaps check formatting, key-capitalization or whitespace?", 'Line: %s'],
139
+ API_ENDPOINTS_MISSING => ['API END-POINTS MISSING', "The following #{Blufin::Terminal::format_action('table(s)')} require all HTTP method end-points because they are #{Blufin::Terminal::format_action(Blufin::ScannerJavaEmbeddedObjects::EMBEDDED)}:", 'Needs GET, POST, PATCH & DELETE.'],
140
+ API_ENDPOINTS_NOT_ALLOWED => ['API END-POINTS NOT ALLOWED', "The following #{Blufin::Terminal::format_action('table(s)')} do not allow POST/PUT/PATCH/DELETE HTTP method(s)because they are #{Blufin::Terminal::format_action(Blufin::ScannerJavaEmbeddedObjects::EMBEDDED)}:", 'Found: %s'],
141
+ API_METHOD_INVALID_FOR_REQUIRED_OBJECT => ['API METHOD INVALID FOR REQUIRED OBJECT', "#{Blufin::Terminal::format_action(Blufin::YmlSchemaValidator::REQUIRED)} and #{Blufin::Terminal::format_action(Blufin::YmlSchemaValidator::REQUIRED_IF)} objects cannot have a #{Blufin::Terminal::format_action(Blufin::YmlConfigValidator::POST)} and/or #{Blufin::Terminal::format_action(Blufin::YmlConfigValidator::DELETE)} because they may require a parent:", 'Found: %s'],
142
+ WORKER_MESSAGE_TYPE_NOT_FOUND => ['INVALID MESSAGE TYPE', "The following #{Blufin::Terminal::format_action('MessageTypes(s)', false)} are not defined in the worker-service:", 'Unrecognized MessageType: %s'],
143
+ DATA_NOT_ALPHABETICAL => ['DATA NOT ALPHABETICAL', "The YML parser expected the data in a section to be in #{Blufin::Terminal::format_action('alphabetical')} order:", 'Not in correct order: %s'],
144
+ MAVEN_MODULE_UNRECOGNIZED => ['MAVEN MODULE UNRECOGNIZED', "A maven module has been defined but #{Blufin::Terminal::format_action('not found within the file system')}:", 'Unrecognized module: %s'],
145
+ MAVEN_MODULE_NOT_DEFINED => ['MAVEN MODULE NOT DEFINED', "A maven module found within the file system has #{Blufin::Terminal::format_action('no definition')}:", 'Undefined module: %s'],
146
+ MAVEN_MODULE_NOT_REGISTERED => ['MAVEN MODULE NOT REGISTERED', "A maven module reference has #{Blufin::Terminal::format_action('not been registered')}:", 'Unregistered module: %s'],
147
+ MAVEN_MODULE_DUPLICATE => ['DUPLICATE MAVEN MODULE', "A #{Blufin::Terminal::format_action('duplicate')} maven module was found:", 'Duplicate module: %s'],
148
+ MAVEN_MODULE_ORDER => ['MAVEN MODULE ORDER MISMATCH', "The YML parser expected maven modules to be in #{Blufin::Terminal::format_action('alphabetical order')}:", 'Not in order: %s'],
149
+ MAVEN_MODULE_UNDEFINED_PARENT => ['MAVEN MODULE UNDEFINED PARENT', "A maven module parent has #{Blufin::Terminal::format_action('not been defined')}:", 'Undefined parent: %s'],
150
+ MAVEN_MODULE_UNUSED_PARENT => ['MAVEN MODULE UNUSED PARENT', "A maven module parent has #{Blufin::Terminal::format_action('not been used')}:", 'Unused parent: %s'],
151
+ EMBEDDED_OBJECT_NOT_FOUND => ['OBJECT NOT FOUND', "Java Scanner expected exactly ONE object to be #{Blufin::Terminal::format_action('embedded')} with annotation/value but it wasn't:", "Missing: #{Blufin::ScannerJavaEmbeddedObjects::EMBEDDED}(\"%s\")"],
152
+ EMBEDDED_OBJECT_NO_ANNOTATION => ['EMBEDDED ANNOTATION MISSING', "Java Scanner did not find an #{Blufin::Terminal::format_action(Blufin::ScannerJavaEmbeddedObjects::EMBEDDED)} annotation:", "Missing #{Blufin::ScannerJavaEmbeddedObjects::EMBEDDED} annotation:"],
153
+ EMBEDDED_OBJECT_NO_TABLE => ['TABLE NOT FOUND', "A required #{Blufin::Terminal::format_action('embedded object')} doesn't have a schema counter-part table:", 'Missing table: %s'],
154
+ EMBEDDED_OBJECT_INVALID_SCHEMA => ['INVALID OBJECT SCHEMA', "Java Scanner was unable to attribute a #{Blufin::Terminal::format_action('valid schema')} to an embedded object:", 'Unrecognized schema: %s'],
155
+ EMBEDDED_OBJECT_INVALID_NAME => ['INVALID OBJECT NAME', "Java Scanner was unable to resolve a #{Blufin::Terminal::format_action('valid name')} for an embedded object:", "'%s' needs to start with 'Abstract...':"],
156
+ EMBEDDED_OBJECT_INVALID_REF_REGEX => ['INVALID REFERENCE', "The #{Blufin::Terminal::format_action('reference')} used for an embedded object is invalid:", '%s needs to be lowercase & snake-case.'],
157
+ EMBEDDED_OBJECT_INVALID_REF_LENGTH => ['INVALID REFERENCE', "The #{Blufin::Terminal::format_action('reference')} used for an embedded object is invalid:", "%s needs to be less than #{Blufin::YmlSchemaValidator::MAX_TABLE_CHARACTERS} characters:"],
158
+ EMBEDDED_OBJECT_INVALID_ABSTRACTION => ['INVALID OBJECT ABSTRACTION', "Java Scanner expected embedded object(s) NOT to be #{Blufin::Terminal::format_action('abstract', false)}:", '%s cannot be abstract.'],
159
+ EMBEDDED_OBJECT_INVALID_EXTENSION => ['INVALID OBJECT INTERFACE', "Java Scanner expected embedded object to extend #{Blufin::Terminal::format_action('PersistentDtoEmbedded', false)}:", '%s needs to implement PersistentDtoEmbedded.'],
160
+ EMBEDDED_OBJECT_INVALID_LINE => ['INVALID LINE', "Embedded Object(s). Something is wrong with the following #{Blufin::Terminal::format_action('line(s)')}:", '%s'],
161
+ EMBEDDED_OBJECT_INVALID_REGEX => ['INVALID REGEX', "Embedded Object(s). Object name needs to match #{Blufin::Terminal::format_action('regex')}:", '%s does not match regex: %s'],
162
+ EMBEDDED_OBJECT_DATA_NOT_FOUND => ['NO DATA WITHIN OBJECT', "Java Scanner was unable to resolve #{Blufin::Terminal::format_action('fields')} for an embedded object:", 'No fields in: %s'],
163
+ EMBEDDED_FIELD_MISSING => ['MISSING FIELD', "Embedded object(s) is/are missing expected #{Blufin::Terminal::format_action('fields')}:", 'Missing: %s'],
164
+ EMBEDDED_FIELD_WRONG_TYPE => ['WRONG FIELD TYPE', "Embedded object(s) field(s) are of incorrect #{Blufin::Terminal::format_action('type')}:"],
165
+ EMBEDDED_ANNOTATION_MISSING => ['MISSING ANNOTATION', "Embedded object(s) are missing expected #{Blufin::Terminal::format_action('annotations')}:", 'Missing: %s'],
166
+ EMBEDDED_ANNOTATION_UNNECESSARY => ['UNNECESSARY ANNOTATION', "The following embedded object(s) #{Blufin::Terminal::format_action('annotation value(s)')} are not required:", '%s'],
167
+ EMBEDDED_EXTRA_VALUE_INVALID => ['INVALID EXTRA VALUE', "Embedded object(s) field #{Blufin::Terminal::format_action('extra value')} is invalid:", 'Expected: %s Got: %s'],
168
+ EMBEDDED_DATA_TYPE_INVALID => ['INVALID DATA TYPE', "Embedded object(s) field #{Blufin::Terminal::format_action('data-type')} is invalid:", 'Expected: %s Got: %s'],
169
+ EMBEDDED_FLAGS_INVALID => ['INVALID FLAGS', "Embedded object(s) field has invalid #{Blufin::Terminal::format_action('flags')}:"],
170
+ EMBEDDED_FKEY_INVALID => ['INVALID/MISSING FKEY', "Embedded object(s) field has an invalid/missing #{Blufin::Terminal::format_action('fkey')} property:"],
171
+ EMBEDDED_MUST_BE_ENCRYPTED => ['FIELD MUST BE ENCRYPTED', "Embedded object(s) field must be #{Blufin::Terminal::format_action('encrypted')}:"],
172
+ EMBEDDED_CONFIG_CANNOT_BE_ENCRYPTED => ['FIELD CANNOT BE ENCRYPTED', "Embedded object(s) within the config schema cannot be #{Blufin::Terminal::format_action('encrypted')}:"],
173
+ UNEXPECTED_EXCEPTION => ['UNEXPECTED EXCEPTION', "The YML parser encountered an #{Blufin::Terminal::format_action('unexpected exception')}", '%s']
174
+ }
175
+ end
176
+
177
+ # Initializes the Error Handler.
178
+ # @return void
179
+ def initialize(site)
180
+
181
+ @site = Blufin::SiteResolver::validate_site(site)
182
+ @site_path = Blufin::SiteResolver::get_site_location(@site)
183
+ @errors = []
184
+
185
+ end
186
+
187
+ # Adds an YmlError object to the @error Array.
188
+ # @return void
189
+ def add_error(type, file, section, field, message = nil)
190
+ @errors << Blufin::YmlError.new(validate_error_type(type), file, section, field, message)
191
+ end
192
+
193
+ # Adds an SchemaError object to the @error Array.
194
+ # @return void
195
+ def add_error_schema(error_object)
196
+ @errors << error_object
197
+ end
198
+
199
+ # Displays errors (if any) and halts the script if so.
200
+ # @return Boolean
201
+ def display_errors_if_any(exit = false)
202
+ self.class.output_errors(@errors, @site_path, exit)
203
+ end
204
+
205
+ # Returns a count of how many errors are currently stored.
206
+ # @return Integer
207
+ def get_error_count
208
+ @errors.size
209
+ end
210
+
211
+ private
212
+
213
+ # Validate the error type.
214
+ # @return String
215
+ def validate_error_type(type)
216
+ raise RuntimeError, "Invalid error type: #{type} \xe2\x80\x94 perhaps you forgot to add it to the valid type array in Blufin::YmlErrorHandler ?" unless self.class.error_type_meta.keys.include?(type)
217
+ type
218
+ end
219
+
220
+ # Must be static because of Columnist.
221
+ # @return void
222
+ def self.output_errors(errors, site_path, exit = false)
223
+
224
+ return false unless errors.any?
225
+
226
+ puts
227
+
228
+ errors_schema = []
229
+ errors_groups = {}
230
+ errors_groups_non_yml = {}
231
+
232
+ errors.each do |error|
233
+ if error.class.to_s == 'Blufin::YmlError'
234
+ if error.type >= 5000
235
+ errors_groups_non_yml[error.type] = [] if errors_groups_non_yml[error.type].nil?
236
+ errors_groups_non_yml[error.type] << error
237
+ else
238
+ errors_groups[error.type] = [] if errors_groups[error.type].nil?
239
+ errors_groups[error.type] << error
240
+ end
241
+ elsif error.class.to_s == 'Blufin::SchemaError'
242
+ errors_schema << error
243
+ end
244
+ end
245
+
246
+ wc1 = 4
247
+ wc2 = 32
248
+ wc3 = 16
249
+ wc4 = 38
250
+ wc5 = Blufin::Terminal::get_terminal_width - (wc1 + wc2 + wc3 + wc4 + 6)
251
+
252
+ # Renders NORMAL errors.
253
+ errors_groups.each do |error_type, error_group|
254
+ Blufin::Terminal::custom(error_type_meta[error_type][0], 88, error_type_meta[error_type][1])
255
+ table(:border => false) do
256
+ row do
257
+ column('', :align => 'left', :width => wc1)
258
+ column('File', :align => 'left', :width => wc2, :color => COLOR_TITLE)
259
+ column('Section', :align => 'left', :width => wc3, :color => COLOR_TITLE)
260
+ column('Field(s)', :align => 'left', :width => wc4, :color => COLOR_TITLE)
261
+ column('Error', :align => 'left', :width => wc5, :color => COLOR_TITLE)
262
+ end
263
+ error_group.each do |error|
264
+ file = error.file.nil? ? MDASH : error.file
265
+ unless file == MDASH
266
+ paf = Blufin::YmlCommon::split_to_path_file(file, site_path)
267
+ file = "#{paf[0]}/#{paf[1]}"
268
+ file = paf[1] if file.length > wc2 - 4
269
+ end
270
+ section = error.section.nil? ? MDASH : error.section
271
+ begin
272
+ field = error.field.nil? ? MDASH : error.field.gsub('|', '.')
273
+ rescue
274
+ # In case field is not a String.
275
+ field = "BUG - Expected String but got: #{error.field.class}"
276
+ end
277
+ message = get_error_message(error)
278
+ row do
279
+ column('', :align => 'left', :width => 4)
280
+ column("#{file}", :color => COLOR_ERROR_MESSAGE)
281
+ column(section, :color => COLOR_ERROR_MESSAGE)
282
+ column(field, :color => COLOR_ERROR_MESSAGE)
283
+ column(message.length > 0 ? message[0] : '', :color => COLOR_ERROR_MESSAGE)
284
+ end
285
+ if message.length > 1
286
+ message.each_with_index do |message, idx|
287
+ next if idx == 0
288
+ row do
289
+ column('')
290
+ column('')
291
+ column('')
292
+ column('')
293
+ column(message, :color => COLOR_ERROR_MESSAGE)
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
299
+ puts
300
+ end
301
+
302
+ wc1 = 4
303
+ wc2 = 88
304
+ wc3 = Blufin::Terminal::get_terminal_width - (wc1 + wc2 + 6)
305
+
306
+ # Renders NORMAL (non-YML) errors.
307
+ errors_groups_non_yml.each do |error_type, error_group|
308
+ Blufin::Terminal::custom(error_type_meta[error_type][0], 88, error_type_meta[error_type][1])
309
+ table(:border => false) do
310
+ row do
311
+ column('', :align => 'left', :width => wc1)
312
+ column('File', :align => 'left', :width => wc2, :color => COLOR_TITLE)
313
+ column('Error', :align => 'left', :width => wc3, :color => COLOR_TITLE)
314
+ end
315
+
316
+ error_group.each do |error|
317
+ file = error.file.nil? ? MDASH : error.file
318
+ unless file == MDASH
319
+ file.gsub!(Blufin::Config::get_path('Paths', 'BlufinJava'), '')
320
+ file.gsub!(/\A\//, '')
321
+ end
322
+ message = get_error_message(error)
323
+ row do
324
+ column('', :align => 'left', :width => 4)
325
+ column("#{file}", :color => COLOR_ERROR_MESSAGE)
326
+ column(message.length > 0 ? message[0] : '', :color => COLOR_ERROR_MESSAGE)
327
+ end
328
+ if message.length > 1
329
+ message.each_with_index do |message, idx|
330
+ next if idx == 0
331
+ row do
332
+ column('')
333
+ column('')
334
+ column(message, :color => COLOR_ERROR_MESSAGE)
335
+ end
336
+ end
337
+ end
338
+ end
339
+ end
340
+ puts
341
+ end
342
+
343
+ wc1 = 4
344
+ wc2 = 32
345
+ wc3 = 16
346
+ wc4 = 38
347
+ wc6 = 32
348
+ wc5 = Blufin::Terminal::get_terminal_width - (wc1 + wc2 + wc3 + wc4 + 6 + wc6)
349
+
350
+ # Renders SCHEMA (legacy) errors.
351
+ if errors_schema.length > 0
352
+ Blufin::Terminal::custom('SCHEMA ERROR(S)', 88, 'There are problems with your schema definition(s):')
353
+ table(:border => false) do
354
+ row do
355
+ column('', :align => 'left', :width => wc1)
356
+ column('File', :align => 'left', :width => wc2, :color => COLOR_TITLE)
357
+ column('Section', :align => 'left', :width => wc3, :color => COLOR_TITLE)
358
+ column('Field(s)', :align => 'left', :width => wc4, :color => COLOR_TITLE)
359
+ column('Error', :align => 'left', :width => wc5, :color => COLOR_TITLE)
360
+ column('Detail', :align => 'left', :width => wc6, :color => COLOR_TITLE)
361
+ end
362
+ errors_schema.each do |error|
363
+ if error.file.nil? || error.file == MDASH || error.file == '' || error.file == '—'
364
+ file_output = MDASH
365
+ else
366
+ file = Blufin::YmlCommon::split_to_path_file(error.file, site_path)
367
+ file_output = file[1]
368
+ end
369
+ section = error.section
370
+ field = error.schema_address[2].nil? ? MDASH : error.schema_address[2]
371
+ row do
372
+ column('', :align => 'left', :width => 4)
373
+ column(file_output, :color => COLOR_ERROR_MESSAGE)
374
+ column(section, :color => COLOR_ERROR_MESSAGE)
375
+ column(field, :color => COLOR_ERROR_MESSAGE)
376
+ column(error.error_message, :color => COLOR_ERROR_MESSAGE)
377
+ column(error.error_detail, :color => COLOR_ERROR_MESSAGE)
378
+ end
379
+ multi_content = error.multi_line_content
380
+ if !multi_content.nil? && multi_content.length > 0
381
+ # row { column(''); column(''); column(''); column(''); column(''); column('') }
382
+ multi_content.each do |line|
383
+ row do
384
+ column('')
385
+ column('')
386
+ column('')
387
+ column('')
388
+ column("\x1B[38;5;154m#{line}", :color => COLOR_ERROR_MESSAGE)
389
+ column('')
390
+ end
391
+ end
392
+ row { column(''); column(''); column(''); column(''); column(''); column('') }
393
+ end
394
+
395
+ end
396
+ end
397
+ puts
398
+ end
399
+
400
+ puts
401
+
402
+ exit 1 if exit
403
+
404
+ true
405
+
406
+ end
407
+
408
+ # Gets the error message (or a default message if one is defined).
409
+ # @return Array
410
+ def self.get_error_message(error)
411
+ message = error.message
412
+ begin
413
+ raise nil if error_type_meta[error.type][2].nil?
414
+ error_values = nil
415
+ error_values = [error.message] unless error.message.is_a?(Array)
416
+ error_values = error.message if error.message.is_a?(Array)
417
+ error_values = error_values.map { |value| "\x1B[38;5;196m#{value}\x1B[38;5;#{COLOR_ERROR_MESSAGE}m" } unless error_values.nil?
418
+ message = [error_type_meta[error.type][2] % error_values]
419
+ rescue
420
+ end
421
+ message = [MDASH] if message.nil?
422
+ message
423
+ end
424
+
425
+ # Used for creating a consistent way of displaying Expected/Actual output in errors.
426
+ # @return Array
427
+ def self.error_expected_actual(expected, actual)
428
+ [
429
+ "Expected: \x1B[38;5;118m#{expected}\x1B[38;5;#{COLOR_ERROR_MESSAGE}m",
430
+ " Actual: \x1B[38;5;196m#{actual}",
431
+ nil
432
+ ]
433
+ end
434
+
435
+ end
436
+
437
+ end