Module: AnnFlavorCore::Parser
- Defined in:
- lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb
Overview
Single source of truth for parsing annspec.yaml.
Two entry points:
AnnFlavorCore::Parser.parse(yaml_string) — from raw YAML text
AnnFlavorCore::Parser.parse_file(path) — from a file path
AnnFlavorCore::Parser.from_hash(hash) — from a pre-parsed Hash
(e.g. in-memory UI data)
After parsing, pass the AnnSpec to AnnFlavorCore::Resolver.resolve_all to obtain all resolved (effective) values per flavor × build-type.
Constant Summary collapse
- DART_DEFINES_ACTION_KEYS =
%w[compile run deploy].freeze
Class Method Summary collapse
- .from_hash(raw) ⇒ Object
-
.h(map, key) ⇒ Object
Safe Hash accessor — returns {} when key is missing or value is not a Hash.
- .normalize_custom_value(v) ⇒ Object
- .parse(yaml_string) ⇒ Object
-
.parse_android(m) ⇒ Object
── Android ───────────────────────────────────────────────────────────────.
- .parse_android_credentials(m) ⇒ Object
- .parse_android_default(m) ⇒ Object
- .parse_android_flavor(m) ⇒ Object
- .parse_android_sdk(m) ⇒ Object
-
.parse_ann_app(m) ⇒ Object
── AnnApp ────────────────────────────────────────────────────────────────.
- .parse_auth_config(m) ⇒ Object
- .parse_build_type_configs(m) ⇒ Object
- .parse_cloudflare(m) ⇒ Object
- .parse_custom_config(m) ⇒ Object
-
.parse_dart_defines(m) ⇒ Object
Parses dart_defines: — plain string entries are the common map; the three reserved sub-keys compile/run/deploy (each a nested map) become the corresponding action scope.
- .parse_debug_config(m) ⇒ Object
- .parse_file(path) ⇒ Object
-
.parse_firebase_config(m) ⇒ Object
── Shared parsers ────────────────────────────────────────────────────────.
- .parse_flavor_stores(m) ⇒ Object
- .parse_flavors(flavor_map, &parse_fn) ⇒ Object
- .parse_general(_m) ⇒ Object
- .parse_integrations(m) ⇒ Object
-
.parse_ios(m) ⇒ Object
── iOS ───────────────────────────────────────────────────────────────────.
- .parse_ios_credentials(m) ⇒ Object
- .parse_ios_default(m) ⇒ Object
- .parse_ios_flavor(m) ⇒ Object
- .parse_tooling(m) ⇒ Object
-
.parse_web(m) ⇒ Object
── Web ───────────────────────────────────────────────────────────────────.
- .parse_web_default(m) ⇒ Object
- .parse_web_flavor(m) ⇒ Object
-
.parse_windows(m) ⇒ Object
── Windows ───────────────────────────────────────────────────────────────.
- .parse_windows_default(m) ⇒ Object
- .parse_windows_flavor(m) ⇒ Object
Class Method Details
.from_hash(raw) ⇒ Object
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 27 def self.from_hash(raw) app_hash = h(raw, 'app') tooling_hash = h(raw, 'tooling') AnnSpec.new( app: parse_ann_app(app_hash), enabled: raw.fetch('enabled', true), debug_config: parse_debug_config(h(raw, 'debug')), tooling: (parse_tooling(tooling_hash) unless tooling_hash.empty?), ) end |
.h(map, key) ⇒ Object
Safe Hash accessor — returns {} when key is missing or value is not a Hash
352 353 354 355 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 352 def self.h(map, key) val = map.is_a?(Hash) ? map[key] : nil val.is_a?(Hash) ? val : {} end |
.normalize_custom_value(v) ⇒ Object
46 47 48 49 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 46 def self.normalize_custom_value(v) return v.map { |e| e.nil? ? '' : e.to_s } if v.is_a?(Array) v end |
.parse(yaml_string) ⇒ Object
18 19 20 21 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 18 def self.parse(yaml_string) raw = YAML.safe_load(yaml_string, aliases: true) || {} from_hash(raw) end |
.parse_android(m) ⇒ Object
── Android ───────────────────────────────────────────────────────────────
82 83 84 85 86 87 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 82 def self.parse_android(m) AndroidPlatform.new( default: parse_android_default(h(m, 'default')), flavors: parse_flavors(h(m, 'flavor')) { |v| parse_android_flavor(v) }, ) end |
.parse_android_credentials(m) ⇒ Object
131 132 133 134 135 136 137 138 139 140 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 131 def self.parse_android_credentials(m) AndroidCredentials.new( signing: (AndroidSigning.new(key_file: h(m, 'signing')['key_file']) unless h(m, 'signing').empty?), google_play: (GooglePlayCredentials.new(api_key: h(m, 'google_play')['api_key']) unless h(m, 'google_play').empty?), samsung_galaxy: (SamsungGalaxyCredentials.new(seller_id: h(m, 'samsung_galaxy')['seller_id'], api_key: h(m, 'samsung_galaxy')['api_key']) unless h(m, 'samsung_galaxy').empty?), amazon: (AmazonCredentials.new(client_id: h(m, 'amazon')['client_id'], client_secret: h(m, 'amazon')['client_secret']) unless h(m, 'amazon').empty?), ) end |
.parse_android_default(m) ⇒ Object
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 89 def self.parse_android_default(m) AndroidDefault.new( id: m['id'], name: m['name'], version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], admob: (AdmobConfig.new(gms_ads_id: h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']) unless (h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']).nil?), icon: m['icon'], sdk: (parse_android_sdk(h(m, 'sdk')) unless h(m, 'sdk').empty?), credentials: (parse_android_credentials(h(m, 'credentials')) unless h(m, 'credentials').empty?), firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), ) end |
.parse_android_flavor(m) ⇒ Object
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 107 def self.parse_android_flavor(m) AndroidFlavor.new( id: m['id'], id_suffix: m.fetch('id_suffix', '').to_s, name: m['name'], name_suffix: m.fetch('name_suffix', '').to_s, version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], admob: (AdmobConfig.new(gms_ads_id: h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']) unless (h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']).nil?), icon: m['icon'], firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), stores: (parse_flavor_stores(h(m, 'stores')) unless h(m, 'stores').empty?), credentials: (parse_android_credentials(h(m, 'credentials')) unless h(m, 'credentials').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), ) end |
.parse_android_sdk(m) ⇒ Object
127 128 129 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 127 def self.parse_android_sdk(m) AndroidSdk.new(min_sdk: m['minSdk'], compile_sdk: m['compileSdk'], target_sdk: m['targetSdk']) end |
.parse_ann_app(m) ⇒ Object
── AnnApp ────────────────────────────────────────────────────────────────
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 61 def self.parse_ann_app(m) AnnApp.new( android: (parse_android(h(m, 'android')) unless h(m, 'android').empty?), ios: (parse_ios(h(m, 'ios')) unless h(m, 'ios').empty?), web: (parse_web(h(m, 'web')) unless h(m, 'web').empty?), windows: (parse_windows(h(m, 'windows')) unless h(m, 'windows').empty?), general: (parse_general(h(m, 'general')) unless h(m, 'general').empty?), integrations: (parse_integrations(h(m, 'integrations')) unless h(m, 'integrations').empty?), ) end |
.parse_auth_config(m) ⇒ Object
293 294 295 296 297 298 299 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 293 def self.parse_auth_config(m) AuthConfig.new( client_id: m['clientId'], reversed_client_id: m['reversedClientId'], others: h(m, 'others'), ) end |
.parse_build_type_configs(m) ⇒ Object
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 301 def self.parse_build_type_configs(m) m.transform_values do |v| v = v.is_a?(Hash) ? v : {} BuildTypeConfig.new( id_suffix: v.fetch('id_suffix', '').to_s, name_suffix: v.fetch('name_suffix', '').to_s, firebase: (parse_firebase_config(h(v, 'firebase')) unless h(v, 'firebase').empty?), auth: (parse_auth_config(h(v, 'auth')) unless h(v, 'auth').empty?), admob: (AdmobConfig.new(gms_ads_id: h(v, 'admob')['gms_ads_id']) unless h(v, 'admob').empty?), minify_enabled: v['minifyEnabled'], shrink_resources: v['shrinkResources'], lint_check_release_builds: v['lintCheckReleaseBuilds'], ndk_version: v['ndkVersion'], ndk_debug_symbol_level: v['ndkDebugSymbolLevel'], ndk_abi_filters: (v['ndkAbiFilters'].is_a?(Array) ? v['ndkAbiFilters'] : []), custom: parse_custom_config(h(v, 'custom')), dart_defines: parse_dart_defines(h(v, 'dart_defines')), info_plist: v['info_plist'], ) end end |
.parse_cloudflare(m) ⇒ Object
238 239 240 241 242 243 244 245 246 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 238 def self.parse_cloudflare(m) return nil if m.empty? CloudflareConfig.new( project_name: m['project_name'], account_id: m['account_id'], branch: m['branch'], mode: m['mode'], ) end |
.parse_custom_config(m) ⇒ Object
38 39 40 41 42 43 44 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 38 def self.parse_custom_config(m) return {} unless m.is_a?(Hash) m.transform_values do |group_val| next {} unless group_val.is_a?(Hash) group_val.transform_values { |v| normalize_custom_value(v) } end end |
.parse_dart_defines(m) ⇒ Object
Parses dart_defines: — plain string entries are the common map; the three reserved sub-keys compile/run/deploy (each a nested map) become the corresponding action scope. Values are coerced to strings.
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 362 def self.parse_dart_defines(m) return DartDefines.defaults unless m.is_a?(Hash) string_map = ->(raw) { return {} unless raw.is_a?(Hash) raw.transform_values { |v| v.nil? ? '' : v.to_s } } common = m.reject { |k, _| DART_DEFINES_ACTION_KEYS.include?(k) } .transform_values { |v| v.nil? ? '' : v.to_s } DartDefines.new( common: common, compile: string_map.call(m['compile']), run: string_map.call(m['run']), deploy: string_map.call(m['deploy']), ) end |
.parse_debug_config(m) ⇒ Object
337 338 339 340 341 342 343 344 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 337 def self.parse_debug_config(m) DebugConfig.new( print_debug: m.fetch('printDebug', false), print_build_and_flavor_info: m.fetch('printBuildAndFlavorInfo', true), print_sdk_versions: m.fetch('printSdkVersions', true), print_release_build_type_info: m.fetch('printReleaseBuildTypeInfo', false), ) end |
.parse_file(path) ⇒ Object
23 24 25 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 23 def self.parse_file(path) parse(File.read(path)) end |
.parse_firebase_config(m) ⇒ Object
── Shared parsers ────────────────────────────────────────────────────────
284 285 286 287 288 289 290 291 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 284 def self.parse_firebase_config(m) FirebaseConfig.new( project_id: m['project_id'], config_file: m['config_file'], service_account: m['service_account'], target: m['target'], ) end |
.parse_flavor_stores(m) ⇒ Object
323 324 325 326 327 328 329 330 331 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 323 def self.parse_flavor_stores(m) FlavorStores.new( google_play: (GooglePlayFlavorStore.new(priority: h(m, 'google_play')['priority']) unless h(m, 'google_play').empty?), samsung_galaxy: (SamsungGalaxyFlavorStore.new(app_id: h(m, 'samsung_galaxy')['app_id']) unless h(m, 'samsung_galaxy').empty?), amazon: (AmazonFlavorStore.new(app_id: h(m, 'amazon')['app_id']) unless h(m, 'amazon').empty?), app_store: (AppStoreFlavorStore.new(apple_id: h(m, 'app_store')['apple_id'], team_id: h(m, 'app_store')['team_id']) unless h(m, 'app_store').empty?), ) end |
.parse_flavors(flavor_map, &parse_fn) ⇒ Object
346 347 348 349 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 346 def self.parse_flavors(flavor_map, &parse_fn) return {} unless flavor_map.is_a?(Hash) flavor_map.transform_values { |v| parse_fn.call(v.is_a?(Hash) ? v : {}) } end |
.parse_general(_m) ⇒ Object
333 334 335 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 333 def self.parse_general(_m) GeneralConfig.new end |
.parse_integrations(m) ⇒ Object
72 73 74 75 76 77 78 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 72 def self.parse_integrations(m) AnnIntegrations.new( fastlane: m.fetch('fastlane', false), melos: m.fetch('melos', false), firebase: m.fetch('firebase', false), ) end |
.parse_ios(m) ⇒ Object
── iOS ───────────────────────────────────────────────────────────────────
144 145 146 147 148 149 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 144 def self.parse_ios(m) IosPlatform.new( default: parse_ios_default(h(m, 'default')), flavors: parse_flavors(h(m, 'flavor')) { |v| parse_ios_flavor(v) }, ) end |
.parse_ios_credentials(m) ⇒ Object
190 191 192 193 194 195 196 197 198 199 200 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 190 def self.parse_ios_credentials(m) IosCredentials.new( signing: (IosSigning.new(team_id: h(m, 'signing')['team_id']) unless h(m, 'signing').empty?), app_store: (AppStoreCredentials.new( api_key: h(m, 'app_store')['api_key'], export_options_plist: h(m, 'app_store')['export_options_plist'], export_options_team_id: h(m, 'app_store')['export_options_team_id'], export_options_signing_certificate: h(m, 'app_store')['export_options_signing_certificate'], ) unless h(m, 'app_store').empty?), ) end |
.parse_ios_default(m) ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 151 def self.parse_ios_default(m) IosDefault.new( id: m['id'], name: m['name'], version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], admob: (AdmobConfig.new(gms_ads_id: h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']) unless (h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']).nil?), icon: m['icon'], credentials: (parse_ios_credentials(h(m, 'credentials')) unless h(m, 'credentials').empty?), firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), info_plist: m['info_plist'], ) end |
.parse_ios_flavor(m) ⇒ Object
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 169 def self.parse_ios_flavor(m) IosFlavor.new( id: m['id'], id_suffix: m.fetch('id_suffix', '').to_s, name: m['name'], name_suffix: m.fetch('name_suffix', '').to_s, version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], admob: (AdmobConfig.new(gms_ads_id: h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']) unless (h(m, 'admob')['gms_ads_id'] || m['gms_ads_id']).nil?), icon: m['icon'], firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), stores: (parse_flavor_stores(h(m, 'stores')) unless h(m, 'stores').empty?), credentials: (parse_ios_credentials(h(m, 'credentials')) unless h(m, 'credentials').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), info_plist: m['info_plist'], ) end |
.parse_tooling(m) ⇒ Object
51 52 53 54 55 56 57 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 51 def self.parse_tooling(m) ToolingConfig.new( gradle_plugin: m['gradle_plugin'], cocoapods_plugin: m['cocoapods_plugin'], fastlane_plugin: m['fastlane_plugin'], ) end |
.parse_web(m) ⇒ Object
── Web ───────────────────────────────────────────────────────────────────
204 205 206 207 208 209 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 204 def self.parse_web(m) WebPlatform.new( default: parse_web_default(h(m, 'default')), flavors: parse_flavors(h(m, 'flavor')) { |v| parse_web_flavor(v) }, ) end |
.parse_web_default(m) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 211 def self.parse_web_default(m) WebDefault.new( id: m['id'], name: m['name'], version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], icon: m['icon'], cloudflare: parse_cloudflare(h(m, 'cloudflare')), firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), ) end |
.parse_web_flavor(m) ⇒ Object
224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 224 def self.parse_web_flavor(m) WebFlavor.new( id: m['id'], id_suffix: m.fetch('id_suffix', '').to_s, name: m['name'], name_suffix: m.fetch('name_suffix', '').to_s, version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], icon: m['icon'], cloudflare: parse_cloudflare(h(m, 'cloudflare')), firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), ) end |
.parse_windows(m) ⇒ Object
── Windows ───────────────────────────────────────────────────────────────
250 251 252 253 254 255 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 250 def self.parse_windows(m) WindowsPlatform.new( default: parse_windows_default(h(m, 'default')), flavors: parse_flavors(h(m, 'flavor')) { |v| parse_windows_flavor(v) }, ) end |
.parse_windows_default(m) ⇒ Object
257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 257 def self.parse_windows_default(m) WindowsDefault.new( id: m['id'], name: m['name'], version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), ) end |
.parse_windows_flavor(m) ⇒ Object
269 270 271 272 273 274 275 276 277 278 279 280 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb', line 269 def self.parse_windows_flavor(m) WindowsFlavor.new( id: m['id'], id_suffix: m.fetch('id_suffix', '').to_s, name: m['name'], name_suffix: m.fetch('name_suffix', '').to_s, version_name: m['version_name']&.to_s, version_code: m['version_code']&.to_i, main_file: m['main_file'], firebase: (parse_firebase_config(h(m, 'firebase')) unless h(m, 'firebase').empty?), build_types: parse_build_type_configs(h(m, 'build_types')), custom: parse_custom_config(h(m, 'custom')), dart_defines: parse_dart_defines(h(m, 'dart_defines')), ) end |