blufin 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/bf +5 -0
- data/bin/blufin +5 -0
- data/lib/blufin.rb +245 -0
- data/lib/core/code_scanners/common/scanner_common.rb +83 -0
- data/lib/core/code_scanners/common/scanner_java.rb +106 -0
- data/lib/core/code_scanners/scanner_java_embedded_objects.rb +386 -0
- data/lib/core/code_scanners/scanner_java_enums.rb +125 -0
- data/lib/core/code_scanners/scanner_java_source.rb +29 -0
- data/lib/core/code_scanners/scanner_java_tests.rb +157 -0
- data/lib/core/error_handling/schema_error.rb +9 -0
- data/lib/core/error_handling/sql_error.rb +21 -0
- data/lib/core/error_handling/sql_error_handler.rb +149 -0
- data/lib/core/error_handling/yml_error.rb +21 -0
- data/lib/core/error_handling/yml_error_handler.rb +437 -0
- data/lib/core/mysql.rb +347 -0
- data/lib/core/opt.rb +21 -0
- data/lib/core/site/site.rb +26 -0
- data/lib/core/site/site_auth.rb +88 -0
- data/lib/core/site/site_embedded.rb +27 -0
- data/lib/core/site/site_ports.rb +9 -0
- data/lib/core/site/site_resolver.rb +276 -0
- data/lib/core/site/site_services.rb +162 -0
- data/lib/core/site/site_ui.rb +16 -0
- data/lib/core/yml/config/yml_config_validator.rb +219 -0
- data/lib/core/yml/maven/yml_maven_validator.rb +1132 -0
- data/lib/core/yml/resource/yml_resource_validator.rb +154 -0
- data/lib/core/yml/schema/yml_schema_flags.rb +9 -0
- data/lib/core/yml/schema/yml_schema_validator.rb +1850 -0
- data/lib/core/yml/yml_cache_handler.rb +115 -0
- data/lib/core/yml/yml_common.rb +487 -0
- data/lib/core/yml/yml_meta_writer_base.rb +300 -0
- data/lib/core/yml/yml_outputter.rb +307 -0
- data/lib/core/yml/yml_validator_base.rb +630 -0
- data/lib/core/yml_writers/yml_configuration_writer.rb +40 -0
- data/lib/core/yml_writers/yml_java_api_resource_writer.rb +348 -0
- data/lib/core/yml_writers/yml_java_cron_type_writer.rb +113 -0
- data/lib/core/yml_writers/yml_java_css_dependency_writer.rb +59 -0
- data/lib/core/yml_writers/yml_java_dao_writer.rb +364 -0
- data/lib/core/yml_writers/yml_java_dto_writer.rb +251 -0
- data/lib/core/yml_writers/yml_java_embedded_object_writer.rb +968 -0
- data/lib/core/yml_writers/yml_java_enum_writer.rb +161 -0
- data/lib/core/yml_writers/yml_java_js_dependency_writer.rb +59 -0
- data/lib/core/yml_writers/yml_java_message_type_writer.rb +106 -0
- data/lib/core/yml_writers/yml_java_meta_writer.rb +173 -0
- data/lib/core/yml_writers/yml_java_model_writer.rb +510 -0
- data/lib/core/yml_writers/yml_java_pom_writer.rb +1050 -0
- data/lib/core/yml_writers/yml_java_resource_data_writer.rb +251 -0
- data/lib/core/yml_writers/yml_java_sdk_writer.rb +732 -0
- data/lib/core/yml_writers/yml_java_validator_writer.rb +280 -0
- data/lib/core/yml_writers/yml_java_worker_writer.rb +81 -0
- data/lib/core/yml_writers/yml_sql_structure_writer.rb +307 -0
- data/lib/core/yml_writers/yml_sql_template_writer.rb +243 -0
- data/lib/core/yml_writers/yml_vue_service_writer.rb +170 -0
- data/lib/core/yml_writers/yml_writer_base.rb +114 -0
- data/lib/routes/api_list.rb +35 -0
- data/lib/routes/api_meta.rb +59 -0
- data/lib/routes/build.rb +46 -0
- data/lib/routes/create/create_api.rb +35 -0
- data/lib/routes/create/create_ui.rb +84 -0
- data/lib/routes/export.rb +56 -0
- data/lib/routes/generate/generate_api.rb +225 -0
- data/lib/routes/generate/generate_img_favicon.rb +56 -0
- data/lib/routes/generate/generate_img_landing.rb +94 -0
- data/lib/routes/generate/generate_lambda.rb +43 -0
- data/lib/routes/lint.rb +35 -0
- data/lib/routes/mysql_reset.rb +43 -0
- data/lib/routes/release_blufin.rb +351 -0
- data/lib/routes/run.rb +35 -0
- data/lib/version.rb +1 -0
- data/opt/README.MD +2 -0
- data/opt/config/schema.yml +73 -0
- data/opt/config/template.yml +25 -0
- data/opt/sql/data/config/data-client.sql +7 -0
- data/opt/sql/data/config/data-db-configuration-property.sql +47 -0
- data/opt/sql/data/config/data-db-configuration.sql +9 -0
- data/opt/sql/data/config/data-db.sql +175 -0
- data/opt/sql/data/config/data-profile-api.sql +47 -0
- data/opt/sql/data/config/data-profile-cron.sql +0 -0
- data/opt/sql/data/config/data-profile-worker.sql +0 -0
- data/opt/sql/data/config/data-profile.sql +87 -0
- data/opt/sql/data/config/data-project.sql +95 -0
- data/opt/sql/structure/blufin-master-structure-fks.sql +65 -0
- data/opt/sql/structure/blufin-master-structure.sql +97 -0
- data/opt/sql/structure/blufin-mock-structure-fks.sql +38 -0
- data/opt/sql/structure/blufin-mock-structure.sql +98 -0
- data/opt/sql/templates/config/template-client.sql +7 -0
- data/opt/sql/templates/config/template-db-configuration-property.sql +11 -0
- data/opt/sql/templates/config/template-db-configuration.sql +9 -0
- data/opt/sql/templates/config/template-db.sql +21 -0
- data/opt/sql/templates/config/template-profile-api.sql +11 -0
- data/opt/sql/templates/config/template-profile-cron.sql +7 -0
- data/opt/sql/templates/config/template-profile-worker.sql +7 -0
- data/opt/sql/templates/config/template-profile.sql +21 -0
- data/opt/sql/templates/config/template-project.sql +23 -0
- data/opt/yml/api/schema/config/client.yml +14 -0
- data/opt/yml/api/schema/config/db.yml +45 -0
- data/opt/yml/api/schema/config/db_configuration.yml +22 -0
- data/opt/yml/api/schema/config/db_configuration_property.yml +22 -0
- data/opt/yml/api/schema/config/profile.yml +53 -0
- data/opt/yml/api/schema/config/profile_api.yml +22 -0
- data/opt/yml/api/schema/config/profile_cron.yml +14 -0
- data/opt/yml/api/schema/config/profile_worker.yml +14 -0
- data/opt/yml/api/schema/config/project.yml +48 -0
- data/opt/yml/api/schema/mock/mock.yml +99 -0
- data/opt/yml/api/schema/mock/mock_nested_if_enum.yml +16 -0
- data/opt/yml/api/schema/mock/mock_nested_if_enum_system.yml +16 -0
- data/opt/yml/api/schema/mock/mock_nested_linked.yml +43 -0
- data/opt/yml/api/schema/mock/mock_nested_multiple.yml +61 -0
- data/opt/yml/api/schema/mock/mock_nested_single.yml +67 -0
- data/opt/yml/api/schema/mock/mock_nested_single_super_deep.yml +32 -0
- data/opt/yml/api/schema/mock/mock_nested_single_super_super_deep.yml +17 -0
- 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,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
|