solara 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/solara/lib/core/.DS_Store +0 -0
- data/solara/lib/core/aliases/alias_generator.rb +1 -0
- data/solara/lib/core/aliases/alias_generator_manager.rb +2 -1
- data/solara/lib/core/aliases/solara_terminal_setup.rb +1 -1
- data/solara/lib/core/brands/brand_font_switcher.rb +154 -0
- data/solara/lib/core/brands/brand_onboarder.rb +8 -6
- data/solara/lib/core/brands/brand_switcher.rb +232 -166
- data/solara/lib/core/brands/brands_manager.rb +15 -39
- data/solara/lib/core/dashboard/brand/BrandDetail.js +19 -0
- data/solara/lib/core/dashboard/brand/BrandDetailController.js +50 -8
- data/solara/lib/core/dashboard/brand/BrandDetailModel.js +9 -30
- data/solara/lib/core/dashboard/brand/BrandDetailView.js +49 -3
- data/solara/lib/core/dashboard/brand/InfoPlistStringCatalogManager.js +19 -0
- data/solara/lib/core/dashboard/brand/brand.html +209 -62
- data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +1 -1
- data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +38 -53
- data/solara/lib/core/dashboard/brands/BrandsController.js +6 -5
- data/solara/lib/core/dashboard/brands/BrandsModel.js +2 -2
- data/solara/lib/core/dashboard/brands/BrandsView.js +2 -2
- data/solara/lib/core/dashboard/brands/brands.html +3 -1
- data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +7 -5
- data/solara/lib/core/dashboard/dashboard_manager.rb +2 -0
- data/solara/lib/core/dashboard/dashboard_server.rb +1 -3
- data/solara/lib/core/dashboard/handler/brand_alisases_handler.rb +4 -11
- data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +11 -11
- data/solara/lib/core/dashboard/handler/{brand_configurations_handler.rb → brand_details_handler.rb} +4 -4
- data/solara/lib/core/dashboard/handler/brands_handler.rb +1 -1
- data/solara/lib/core/dashboard/handler/edit_section_handler.rb +8 -8
- data/solara/lib/core/doctor/brand_doctor.rb +31 -31
- data/solara/lib/core/doctor/doctor_manager.rb +0 -1
- data/solara/lib/core/doctor/project_doctor.rb +0 -1
- data/solara/lib/core/doctor/schema/platform/android/android_config.json +0 -4
- data/solara/lib/core/doctor/schema/platform/ios/InfoPlist.xcstrings +15 -0
- data/solara/lib/core/doctor/schema/platform/ios/ios_config.json +0 -5
- data/solara/lib/core/doctor/schema/platform/shared/brand_config.json +9 -0
- data/solara/lib/core/doctor/schema/platform/shared/theme.json +94 -9
- data/solara/lib/core/doctor/validator/brand_settings_validator.rb +6 -0
- data/solara/lib/core/doctor/validator/brand_settings_validator_manager.rb +9 -21
- data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +22 -4
- data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +22 -6
- data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +22 -4
- data/solara/lib/core/scripts/brand_config_generator.rb +1 -0
- data/solara/lib/core/scripts/brand_config_manager.rb +2 -4
- data/solara/lib/core/scripts/brand_exporter.rb +1 -1
- data/solara/lib/core/scripts/brand_importer.rb +2 -3
- data/solara/lib/core/scripts/brand_offboarder.rb +5 -0
- data/solara/lib/core/scripts/brand_resources_manager.rb +127 -54
- data/solara/lib/core/scripts/directory_creator.rb +2 -2
- data/solara/lib/core/scripts/file_manager.rb +53 -19
- data/solara/lib/core/scripts/file_path.rb +175 -30
- data/solara/lib/core/scripts/folder_copier.rb +3 -7
- data/solara/lib/core/scripts/gitignore_manager.rb +21 -10
- data/solara/lib/core/scripts/interactive_file_system_validator.rb +8 -2
- data/solara/lib/core/scripts/platform/android/android_manifest_switcher.rb +3 -3
- data/solara/lib/core/scripts/platform/android/android_strings_switcher.rb +26 -24
- data/solara/lib/core/scripts/platform/android/gradle_switcher.rb +7 -6
- data/solara/lib/core/scripts/platform/ios/infoplist_string_catalog_manager.rb +123 -0
- data/solara/lib/core/scripts/platform/ios/infoplist_switcher.rb +59 -0
- data/solara/lib/core/scripts/platform/ios/ios_plist_manager.rb +11 -20
- data/solara/lib/core/scripts/platform/ios/plist_font_manager.rb +33 -0
- data/solara/lib/core/scripts/platform/ios/xcconfig_generator.rb +15 -3
- data/solara/lib/core/scripts/platform/ios/xcode_asset_manager.rb +2 -3
- data/solara/lib/core/scripts/platform/ios/xcode_project_manager.rb +80 -1
- data/solara/lib/core/scripts/platform/ios/xcode_project_switcher.rb +15 -34
- data/solara/lib/core/scripts/solara_logger.rb +10 -0
- data/solara/lib/core/scripts/solara_settings_manager.rb +26 -1
- data/solara/lib/core/scripts/strings_xml_manager.rb +17 -2
- data/solara/lib/core/scripts/theme_generator.rb +133 -130
- data/solara/lib/core/scripts/yaml_manager.rb +23 -0
- data/solara/lib/core/solara_configurator.rb +1 -1
- data/solara/lib/core/template/brands/android/android_config.json +0 -1
- data/solara/lib/core/template/brands/android/res/values/strings.xml +4 -0
- data/solara/lib/core/template/brands/ios/InfoPlist.xcstrings +30 -0
- data/solara/lib/core/template/brands/ios/ios_config.json +1 -2
- data/solara/lib/core/template/brands/shared/brand_config.json +1 -0
- data/solara/lib/core/template/brands/shared/theme.json +3 -3
- data/solara/lib/core/template/config/android_template_config.json +11 -1
- data/solara/lib/core/template/config/flutter_template_config.json +12 -2
- data/solara/lib/core/template/config/ios_template_config.json +11 -1
- data/solara/lib/core/template/project_template_generator.rb +8 -3
- data/solara/lib/solara/version.rb +1 -1
- data/solara/lib/solara.rb +8 -4
- data/solara/lib/solara_initializer.rb +5 -2
- data/solara/lib/solara_manager.rb +1 -1
- metadata +62 -43
- data/solara/lib/core/dashboard/handler/brand_section_handler.rb +0 -20
- data/solara/lib/core/doctor/validator/directory_structure_validator.rb +0 -38
- data/solara/lib/core/doctor/validator/file_structure_validator.rb +0 -37
- data/solara/lib/core/scripts/platform/ios/ios_file_path_manager.rb +0 -109
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/.DS_Store +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/100.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/102.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/1024.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/114.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/120.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/128.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/144.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/152.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/16.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/167.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/172.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/180.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/196.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/20.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/216.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/256.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/29.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/32.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/40.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/48.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/50.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/512.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/55.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/57.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/58.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/60.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/64.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/66.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/72.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/76.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/80.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/87.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/88.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/92.png +0 -0
- /data/solara/lib/core/template/brands/ios/{assets → xcassets}/AppIcon.appiconset/Contents.json +0 -0
@@ -90,26 +90,28 @@ class AliasesBottomSheet extends HTMLElement {
|
|
90
90
|
this.overlay.onclick = () => this.hide();
|
91
91
|
}
|
92
92
|
|
93
|
-
show(aliases,
|
93
|
+
show(aliases, brandKey) {
|
94
94
|
const commonAliasesList = this.shadowRoot.getElementById('commonAliasesList');
|
95
95
|
const brandAliasesList = this.shadowRoot.getElementById('brandAliasesList');
|
96
96
|
|
97
97
|
commonAliasesList.innerHTML = '';
|
98
98
|
brandAliasesList.innerHTML = '';
|
99
99
|
|
100
|
+
const pattern = /alias|='[^']*'/g;
|
101
|
+
|
100
102
|
aliases.aliases.common_aliases.forEach(alias => {
|
101
103
|
const li = document.createElement('li');
|
102
|
-
li.textContent = alias;
|
104
|
+
li.textContent = alias.replace(pattern, '').trim();
|
103
105
|
commonAliasesList.appendChild(li);
|
104
106
|
});
|
105
107
|
|
106
|
-
const brandAliases = aliases.aliases.brand_aliases[
|
108
|
+
const brandAliases = aliases.aliases.brand_aliases[brandKey] || [];
|
109
|
+
|
107
110
|
brandAliases.forEach(alias => {
|
108
111
|
const li = document.createElement('li');
|
109
|
-
li.textContent = alias;
|
112
|
+
li.textContent = alias.replace(pattern, '').trim();
|
110
113
|
brandAliasesList.appendChild(li);
|
111
114
|
});
|
112
|
-
|
113
115
|
this.aliasesBottomSheet.style.display = 'block';
|
114
116
|
this.overlay.style.display = 'block';
|
115
117
|
|
@@ -1,6 +1,8 @@
|
|
1
1
|
class DashboardManager
|
2
2
|
|
3
3
|
def start(brand_key = nil, port = 8000)
|
4
|
+
return if SolaraEnvironment.is_test
|
5
|
+
|
4
6
|
Solara.logger.header("Solara Dashboard #{brand_key.nil? || brand_key.empty? ? "" : "for #{brand_key}"}")
|
5
7
|
if brand_key.nil? || brand_key.empty?
|
6
8
|
open("brands/brands.html?source=local", port)
|
@@ -1,5 +1,4 @@
|
|
1
1
|
Dir[File.expand_path('handler/*.rb', __dir__)].each { |file| require_relative file }
|
2
|
-
Dir[File.expand_path('../.solara/core/brands/*.rb')].each { |file| require_relative file }
|
3
2
|
Dir[File.expand_path('platform/android/*.rb', __dir__)].each { |file| require_relative file }
|
4
3
|
Dir[File.expand_path('scripts/*.rb', __dir__)].each { |file| require_relative file }
|
5
4
|
|
@@ -65,10 +64,9 @@ class DashboardServer
|
|
65
64
|
return if @router.nil?
|
66
65
|
|
67
66
|
@router.register_handler(RedirectHandler)
|
68
|
-
@router.register_handler(BrandSectionHandler)
|
69
67
|
@router.register_handler(SwitchToBrandHandler)
|
70
68
|
@router.register_handler(CurrentBrandHandler)
|
71
|
-
@router.register_handler(
|
69
|
+
@router.register_handler(BrandDetailsHandler)
|
72
70
|
@router.register_handler(BrandsHandler)
|
73
71
|
@router.register_handler(EditSectionHandler)
|
74
72
|
@router.register_handler(OnboardBrandHandler)
|
@@ -3,17 +3,10 @@ class BrandAliasesHandler < BaseHandler
|
|
3
3
|
@server.mount_proc('/brand/aliases') do |req, res|
|
4
4
|
if req.request_method == 'GET'
|
5
5
|
begin
|
6
|
-
|
7
|
-
|
6
|
+
aliases = get_brand_aliases
|
7
|
+
res.status = 200
|
8
|
+
res.body = JSON.generate({ success: true, aliases: aliases })
|
8
9
|
|
9
|
-
if brand_key
|
10
|
-
aliases = get_brand_aliases(brand_key)
|
11
|
-
res.status = 200
|
12
|
-
res.body = JSON.generate({ success: true, aliases: aliases })
|
13
|
-
else
|
14
|
-
res.status = 400
|
15
|
-
res.body = JSON.generate({ success: false, error: 'Missing brand_key parameter' })
|
16
|
-
end
|
17
10
|
rescue StandardError => e
|
18
11
|
handle_error(res, e, "Error fetching brand aliases")
|
19
12
|
end
|
@@ -24,7 +17,7 @@ class BrandAliasesHandler < BaseHandler
|
|
24
17
|
end
|
25
18
|
end
|
26
19
|
|
27
|
-
def get_brand_aliases
|
20
|
+
def get_brand_aliases
|
28
21
|
AliasGeneratorManager.aliases_json
|
29
22
|
rescue StandardError => e
|
30
23
|
Solara.logger.failure("Error getting brand aliases: #{e.message}")
|
@@ -11,37 +11,37 @@ class BrandConfigurationsManager
|
|
11
11
|
def templates
|
12
12
|
[
|
13
13
|
{
|
14
|
-
key: '
|
15
|
-
name: 'Theme Configuration',
|
16
|
-
input_type: 'color',
|
17
|
-
path: FilePath.brand_theme(@brand_key)
|
18
|
-
},
|
19
|
-
{
|
20
|
-
key: 'brand_config',
|
14
|
+
key: 'brand_config.json',
|
21
15
|
name: 'Brand Configuration',
|
22
16
|
input_type: 'text',
|
23
17
|
path: FilePath.brand_config(@brand_key)
|
24
18
|
},
|
25
19
|
{
|
26
|
-
key: '
|
20
|
+
key: 'theme.json',
|
21
|
+
name: 'Theme Configuration',
|
22
|
+
input_type: 'color',
|
23
|
+
path: FilePath.brand_theme(@brand_key)
|
24
|
+
},
|
25
|
+
{
|
26
|
+
key: 'android_config.json',
|
27
27
|
name: 'Android Platform Configuration',
|
28
28
|
input_type: 'text',
|
29
29
|
path: FilePath.android_brand_config(@brand_key)
|
30
30
|
},
|
31
31
|
{
|
32
|
-
key: 'android_signing',
|
32
|
+
key: 'android_signing.json',
|
33
33
|
name: 'Android Signing',
|
34
34
|
input_type: 'text',
|
35
35
|
path: FilePath.brand_signing(@brand_key, Platform::Android)
|
36
36
|
},
|
37
37
|
{
|
38
|
-
key: 'ios_config',
|
38
|
+
key: 'ios_config.json',
|
39
39
|
name: 'iOS Platform Configuration',
|
40
40
|
input_type: 'text',
|
41
41
|
path: FilePath.ios_config(@brand_key)
|
42
42
|
},
|
43
43
|
{
|
44
|
-
key: 'ios_signing',
|
44
|
+
key: 'ios_signing.json',
|
45
45
|
name: 'iOS Signing',
|
46
46
|
input_type: 'text',
|
47
47
|
path: FilePath.brand_signing(@brand_key, Platform::IOS)
|
data/solara/lib/core/dashboard/handler/{brand_configurations_handler.rb → brand_details_handler.rb}
RENAMED
@@ -1,15 +1,15 @@
|
|
1
|
-
class
|
1
|
+
class BrandDetailsHandler < BaseHandler
|
2
2
|
def mount
|
3
|
-
@server.mount_proc('/
|
3
|
+
@server.mount_proc('/brand/details') do |req, res|
|
4
4
|
begin
|
5
5
|
query = CGI.parse(req.query_string)
|
6
6
|
brand_key = query['brand_key']&.first
|
7
7
|
|
8
8
|
response_data = BrandsManager.instance.brand_with_configurations(brand_key)
|
9
|
-
res.body = JSON.generate({ success: true, message: "
|
9
|
+
res.body = JSON.generate({ success: true, message: "Brand details response", result: response_data })
|
10
10
|
res['Content-Type'] = 'application/json'
|
11
11
|
rescue StandardError => e
|
12
|
-
handle_error(res, e, "Error in brand
|
12
|
+
handle_error(res, e, "Error in brand details handler")
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -31,8 +31,13 @@ class EditSectionHandler < BaseHandler
|
|
31
31
|
template = BrandConfigurationsManager.new(brand_key).template_with_key(key)
|
32
32
|
|
33
33
|
path = template[:path]
|
34
|
+
|
34
35
|
if File.exist?(path)
|
35
|
-
|
36
|
+
if key === 'InfoPlist.xcstrings'
|
37
|
+
InfoPListStringCatalogManager.new(FilePath.brand_infoplist_string_catalog(brand_key)).update(data)
|
38
|
+
else
|
39
|
+
File.write(path, JSON.pretty_generate(data))
|
40
|
+
end
|
36
41
|
Solara.logger.debug("Updated Config for #{path}: #{data}")
|
37
42
|
else
|
38
43
|
raise "Config file not found: #{path}"
|
@@ -42,14 +47,9 @@ class EditSectionHandler < BaseHandler
|
|
42
47
|
raise
|
43
48
|
end
|
44
49
|
|
45
|
-
def update_theme(path, data)
|
46
|
-
json = JSON.parse(File.read(path))
|
47
|
-
json['colors'] = data
|
48
|
-
File.write(path, JSON.pretty_generate(json))
|
49
|
-
end
|
50
|
-
|
51
50
|
def set_current_brand_content_changed(brand_key, changed)
|
52
51
|
BrandsManager.instance.set_current_brand_content_changed(brand_key, changed)
|
53
52
|
end
|
54
53
|
|
55
|
-
end
|
54
|
+
end
|
55
|
+
|
@@ -1,35 +1,6 @@
|
|
1
1
|
Dir.glob("#{__dir__}/*.rb").each { |file| require file }
|
2
|
-
Dir.glob("#{__dir__}/../../.solara/core/brands/*.rb").each { |file| require file }
|
3
2
|
Dir.glob("#{__dir__}/validator/template/*.rb").each { |file| require file }
|
4
3
|
|
5
|
-
class Issue < StandardError
|
6
|
-
ERROR = 'ERROR'
|
7
|
-
WARNING = 'WARNING'
|
8
|
-
|
9
|
-
attr_reader :type, :error
|
10
|
-
|
11
|
-
def initialize(type, error)
|
12
|
-
@type = type
|
13
|
-
@error = error
|
14
|
-
end
|
15
|
-
|
16
|
-
def to_s
|
17
|
-
"#{@type}: #{@error}"
|
18
|
-
end
|
19
|
-
|
20
|
-
def <=>(other)
|
21
|
-
[type, error] <=> [other.type, other.error]
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.error(error)
|
25
|
-
Issue.new(ERROR, error)
|
26
|
-
end
|
27
|
-
|
28
|
-
def self.warning(error)
|
29
|
-
Issue.new(WARNING, error)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
4
|
class BrandDoctor
|
34
5
|
def initialize
|
35
6
|
end
|
@@ -37,6 +8,7 @@ class BrandDoctor
|
|
37
8
|
def visit(brand_keys = [], print_logs: true)
|
38
9
|
keys = brand_keys.empty? ? BrandsManager.instance.brands_list.map { |brand| brand['key'] } : brand_keys
|
39
10
|
issues = []
|
11
|
+
has_template_errors = false
|
40
12
|
|
41
13
|
keys.each do |brand_key|
|
42
14
|
validator = TemplateValidator.new(FilePath.brand(brand_key), FilePath.template_validation_config)
|
@@ -45,15 +17,16 @@ class BrandDoctor
|
|
45
17
|
errors.each { |error|
|
46
18
|
issues << Issue.error(error)
|
47
19
|
}
|
20
|
+
has_template_errors = true unless issues.select { |issue| issue.type == Issue::ERROR }.empty?
|
48
21
|
end
|
49
22
|
|
50
23
|
# Validate settings only if all validations so far are passed to avoid files issues
|
51
|
-
|
24
|
+
unless has_template_errors
|
52
25
|
issues += BrandSettingsValidatorManager.new.validate
|
53
26
|
end
|
54
27
|
|
55
28
|
if print_logs && !issues.empty?
|
56
|
-
Solara.logger.title("
|
29
|
+
Solara.logger.title("Health Check Result")
|
57
30
|
|
58
31
|
issues.sort!.each { |issue|
|
59
32
|
case issue.type
|
@@ -92,3 +65,30 @@ class BrandDoctor
|
|
92
65
|
end
|
93
66
|
end
|
94
67
|
|
68
|
+
class Issue < StandardError
|
69
|
+
ERROR = 'ERROR'
|
70
|
+
WARNING = 'WARNING'
|
71
|
+
|
72
|
+
attr_reader :type, :error
|
73
|
+
|
74
|
+
def initialize(type, error)
|
75
|
+
@type = type
|
76
|
+
@error = error
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_s
|
80
|
+
"#{@type}: #{@error}"
|
81
|
+
end
|
82
|
+
|
83
|
+
def <=>(other)
|
84
|
+
[type, error] <=> [other.type, other.error]
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.error(error)
|
88
|
+
Issue.new(ERROR, error)
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.warning(error)
|
92
|
+
Issue.new(WARNING, error)
|
93
|
+
end
|
94
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
Dir.glob("#{__dir__}/*.rb").each { |file| require file }
|
2
2
|
Dir.glob("#{__dir__}/validator/*.rb").each { |file| require file }
|
3
3
|
Dir.glob("#{__dir__}/brand/*.rb").each { |file| require file }
|
4
|
-
Dir.glob("#{__dir__}/../../.solara/core/brands/*.rb").each { |file| require file }
|
5
4
|
|
6
5
|
class DoctorManager
|
7
6
|
def initialize
|
@@ -1,10 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"type": "object",
|
3
3
|
"properties": {
|
4
|
-
"PRODUCT_NAME": {
|
5
|
-
"type": "string",
|
6
|
-
"description": "The name of the product."
|
7
|
-
},
|
8
4
|
"PRODUCT_BUNDLE_IDENTIFIER": {
|
9
5
|
"type": "string",
|
10
6
|
"description": "The bundle identifier of the product."
|
@@ -19,7 +15,6 @@
|
|
19
15
|
}
|
20
16
|
},
|
21
17
|
"required": [
|
22
|
-
"PRODUCT_NAME",
|
23
18
|
"PRODUCT_BUNDLE_IDENTIFIER",
|
24
19
|
"MARKETING_VERSION",
|
25
20
|
"BUNDLE_VERSION"
|
@@ -3,8 +3,7 @@
|
|
3
3
|
"properties": {
|
4
4
|
"colors": {
|
5
5
|
"type": "object",
|
6
|
-
"properties": {
|
7
|
-
},
|
6
|
+
"properties": {},
|
8
7
|
"required": []
|
9
8
|
},
|
10
9
|
"typography": {
|
@@ -13,36 +12,122 @@
|
|
13
12
|
"fontFamily": {
|
14
13
|
"type": "object",
|
15
14
|
"properties": {
|
15
|
+
"regular": {
|
16
|
+
"type": "string"
|
17
|
+
},
|
18
|
+
"medium": {
|
19
|
+
"type": "string"
|
20
|
+
},
|
21
|
+
"bold": {
|
22
|
+
"type": "string"
|
23
|
+
}
|
16
24
|
},
|
17
|
-
"required": [
|
25
|
+
"required": [
|
26
|
+
"regular",
|
27
|
+
"medium",
|
28
|
+
"bold"
|
29
|
+
]
|
18
30
|
},
|
19
31
|
"fontSize": {
|
20
32
|
"type": "object",
|
21
33
|
"properties": {
|
34
|
+
"small": {
|
35
|
+
"type": "number"
|
36
|
+
},
|
37
|
+
"medium": {
|
38
|
+
"type": "number"
|
39
|
+
},
|
40
|
+
"large": {
|
41
|
+
"type": "number"
|
42
|
+
},
|
43
|
+
"extraLarge": {
|
44
|
+
"type": "number"
|
45
|
+
}
|
22
46
|
},
|
23
|
-
"required": [
|
47
|
+
"required": [
|
48
|
+
"small",
|
49
|
+
"medium",
|
50
|
+
"large",
|
51
|
+
"extraLarge"
|
52
|
+
]
|
24
53
|
}
|
25
54
|
},
|
26
|
-
"required": [
|
55
|
+
"required": [
|
56
|
+
"fontFamily",
|
57
|
+
"fontSize"
|
58
|
+
]
|
27
59
|
},
|
28
60
|
"spacing": {
|
29
61
|
"type": "object",
|
30
62
|
"properties": {
|
63
|
+
"small": {
|
64
|
+
"type": "number"
|
65
|
+
},
|
66
|
+
"medium": {
|
67
|
+
"type": "number"
|
68
|
+
},
|
69
|
+
"large": {
|
70
|
+
"type": "number"
|
71
|
+
},
|
72
|
+
"extraLarge": {
|
73
|
+
"type": "number"
|
74
|
+
}
|
31
75
|
},
|
32
|
-
"required": [
|
76
|
+
"required": [
|
77
|
+
"small",
|
78
|
+
"medium",
|
79
|
+
"large",
|
80
|
+
"extraLarge"
|
81
|
+
]
|
33
82
|
},
|
34
83
|
"borderRadius": {
|
35
84
|
"type": "object",
|
36
85
|
"properties": {
|
86
|
+
"small": {
|
87
|
+
"type": "number"
|
88
|
+
},
|
89
|
+
"medium": {
|
90
|
+
"type": "number"
|
91
|
+
},
|
92
|
+
"large": {
|
93
|
+
"type": "number"
|
94
|
+
}
|
37
95
|
},
|
38
|
-
"required": [
|
96
|
+
"required": [
|
97
|
+
"small",
|
98
|
+
"medium",
|
99
|
+
"large"
|
100
|
+
]
|
39
101
|
},
|
40
102
|
"elevation": {
|
41
103
|
"type": "object",
|
42
104
|
"properties": {
|
105
|
+
"none": {
|
106
|
+
"type": "number"
|
107
|
+
},
|
108
|
+
"low": {
|
109
|
+
"type": "number"
|
110
|
+
},
|
111
|
+
"medium": {
|
112
|
+
"type": "number"
|
113
|
+
},
|
114
|
+
"high": {
|
115
|
+
"type": "number"
|
116
|
+
}
|
43
117
|
},
|
44
|
-
"required": [
|
118
|
+
"required": [
|
119
|
+
"none",
|
120
|
+
"low",
|
121
|
+
"medium",
|
122
|
+
"high"
|
123
|
+
]
|
45
124
|
}
|
46
125
|
},
|
47
|
-
"required": [
|
126
|
+
"required": [
|
127
|
+
"colors",
|
128
|
+
"typography",
|
129
|
+
"spacing",
|
130
|
+
"borderRadius",
|
131
|
+
"elevation"
|
132
|
+
]
|
48
133
|
}
|
@@ -25,6 +25,12 @@ class BrandSettingsValidator
|
|
25
25
|
|
26
26
|
brands.each do |brand|
|
27
27
|
brand_key = brand['key']
|
28
|
+
|
29
|
+
unless File.exist?(FilePath.brand(brand_key))
|
30
|
+
Solara.logger.fatal("#{brand_key} not found in #{FilePath.brands}")
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
28
34
|
property_value = fetch_json_property(property_name, FilePath.public_send(file_path_method, brand_key))
|
29
35
|
|
30
36
|
if property_value.to_s.strip.empty?
|
@@ -8,7 +8,8 @@ class BrandSettingsValidatorManager
|
|
8
8
|
issues = ios_config
|
9
9
|
issues += ios_signing
|
10
10
|
issues += android_config
|
11
|
-
issues
|
11
|
+
issues += android_signing
|
12
|
+
issues + brand_config
|
12
13
|
end
|
13
14
|
|
14
15
|
def ios_config
|
@@ -17,16 +18,6 @@ class BrandSettingsValidatorManager
|
|
17
18
|
:ios_config,
|
18
19
|
issue_type: Issue::ERROR)
|
19
20
|
|
20
|
-
issues += @validator.validate_single_property(
|
21
|
-
'PRODUCT_NAME',
|
22
|
-
:ios_config,
|
23
|
-
issue_type: Issue::ERROR)
|
24
|
-
|
25
|
-
issues += @validator.validate_property_duplicates(
|
26
|
-
'PRODUCT_NAME',
|
27
|
-
:ios_config,
|
28
|
-
issue_type: Issue::WARNING)
|
29
|
-
|
30
21
|
issues += @validator.validate_single_property(
|
31
22
|
'PRODUCT_BUNDLE_IDENTIFIER',
|
32
23
|
:ios_config,
|
@@ -58,16 +49,6 @@ class BrandSettingsValidatorManager
|
|
58
49
|
:android_config,
|
59
50
|
issue_type: Issue::ERROR)
|
60
51
|
|
61
|
-
issues += @validator.validate_single_property(
|
62
|
-
'brandName',
|
63
|
-
:android_config,
|
64
|
-
issue_type: Issue::ERROR)
|
65
|
-
|
66
|
-
issues += @validator.validate_property_duplicates(
|
67
|
-
'brandName',
|
68
|
-
:android_config,
|
69
|
-
issue_type: Issue::WARNING)
|
70
|
-
|
71
52
|
issues += @validator.validate_single_property(
|
72
53
|
'applicationId',
|
73
54
|
:android_config,
|
@@ -79,4 +60,11 @@ class BrandSettingsValidatorManager
|
|
79
60
|
issue_type: Issue::ERROR)
|
80
61
|
end
|
81
62
|
|
63
|
+
def brand_config
|
64
|
+
@validator.validate_single_property(
|
65
|
+
'brandName',
|
66
|
+
:brand_config,
|
67
|
+
issue_type: Issue::ERROR)
|
68
|
+
end
|
69
|
+
|
82
70
|
end
|
@@ -2,10 +2,17 @@ structure:
|
|
2
2
|
android:
|
3
3
|
type: directory
|
4
4
|
contents:
|
5
|
-
assets:
|
6
|
-
type: directory
|
7
5
|
res:
|
8
6
|
type: directory
|
7
|
+
contents:
|
8
|
+
values:
|
9
|
+
type: directory
|
10
|
+
contents:
|
11
|
+
strings.xml:
|
12
|
+
type: file
|
13
|
+
validations:
|
14
|
+
- type: content_includes
|
15
|
+
value: <string name="app_name">
|
9
16
|
android_config.json:
|
10
17
|
type: file
|
11
18
|
validations:
|
@@ -21,8 +28,6 @@ structure:
|
|
21
28
|
ios:
|
22
29
|
type: directory
|
23
30
|
contents:
|
24
|
-
assets:
|
25
|
-
type: directory
|
26
31
|
ios_config.json:
|
27
32
|
type: file
|
28
33
|
validations:
|
@@ -35,6 +40,17 @@ structure:
|
|
35
40
|
- type: valid_json
|
36
41
|
- type: json_schema
|
37
42
|
schema_path: platform/ios/ios_signing.json
|
43
|
+
InfoPlist.xcstrings:
|
44
|
+
type: file
|
45
|
+
validations:
|
46
|
+
- type: valid_json
|
47
|
+
- type: json_schema
|
48
|
+
schema_path: platform/ios/InfoPlist.xcstrings
|
49
|
+
xcassets:
|
50
|
+
type: directory
|
51
|
+
contents:
|
52
|
+
AppIcon.appiconset:
|
53
|
+
type: directory
|
38
54
|
shared:
|
39
55
|
type: directory
|
40
56
|
contents:
|
@@ -42,6 +58,8 @@ structure:
|
|
42
58
|
type: file
|
43
59
|
validations:
|
44
60
|
- type: valid_json
|
61
|
+
- type: json_schema
|
62
|
+
schema_path: platform/shared/brand_config.json
|
45
63
|
theme.json:
|
46
64
|
type: file
|
47
65
|
validations:
|