Module: AnnFlavorCore::Resolver
- Defined in:
- lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb
Constant Summary collapse
- STANDARD_BUILD_TYPES =
%w[debug release profile].freeze
Class Method Summary collapse
- .effective_bt_config(flavor_bts, default_bts, build_type) ⇒ Object
-
.effective_build_type_suffix(flavor_suffix, default_suffix) ⇒ Object
── Low-level cascade helpers (used by all plugins) ───────────────────────.
- .merge_auth_config(flavor, default) ⇒ Object
-
.merge_defines_map(default_map, default_bt_map, flavor_map, flavor_bt_map) ⇒ Object
Shallow key-union across all four cascade levels — most specific key wins.
- .merge_firebase_config(flavor, default) ⇒ Object
-
.resolve_all(spec, build_types: STANDARD_BUILD_TYPES) ⇒ Object
── High-level resolver ───────────────────────────────────────────────────.
- .resolve_android(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
-
.resolve_android_flavor(flavor, defaults, build_type) ⇒ Object
── Per-flavor resolvers (callable directly from UI / in-memory data) ─────.
- .resolve_cloudflare(flavor_cf, default_cf) ⇒ Object
-
.resolve_custom(default_custom, default_bt_custom, flavor_custom, flavor_bt_custom) ⇒ Object
Deep-merges custom config — lowest priority first, key-by-key within each group.
-
.resolve_dart_defines(default_defines, default_bt_defines, flavor_defines, flavor_bt_defines) ⇒ Object
Resolves all four dart_defines sub-maps (common + three action scopes) independently.
- .resolve_firebase(flavor_bt, flavor_top, default_bt, default_top) ⇒ Object
- .resolve_id(base_id, id_suffix, build_type_id_suffix = '') ⇒ Object
- .resolve_ios(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
- .resolve_ios_flavor(flavor, defaults, build_type) ⇒ Object
- .resolve_name(base_name, name_suffix, build_type_name_suffix = '') ⇒ Object
- .resolve_web(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
- .resolve_web_flavor(flavor, defaults, build_type) ⇒ Object
- .resolve_windows(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
- .resolve_windows_flavor(flavor, defaults, build_type) ⇒ Object
Class Method Details
.effective_bt_config(flavor_bts, default_bts, build_type) ⇒ Object
201 202 203 204 205 206 207 208 209 210 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 201 def self.effective_bt_config(flavor_bts, default_bts, build_type) f = (flavor_bts || {})[build_type] d = (default_bts || {})[build_type] BuildTypeConfig.new( id_suffix: effective_build_type_suffix(f&.id_suffix, d&.id_suffix), name_suffix: effective_build_type_suffix(f&.name_suffix, d&.name_suffix), firebase: merge_firebase_config(f&.firebase, d&.firebase), auth: merge_auth_config(f&.auth, d&.auth), ) end |
.effective_build_type_suffix(flavor_suffix, default_suffix) ⇒ Object
── Low-level cascade helpers (used by all plugins) ───────────────────────
9 10 11 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 9 def self.effective_build_type_suffix(flavor_suffix, default_suffix) flavor_suffix.to_s.empty? ? default_suffix.to_s : flavor_suffix.to_s end |
.merge_auth_config(flavor, default) ⇒ Object
256 257 258 259 260 261 262 263 264 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 256 def self.merge_auth_config(flavor, default) return default if flavor.nil? return flavor if default.nil? AuthConfig.new( client_id: flavor.client_id || default.client_id, reversed_client_id: flavor.reversed_client_id || default.reversed_client_id, others: (default.others || {}).merge(flavor.others || {}), ) end |
.merge_defines_map(default_map, default_bt_map, flavor_map, flavor_bt_map) ⇒ Object
Shallow key-union across all four cascade levels — most specific key wins.
179 180 181 182 183 184 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 179 def self.merge_defines_map(default_map, default_bt_map, flavor_map, flavor_bt_map) (default_map || {}) .merge(default_bt_map || {}) .merge(flavor_map || {}) .merge(flavor_bt_map || {}) end |
.merge_firebase_config(flavor, default) ⇒ Object
243 244 245 246 247 248 249 250 251 252 253 254 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 243 def self.merge_firebase_config(flavor, default) return default if flavor.nil? return flavor if default.nil? # service_account cascades independently — a flavor can override project_id without having to # repeat the service_account key, and vice versa. FirebaseConfig.new( project_id: flavor.project_id || default.project_id, config_file: flavor.config_file || default.config_file, service_account: flavor.service_account || default.service_account, target: flavor.target || default.target, ) end |
.resolve_all(spec, build_types: STANDARD_BUILD_TYPES) ⇒ Object
── High-level resolver ───────────────────────────────────────────────────
Usage patterns:
# From YAML (batch — all platforms, all build types)
spec = AnnFlavorCore::Parser.parse_file('annspec.yaml')
resolved = AnnFlavorCore::Resolver.resolve_all(spec)
# From in-memory model (e.g. live UI data before saving to YAML)
output = AnnFlavorCore::Resolver.resolve_android_flavor(flavor, defaults, 'debug')
32 33 34 35 36 37 38 39 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 32 def self.resolve_all(spec, build_types: STANDARD_BUILD_TYPES) ResolvedSpec.new( android: spec.app&.android ? resolve_android(spec.app.android, build_types: build_types) : {}, ios: spec.app&.ios ? resolve_ios(spec.app.ios, build_types: build_types) : {}, web: spec.app&.web ? resolve_web(spec.app.web, build_types: build_types) : {}, windows: spec.app&.windows ? resolve_windows(spec.app.windows, build_types: build_types) : {}, ) end |
.resolve_android(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
41 42 43 44 45 46 47 48 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 41 def self.resolve_android(platform, build_types: STANDARD_BUILD_TYPES) platform.flavors.each_with_object({}) do |(name, flavor), result| result[name] = ResolvedFlavor.new( flavor_name: name, by_build_type: build_types.each_with_object({}) { |bt, h| h[bt] = resolve_android_flavor(flavor, platform.default, bt) }, ) end end |
.resolve_android_flavor(flavor, defaults, build_type) ⇒ Object
── Per-flavor resolvers (callable directly from UI / in-memory data) ─────
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 79 def self.resolve_android_flavor(flavor, defaults, build_type) bt = effective_bt_config(flavor.build_types, defaults.build_types, build_type) ResolvedBuildOutput.new( flavor_name: nil, build_type: build_type, effective_id: resolve_id((flavor.id || defaults.id).to_s, flavor.id_suffix.to_s, bt.id_suffix), effective_name: resolve_name((flavor.name || defaults.name).to_s, flavor.name_suffix.to_s, bt.name_suffix), effective_version_name: (flavor.version_name || defaults.version_name).to_s, effective_version_code: flavor.version_code || defaults.version_code, effective_main_file: flavor.main_file || defaults.main_file, effective_firebase: resolve_firebase(flavor.build_types[build_type]&.firebase, flavor.firebase, defaults.build_types[build_type]&.firebase, defaults.firebase), effective_auth: bt.auth, effective_gms_ads_id: flavor.admob&.gms_ads_id || defaults.admob&.gms_ads_id, effective_icon: flavor.icon || defaults.icon, effective_custom: resolve_custom(defaults.custom, defaults.build_types[build_type]&.custom, flavor.custom, flavor.build_types[build_type]&.custom), effective_dart_defines: resolve_dart_defines(defaults.dart_defines, defaults.build_types[build_type]&.dart_defines, flavor.dart_defines, flavor.build_types[build_type]&.dart_defines), ) end |
.resolve_cloudflare(flavor_cf, default_cf) ⇒ Object
137 138 139 140 141 142 143 144 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 137 def self.resolve_cloudflare(flavor_cf, default_cf) CloudflareConfig.new( project_name: flavor_cf&.project_name, account_id: flavor_cf&.account_id || default_cf&.account_id, branch: flavor_cf&.branch || default_cf&.branch || 'main', mode: flavor_cf&.mode || default_cf&.mode || 'pages', ) end |
.resolve_custom(default_custom, default_bt_custom, flavor_custom, flavor_bt_custom) ⇒ Object
Deep-merges custom config — lowest priority first, key-by-key within each group.
168 169 170 171 172 173 174 175 176 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 168 def self.resolve_custom(default_custom, default_bt_custom, flavor_custom, flavor_bt_custom) merge = lambda do |base, over| next base if over.nil? || over.empty? result = base.dup over.each { |group, group_map| result[group] = (result[group] || {}).merge(group_map) } result end merge.call(merge.call(merge.call(default_custom || {}, default_bt_custom), flavor_custom), flavor_bt_custom) end |
.resolve_dart_defines(default_defines, default_bt_defines, flavor_defines, flavor_bt_defines) ⇒ Object
Resolves all four dart_defines sub-maps (common + three action scopes) independently.
188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 188 def self.resolve_dart_defines(default_defines, default_bt_defines, flavor_defines, flavor_bt_defines) d = default_defines || DartDefines.defaults db = default_bt_defines || DartDefines.defaults f = flavor_defines || DartDefines.defaults fb = flavor_bt_defines || DartDefines.defaults DartDefines.new( common: merge_defines_map(d.common, db.common, f.common, fb.common), compile: merge_defines_map(d.compile, db.compile, f.compile, fb.compile), run: merge_defines_map(d.run, db.run, f.run, fb.run), deploy: merge_defines_map(d.deploy, db.deploy, f.deploy, fb.deploy), ) end |
.resolve_firebase(flavor_bt, flavor_top, default_bt, default_top) ⇒ Object
Full 4-level cascade for every firebase field (most specific wins):
L1: flavor_bt — flavor.build_types[bt].firebase
L2: flavor_top — flavor.firebase
L3: default_bt — default.build_types[bt].firebase
L4: default_top — defaults.firebase
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 217 def self.resolve_firebase(flavor_bt, flavor_top, default_bt, default_top) project_id = flavor_bt&.project_id || flavor_top&.project_id || default_bt&.project_id || default_top&.project_id config_file = flavor_bt&.config_file || flavor_top&.config_file || default_bt&.config_file || default_top&.config_file sa = flavor_bt&.service_account || flavor_top&.service_account || default_bt&.service_account || default_top&.service_account target = flavor_bt&.target || flavor_top&.target || default_bt&.target || default_top&.target return nil if project_id.nil? && config_file.nil? && sa.nil? && target.nil? FirebaseConfig.new( project_id: project_id, config_file: config_file, service_account: sa, target: target, ) end |
.resolve_id(base_id, id_suffix, build_type_id_suffix = '') ⇒ Object
13 14 15 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 13 def self.resolve_id(base_id, id_suffix, build_type_id_suffix = '') base_id.to_s + id_suffix.to_s + build_type_id_suffix.to_s end |
.resolve_ios(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
50 51 52 53 54 55 56 57 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 50 def self.resolve_ios(platform, build_types: STANDARD_BUILD_TYPES) platform.flavors.each_with_object({}) do |(name, flavor), result| result[name] = ResolvedFlavor.new( flavor_name: name, by_build_type: build_types.each_with_object({}) { |bt, h| h[bt] = resolve_ios_flavor(flavor, platform.default, bt) }, ) end end |
.resolve_ios_flavor(flavor, defaults, build_type) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 98 def self.resolve_ios_flavor(flavor, defaults, build_type) bt = effective_bt_config(flavor.build_types, defaults.build_types, build_type) ResolvedBuildOutput.new( flavor_name: nil, build_type: build_type, effective_id: resolve_id((flavor.id || defaults.id).to_s, flavor.id_suffix.to_s, bt.id_suffix), effective_name: resolve_name((flavor.name || defaults.name).to_s, flavor.name_suffix.to_s, bt.name_suffix), effective_version_name: (flavor.version_name || defaults.version_name).to_s, effective_version_code: flavor.version_code || defaults.version_code, effective_main_file: flavor.main_file || defaults.main_file, effective_firebase: resolve_firebase(flavor.build_types[build_type]&.firebase, flavor.firebase, defaults.build_types[build_type]&.firebase, defaults.firebase), effective_auth: bt.auth, effective_gms_ads_id: flavor.admob&.gms_ads_id || defaults.admob&.gms_ads_id, effective_icon: flavor.icon || defaults.icon, effective_custom: resolve_custom(defaults.custom, defaults.build_types[build_type]&.custom, flavor.custom, flavor.build_types[build_type]&.custom), effective_dart_defines: resolve_dart_defines(defaults.dart_defines, defaults.build_types[build_type]&.dart_defines, flavor.dart_defines, flavor.build_types[build_type]&.dart_defines), ) end |
.resolve_name(base_name, name_suffix, build_type_name_suffix = '') ⇒ Object
17 18 19 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 17 def self.resolve_name(base_name, name_suffix, build_type_name_suffix = '') base_name.to_s + name_suffix.to_s + build_type_name_suffix.to_s end |
.resolve_web(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
59 60 61 62 63 64 65 66 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 59 def self.resolve_web(platform, build_types: STANDARD_BUILD_TYPES) platform.flavors.each_with_object({}) do |(name, flavor), result| result[name] = ResolvedFlavor.new( flavor_name: name, by_build_type: build_types.each_with_object({}) { |bt, h| h[bt] = resolve_web_flavor(flavor, platform.default, bt) }, ) end end |
.resolve_web_flavor(flavor, defaults, build_type) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 117 def self.resolve_web_flavor(flavor, defaults, build_type) bt = effective_bt_config(flavor.build_types, defaults.build_types, build_type) ResolvedBuildOutput.new( flavor_name: nil, build_type: build_type, effective_id: resolve_id((flavor.id || defaults.id).to_s, flavor.id_suffix.to_s, bt.id_suffix), effective_name: resolve_name((flavor.name || defaults.name).to_s, flavor.name_suffix.to_s, bt.name_suffix), effective_version_name: (flavor.version_name || defaults.version_name).to_s, effective_version_code: flavor.version_code || defaults.version_code, effective_main_file: flavor.main_file || defaults.main_file, effective_firebase: resolve_firebase(flavor.build_types[build_type]&.firebase, flavor.firebase, defaults.build_types[build_type]&.firebase, defaults.firebase), effective_auth: bt.auth, effective_gms_ads_id: nil, effective_icon: flavor.icon || defaults.icon, effective_cloudflare: resolve_cloudflare(flavor.cloudflare, defaults.cloudflare), effective_custom: resolve_custom(defaults.custom, defaults.build_types[build_type]&.custom, flavor.custom, flavor.build_types[build_type]&.custom), effective_dart_defines: resolve_dart_defines(defaults.dart_defines, defaults.build_types[build_type]&.dart_defines, flavor.dart_defines, flavor.build_types[build_type]&.dart_defines), ) end |
.resolve_windows(platform, build_types: STANDARD_BUILD_TYPES) ⇒ Object
68 69 70 71 72 73 74 75 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 68 def self.resolve_windows(platform, build_types: STANDARD_BUILD_TYPES) platform.flavors.each_with_object({}) do |(name, flavor), result| result[name] = ResolvedFlavor.new( flavor_name: name, by_build_type: build_types.each_with_object({}) { |bt, h| h[bt] = resolve_windows_flavor(flavor, platform.default, bt) }, ) end end |
.resolve_windows_flavor(flavor, defaults, build_type) ⇒ Object
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb', line 146 def self.resolve_windows_flavor(flavor, defaults, build_type) bt = effective_bt_config(flavor.build_types, defaults.build_types, build_type) ResolvedBuildOutput.new( flavor_name: nil, build_type: build_type, effective_id: resolve_id((flavor.id || defaults.id).to_s, flavor.id_suffix.to_s, bt.id_suffix), effective_name: resolve_name((flavor.name || defaults.name).to_s, flavor.name_suffix.to_s, bt.name_suffix), effective_version_name: (flavor.version_name || defaults.version_name).to_s, effective_version_code: flavor.version_code || defaults.version_code, effective_main_file: flavor.main_file || defaults.main_file, effective_firebase: resolve_firebase(flavor.build_types[build_type]&.firebase, flavor.firebase, defaults.build_types[build_type]&.firebase, defaults.firebase), effective_auth: bt.auth, effective_gms_ads_id: nil, effective_icon: nil, effective_custom: resolve_custom(defaults.custom, defaults.build_types[build_type]&.custom, flavor.custom, flavor.build_types[build_type]&.custom), effective_dart_defines: resolve_dart_defines(defaults.dart_defines, defaults.build_types[build_type]&.dart_defines, flavor.dart_defines, flavor.build_types[build_type]&.dart_defines), ) end |