solara 0.1.0
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 +7 -0
- data/bin/solara +18 -0
- data/solara/lib/.DS_Store +0 -0
- data/solara/lib/core/.DS_Store +0 -0
- data/solara/lib/core/aliases/alias_generator.rb +128 -0
- data/solara/lib/core/aliases/alias_generator_manager.rb +28 -0
- data/solara/lib/core/aliases/solara_terminal_setup.rb +103 -0
- data/solara/lib/core/brands/brand_onboarder.rb +46 -0
- data/solara/lib/core/brands/brand_switcher.rb +204 -0
- data/solara/lib/core/brands/brands_manager.rb +154 -0
- data/solara/lib/core/dashboard/.DS_Store +0 -0
- data/solara/lib/core/dashboard/brand/.DS_Store +0 -0
- data/solara/lib/core/dashboard/brand/BrandDetail.js +11 -0
- data/solara/lib/core/dashboard/brand/BrandDetailController.js +361 -0
- data/solara/lib/core/dashboard/brand/BrandDetailModel.js +155 -0
- data/solara/lib/core/dashboard/brand/BrandDetailView.js +245 -0
- data/solara/lib/core/dashboard/brand/brand.html +477 -0
- data/solara/lib/core/dashboard/brand/source/BrandLocalSource.js +123 -0
- data/solara/lib/core/dashboard/brand/source/BrandRemoteSource.js +260 -0
- data/solara/lib/core/dashboard/brands/Brands.js +10 -0
- data/solara/lib/core/dashboard/brands/BrandsController.js +155 -0
- data/solara/lib/core/dashboard/brands/BrandsModel.js +136 -0
- data/solara/lib/core/dashboard/brands/BrandsView.js +136 -0
- data/solara/lib/core/dashboard/brands/brands.html +345 -0
- data/solara/lib/core/dashboard/component/AddFieldSheet.js +212 -0
- data/solara/lib/core/dashboard/component/AliasesBottomSheet.js +128 -0
- data/solara/lib/core/dashboard/component/BrandOptionsBottomSheet.js +130 -0
- data/solara/lib/core/dashboard/component/ConfirmationDialog.js +103 -0
- data/solara/lib/core/dashboard/component/MessageBottomSheet.js +80 -0
- data/solara/lib/core/dashboard/component/OnboardBrandBottomSheet.js +214 -0
- data/solara/lib/core/dashboard/dashboard_manager.rb +19 -0
- data/solara/lib/core/dashboard/dashboard_server.rb +132 -0
- data/solara/lib/core/dashboard/handler/base_handler.rb +25 -0
- data/solara/lib/core/dashboard/handler/brand_alisases_handler.rb +33 -0
- data/solara/lib/core/dashboard/handler/brand_configurations_handler.rb +18 -0
- data/solara/lib/core/dashboard/handler/brand_configurations_manager.rb +73 -0
- data/solara/lib/core/dashboard/handler/brand_icon_handler.rb +20 -0
- data/solara/lib/core/dashboard/handler/brand_section_handler.rb +20 -0
- data/solara/lib/core/dashboard/handler/brands_handler.rb +14 -0
- data/solara/lib/core/dashboard/handler/current_brand_handler.rb +18 -0
- data/solara/lib/core/dashboard/handler/doctor_handler.rb +39 -0
- data/solara/lib/core/dashboard/handler/edit_section_handler.rb +55 -0
- data/solara/lib/core/dashboard/handler/offboard_brand_handler.rb +34 -0
- data/solara/lib/core/dashboard/handler/onboard_brand_handler.rb +53 -0
- data/solara/lib/core/dashboard/handler/redirect_handler.rb +12 -0
- data/solara/lib/core/dashboard/handler/switch_handler.rb +25 -0
- data/solara/lib/core/dashboard/index.html +36 -0
- data/solara/lib/core/dashboard/local.html +41 -0
- data/solara/lib/core/dashboard/res/favicon/android-chrome-192x192.png +0 -0
- data/solara/lib/core/dashboard/res/favicon/android-chrome-512x512.png +0 -0
- data/solara/lib/core/dashboard/res/favicon/apple-touch-icon.png +0 -0
- data/solara/lib/core/dashboard/res/favicon/favicon-16x16.png +0 -0
- data/solara/lib/core/dashboard/res/favicon/favicon-32x32.png +0 -0
- data/solara/lib/core/dashboard/res/favicon/favicon.ico +0 -0
- data/solara/lib/core/dashboard/res/favicon/site.webmanifest +1 -0
- data/solara/lib/core/dashboard/solara.png +0 -0
- data/solara/lib/core/doctor/brand_doctor.rb +94 -0
- data/solara/lib/core/doctor/doctor_manager.rb +35 -0
- data/solara/lib/core/doctor/project_doctor.rb +8 -0
- data/solara/lib/core/doctor/schema/brand_configurations.json +60 -0
- data/solara/lib/core/doctor/schema/platform/android/android_config.json +23 -0
- data/solara/lib/core/doctor/schema/platform/android/android_signing.json +23 -0
- data/solara/lib/core/doctor/schema/platform/ios/ios_config.json +27 -0
- data/solara/lib/core/doctor/schema/platform/ios/ios_signing.json +27 -0
- data/solara/lib/core/doctor/schema/platform/shared/theme.json +48 -0
- data/solara/lib/core/doctor/validator/brand_settings_validator.rb +55 -0
- data/solara/lib/core/doctor/validator/brand_settings_validator_manager.rb +82 -0
- data/solara/lib/core/doctor/validator/directory_structure_validator.rb +38 -0
- data/solara/lib/core/doctor/validator/file_structure_validator.rb +37 -0
- data/solara/lib/core/doctor/validator/json_file_validator.rb +21 -0
- data/solara/lib/core/doctor/validator/json_schema_validator.rb +32 -0
- data/solara/lib/core/doctor/validator/project_filesystem_validator.rb +70 -0
- data/solara/lib/core/doctor/validator/template/android_template_validation_config.yml +51 -0
- data/solara/lib/core/doctor/validator/template/flutter_template_validation_config.yml +53 -0
- data/solara/lib/core/doctor/validator/template/ios_template_validation_config.yml +51 -0
- data/solara/lib/core/doctor/validator/template/template_validator.rb +108 -0
- data/solara/lib/core/doctor/validator/validation_strategy.rb +7 -0
- data/solara/lib/core/scripts/brand_config_generator.rb +245 -0
- data/solara/lib/core/scripts/brand_config_manager.rb +90 -0
- data/solara/lib/core/scripts/brand_exporter.rb +38 -0
- data/solara/lib/core/scripts/brand_importer.rb +84 -0
- data/solara/lib/core/scripts/brand_offboarder.rb +19 -0
- data/solara/lib/core/scripts/brand_resources_manager.rb +77 -0
- data/solara/lib/core/scripts/directory_creator.rb +22 -0
- data/solara/lib/core/scripts/file_manager.rb +90 -0
- data/solara/lib/core/scripts/file_path.rb +327 -0
- data/solara/lib/core/scripts/folder_copier.rb +41 -0
- data/solara/lib/core/scripts/gitignore_manager.rb +54 -0
- data/solara/lib/core/scripts/interactive_file_system_validator.rb +110 -0
- data/solara/lib/core/scripts/platform/android/android_manifest_switcher.rb +24 -0
- data/solara/lib/core/scripts/platform/android/android_strings_switcher.rb +39 -0
- data/solara/lib/core/scripts/platform/android/gradle_switcher.rb +233 -0
- data/solara/lib/core/scripts/platform/android/properties_generator.rb +31 -0
- data/solara/lib/core/scripts/platform/ios/ios_file_path_manager.rb +109 -0
- data/solara/lib/core/scripts/platform/ios/ios_plist_manager.rb +42 -0
- data/solara/lib/core/scripts/platform/ios/xcconfig_generator.rb +44 -0
- data/solara/lib/core/scripts/platform/ios/xcode_asset_manager.rb +56 -0
- data/solara/lib/core/scripts/platform/ios/xcode_project_manager.rb +82 -0
- data/solara/lib/core/scripts/platform/ios/xcode_project_switcher.rb +130 -0
- data/solara/lib/core/scripts/project_settings_manager.rb +39 -0
- data/solara/lib/core/scripts/solara_logger.rb +103 -0
- data/solara/lib/core/scripts/solara_settings_manager.rb +73 -0
- data/solara/lib/core/scripts/solara_status_manager.rb +55 -0
- data/solara/lib/core/scripts/solara_version_manager.rb +42 -0
- data/solara/lib/core/scripts/strings_xml_manager.rb +22 -0
- data/solara/lib/core/scripts/terminal_input_manager.rb +22 -0
- data/solara/lib/core/scripts/theme_generator.rb +250 -0
- data/solara/lib/core/scripts/yaml_manager.rb +72 -0
- data/solara/lib/core/solara_configurator.rb +15 -0
- data/solara/lib/core/template/brands/android/android_config.json +8 -0
- data/solara/lib/core/template/brands/android/android_signing.json +6 -0
- data/solara/lib/core/template/brands/android/res/.DS_Store +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-hdpi/ic_launcher.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-hdpi/ic_launcher_round.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-mdpi/ic_launcher.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-mdpi/ic_launcher_round.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-xhdpi/ic_launcher.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-xhdpi/ic_launcher_round.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- data/solara/lib/core/template/brands/android/res/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- data/solara/lib/core/template/brands/brands.json +4 -0
- data/solara/lib/core/template/brands/ios/assets/.DS_Store +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/100.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/102.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/1024.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/114.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/120.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/128.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/144.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/152.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/16.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/167.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/172.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/180.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/196.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/20.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/216.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/256.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/29.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/32.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/40.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/48.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/50.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/512.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/55.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/57.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/58.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/60.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/64.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/66.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/72.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/76.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/80.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/87.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/88.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/92.png +0 -0
- data/solara/lib/core/template/brands/ios/assets/AppIcon.appiconset/Contents.json +1 -0
- data/solara/lib/core/template/brands/ios/ios_config.json +7 -0
- data/solara/lib/core/template/brands/ios/ios_signing.json +7 -0
- data/solara/lib/core/template/brands/shared/.DS_Store +0 -0
- data/solara/lib/core/template/brands/shared/brand_config.json +2 -0
- data/solara/lib/core/template/brands/shared/theme.json +46 -0
- data/solara/lib/core/template/config/android_template_config.json +57 -0
- data/solara/lib/core/template/config/flutter_template_config.json +62 -0
- data/solara/lib/core/template/config/ios_template_config.json +57 -0
- data/solara/lib/core/template/project_template_generator.rb +63 -0
- data/solara/lib/platform_detector.rb +84 -0
- data/solara/lib/solara/cli.rb +5 -0
- data/solara/lib/solara/version.rb +3 -0
- data/solara/lib/solara.rb +238 -0
- data/solara/lib/solara_initializer.rb +44 -0
- data/solara/lib/solara_manager.rb +73 -0
- metadata +346 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 145b33e1ba6fda109d59904bf8e356ed6ec8f4990b16857e5fbde74fb2d5e2da
|
|
4
|
+
data.tar.gz: 401d6f18d80006e0e030d1873ad6488a845301fc8f6fb91700ecd7cf2b959c25
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4dbd300836c1b9c4885c24e9f9506f0b10fb0baa987a5a851d95aa24d5e592e9af496d96601c05f248e386736589151916baab4a53034af1d2723ccd99f26482
|
|
7
|
+
data.tar.gz: 3bbc2fc137767dd083228dd520a8b47e8ab7a06eb1b78ea81fa6184524d70630167419665021f1eefb08ddab649cdaa771d265685e5288d4ec1b53778c4a2016
|
data/bin/solara
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
if RUBY_VERSION < '2.0.0'
|
|
4
|
+
abort("Solara requires Ruby 2.0.0 or higher")
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
Dir.glob("#{__dir__}/core/scripts/*.rb").each { |file| require file }
|
|
8
|
+
Dir.glob("#{__dir__}/core/scripts/*.rb").each { |file| require file }
|
|
9
|
+
Dir.glob("#{__dir__}/core/*.rb").each { |file| require file }
|
|
10
|
+
Dir.glob("#{__dir__}/core/doctor/*.rb").each { |file| require file }
|
|
11
|
+
Dir.glob("#{__dir__}/core/aliases/*.rb").each { |file| require file }
|
|
12
|
+
Dir.glob("#{__dir__}/core/dashboard/*.rb").each { |file| require file }
|
|
13
|
+
Dir.glob("#{__dir__}/core/brands/*.rb").each { |file| require file }
|
|
14
|
+
|
|
15
|
+
require 'solara'
|
|
16
|
+
|
|
17
|
+
Solara::Setup.new.setup
|
|
18
|
+
Solara::CLI.start(ARGV)
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Dir[File.expand_path('../scripts/*.rb', __dir__)].each { |file| require_relative file }
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
class AliasGenerator
|
|
5
|
+
def initialize
|
|
6
|
+
@output_file = FilePath.solara_aliases_sh
|
|
7
|
+
FileManager.create_file_if_not_exist(@output_file)
|
|
8
|
+
|
|
9
|
+
@readme_file = FilePath.solara_aliases_readme
|
|
10
|
+
FileManager.create_file_if_not_exist(@readme_file)
|
|
11
|
+
|
|
12
|
+
@json_file = FilePath.solara_aliases_json
|
|
13
|
+
FileManager.create_file_if_not_exist(@json_file)
|
|
14
|
+
|
|
15
|
+
@brand_aliases = {}
|
|
16
|
+
@common_aliases = []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def add_brand_aliases(brands)
|
|
20
|
+
alias_templates = [
|
|
21
|
+
"solara_offboard_{brand_key}='solara offboard -k {brand_key}'",
|
|
22
|
+
"solara_switch_{brand_key}='solara switch -k {brand_key}'",
|
|
23
|
+
"solara_doctor_{brand_key}='solara doctor -k {brand_key}'",
|
|
24
|
+
"solara_dashboard_{brand_key}='solara dashboard -k {brand_key}'"
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
brands.each do |app|
|
|
28
|
+
brand_key = app['key']
|
|
29
|
+
@brand_aliases[brand_key] = []
|
|
30
|
+
alias_templates.each do |template|
|
|
31
|
+
alias_line = template.gsub('{brand_key}', brand_key)
|
|
32
|
+
@brand_aliases[brand_key] << "alias #{alias_line}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def add_common_aliases(common_aliases)
|
|
38
|
+
@common_aliases = common_aliases.map { |alias_line| "alias #{alias_line}" }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def generate_shell_file
|
|
42
|
+
existing_content = File.exist?(@output_file) ? File.read(@output_file) : ""
|
|
43
|
+
new_content = []
|
|
44
|
+
|
|
45
|
+
new_content << "#!/bin/bash" if existing_content.empty?
|
|
46
|
+
|
|
47
|
+
common_aliases_added = false
|
|
48
|
+
@common_aliases.each do |alias_line|
|
|
49
|
+
unless existing_content.include?(alias_line)
|
|
50
|
+
new_content << "# Common Aliases" unless common_aliases_added
|
|
51
|
+
common_aliases_added = true
|
|
52
|
+
new_content << alias_line
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
brand_aliases_added = false
|
|
57
|
+
@brand_aliases.each do |brand_name, brand_aliases|
|
|
58
|
+
brand_aliases_for_this_brand_added = false
|
|
59
|
+
brand_aliases.each do |alias_line|
|
|
60
|
+
unless existing_content.include?(alias_line)
|
|
61
|
+
unless brand_aliases_added
|
|
62
|
+
brand_aliases_added = true
|
|
63
|
+
end
|
|
64
|
+
unless brand_aliases_for_this_brand_added
|
|
65
|
+
new_content << "" # Add a new line before each brand name
|
|
66
|
+
new_content << "# #{brand_name}"
|
|
67
|
+
brand_aliases_for_this_brand_added = true
|
|
68
|
+
end
|
|
69
|
+
new_content << alias_line
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
new_content.reject!(&:empty?) if new_content.size == 1
|
|
75
|
+
|
|
76
|
+
if new_content.any? && !(new_content.size == 1 && new_content.first == "#!/bin/bash")
|
|
77
|
+
File.open(@output_file, 'a') do |file|
|
|
78
|
+
file.puts new_content
|
|
79
|
+
end
|
|
80
|
+
Solara.logger.debug("Aliases have been appended to #{@output_file}")
|
|
81
|
+
else
|
|
82
|
+
Solara.logger.debug("No new aliases to add to #{@output_file}")
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def generate_readme
|
|
87
|
+
File.open(@readme_file, 'w') do |file|
|
|
88
|
+
file.puts "# Aliases"
|
|
89
|
+
file.puts
|
|
90
|
+
file.puts "This document provides an overview of all available aliases."
|
|
91
|
+
file.puts
|
|
92
|
+
|
|
93
|
+
if @common_aliases.any?
|
|
94
|
+
file.puts "## Common Aliases"
|
|
95
|
+
file.puts
|
|
96
|
+
@common_aliases.each do |alias_line|
|
|
97
|
+
alias_name = alias_line.split('=').first.strip.gsub('alias ', '')
|
|
98
|
+
file.puts "- `#{alias_name}`"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
file.puts
|
|
103
|
+
|
|
104
|
+
file.puts
|
|
105
|
+
@brand_aliases.each do |brand_name, brand_aliases|
|
|
106
|
+
file.puts "## #{brand_name}"
|
|
107
|
+
file.puts
|
|
108
|
+
brand_aliases.each do |alias_line|
|
|
109
|
+
alias_name = alias_line.split('=').first.strip.gsub('alias ', '')
|
|
110
|
+
file.puts "- `#{alias_name}`"
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
Solara.logger.debug("README.md has been generated in #{@readme_file}")
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def save_aliases_to_json
|
|
118
|
+
json_data = {
|
|
119
|
+
"common_aliases" => @common_aliases,
|
|
120
|
+
"brand_aliases" => @brand_aliases
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
File.open(@json_file, 'w') do |file|
|
|
124
|
+
file.puts JSON.pretty_generate(json_data)
|
|
125
|
+
end
|
|
126
|
+
Solara.logger.debug("Aliases have been saved in JSON format in #{@json_file}")
|
|
127
|
+
end
|
|
128
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class AliasGeneratorManager
|
|
2
|
+
def initialize
|
|
3
|
+
@generator = AliasGenerator.new()
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def start
|
|
7
|
+
Solara.logger.start_step("Generate terminal command aliases")
|
|
8
|
+
common_aliases = [
|
|
9
|
+
"solara_dashboard='solara dashboard'",
|
|
10
|
+
"solara_doctor='solara doctor'",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
@generator.add_brand_aliases(BrandsManager.instance.brands_list)
|
|
14
|
+
@generator.add_common_aliases(common_aliases)
|
|
15
|
+
@generator.generate_shell_file
|
|
16
|
+
@generator.save_aliases_to_json
|
|
17
|
+
@generator.generate_readme
|
|
18
|
+
|
|
19
|
+
SolaraSetup.new.run
|
|
20
|
+
Solara.logger.end_step("Generate terminal command aliases")
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.aliases_json
|
|
24
|
+
path = FilePath.solara_aliases_json
|
|
25
|
+
JSON.parse(File.read(path))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
Dir.glob("../scripts/*.rb").each { |file| require file }
|
|
4
|
+
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'rbconfig'
|
|
7
|
+
|
|
8
|
+
class SolaraSetup
|
|
9
|
+
def initialize
|
|
10
|
+
@aliases_file = FilePath.solara_aliases_sh
|
|
11
|
+
@setup_dir = File.join(ENV['HOME'], '.solara')
|
|
12
|
+
@unix_setup_file = File.join(@setup_dir, 'setup.sh')
|
|
13
|
+
@windows_setup_file = File.join(@setup_dir, 'setup.bat')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def run
|
|
17
|
+
create_setup_directory
|
|
18
|
+
create_unix_setup_script
|
|
19
|
+
create_windows_setup_script
|
|
20
|
+
|
|
21
|
+
case RbConfig::CONFIG['host_os']
|
|
22
|
+
when /mswin|mingw|cygwin/
|
|
23
|
+
setup_windows
|
|
24
|
+
when /darwin|mac os|linux/
|
|
25
|
+
setup_unix
|
|
26
|
+
else
|
|
27
|
+
Solara.logger.fatal("Unsupported operating system. Please set up manually.")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def create_setup_directory
|
|
34
|
+
FileUtils.mkdir_p(@setup_dir)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def create_unix_setup_script
|
|
38
|
+
File.open(@unix_setup_file, 'w') do |file|
|
|
39
|
+
file.puts <<~SCRIPT
|
|
40
|
+
#!/bin/bash
|
|
41
|
+
source "#{@aliases_file}"
|
|
42
|
+
SCRIPT
|
|
43
|
+
end
|
|
44
|
+
FileUtils.chmod(0755, @unix_setup_file)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def create_windows_setup_script
|
|
48
|
+
File.open(@windows_setup_file, 'w') do |file|
|
|
49
|
+
file.puts <<~SCRIPT
|
|
50
|
+
@echo off
|
|
51
|
+
call "#{@aliases_file.gsub('/', '\\')}"
|
|
52
|
+
SCRIPT
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def setup_unix
|
|
57
|
+
shell_config_file = determine_shell_config_file
|
|
58
|
+
setup_line = "source #{@unix_setup_file}"
|
|
59
|
+
|
|
60
|
+
if File.exist?(shell_config_file)
|
|
61
|
+
content = File.read(shell_config_file)
|
|
62
|
+
unless content.include?(setup_line)
|
|
63
|
+
File.open(shell_config_file, 'a') do |file|
|
|
64
|
+
file.puts "\n# Solara Setup"
|
|
65
|
+
file.puts setup_line
|
|
66
|
+
end
|
|
67
|
+
Solara.logger.debug("Configuration added to #{shell_config_file}")
|
|
68
|
+
Solara.logger.success("Please restart your terminal or run 'source #{shell_config_file}' to apply changes.")
|
|
69
|
+
else
|
|
70
|
+
Solara.logger.debug("Configuration already exists in #{shell_config_file}")
|
|
71
|
+
end
|
|
72
|
+
else
|
|
73
|
+
Solara.logger.failure("Shell configuration file not found. Please add the following line manually to your shell configuration:")
|
|
74
|
+
Solara.logger.failure(setup_line)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def setup_windows
|
|
79
|
+
require 'win32/registry'
|
|
80
|
+
|
|
81
|
+
begin
|
|
82
|
+
Win32::Registry::HKEY_CURRENT_USER.create('Software\Microsoft\Command Processor') do |reg|
|
|
83
|
+
reg['AutoRun', Win32::Registry::REG_EXPAND_SZ] = @windows_setup_file
|
|
84
|
+
end
|
|
85
|
+
Solara.logger.success("Windows AutoRun registry key set up successfully.")
|
|
86
|
+
pSolara.logger.warn("Please restart your Command Prompt to apply changes.")
|
|
87
|
+
rescue Win32::Registry::Error => e
|
|
88
|
+
Solara.logger.failure("Failed to set up Windows registry: #{e.message}")
|
|
89
|
+
Solara.logger.failure("Please add the following file path to your AutoRun registry key manually:")
|
|
90
|
+
Solara.logger.failure(@windows_setup_file)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def determine_shell_config_file
|
|
95
|
+
if ENV['SHELL'] =~ /zsh/
|
|
96
|
+
File.expand_path('~/.zshrc')
|
|
97
|
+
elsif ENV['SHELL'] =~ /bash/
|
|
98
|
+
File.expand_path('~/.bashrc')
|
|
99
|
+
else
|
|
100
|
+
File.expand_path('~/.profile')
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
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
|
+
|
|
7
|
+
class BrandOnboarder
|
|
8
|
+
def initialize(brand_key, brand_name, clone_brand_key: nil)
|
|
9
|
+
@brand_key = brand_key
|
|
10
|
+
@brand_name = brand_name
|
|
11
|
+
@clone_brand_key = clone_brand_key
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def onboard
|
|
15
|
+
if @clone_brand_key.nil? || @clone_brand_key.empty?
|
|
16
|
+
generate_brand_template
|
|
17
|
+
else
|
|
18
|
+
clone_brand
|
|
19
|
+
end
|
|
20
|
+
add_to_brands_list
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def add_to_brands_list
|
|
24
|
+
BrandsManager.instance.add_brand(@brand_name, @brand_key)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def generate_brand_template
|
|
28
|
+
Solara.logger.debug("Onboarding #{@brand_key} from template.")
|
|
29
|
+
|
|
30
|
+
template_dir = FilePath.template_brands
|
|
31
|
+
target_dir = File.join(FilePath.solara, 'brands', @brand_key)
|
|
32
|
+
config_file = FilePath.template_config
|
|
33
|
+
|
|
34
|
+
generator = ProjectTemplateGenerator.new(template_dir, target_dir, config_file)
|
|
35
|
+
generator.create_project
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clone_brand
|
|
39
|
+
Solara.logger.debug("Cloning #{@clone_brand_key} to #{@brand_key}")
|
|
40
|
+
source = FilePath.brand(@clone_brand_key)
|
|
41
|
+
destination = File.join(FilePath.solara, 'brands', @brand_key)
|
|
42
|
+
FolderCopier.new(source, destination).copy
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
Dir[File.expand_path('scripts/*.rb', __dir__)].each { |file| require_relative file }
|
|
2
|
+
Dir[File.expand_path('platform/android/*.rb', __dir__)].each { |file| require_relative file }
|
|
3
|
+
Dir[File.expand_path('platform/ios/*.rb', __dir__)].each { |file| require_relative file }
|
|
4
|
+
Dir[File.expand_path('platform/flutter/*.rb', __dir__)].each { |file| require_relative file }
|
|
5
|
+
|
|
6
|
+
class BrandSwitcher
|
|
7
|
+
def initialize(brand_key, ignore_health_check: false)
|
|
8
|
+
Solara.logger.debug("ignore_health_check = #{ignore_health_check}")
|
|
9
|
+
@brand_key = brand_key
|
|
10
|
+
@ignore_health_check = ignore_health_check
|
|
11
|
+
@platform = SolaraSettingsManager.instance.platform
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.switch_to_first_brand(ignore_health_check: true)
|
|
15
|
+
first_brand_key = BrandsManager.instance.first_brand_key
|
|
16
|
+
if first_brand_key.nil?
|
|
17
|
+
return
|
|
18
|
+
end
|
|
19
|
+
BrandSwitcher.new(first_brand_key, ignore_health_check: ignore_health_check).start
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def start
|
|
23
|
+
Solara.logger.header("Switching to #{@brand_key}")
|
|
24
|
+
|
|
25
|
+
health_errors = SolaraManager.new.doctor([@brand_key]).select { |issue| issue.type == Issue::ERROR }
|
|
26
|
+
unless health_errors.empty?
|
|
27
|
+
unless @ignore_health_check
|
|
28
|
+
errors_with_index = health_errors.each_with_index.map { |error, index| "#{index + 1}: #{error}" }
|
|
29
|
+
raise "Health check completed with errors: \n\n#{errors_with_index.join("\n")}."
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
BrandsManager.instance.save_current_brand(@brand_key)
|
|
34
|
+
|
|
35
|
+
Solara.logger.start_step("Create artifacts directories")
|
|
36
|
+
create_artifacts_dirs
|
|
37
|
+
Solara.logger.end_step("Create artifacts directories")
|
|
38
|
+
|
|
39
|
+
switch
|
|
40
|
+
|
|
41
|
+
SolaraConfigurator.new.start
|
|
42
|
+
|
|
43
|
+
Solara.logger.success("Switched to #{@brand_key} successfully.")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def create_artifacts_dirs
|
|
47
|
+
case @platform
|
|
48
|
+
when Platform::Flutter
|
|
49
|
+
directories = [
|
|
50
|
+
FilePath::flutter_artifacts,
|
|
51
|
+
FilePath::android_artifacts,
|
|
52
|
+
IOSFilePathManager.instance.artifacts
|
|
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
|
|
71
|
+
|
|
72
|
+
def switch
|
|
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
|
|
88
|
+
|
|
89
|
+
def generate_theme_kotlin
|
|
90
|
+
generate_theme(
|
|
91
|
+
'BrandTheme.kt',
|
|
92
|
+
Language::Kotlin,
|
|
93
|
+
Platform::Android)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def generate_theme_swift
|
|
97
|
+
generate_theme(
|
|
98
|
+
'BrandTheme.swift',
|
|
99
|
+
Language::Swift,
|
|
100
|
+
Platform::IOS)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def generate_theme_dart
|
|
104
|
+
generate_theme(
|
|
105
|
+
'brand_theme.dart',
|
|
106
|
+
Language::Dart,
|
|
107
|
+
Platform::Flutter)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def generate_theme(
|
|
111
|
+
name,
|
|
112
|
+
language,
|
|
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
|
+
|
|
123
|
+
def generate_app_config_kotlin
|
|
124
|
+
generate_brand_config(
|
|
125
|
+
'BrandConfig.kt',
|
|
126
|
+
Language::Kotlin,
|
|
127
|
+
Platform::Android
|
|
128
|
+
)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def generate_app_config_swift
|
|
132
|
+
generate_brand_config(
|
|
133
|
+
'BrandConfig.swift',
|
|
134
|
+
Language::Swift,
|
|
135
|
+
Platform::IOS)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def generate_app_config_dart
|
|
139
|
+
generate_brand_config(
|
|
140
|
+
'brand_config.dart',
|
|
141
|
+
Language::Dart,
|
|
142
|
+
Platform::Flutter)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def generate_brand_config(
|
|
146
|
+
name,
|
|
147
|
+
language,
|
|
148
|
+
platform)
|
|
149
|
+
BrandConfigManager.new(@brand_key).generate_brand_config(
|
|
150
|
+
name,
|
|
151
|
+
language,
|
|
152
|
+
platform)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def switch_flutter
|
|
156
|
+
generate_theme_dart
|
|
157
|
+
generate_app_config_dart
|
|
158
|
+
BrandResourcesManager.new(@brand_key).update_flutter
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def switch_android
|
|
162
|
+
BrandConfigManager.new(@brand_key).generate_android_properties
|
|
163
|
+
config_path = FilePath.android_brand_config(@brand_key)
|
|
164
|
+
config = JSON.parse(File.read(config_path))
|
|
165
|
+
update_build_gradle
|
|
166
|
+
update_manifest(config)
|
|
167
|
+
update_strings_xml(config)
|
|
168
|
+
BrandResourcesManager.new(@brand_key).update_android
|
|
169
|
+
generate_theme_kotlin
|
|
170
|
+
generate_app_config_kotlin
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def update_build_gradle
|
|
174
|
+
switcher = GradleSwitcher.new(@brand_key)
|
|
175
|
+
switcher.update_build_gradle
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def update_manifest(config)
|
|
179
|
+
switcher = AndroidManifestSwitcher.new
|
|
180
|
+
switcher.update_manifest(config)
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def update_strings_xml(config)
|
|
184
|
+
switcher = AndroidStringsSwitcher.new
|
|
185
|
+
switcher.update(config)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def switch_ios
|
|
189
|
+
BrandConfigManager.new(@brand_key).generate_ios_xcconfig
|
|
190
|
+
generate_theme_swift
|
|
191
|
+
generate_app_config_swift
|
|
192
|
+
update_xcode_project
|
|
193
|
+
BrandResourcesManager.new(@brand_key).update_ios
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def update_xcode_project
|
|
197
|
+
Solara.logger.start_step("Update Xcode project")
|
|
198
|
+
project_path = IOSFilePathManager.instance.xcode_project
|
|
199
|
+
switcher = XcodeProjectSwitcher.new(project_path, @brand_key)
|
|
200
|
+
switcher.switch
|
|
201
|
+
Solara.logger.end_step("Update Xcode project")
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
end
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
require 'singleton'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'rubygems'
|
|
4
|
+
|
|
5
|
+
class BrandsManager
|
|
6
|
+
include Singleton
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
brands_list_path = FilePath.brands_list
|
|
10
|
+
@brands_list = JSON.parse(File.read(brands_list_path))
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def first_brand
|
|
14
|
+
brands_list.first
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def first_brand_key
|
|
18
|
+
brands_list.first["key"]
|
|
19
|
+
rescue
|
|
20
|
+
nil
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def brand_name(brand_key)
|
|
24
|
+
brand_data(brand_key)["name"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def brand_with_configurations(brand_key)
|
|
28
|
+
configurations = BrandConfigurationsManager.new(brand_key).create
|
|
29
|
+
{
|
|
30
|
+
solaraVersion: Gem.loaded_specs['solara'].version.to_s,
|
|
31
|
+
brand: brand_data(brand_key),
|
|
32
|
+
configurations: configurations
|
|
33
|
+
}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def brand_data(brand_key)
|
|
37
|
+
brands_list.find { |brand| brand["key"] == brand_key }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def brands_list
|
|
41
|
+
@brands_list["brands"]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def find(brand_key)
|
|
45
|
+
brands = brands_list
|
|
46
|
+
brands.find { |b| b["key"] == brand_key }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def brands_json
|
|
50
|
+
@brands_list
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def exists(brand_key)
|
|
54
|
+
!brand_data(brand_key).nil?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def add_brand(brand_name, brand_key)
|
|
58
|
+
brand = { 'key' => brand_key, 'name' => brand_name }
|
|
59
|
+
existing_brand = brand_data(brand_key)
|
|
60
|
+
if existing_brand
|
|
61
|
+
update_brand(brands_list.index(existing_brand), brand)
|
|
62
|
+
Solara.logger.debug("#{brand_name} Brand updated in the list.")
|
|
63
|
+
else
|
|
64
|
+
brands_list.push(brand)
|
|
65
|
+
save_brands_list
|
|
66
|
+
Solara.logger.debug("#{brand_name} added to the list.")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def current_brand
|
|
71
|
+
JSON.parse(File.read(FilePath.current_brand))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def current_brand_content_changed(brand_key)
|
|
75
|
+
unless is_current_brand(brand_key)
|
|
76
|
+
return false
|
|
77
|
+
end
|
|
78
|
+
current_brand['content_changed'] == true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def set_current_brand_content_changed(brand_key, changed)
|
|
82
|
+
unless is_current_brand(brand_key)
|
|
83
|
+
return false
|
|
84
|
+
end
|
|
85
|
+
Solara.logger.debug("")
|
|
86
|
+
brand = current_brand
|
|
87
|
+
brand['content_changed'] = changed
|
|
88
|
+
save_current_brand_date(brand)
|
|
89
|
+
Solara.logger.debug("#{brand_key} changed saved to current_brand.json.")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def is_current_brand(brand_key)
|
|
93
|
+
current_brand['key'] == brand_key
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def save_current_brand(brand_key)
|
|
97
|
+
brand = brand_data(brand_key)
|
|
98
|
+
save_current_brand_date(brand)
|
|
99
|
+
Solara.logger.debug("#{brand_key} saved as current brand.")
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def save_current_brand_date(brand_data)
|
|
103
|
+
current_brand = FilePath.current_brand
|
|
104
|
+
|
|
105
|
+
# Create the file if it doesn't exist
|
|
106
|
+
FileUtils.touch(current_brand) unless File.exist?(current_brand)
|
|
107
|
+
|
|
108
|
+
File.open(current_brand, 'w') do |file|
|
|
109
|
+
file.write(JSON.pretty_generate(brand_data))
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def update_brand(index, new_brand)
|
|
115
|
+
brands_list[index] = new_brand
|
|
116
|
+
save_brands_list
|
|
117
|
+
Solara.logger.debug("Brand updated.")
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def remove_brand(index)
|
|
121
|
+
brands_list.delete_at(index)
|
|
122
|
+
save_brands_list
|
|
123
|
+
Solara.logger.debug("Brand removed.")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def offboard(brand_key)
|
|
127
|
+
index = brands_list.find_index { |brand| brand["key"] == brand_key }
|
|
128
|
+
if index
|
|
129
|
+
brand_dir = FilePath.brand(brand_key)
|
|
130
|
+
remove_brand(index)
|
|
131
|
+
FileUtils.rm_rf(brand_dir)
|
|
132
|
+
save_brands_list
|
|
133
|
+
Solara.logger.debug("Brand removed.")
|
|
134
|
+
else
|
|
135
|
+
Solara.logger.debug("Brand not found (#{brand_key}).")
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Class method to access the singleton instance
|
|
140
|
+
def self.instance
|
|
141
|
+
@instance ||= new
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def save_brands_list
|
|
147
|
+
brands_list_path = FilePath.brands_list
|
|
148
|
+
File.open(brands_list_path, 'w') do |file|
|
|
149
|
+
file.write(JSON.pretty_generate(@brands_list))
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
private_class_method :new
|
|
154
|
+
end
|
|
Binary file
|
|
Binary file
|