solara 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dea7da41ec79265551adc948a5586af994164b9c04ef3576b2c37b9fab2f108f
|
|
4
|
+
data.tar.gz: 31352f627b65fa267a082095bfec2346b03173a944e2c967974107c0c30f7e9b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a4623541490f240d2ffacbb682d8b9388058633af6e40d548cd998cad186f87addd4efc4675e2257d4c90102f42ce7589e3c90d400f84775d8ca25f1af201f5b
|
|
7
|
+
data.tar.gz: c5158cd2c02abd104155d482c3e59e8c7a79b4289eb4316a5c9ee7de101892b6ae1d1341c247b97a38611041add484a4abaaf9d414c4380fa7cebbf12ecbbf35
|
data/solara/lib/core/.DS_Store
CHANGED
|
Binary file
|
|
@@ -18,6 +18,7 @@ class AliasGenerator
|
|
|
18
18
|
|
|
19
19
|
def add_brand_aliases(brands)
|
|
20
20
|
alias_templates = [
|
|
21
|
+
"solara_export_{brand_key}='solara export --brand_keys {brand_key}'",
|
|
21
22
|
"solara_offboard_{brand_key}='solara offboard -k {brand_key}'",
|
|
22
23
|
"solara_switch_{brand_key}='solara switch -k {brand_key}'",
|
|
23
24
|
"solara_doctor_{brand_key}='solara doctor -k {brand_key}'",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
class AliasGeneratorManager
|
|
2
2
|
def initialize
|
|
3
|
-
@generator = AliasGenerator.new
|
|
3
|
+
@generator = AliasGenerator.new
|
|
4
4
|
end
|
|
5
5
|
|
|
6
6
|
def start
|
|
@@ -8,6 +8,7 @@ class AliasGeneratorManager
|
|
|
8
8
|
common_aliases = [
|
|
9
9
|
"solara_dashboard='solara dashboard'",
|
|
10
10
|
"solara_doctor='solara doctor'",
|
|
11
|
+
"solara_status='solara status'",
|
|
11
12
|
]
|
|
12
13
|
|
|
13
14
|
@generator.add_brand_aliases(BrandsManager.instance.brands_list)
|
|
@@ -83,7 +83,7 @@ class SolaraSetup
|
|
|
83
83
|
reg['AutoRun', Win32::Registry::REG_EXPAND_SZ] = @windows_setup_file
|
|
84
84
|
end
|
|
85
85
|
Solara.logger.success("Windows AutoRun registry key set up successfully.")
|
|
86
|
-
|
|
86
|
+
Solara.logger.warn("Please restart your Command Prompt to apply changes.")
|
|
87
87
|
rescue Win32::Registry::Error => e
|
|
88
88
|
Solara.logger.failure("Failed to set up Windows registry: #{e.message}")
|
|
89
89
|
Solara.logger.failure("Please add the following file path to your AutoRun registry key manually:")
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Dir[File.expand_path('scripts/*.rb', __dir__)].each { |file| require_relative file }
|
|
2
|
+
Dir[File.expand_path('../template/*.rb', __dir__)].each { |file| require_relative file }
|
|
3
|
+
Dir[File.expand_path('platform/android/*.rb', __dir__)].each { |file| require_relative file }
|
|
4
|
+
Dir[File.expand_path('platform/ios/*.rb', __dir__)].each { |file| require_relative file }
|
|
5
|
+
Dir[File.expand_path('platform/flutter/*.rb', __dir__)].each { |file| require_relative file }
|
|
6
|
+
class BrandFontSwitcher
|
|
7
|
+
def initialize(brand_key)
|
|
8
|
+
@brand_key = brand_key
|
|
9
|
+
@fonts_path = FilePath.brand_fonts
|
|
10
|
+
@font_files = Dir.glob(File.join(@fonts_path, '*.{ttf,otf}'))
|
|
11
|
+
Solara.logger.end_step("Switch Info.plist")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def switch
|
|
15
|
+
Solara.logger.header("Switch Fonts")
|
|
16
|
+
|
|
17
|
+
case SolaraSettingsManager.instance.platform
|
|
18
|
+
when Platform::Flutter
|
|
19
|
+
FlutterFontSwitcher.new(@brand_key, @font_files).switch
|
|
20
|
+
AndroidFontSwitcher.new(@brand_key, @font_files).switch
|
|
21
|
+
IOSFontSwitcher.new(@brand_key, @font_files).switch
|
|
22
|
+
when Platform::Android
|
|
23
|
+
AndroidFontSwitcher.new(@brand_key, @font_files).switch
|
|
24
|
+
when Platform::IOS
|
|
25
|
+
IOSFontSwitcher.new(@brand_key, @font_files).switch
|
|
26
|
+
else
|
|
27
|
+
raise ArgumentError, "Invalid platform: #{SolaraSettingsManager.instance.platform}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class FlutterFontSwitcher
|
|
33
|
+
def initialize(brand_key, font_files)
|
|
34
|
+
@brand_key = brand_key
|
|
35
|
+
@font_files = font_files
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def switch
|
|
39
|
+
Solara.logger.start_step("Switch Flutter fonts")
|
|
40
|
+
destination = FilePath.flutter_project_fonts
|
|
41
|
+
copy_fonts(destination)
|
|
42
|
+
|
|
43
|
+
add_fonts_to_pubspec
|
|
44
|
+
Solara.logger.end_step("Switch Flutter fonts")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def add_fonts_to_pubspec
|
|
50
|
+
yaml_manager = YamlManager.new(FilePath.pub_spec_yaml)
|
|
51
|
+
font_families = Hash.new { |hash, key| hash[key] = [] }
|
|
52
|
+
|
|
53
|
+
font_names = @font_files.map { |file| File.basename(file) }
|
|
54
|
+
font_names.each do |font_file|
|
|
55
|
+
base_name = File.basename(font_file, File.extname(font_file))
|
|
56
|
+
family_name = base_name.split('-').first
|
|
57
|
+
font_families[family_name] << font_file
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
font_families.each do |family_name, files|
|
|
61
|
+
assets = files.map { |file| { 'asset' => "assets/solara_fonts/#{file}" } }
|
|
62
|
+
yaml_manager.add_font(family_name, assets)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def copy_fonts(destination)
|
|
67
|
+
FontCopier.new.copy(destination, @font_files)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
class AndroidFontSwitcher
|
|
72
|
+
def initialize(brand_key, font_files)
|
|
73
|
+
@brand_key = brand_key
|
|
74
|
+
@font_files = font_files
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def switch
|
|
78
|
+
Solara.logger.start_step("Switch Android fonts")
|
|
79
|
+
destination = FilePath.android_project_fonts
|
|
80
|
+
copy_fonts(destination)
|
|
81
|
+
rename_fonts_in_directory(FilePath.android_project_fonts)
|
|
82
|
+
Solara.logger.end_step("Switch Android fonts")
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def rename_fonts_in_directory(directory)
|
|
88
|
+
Dir.foreach(directory) do |file|
|
|
89
|
+
next if file == '.' || file == '..' # Skip current and parent directory entries
|
|
90
|
+
|
|
91
|
+
old_path = File.join(directory, file)
|
|
92
|
+
if File.file?(old_path)
|
|
93
|
+
new_name = sanitize_font_name(file)
|
|
94
|
+
new_path = File.join(directory, new_name)
|
|
95
|
+
|
|
96
|
+
# Rename the file if the new name is different
|
|
97
|
+
unless old_path == new_path
|
|
98
|
+
FileUtils.mv(old_path, new_path)
|
|
99
|
+
Solara.logger.debug("Renamed: #{file} -> #{new_name}")
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def sanitize_font_name(font_name)
|
|
106
|
+
# Convert to lowercase
|
|
107
|
+
sanitized_name = font_name.downcase
|
|
108
|
+
# Replace spaces with underscores
|
|
109
|
+
sanitized_name.gsub!('-', '_')
|
|
110
|
+
sanitized_name.gsub!(' ', '_')
|
|
111
|
+
# Remove special characters (except underscores and dots)
|
|
112
|
+
sanitized_name.gsub!(/[^a-z0-9_.]/, '')
|
|
113
|
+
sanitized_name
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def copy_fonts(destination)
|
|
117
|
+
FontCopier.new.copy(destination, @font_files)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
class IOSFontSwitcher
|
|
122
|
+
def initialize(brand_key, font_files)
|
|
123
|
+
@brand_key = brand_key
|
|
124
|
+
@font_files = font_files
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def switch
|
|
128
|
+
Solara.logger.start_step("Switch iOS fonts")
|
|
129
|
+
destination = FilePath.ios_project_fonts
|
|
130
|
+
copy_fonts(destination)
|
|
131
|
+
|
|
132
|
+
font_names = @font_files.map { |file| File.basename(file) }
|
|
133
|
+
info_plist_path = FilePath.info_plist
|
|
134
|
+
manager = IOSPlistManager.new(@project, info_plist_path)
|
|
135
|
+
manager.add_fonts(font_names)
|
|
136
|
+
|
|
137
|
+
Solara.logger.end_step("Switch iOS fonts")
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
private
|
|
141
|
+
|
|
142
|
+
def copy_fonts(destination)
|
|
143
|
+
FontCopier.new.copy(destination, @font_files)
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class FontCopier
|
|
148
|
+
def copy(destination, font_files)
|
|
149
|
+
FileUtils.mkdir_p(destination)
|
|
150
|
+
return if font_files.empty?
|
|
151
|
+
|
|
152
|
+
FolderCopier.new(FilePath.brand_fonts, destination).copy
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -20,15 +20,11 @@ class BrandOnboarder
|
|
|
20
20
|
add_to_brands_list
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
def add_to_brands_list
|
|
24
|
-
BrandsManager.instance.add_brand(@brand_name, @brand_key)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
23
|
def generate_brand_template
|
|
28
24
|
Solara.logger.debug("Onboarding #{@brand_key} from template.")
|
|
29
25
|
|
|
30
26
|
template_dir = FilePath.template_brands
|
|
31
|
-
target_dir =
|
|
27
|
+
target_dir = FilePath.brand(@brand_key)
|
|
32
28
|
config_file = FilePath.template_config
|
|
33
29
|
|
|
34
30
|
generator = ProjectTemplateGenerator.new(template_dir, target_dir, config_file)
|
|
@@ -38,9 +34,15 @@ class BrandOnboarder
|
|
|
38
34
|
def clone_brand
|
|
39
35
|
Solara.logger.debug("Cloning #{@clone_brand_key} to #{@brand_key}")
|
|
40
36
|
source = FilePath.brand(@clone_brand_key)
|
|
41
|
-
destination =
|
|
37
|
+
destination = FilePath.brand(@brand_key)
|
|
38
|
+
|
|
39
|
+
FileManager.delete_if_exists(destination)
|
|
42
40
|
FolderCopier.new(source, destination).copy
|
|
43
41
|
end
|
|
44
42
|
|
|
43
|
+
def add_to_brands_list
|
|
44
|
+
BrandsManager.instance.add_brand(@brand_name, @brand_key)
|
|
45
|
+
end
|
|
46
|
+
|
|
45
47
|
end
|
|
46
48
|
|
|
@@ -1,204 +1,270 @@
|
|
|
1
|
+
# Load required files
|
|
1
2
|
Dir[File.expand_path('scripts/*.rb', __dir__)].each { |file| require_relative file }
|
|
2
3
|
Dir[File.expand_path('platform/android/*.rb', __dir__)].each { |file| require_relative file }
|
|
3
4
|
Dir[File.expand_path('platform/ios/*.rb', __dir__)].each { |file| require_relative file }
|
|
4
5
|
Dir[File.expand_path('platform/flutter/*.rb', __dir__)].each { |file| require_relative file }
|
|
5
6
|
|
|
6
7
|
class BrandSwitcher
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
def initialize(brand_key, ignore_health_check: false)
|
|
9
|
+
@brand_key = brand_key
|
|
10
|
+
@ignore_health_check = ignore_health_check
|
|
11
|
+
@platform = SolaraSettingsManager.instance.platform
|
|
12
|
+
@health_checker = HealthChecker.new(@brand_key, @ignore_health_check)
|
|
13
|
+
@artifacts_switcher = ArtifactSwitcher.new(@platform)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def start
|
|
17
|
+
Solara.logger.header("Switching to #{@brand_key}")
|
|
18
|
+
|
|
19
|
+
@health_checker.check_health
|
|
20
|
+
BrandsManager.instance.save_current_brand(@brand_key)
|
|
21
|
+
@artifacts_switcher.switch
|
|
22
|
+
switch
|
|
23
|
+
SolaraConfigurator.new.start
|
|
24
|
+
|
|
25
|
+
Solara.logger.success("Switched to #{@brand_key} successfully.")
|
|
26
|
+
end
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def switch
|
|
31
|
+
BrandFontSwitcher.new(@brand_key).switch
|
|
32
|
+
|
|
33
|
+
case @platform
|
|
34
|
+
when Platform::Flutter
|
|
35
|
+
IOSBrandSwitcher.new(@brand_key).switch
|
|
36
|
+
AndroidBrandSwitcher.new(@brand_key).switch
|
|
37
|
+
FlutterBrandSwitcher.new(@brand_key).switch
|
|
38
|
+
when Platform::IOS
|
|
39
|
+
IOSBrandSwitcher.new(@brand_key).switch
|
|
40
|
+
when Platform::Android
|
|
41
|
+
AndroidBrandSwitcher.new(@brand_key).switch
|
|
42
|
+
else
|
|
43
|
+
raise ArgumentError, "Invalid platform: #{@platform}"
|
|
20
44
|
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
21
47
|
|
|
22
|
-
|
|
23
|
-
|
|
48
|
+
class FlutterBrandSwitcher
|
|
49
|
+
def initialize(brand_key)
|
|
50
|
+
@brand_key = brand_key
|
|
51
|
+
@theme_switcher = ThemeSwitcher.new(@brand_key)
|
|
52
|
+
@brand_config_switcher = BrandConfigSwitcher.new(@brand_key)
|
|
53
|
+
end
|
|
24
54
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
55
|
+
def switch
|
|
56
|
+
@theme_switcher.switch(Language::Dart)
|
|
57
|
+
@brand_config_switcher.switch(Language::Dart)
|
|
58
|
+
BrandResourcesSwitcher.new(@brand_key).switch(Platform::Flutter)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
32
61
|
|
|
33
|
-
|
|
62
|
+
class AndroidBrandSwitcher
|
|
63
|
+
def initialize(brand_key)
|
|
64
|
+
@brand_key = brand_key
|
|
65
|
+
@theme_switcher = ThemeSwitcher.new(@brand_key)
|
|
66
|
+
@brand_config_switcher = BrandConfigSwitcher.new(@brand_key)
|
|
67
|
+
end
|
|
34
68
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Solara.logger.end_step("Create artifacts directories")
|
|
69
|
+
def switch
|
|
70
|
+
BrandConfigManager.new(@brand_key).generate_android_properties
|
|
38
71
|
|
|
39
|
-
|
|
72
|
+
config_path = FilePath.android_brand_config(@brand_key)
|
|
73
|
+
config = JSON.parse(File.read(config_path))
|
|
40
74
|
|
|
41
|
-
|
|
75
|
+
GradleSwitcher.new(@brand_key).switch
|
|
76
|
+
AndroidManifestSwitcher.new.switch(config)
|
|
77
|
+
@theme_switcher.switch(Language::Kotlin)
|
|
78
|
+
@brand_config_switcher.switch(Language::Kotlin)
|
|
79
|
+
BrandResourcesSwitcher.new(@brand_key).switch(Platform::Android)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
42
82
|
|
|
43
|
-
|
|
44
|
-
|
|
83
|
+
class IOSBrandSwitcher
|
|
84
|
+
def initialize(brand_key)
|
|
85
|
+
@brand_key = brand_key
|
|
86
|
+
@theme_switcher = ThemeSwitcher.new(@brand_key)
|
|
87
|
+
@brand_config_switcher = BrandConfigSwitcher.new(@brand_key)
|
|
88
|
+
end
|
|
45
89
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
DirectoryCreator.create_directories(directories, delete_if_exists: true)
|
|
55
|
-
|
|
56
|
-
when Platform::IOS
|
|
57
|
-
directories = [
|
|
58
|
-
IOSFilePathManager.instance.artifacts
|
|
59
|
-
]
|
|
60
|
-
DirectoryCreator.create_directories(directories, delete_if_exists: true)
|
|
61
|
-
|
|
62
|
-
when Platform::Android
|
|
63
|
-
directories = [
|
|
64
|
-
FilePath::android_artifacts
|
|
65
|
-
]
|
|
66
|
-
DirectoryCreator.create_directories(directories, delete_if_exists: true)
|
|
67
|
-
else
|
|
68
|
-
raise ArgumentError, "Invalid platform: #{@platform}"
|
|
69
|
-
end
|
|
70
|
-
end
|
|
90
|
+
def switch
|
|
91
|
+
BrandConfigManager.new(@brand_key).generate_ios_xcconfig
|
|
92
|
+
@theme_switcher.switch(Language::Swift)
|
|
93
|
+
@brand_config_switcher.switch(Language::Swift)
|
|
94
|
+
switch_infoplist
|
|
95
|
+
BrandResourcesSwitcher.new(@brand_key).switch(Platform::IOS)
|
|
96
|
+
switch_xcode_project
|
|
97
|
+
end
|
|
71
98
|
|
|
72
|
-
|
|
73
|
-
case @platform
|
|
74
|
-
when Platform::Flutter
|
|
75
|
-
switch_flutter
|
|
76
|
-
switch_android
|
|
77
|
-
switch_ios
|
|
78
|
-
|
|
79
|
-
when Platform::IOS
|
|
80
|
-
switch_ios
|
|
81
|
-
|
|
82
|
-
when Platform::Android
|
|
83
|
-
switch_android
|
|
84
|
-
else
|
|
85
|
-
raise ArgumentError, "Invalid platform: #{@platform}"
|
|
86
|
-
end
|
|
87
|
-
end
|
|
99
|
+
private
|
|
88
100
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
101
|
+
def switch_infoplist
|
|
102
|
+
Solara.logger.start_step("Switch Info.plist")
|
|
103
|
+
project_path = FilePath.xcode_project
|
|
104
|
+
InfoPlistSwitcher.new(project_path, @brand_key).switch
|
|
105
|
+
Solara.logger.end_step("Switch Info.plist")
|
|
106
|
+
end
|
|
95
107
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
108
|
+
def switch_xcode_project
|
|
109
|
+
Solara.logger.start_step("Switch Xcode project")
|
|
110
|
+
project_path = FilePath.xcode_project
|
|
111
|
+
XcodeProjectSwitcher.new(project_path, @brand_key).switch
|
|
112
|
+
Solara.logger.end_step("Switch Xcode project")
|
|
113
|
+
end
|
|
114
|
+
end
|
|
102
115
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
end
|
|
116
|
+
class HealthChecker
|
|
117
|
+
def initialize(brand_key, ignore_health_check)
|
|
118
|
+
@brand_key = brand_key
|
|
119
|
+
@ignore_health_check = ignore_health_check
|
|
120
|
+
end
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
platform)
|
|
114
|
-
Solara.logger.start_step("Generate #{language} theme for #{platform}")
|
|
115
|
-
generator = ThemeGenerator.new(
|
|
116
|
-
FilePath.brand_theme(@brand_key),
|
|
117
|
-
FilePath.generated_config(name, platform),
|
|
118
|
-
language)
|
|
119
|
-
generator.generate
|
|
120
|
-
Solara.logger.end_step("Generate #{language} theme for #{platform}")
|
|
121
|
-
end
|
|
122
|
+
def check_health
|
|
123
|
+
health_errors = SolaraManager.new.doctor([@brand_key]).select { |issue| issue.type == Issue::ERROR }
|
|
124
|
+
return if health_errors.empty?
|
|
122
125
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
Language::Kotlin,
|
|
127
|
-
Platform::Android
|
|
128
|
-
)
|
|
126
|
+
unless @ignore_health_check
|
|
127
|
+
errors_with_index = health_errors.each_with_index.map { |error, index| "#{index + 1}: #{error}" }
|
|
128
|
+
raise Issue.error("Health check completed with errors: \n\n#{errors_with_index.join("\n")}.")
|
|
129
129
|
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
130
132
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
Platform::IOS)
|
|
136
|
-
end
|
|
133
|
+
class ArtifactSwitcher
|
|
134
|
+
def initialize(platform)
|
|
135
|
+
@platform = platform
|
|
136
|
+
end
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
138
|
+
def switch
|
|
139
|
+
Solara.logger.start_step("Switch artifacts directories")
|
|
140
|
+
directories = directories_for_platform
|
|
141
|
+
DirectoryCreator.create_directories(directories, delete_if_exists: true)
|
|
142
|
+
Solara.logger.end_step("Switch artifacts directories")
|
|
143
|
+
end
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
name,
|
|
147
|
-
language,
|
|
148
|
-
platform)
|
|
149
|
-
BrandConfigManager.new(@brand_key).generate_brand_config(
|
|
150
|
-
name,
|
|
151
|
-
language,
|
|
152
|
-
platform)
|
|
153
|
-
end
|
|
145
|
+
private
|
|
154
146
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
147
|
+
def directories_for_platform
|
|
148
|
+
case @platform
|
|
149
|
+
when Platform::Flutter
|
|
150
|
+
FlutterArtifactSwitcher.new.directories +
|
|
151
|
+
IOSArtifactSwitcher.new.directories +
|
|
152
|
+
AndroidArtifactSwitcher.new.directories
|
|
153
|
+
when Platform::IOS
|
|
154
|
+
IOSArtifactSwitcher.new.directories
|
|
155
|
+
when Platform::Android
|
|
156
|
+
AndroidArtifactSwitcher.new.directories
|
|
157
|
+
else
|
|
158
|
+
raise ArgumentError, "Invalid platform: #{@platform}"
|
|
159
159
|
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
160
162
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
generate_app_config_kotlin
|
|
171
|
-
end
|
|
163
|
+
class FlutterArtifactSwitcher
|
|
164
|
+
def directories
|
|
165
|
+
[
|
|
166
|
+
FilePath.flutter_lib_artifacts,
|
|
167
|
+
FilePath.flutter_assets_artifacts,
|
|
168
|
+
FilePath.flutter_project_fonts,
|
|
169
|
+
]
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
172
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
class IOSArtifactSwitcher
|
|
174
|
+
def directories
|
|
175
|
+
[
|
|
176
|
+
FilePath.ios_project_root_artifacts,
|
|
177
|
+
FilePath.ios_project_assets_artifacts,
|
|
178
|
+
]
|
|
179
|
+
end
|
|
180
|
+
end
|
|
177
181
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
+
class AndroidArtifactSwitcher
|
|
183
|
+
def directories
|
|
184
|
+
[
|
|
185
|
+
FilePath.android_project_root_artifacts,
|
|
186
|
+
FilePath.android_project_main_artifacts,
|
|
187
|
+
FilePath.android_project_java_artifacts,
|
|
188
|
+
FilePath.android_project_assets_artifacts
|
|
189
|
+
]
|
|
190
|
+
end
|
|
191
|
+
end
|
|
182
192
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
193
|
+
class ThemeSwitcher
|
|
194
|
+
def initialize(brand_key)
|
|
195
|
+
@brand_key = brand_key
|
|
196
|
+
end
|
|
187
197
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
def switch(language)
|
|
199
|
+
case language
|
|
200
|
+
when Language::Dart
|
|
201
|
+
generate_dart
|
|
202
|
+
when Language::Kotlin
|
|
203
|
+
generate_kotlin
|
|
204
|
+
when Language::Swift
|
|
205
|
+
generate_swift
|
|
206
|
+
else
|
|
207
|
+
raise ArgumentError, "Invalid language: #{language}"
|
|
194
208
|
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def generate_dart
|
|
212
|
+
generate_theme('brand_theme.dart', Language::Dart, Platform::Flutter)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def generate_kotlin
|
|
216
|
+
generate_theme('BrandTheme.kt', Language::Kotlin, Platform::Android)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def generate_swift
|
|
220
|
+
generate_theme('BrandTheme.swift', Language::Swift, Platform::IOS)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
private
|
|
224
|
+
|
|
225
|
+
def generate_theme(name, language, platform)
|
|
226
|
+
Solara.logger.start_step("Generate #{name} for #{platform}")
|
|
195
227
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
228
|
+
theme_manager = ThemeGeneratorManager.new(FilePath.brand_theme(@brand_key))
|
|
229
|
+
theme_manager.generate(language, FilePath.generated_config(name, platform))
|
|
230
|
+
|
|
231
|
+
Solara.logger.end_step("Generate #{name} for #{platform}")
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
class BrandConfigSwitcher
|
|
236
|
+
def initialize(brand_key)
|
|
237
|
+
@brand_key = brand_key
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
def switch(language)
|
|
241
|
+
case language
|
|
242
|
+
when Language::Dart
|
|
243
|
+
generate_dart
|
|
244
|
+
when Language::Kotlin
|
|
245
|
+
generate_kotlin
|
|
246
|
+
when Language::Swift
|
|
247
|
+
generate_swift
|
|
248
|
+
else
|
|
249
|
+
raise ArgumentError, "Invalid language: #{language}"
|
|
202
250
|
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def generate_dart
|
|
254
|
+
generate_brand_config('brand_config.dart', Language::Dart, Platform::Flutter)
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def generate_kotlin
|
|
258
|
+
generate_brand_config('BrandConfig.kt', Language::Kotlin, Platform::Android)
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
def generate_swift
|
|
262
|
+
generate_brand_config('BrandConfig.swift', Language::Swift, Platform::IOS)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
private
|
|
203
266
|
|
|
267
|
+
def generate_brand_config(name, language, platform)
|
|
268
|
+
BrandConfigManager.new(@brand_key).generate_brand_config(name, language, platform)
|
|
269
|
+
end
|
|
204
270
|
end
|