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,115 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Blufin
|
4
|
+
|
5
|
+
class YmlCacheHandler
|
6
|
+
|
7
|
+
FORMAT_EXTENSION = '.txt'
|
8
|
+
FORMAT_DATE = '%Y-%d-%m-%H-%M-%S'
|
9
|
+
|
10
|
+
CONFIG = 'config'
|
11
|
+
SCHEMA_CONFIG = 'schema-config'
|
12
|
+
SCHEMA_DATA = 'schema-data'
|
13
|
+
SCHEMA_DESCRIPTIONS = 'schema-descriptions'
|
14
|
+
SCHEMA_FKS = 'schema-fks'
|
15
|
+
SCHEMA_FKS_DEPENDENCIES = 'schema-fks-dependencies'
|
16
|
+
SCHEMA_FKS_PLACEHOLDERS = 'schema-fks-placeholders'
|
17
|
+
SCHEMA_FKS_LINKS = 'schema-fks-links'
|
18
|
+
SCHEMA_RESOURCES = 'schema-resources'
|
19
|
+
|
20
|
+
VALID_KEYS = [
|
21
|
+
CONFIG,
|
22
|
+
SCHEMA_CONFIG,
|
23
|
+
SCHEMA_DATA,
|
24
|
+
SCHEMA_DESCRIPTIONS,
|
25
|
+
SCHEMA_FKS,
|
26
|
+
SCHEMA_FKS_DEPENDENCIES,
|
27
|
+
SCHEMA_FKS_PLACEHOLDERS,
|
28
|
+
SCHEMA_FKS_LINKS,
|
29
|
+
SCHEMA_RESOURCES
|
30
|
+
]
|
31
|
+
|
32
|
+
KEY_DATE = 'date'
|
33
|
+
KEY_DATA = 'data'
|
34
|
+
|
35
|
+
# Stores a Yaml HASH.
|
36
|
+
# @return void
|
37
|
+
def self.store(site, key, data)
|
38
|
+
|
39
|
+
Blufin::SiteResolver::validate_site(site)
|
40
|
+
|
41
|
+
validate_key(key)
|
42
|
+
delete_pre_existing_cache_files(site, key)
|
43
|
+
|
44
|
+
Blufin::Files::write_file_string("#{get_cache_directory(site)}/#{key}-#{get_timestamp}#{FORMAT_EXTENSION}", data.inspect)
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
# Retrieves a Yaml HASH.
|
49
|
+
# @return Hash
|
50
|
+
def self.get(site, key, with_date = false)
|
51
|
+
|
52
|
+
files = get_files_for_key(site, key)
|
53
|
+
|
54
|
+
# Throw crude error if cache file doesn't exist.
|
55
|
+
# TODO - This currently throws RunTimeError but should ideally run 'blufin s g' or something to rebuild the cache automatically...
|
56
|
+
raise RuntimeError, "Cache file for key '#{key}' doesn't exist. Please run: #{Blufin::Terminal::format_command("blufin s g #{site}")}" unless files.any?
|
57
|
+
|
58
|
+
# Get the last file -- although there should never be more than 1.
|
59
|
+
file = files[files.length - 1]
|
60
|
+
|
61
|
+
date = File.basename(file).gsub("#{key}-", '').gsub(FORMAT_EXTENSION, '')
|
62
|
+
date = DateTime.strptime(date, FORMAT_DATE)
|
63
|
+
date = date.strftime("%A \xe2\x80\x94 %B %d [%H:%M:%S]")
|
64
|
+
|
65
|
+
hash = {}
|
66
|
+
|
67
|
+
eval("hash = #{Blufin::Files::read_file(file)[0]}")
|
68
|
+
|
69
|
+
return with_date ? { KEY_DATE => date.to_s, KEY_DATA => hash } : hash
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
# Makes sure the 'key' is a constant within this class.
|
76
|
+
# @return void
|
77
|
+
def self.validate_key(key)
|
78
|
+
raise RuntimeError, "Invalid YmlCacheHandler key: #{key}" unless VALID_KEYS.include?(key)
|
79
|
+
end
|
80
|
+
|
81
|
+
# Removes any pre-existing cache files from the /tmp dir.
|
82
|
+
# @return void
|
83
|
+
def self.delete_pre_existing_cache_files(site, key)
|
84
|
+
get_files_for_key(site, key).each do |file|
|
85
|
+
Blufin::Files::delete_file(file)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Gets an Array of files for specific key.
|
90
|
+
# @return Array
|
91
|
+
def self.get_files_for_key(site, key)
|
92
|
+
files_return = []
|
93
|
+
Blufin::Files::get_files_in_dir(get_cache_directory(site)).each do |file|
|
94
|
+
files_return << file if File.basename(file) =~ /\A#{key}-[0-9-]+#{FORMAT_EXTENSION}\z/
|
95
|
+
end
|
96
|
+
files_return
|
97
|
+
end
|
98
|
+
|
99
|
+
# Get the cache directory.
|
100
|
+
# @return String
|
101
|
+
def self.get_cache_directory(site)
|
102
|
+
cache_directory = "/tmp/cache-#{Blufin::SiteResolver::get_site_name(site)}/"
|
103
|
+
Blufin::Files::create_directory(cache_directory) unless Blufin::Files::path_exists(cache_directory)
|
104
|
+
cache_directory
|
105
|
+
end
|
106
|
+
|
107
|
+
# Get a timestamp of the current time.
|
108
|
+
# @return String
|
109
|
+
def self.get_timestamp
|
110
|
+
Time.now.strftime(FORMAT_DATE)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,487 @@
|
|
1
|
+
module Blufin
|
2
|
+
|
3
|
+
class YmlCommon
|
4
|
+
|
5
|
+
@@enum_scanner = nil
|
6
|
+
|
7
|
+
# Return TRUE if file is .yml -- FALSE if not.
|
8
|
+
# @return boolean
|
9
|
+
def self.is_yml_file(file_path)
|
10
|
+
File.extname(file_path).downcase == '.yml'
|
11
|
+
end
|
12
|
+
|
13
|
+
# Returns nil on success, otherwise an array of invalid keys.
|
14
|
+
# @return nil|Array
|
15
|
+
def self.validate_keys(key_set, valid_keys_as_array)
|
16
|
+
invalid_keys = []
|
17
|
+
key_set.each do |key|
|
18
|
+
invalid_keys << key unless valid_keys_as_array.include?(key)
|
19
|
+
end
|
20
|
+
return invalid_keys if invalid_keys.any?
|
21
|
+
end
|
22
|
+
|
23
|
+
# Returns TYPE_ENUM, TYPE_ENUM_CUSTOM or TYPE_ENUM_SYSTEM from ENUM('a','b') string.
|
24
|
+
# @return String
|
25
|
+
def self.enum_type_extractor(enum_string)
|
26
|
+
if enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM
|
27
|
+
Blufin::YmlSchemaValidator::TYPE_ENUM
|
28
|
+
elsif enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM_CUSTOM
|
29
|
+
Blufin::YmlSchemaValidator::TYPE_ENUM_CUSTOM
|
30
|
+
elsif enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM_SYSTEM
|
31
|
+
Blufin::YmlSchemaValidator::TYPE_ENUM_SYSTEM
|
32
|
+
else
|
33
|
+
raise RuntimeError, "'enum_string' doesn't match regex --> #{enum_string}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Returns Array ['a','b'] from ENUM('a','b')
|
38
|
+
# @return Array
|
39
|
+
def self.enum_value_extractor(enum_string, site)
|
40
|
+
if enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM
|
41
|
+
enum_string = enum_string.gsub(/\A#{Blufin::YmlSchemaValidator::TYPE_ENUM}\(/, '').gsub(/\)\z/, '')
|
42
|
+
enum_array = enum_string.split(',')
|
43
|
+
enum_array = enum_array.map { |value|
|
44
|
+
value.gsub!(/\A'/, '').gsub!(/'\z/, '') if value.is_a?(String) && value != ''
|
45
|
+
}
|
46
|
+
return enum_array
|
47
|
+
elsif enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM_CUSTOM
|
48
|
+
enum_array = []
|
49
|
+
enum_string = enum_string.gsub(/\A#{Blufin::YmlSchemaValidator::TYPE_ENUM_CUSTOM}\(/, '').gsub(/\)\z/, '').gsub(/\A'/, '').gsub(/'\z/, '')
|
50
|
+
enum_custom_all = get_enum_scanner(site).get_custom_enums
|
51
|
+
enum_array = enum_custom_all[enum_string] if enum_custom_all.has_key?(enum_string)
|
52
|
+
return enum_array
|
53
|
+
elsif enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM_SYSTEM
|
54
|
+
enum_array = []
|
55
|
+
enum_string = enum_string.gsub(/\A#{Blufin::YmlSchemaValidator::TYPE_ENUM_SYSTEM}\(/, '').gsub(/\)\z/, '').gsub(/\A'/, '').gsub(/'\z/, '')
|
56
|
+
enum_system_all = get_enum_scanner(site).get_system_enums
|
57
|
+
enum_array = enum_system_all[enum_string] if enum_system_all.has_key?(enum_string)
|
58
|
+
return enum_array
|
59
|
+
else
|
60
|
+
raise RuntimeError, "'enum_string' doesn't match regex --> #{enum_string}"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns Array 'Measure' from ENUM_CUSTOM('Measure')
|
65
|
+
# @return Array
|
66
|
+
def self.enum_name_extractor(enum_string)
|
67
|
+
if enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM_CUSTOM
|
68
|
+
return enum_string.gsub(/\A#{Blufin::YmlSchemaValidator::TYPE_ENUM_CUSTOM}\(/, '').gsub(/\)\z/, '').gsub("'", '')
|
69
|
+
elsif enum_string =~ Blufin::YmlSchemaValidator::REGEX_ENUM_SYSTEM
|
70
|
+
return enum_string.gsub(/\A#{Blufin::YmlSchemaValidator::TYPE_ENUM_SYSTEM}\(/, '').gsub(/\)\z/, '').gsub("'", '')
|
71
|
+
else
|
72
|
+
raise RuntimeError, "'#{enum_string}' doesn't match regex for ENUM, ENUM_CUSTOM or ENUM_SYSTEM."
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Abstract method for extracting flags used in Schema definition.
|
77
|
+
# @return Blufin::YmlSchemaFlags
|
78
|
+
def self.extract_flags(flags)
|
79
|
+
raise RuntimeError, "Expected String, instead got:#{flags.class}" unless flags.is_a?(String)
|
80
|
+
errors = []
|
81
|
+
sort_order = 1
|
82
|
+
definition_order = {}
|
83
|
+
flags_object = Blufin::YmlSchemaFlags.new
|
84
|
+
flags_object.flags_raw = flags
|
85
|
+
flags.split(' ').each do |flag|
|
86
|
+
flag_invalid = false
|
87
|
+
case flag
|
88
|
+
when Blufin::YmlSchemaValidator::FLAG_PRIMARY_KEY
|
89
|
+
flags_object.primary_key = true
|
90
|
+
flags_object.primary_key_sort_order = sort_order
|
91
|
+
when Blufin::YmlSchemaValidator::FLAG_INDEX
|
92
|
+
flags_object.index = true
|
93
|
+
flags_object.index_sort_order = sort_order
|
94
|
+
when Blufin::YmlSchemaValidator::FLAG_NULLABLE
|
95
|
+
flags_object.nullable = true
|
96
|
+
flags_object.nullable_sort_order = sort_order
|
97
|
+
when Blufin::YmlSchemaValidator::FLAG_UNIQUE
|
98
|
+
flags_object.unique = true
|
99
|
+
flags_object.unique_sort_order = sort_order
|
100
|
+
else
|
101
|
+
if flag =~ /\A#{Blufin::YmlSchemaValidator::FLAG_AUTO_INCREMENT}\z/
|
102
|
+
flags_object.auto_increment = true
|
103
|
+
flags_object.auto_increment_amount = nil
|
104
|
+
flags_object.auto_increment_sort_order = sort_order
|
105
|
+
elsif flag =~ /\A#{Blufin::YmlSchemaValidator::FLAG_AUTO_INCREMENT}\(\d{1,10}\)\z/
|
106
|
+
auto_increment_amount = flag.match(/\(\d{1,10}\)/)
|
107
|
+
auto_increment_amount = auto_increment_amount[0].gsub('(', '').gsub(')', '')
|
108
|
+
flags_object.auto_increment = true
|
109
|
+
flags_object.auto_increment_amount = auto_increment_amount
|
110
|
+
flags_object.auto_increment_sort_order = sort_order
|
111
|
+
else
|
112
|
+
errors << ["Invalid 'flag' value.", flag]
|
113
|
+
flag_invalid = true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
unless flag_invalid
|
117
|
+
definition_order[flag] = sort_order
|
118
|
+
sort_order = sort_order + 1
|
119
|
+
end
|
120
|
+
end
|
121
|
+
flags_object.definition_order = definition_order
|
122
|
+
[flags_object, errors]
|
123
|
+
end
|
124
|
+
|
125
|
+
# Takes something like app.field[] and returns -> field.
|
126
|
+
# @return String
|
127
|
+
def self.extract_field_name(field)
|
128
|
+
field.gsub(/\A(#{Blufin::YmlSchemaValidator::VALID_SCHEMAS_REGEX})\./, '').gsub(/(\[\]|\[link\])\z/, '')
|
129
|
+
end
|
130
|
+
|
131
|
+
# Extracts 13, 2 from DECIMAL(13,2)
|
132
|
+
# @return List
|
133
|
+
def self.decimal_extract_values(type)
|
134
|
+
decimal_amount = Blufin::Strings::extract_using_regex(type, /\(\d{1,2},\d{1,2}\)\z/, %w{( )})
|
135
|
+
decimal_amount = decimal_amount.split(',')
|
136
|
+
[decimal_amount[0].to_i, decimal_amount[1].to_i]
|
137
|
+
end
|
138
|
+
|
139
|
+
# Extracts 45 from VARCHAR(45)
|
140
|
+
# @return List
|
141
|
+
def self.varchar_extract_max_length(type)
|
142
|
+
Blufin::Strings::extract_using_regex(type, /\(\d{1,3}\)\z/, %w{( )})
|
143
|
+
end
|
144
|
+
|
145
|
+
# Removes formatting (such as asterisks '*') from description strings.
|
146
|
+
# @return String
|
147
|
+
def self.description_without_formatting(description)
|
148
|
+
description.gsub(/\s\*/, ' ').gsub(/\*\s/, ' ')
|
149
|
+
end
|
150
|
+
|
151
|
+
# Determines what a 'LINK' table should be named,
|
152
|
+
# @return String
|
153
|
+
def self.get_link_table_name(source_table, column_name)
|
154
|
+
column = column_name.dup.gsub("[#{Blufin::YmlSchemaValidator::LINK}]", '')
|
155
|
+
raise RuntimeError, "Expected clean column name without brackets, instead got:#{column}" unless column[-1, 1] =~ /[a-z]/i
|
156
|
+
target_table = column.split('.')[1]
|
157
|
+
"#{source_table}_to_#{target_table}_link"
|
158
|
+
end
|
159
|
+
|
160
|
+
# Return TRUE if value is nil, false or empty string.
|
161
|
+
# @return boolean
|
162
|
+
def self.is_empty(value)
|
163
|
+
value.nil? || value == false || value == ''
|
164
|
+
end
|
165
|
+
|
166
|
+
# Converts /Users/Albert/Repos/repos-blufin/[site-name]/yml/worker/amazon.yml -> amazon.yml
|
167
|
+
# @return String
|
168
|
+
def self.convert_filename_to_name(file)
|
169
|
+
file_split = file.split('/')
|
170
|
+
file_split[file_split.length - 1].gsub(/\.yml\z/, '')
|
171
|
+
end
|
172
|
+
|
173
|
+
# Converts Regex to string, IE: =(?-mix:\A[A-Z_]+\z) -> \A[A-Z_]+\z
|
174
|
+
def self.convert_regex_to_string(regex)
|
175
|
+
raise RuntimeError, "Expected Regex, instead got:#{regex.class}" unless regex.nil? || regex.is_a?(Regexp)
|
176
|
+
regex_string = regex.to_s
|
177
|
+
regex_string.gsub(/\A\(\?-mix:/, '').gsub(/\)\z/, '')
|
178
|
+
end
|
179
|
+
|
180
|
+
# Extracts "reference" from "/{reference}.jpg"
|
181
|
+
# @return String
|
182
|
+
def self.extract_jersey_path_reference(value)
|
183
|
+
value.gsub(/\A(.)*\{/, '').gsub(/\}(.)*\z/, '')
|
184
|
+
end
|
185
|
+
|
186
|
+
# Darkens the path and highlights the filename.
|
187
|
+
# @return String
|
188
|
+
def self.colorize_path_and_file(file, site_path)
|
189
|
+
file_split = split_to_path_file(file, site_path)
|
190
|
+
"\x1B[38;5;240m#{file_split[0].gsub(/\/\z/, '')} → \x1B[38;5;140m#{file_split[1]}"
|
191
|
+
end
|
192
|
+
|
193
|
+
# Shortens filenames by removing @site_path.
|
194
|
+
# @return String
|
195
|
+
def self.remove_site_path(path_and_file, site_path)
|
196
|
+
raise RuntimeError, "Expected String, instead got:#{path_and_file.class}" unless path_and_file.is_a?(String)
|
197
|
+
raise RuntimeError, "Expected String, instead got:#{site_path.class}" unless site_path.is_a?(String)
|
198
|
+
sp = site_path.dup
|
199
|
+
sp[0] = ''
|
200
|
+
path_and_file = path_and_file.gsub(/\A\//, '')
|
201
|
+
path_and_file.gsub("#{sp}/", '')
|
202
|
+
end
|
203
|
+
|
204
|
+
# Splits the path & filename.
|
205
|
+
# @return Array
|
206
|
+
def self.split_to_path_file(path_and_file, site_path)
|
207
|
+
raise RuntimeError, "Expected String, instead got:#{path_and_file.class}" unless path_and_file.is_a?(String)
|
208
|
+
raise RuntimeError, "Expected String, instead got:#{site_path.class}" unless site_path.is_a?(String)
|
209
|
+
sp = site_path.dup
|
210
|
+
sp[0] = ''
|
211
|
+
path = ''
|
212
|
+
file = ''
|
213
|
+
file_parts = path_and_file.strip.gsub(/\A\//, '').split('/')
|
214
|
+
file_parts.each_with_index do |part, idx|
|
215
|
+
if idx < file_parts.length - 1
|
216
|
+
path << "#{part}/"
|
217
|
+
else
|
218
|
+
file << part
|
219
|
+
end
|
220
|
+
end
|
221
|
+
[path.gsub("#{sp}/", '').gsub(/\/\z/, ''), file]
|
222
|
+
end
|
223
|
+
|
224
|
+
# Checks that a directory structure (YML directory) matches a certain criteria.
|
225
|
+
# Returns FALSE if fails, TRUE if success
|
226
|
+
# @return boolean
|
227
|
+
def self.validate_directory_structure(site_path, path, files_expected, files_optional, error_handler)
|
228
|
+
raise RuntimeError, "Expected String, instead got:#{path.class}" unless path.is_a?(String)
|
229
|
+
raise RuntimeError, "Expected Array, instead got:#{files_expected.class}" unless files_expected.is_a?(Array)
|
230
|
+
raise RuntimeError, "Expected Array, instead got:#{files_optional.class}" unless files_optional.is_a?(Array)
|
231
|
+
raise RuntimeError, "Expected YmlErrorHandler, instead got:#{error_handler.class}" unless error_handler.is_a?(Blufin::YmlErrorHandler)
|
232
|
+
path = "#{site_path}/#{path}"
|
233
|
+
current_errors = error_handler.get_error_count
|
234
|
+
files_expected = files_expected.map { |value| "#{path}/#{value}" }
|
235
|
+
files_optional = files_optional.map { |value| "#{path}/#{value}" }
|
236
|
+
files_present = []
|
237
|
+
Blufin::Files::get_files_in_dir(path).each do |file|
|
238
|
+
error_handler.add_error(Blufin::YmlErrorHandler::FILE_NOT_EXPECTED, file, nil, nil, remove_site_path(file, site_path)) unless files_expected.include?(file) || files_optional.include?(file)
|
239
|
+
files_present << file
|
240
|
+
end
|
241
|
+
files_expected.each do |file|
|
242
|
+
error_handler.add_error(Blufin::YmlErrorHandler::FILE_NOT_FOUND, file, nil, nil, remove_site_path(file, site_path)) unless files_present.include?(file)
|
243
|
+
end
|
244
|
+
current_errors == error_handler.get_error_count
|
245
|
+
end
|
246
|
+
|
247
|
+
# Checks that a file exists (and if not, creates it) and validates that it matches a basic template.
|
248
|
+
# @return void
|
249
|
+
def self.validate_file_and_contents(site, file, contents = [], contents_ignore = [], error_handler = nil, add_to_git = true)
|
250
|
+
raise RuntimeError, "Expected String, instead got:#{file.class}" unless file.is_a?(String)
|
251
|
+
raise RuntimeError, "Expected Array, instead got:#{contents.class}" unless contents.is_a?(Array)
|
252
|
+
raise RuntimeError, "Expected Array, instead got:#{contents_ignore.class}" unless contents_ignore.is_a?(Array)
|
253
|
+
raise RuntimeError, "Expected YmlErrorHandler (or nil), instead got:#{error_handler.class}" unless error_handler.is_a?(Blufin::YmlErrorHandler) || error_handler.nil?
|
254
|
+
site = Blufin::SiteResolver::validate_site(site)
|
255
|
+
site_path = Blufin::SiteResolver::get_site_location(site)
|
256
|
+
site_name = Blufin::SiteResolver::get_site_name(site)
|
257
|
+
if Blufin::Files::file_exists(file)
|
258
|
+
lines_expected = []
|
259
|
+
contents.each do |line|
|
260
|
+
unless contents_ignore.include?(line)
|
261
|
+
unless line =~ /\Aimport\s/
|
262
|
+
lines_expected << line unless line.strip == ''
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|
266
|
+
contents = Blufin::Files::read_file(file)
|
267
|
+
contents.each do |line|
|
268
|
+
line = line.gsub("\n", '')
|
269
|
+
lines_expected.delete(line) if lines_expected.include?(line)
|
270
|
+
end
|
271
|
+
if lines_expected.length > 0 && !error_handler.nil?
|
272
|
+
lines_expected.map! { |line| "\x1B[38;5;154m#{line}" }
|
273
|
+
file = Blufin::YmlCommon::remove_site_path(file, site_path)
|
274
|
+
file = file.gsub(/(#{Blufin::Site::REGEX_APP_DIRS})\/#{site_name}-(#{Blufin::SiteServices::REGEX_JAVA})\/src\/main\/java\//, '')
|
275
|
+
error_output = ["File: \x1B[38;5;196m#{file}\x1B[0m", 'Line(s) expected but not found:']
|
276
|
+
error_output = error_output + lines_expected + [nil]
|
277
|
+
error_handler.add_error(Blufin::YmlErrorHandler::FILE_CONTENT_MISMATCH, nil, nil, nil, error_output)
|
278
|
+
end
|
279
|
+
else
|
280
|
+
if file =~ /\.java$/
|
281
|
+
Blufin::Files::write_file_java(file, contents, Blufin::Files::JAVA_AUTO_GENERATED_ONCE)
|
282
|
+
else
|
283
|
+
Blufin::Files::write_file(file, contents)
|
284
|
+
end
|
285
|
+
Blufin::Terminal::command("git add #{file}", site_path, false, false) if add_to_git
|
286
|
+
Blufin::Terminal::output(colorize_path_and_file(file, site_path), Blufin::Terminal::MSG_GENERATED)
|
287
|
+
end
|
288
|
+
|
289
|
+
end
|
290
|
+
|
291
|
+
# Converts an Array of lines to a string (for easier gsub replacement).
|
292
|
+
# @return String
|
293
|
+
def self.convert_line_array_to_string(array_of_lines)
|
294
|
+
raise RuntimeError, "Expected Array of lines, instead got: #{array_of_lines.class}" unless array_of_lines.is_a?(Array)
|
295
|
+
string = ''
|
296
|
+
array_of_lines.each_with_index do |line, idx|
|
297
|
+
newline_or_not = (idx == (array_of_lines.length - 1)) ? '' : "\n"
|
298
|
+
string += "#{line}#{newline_or_not}"
|
299
|
+
end
|
300
|
+
string
|
301
|
+
end
|
302
|
+
|
303
|
+
# Converts a string to an Array of lines to a string.
|
304
|
+
# @return String
|
305
|
+
def self.convert_string_to_line_array(string)
|
306
|
+
raise RuntimeError, "Expected String, instead got: #{string.class}" unless string.is_a?(String)
|
307
|
+
array_of_lines = []
|
308
|
+
string.split("\n").each { |line| array_of_lines << line.gsub("\n", '') }
|
309
|
+
array_of_lines
|
310
|
+
end
|
311
|
+
|
312
|
+
# Content Hash is and Hash of Arrays where the inner Array consists of:
|
313
|
+
#
|
314
|
+
# Key = Snake Cased String (such as: amazon, ebay, magento, etc).
|
315
|
+
# Value[0] = Contents -> for Blufin::YmlCommon::validate_file_and_contents()
|
316
|
+
# Value[1] = Contents to Ignore -> for Blufin::YmlCommon::validate_file_and_contents()
|
317
|
+
#
|
318
|
+
# Path parameter is where the root of where the directories will be, so if message handlers (for example) live at the following location:
|
319
|
+
# ../app-infrastructure/{site-name}-worker/src/main/java/io/{site-name}/worker/messages/amazon/AmazonMessageHandler.java
|
320
|
+
#
|
321
|
+
# Then path would be:
|
322
|
+
# ../app-infrastructure/{site-name}-worker/src/main/java/io/{site-name}/worker/messages
|
323
|
+
#
|
324
|
+
# @return void
|
325
|
+
def self.create_boilerplate_files(content_hash, path, site, error_handler, default_nested_paths = %w(data logic))
|
326
|
+
|
327
|
+
raise RuntimeError, "Expected Hash, instead got: #{content_hash.class}" unless content_hash.is_a?(Hash)
|
328
|
+
raise RuntimeError, "Expected String, instead got: #{path.class}" unless path.is_a?(String)
|
329
|
+
raise RuntimeError, "Expected YmlErrorHandler (or nil), instead got:#{error_handler.class}" unless error_handler.is_a?(Blufin::YmlErrorHandler) || error_handler.nil?
|
330
|
+
raise RuntimeError, "Expected Array, instead got: #{default_nested_paths.class}" unless default_nested_paths.is_a?(Array)
|
331
|
+
|
332
|
+
site = Blufin::SiteResolver::validate_site(site)
|
333
|
+
site_path = Blufin::SiteResolver::get_site_location(site)
|
334
|
+
|
335
|
+
path = path.gsub(/\/\z/, '')
|
336
|
+
path_last = path.split('/')
|
337
|
+
path_last = path_last[path_last.length - 1]
|
338
|
+
|
339
|
+
expected_paths = []
|
340
|
+
|
341
|
+
content_hash.each do |key, ca|
|
342
|
+
|
343
|
+
key_camel_cased_lower = Blufin::Strings::snake_case_to_camel_case_lower(key)
|
344
|
+
|
345
|
+
contents = ca[0]
|
346
|
+
contents_ignore = ca[1]
|
347
|
+
path_inner = "#{path}/#{key_camel_cased_lower}"
|
348
|
+
file = "#{path_inner}/#{ca[2]}"
|
349
|
+
|
350
|
+
raise RuntimeError, "Expected String, instead got: #{contents.class}" unless contents.is_a?(String)
|
351
|
+
raise RuntimeError, "Expected Array, instead got: #{contents_ignore.class}" unless contents_ignore.is_a?(Array)
|
352
|
+
|
353
|
+
expected_paths << path_inner
|
354
|
+
|
355
|
+
Blufin::YmlCommon::validate_file_and_contents(site, file, Blufin::YmlCommon::convert_string_to_line_array(contents), contents_ignore, error_handler)
|
356
|
+
|
357
|
+
# Check for Rogue files (inner).
|
358
|
+
existing_files = []
|
359
|
+
Blufin::Files::get_files_in_dir(path_inner).each do |existing_file|
|
360
|
+
begin
|
361
|
+
existing_file_parts = existing_file.split("#{path_last}/#{key_camel_cased_lower}/")
|
362
|
+
existing_file_parts = existing_file_parts[1].split('/')
|
363
|
+
next unless existing_file_parts.length == 1
|
364
|
+
existing_files << existing_file
|
365
|
+
rescue
|
366
|
+
next
|
367
|
+
end
|
368
|
+
end
|
369
|
+
existing_files.each do |existing_file|
|
370
|
+
unless existing_file == file
|
371
|
+
error_handler.add_error(Blufin::YmlErrorHandler::FILE_NOT_EXPECTED, nil, nil, nil, Blufin::YmlCommon::remove_site_path(existing_file, site_path))
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
# Check for Rogue directories (inner) -- and create default_nested paths (if not exist).
|
376
|
+
existing_directories = Blufin::Files::get_dirs_in_dir(path_inner)
|
377
|
+
existing_directories.each do |existing_directory|
|
378
|
+
default_nested_paths_found = false
|
379
|
+
default_nested_paths.each { |default_nested_path| default_nested_paths_found = true if existing_directory == "#{path_inner}/#{default_nested_path}" }
|
380
|
+
error_handler.add_error(Blufin::YmlErrorHandler::DIRECTORY_NOT_EXPECTED, nil, nil, nil, Blufin::YmlCommon::remove_site_path(existing_directory, site_path)) unless default_nested_paths_found
|
381
|
+
end
|
382
|
+
|
383
|
+
# Create "default_nested_path" if no exists.
|
384
|
+
default_nested_paths.each { |default_nested_path| Blufin::Files::create_directory("#{path_inner}/#{default_nested_path}") unless Blufin::Files::path_exists("#{path_inner}/#{default_nested_path}") }
|
385
|
+
end
|
386
|
+
|
387
|
+
# Check for Rogue directories.
|
388
|
+
existing_directories = Blufin::Files::get_dirs_in_dir(path)
|
389
|
+
existing_directories.each do |existing_directory|
|
390
|
+
unless expected_paths.include?(existing_directory)
|
391
|
+
error_handler.add_error(Blufin::YmlErrorHandler::DIRECTORY_NOT_EXPECTED, nil, nil, nil, Blufin::YmlCommon::remove_site_path(existing_directory, site_path))
|
392
|
+
end
|
393
|
+
end
|
394
|
+
|
395
|
+
# Check for Missing directories (in theory this will never be reached as it's created above).
|
396
|
+
expected_paths.each do |expected_path|
|
397
|
+
unless existing_directories.include?(expected_path)
|
398
|
+
error_handler.add_error(Blufin::YmlErrorHandler::DIRECTORY_NOT_FOUND, nil, nil, nil, Blufin::YmlCommon::remove_site_path(expected_path, site_path))
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
# Returns TRUE if resource has specified HTTP method, FALSE otherwise.
|
405
|
+
# @return Boolean
|
406
|
+
def self.has_http_method(http_method_name, resource_data, internal_or_oauth)
|
407
|
+
raise RuntimeError, "Expected 'http_method_name' to be [#{Blufin::YmlConfigValidator::VALID_METHODS}], instead got: #{http_method_name}" unless Blufin::YmlConfigValidator::VALID_METHODS.include?(http_method_name)
|
408
|
+
raise RuntimeError, "Expected 'internal' or 'oauth', instead got: #{internal_or_oauth}" unless [Blufin::YmlSchemaValidator::CONFIG_INTERNAL, Blufin::YmlSchemaValidator::CONFIG_OAUTH].include?(internal_or_oauth)
|
409
|
+
raise RuntimeError, "Expected Hash, instead got: #{resource_data.class}" unless resource_data.is_a?(Hash)
|
410
|
+
methods_key = (internal_or_oauth == Blufin::YmlSchemaValidator::CONFIG_INTERNAL) ? :methods_internal : :methods_oauth
|
411
|
+
if resource_data.has_key?(methods_key)
|
412
|
+
resource_data[methods_key].keys.each do |http_method|
|
413
|
+
return true if http_method_name.downcase == http_method.downcase
|
414
|
+
end
|
415
|
+
end
|
416
|
+
false
|
417
|
+
end
|
418
|
+
|
419
|
+
# Returns TRUE if resource has at least one HTTP method, FALSE otherwise.
|
420
|
+
# @return Boolean
|
421
|
+
def self.has_at_least_one_http_method(resource_data, internal_or_oauth)
|
422
|
+
raise RuntimeError, "Expected 'internal' or 'oauth', instead got: #{internal_or_oauth}" unless [Blufin::YmlSchemaValidator::CONFIG_INTERNAL, Blufin::YmlSchemaValidator::CONFIG_OAUTH].include?(internal_or_oauth)
|
423
|
+
raise RuntimeError, "Expected Hash, instead got: #{resource_data.class}" unless resource_data.is_a?(Hash)
|
424
|
+
methods_key = (internal_or_oauth == Blufin::YmlSchemaValidator::CONFIG_INTERNAL) ? :methods_internal : :methods_oauth
|
425
|
+
if resource_data.has_key?(methods_key)
|
426
|
+
resource_data[methods_key].keys.each do |http_method|
|
427
|
+
if [
|
428
|
+
Blufin::YmlConfigValidator::GET,
|
429
|
+
Blufin::YmlConfigValidator::POST,
|
430
|
+
Blufin::YmlConfigValidator::PATCH,
|
431
|
+
Blufin::YmlConfigValidator::DELETE
|
432
|
+
].include?(http_method)
|
433
|
+
return true
|
434
|
+
else
|
435
|
+
raise RuntimeError, "Un-handled HTTP method: #{http_method}"
|
436
|
+
end
|
437
|
+
end
|
438
|
+
end
|
439
|
+
false
|
440
|
+
end
|
441
|
+
|
442
|
+
# Extracts the <groupID>, <artifactId> & <version> from -> [{"group-id"=>"com.zaxxer"}, {"artifact-id"=>"HikariCP"}, {"version"=>"3.2.0-BLUFIN"}]
|
443
|
+
# @return Hash
|
444
|
+
def self.extract_group_artifact_version_from_array(array)
|
445
|
+
raise RuntimeError, "Expected Array, instead got: #{array.class}" unless array.is_a?(Array)
|
446
|
+
obj = {}
|
447
|
+
array.each do |fragment|
|
448
|
+
raise RuntimeError, "Expected Hash, instead got: #{fragment.class}" unless fragment.is_a?(Hash)
|
449
|
+
obj[Blufin::YmlMavenValidator::DEPENDENCIES_GROUP_ID] = fragment[Blufin::YmlMavenValidator::DEPENDENCIES_GROUP_ID] if fragment.has_key?(Blufin::YmlMavenValidator::DEPENDENCIES_GROUP_ID)
|
450
|
+
obj[Blufin::YmlMavenValidator::DEPENDENCIES_ARTIFACT_ID] = fragment[Blufin::YmlMavenValidator::DEPENDENCIES_ARTIFACT_ID] if fragment.has_key?(Blufin::YmlMavenValidator::DEPENDENCIES_ARTIFACT_ID)
|
451
|
+
obj[Blufin::YmlMavenValidator::DEPENDENCIES_VERSION] = fragment[Blufin::YmlMavenValidator::DEPENDENCIES_VERSION] if fragment.has_key?(Blufin::YmlMavenValidator::DEPENDENCIES_VERSION)
|
452
|
+
end
|
453
|
+
obj
|
454
|
+
end
|
455
|
+
|
456
|
+
# Extracts OBJECT, OBJECT_LIST or nil from @schema_data Hash.
|
457
|
+
# @return String
|
458
|
+
def self.extract_child_type_from_schema_data(schema_data, schema, table)
|
459
|
+
ct = extract_child_type_from_schema_data_for_java(schema_data, schema, table)
|
460
|
+
ct.nil? ? nil : ct.split('.')[1]
|
461
|
+
end
|
462
|
+
|
463
|
+
# Extracts DataType.OBJECT, DataType.OBJECT_LIST or nil from @schema_data Hash.
|
464
|
+
# @return String
|
465
|
+
def self.extract_child_type_from_schema_data_for_java(schema_data, schema, table)
|
466
|
+
schema_data[schema][table].each do |column_name, column_data|
|
467
|
+
if column_data.has_key?(Blufin::YmlSchemaValidator::CHILD_TYPE)
|
468
|
+
return column_data[Blufin::YmlSchemaValidator::CHILD_TYPE]
|
469
|
+
end
|
470
|
+
end
|
471
|
+
nil
|
472
|
+
end
|
473
|
+
|
474
|
+
private
|
475
|
+
|
476
|
+
# Returns a cached instance of the ENUM scanner.
|
477
|
+
# @return Object
|
478
|
+
def self.get_enum_scanner(site)
|
479
|
+
if @@enum_scanner.nil?
|
480
|
+
@@enum_scanner = Blufin::ScannerJavaEnums.new(site)
|
481
|
+
end
|
482
|
+
@@enum_scanner
|
483
|
+
end
|
484
|
+
|
485
|
+
end
|
486
|
+
|
487
|
+
end
|