solara 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/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
|