ann-flavor-cocoapods 0.1.39 → 0.3.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 +4 -4
- data/CHANGELOG.md +48 -0
- data/lib/ann_flavor_cocoapods/podfile_helper.rb +155 -5
- data/lib/ann_flavor_cocoapods/version.rb +1 -1
- data/lib/vendor/ann_flavor_core/lib/ann_flavor_core/model.rb +4 -3
- data/lib/vendor/ann_flavor_core/lib/ann_flavor_core/parser.rb +3 -0
- data/lib/vendor/ann_flavor_core/lib/ann_flavor_core/resolver.rb +3 -0
- data/lib/vendor/ann_flavor_core/lib/ann_flavor_core/strict_mode_checker.rb +7 -6
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 203077b214e8b6dcbf87c8792ea6df6055d34b4b6ea36af00c1c28a94207aab9
|
|
4
|
+
data.tar.gz: fcdbfba3ba5e54184fb3d05ace52259c10476947259d550cc4b134009d83e560
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1968396623737c7d68439d68cb2fb4d8b8ac6d1da7bba9c32722bc9a0408e3d73fc2b6a4087fbff63231d0d8bd1403949d62e46bf2382a7d9361bd33a7d9fbd1
|
|
7
|
+
data.tar.gz: 5f6f3d65b87f5f8c41d52f6201c622fb379da14d81cf7d6338edf5a76bde7168213c2722f067495d0e8571f0ce35415f67e37538f47f4b5d266e297887672cee
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **New `[ann-flavor] Merge Info.plist` build phase composes the final
|
|
7
|
+
Info.plist Xcode builds against at build time**, not sync time: copies
|
|
8
|
+
`ios/Runner/Info.plist` (the generic/base layer, developer-owned, always
|
|
9
|
+
present) to `$(DERIVED_FILE_DIR)/Info-merged.plist`, then merges in every
|
|
10
|
+
key from the current flavor's `ios/ann/Info/Info-<flavor>.plist` delta (see
|
|
11
|
+
`ann_flutter_flavor` 1.2.0 — that file now holds only the flavor's
|
|
12
|
+
`info_plist:` cascade, not a full copy of `Runner/Info.plist`), with the
|
|
13
|
+
flavor's value winning on any key both define. Uses `PlistBuddy`
|
|
14
|
+
(`/usr/libexec/PlistBuddy`), not `python3`/`ruby` — ships as part of Xcode
|
|
15
|
+
itself, so this phase adds no dependency on any scripting runtime beyond
|
|
16
|
+
what Xcode already requires. Every plist value type (string, bool, integer,
|
|
17
|
+
real, array, nested dict — e.g. `SKAdNetworkItems`) round-trips correctly
|
|
18
|
+
through the merge, not just strings. Prints a one-line notice to the Xcode
|
|
19
|
+
build log for any key the flavor delta actually overrides, to make an
|
|
20
|
+
unintentional override easy to spot. Found-and-updated in place on a
|
|
21
|
+
re-run, same UUID-stability guarantee as the Firebase-copy and Print Build
|
|
22
|
+
Info phases.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- **`INFOPLIST_FILE` now points at `$(DERIVED_FILE_DIR)/Info-merged.plist`**
|
|
26
|
+
(the Merge Info.plist phase's output above) instead of directly at
|
|
27
|
+
`ios/ann/Info/Info-<flavor>.plist`. Enables `Runner/Info.plist` to remain a
|
|
28
|
+
live, always-consulted base layer instead of a one-time sync-time template
|
|
29
|
+
— the change this whole release exists to support. See
|
|
30
|
+
[plan 038](../../docs/03-planning/features/038-info-plist-build-time-merge.md)
|
|
31
|
+
and the [`Info.plist`
|
|
32
|
+
keys](../../docs/04-userguide/ios/overview.md#infoplist-keys) section of the
|
|
33
|
+
iOS userguide for the full design and migration notes.
|
|
34
|
+
|
|
35
|
+
## 0.2.0
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
- **Wires the new `entitlements:` schema field (see `ann_flutter_flavor`
|
|
39
|
+
1.1.0) into the Xcode build.** When `ios/ann/Entitlements/<flavor>.entitlements`
|
|
40
|
+
exists on disk for a flavor, `configure_build_configuration` sets
|
|
41
|
+
`CODE_SIGN_ENTITLEMENTS` to it — the same find-or-create-by-name pattern
|
|
42
|
+
already used for `INFOPLIST_FILE`. `entitlements:` is opt-in (unlike
|
|
43
|
+
`info_plist`/the icon catalog, which every flavor always has): a flavor with
|
|
44
|
+
no generated entitlements file gets no `CODE_SIGN_ENTITLEMENTS` set at all,
|
|
45
|
+
and a stale value from a flavor's `entitlements:` being removed from
|
|
46
|
+
`annspec.yaml` is explicitly cleared on the next `pod install` rather than
|
|
47
|
+
left as a dangling, build-breaking reference to a file that no longer
|
|
48
|
+
exists. `CODE_SIGN_ENTITLEMENTS` is also added to `PROJECT_LEVEL_EXCLUDED_KEYS`
|
|
49
|
+
(same shadowing risk as `INFOPLIST_FILE`/`PRODUCT_BUNDLE_IDENTIFIER`).
|
|
50
|
+
|
|
3
51
|
## 0.1.39
|
|
4
52
|
|
|
5
53
|
### Fixed
|
|
@@ -174,14 +174,24 @@ module AnnFlavorCocoapods
|
|
|
174
174
|
# until checked against what the xcconfig #include actually
|
|
175
175
|
# applied).
|
|
176
176
|
xcconfig_path = "ann/xcconfig/#{flavor_key}#{bt.capitalize}.xcconfig"
|
|
177
|
-
info_plist_path = "ann/Info/Info-#{flavor_key}.plist"
|
|
178
177
|
icon_name = "#{flavor_key.capitalize}AppIcon"
|
|
179
178
|
|
|
180
179
|
assert_icon_generated!(user_project, flavor_key, icon_name)
|
|
181
180
|
|
|
181
|
+
# Unlike the icon catalog and Info.plist, entitlements: is
|
|
182
|
+
# opt-in -- ios_generator.dart's _generateEntitlements skips
|
|
183
|
+
# creating ios/ann/Entitlements/ entirely when no annspec.yaml
|
|
184
|
+
# entitlements: block and no stock Runner.entitlements exist
|
|
185
|
+
# anywhere. Only set CODE_SIGN_ENTITLEMENTS when the file
|
|
186
|
+
# actually exists on disk; leaving it unset is correct (no
|
|
187
|
+
# entitlements to sign with), not an error condition.
|
|
188
|
+
entitlements_path = "ann/Entitlements/#{flavor_key}.entitlements"
|
|
189
|
+
entitlements_file = File.join(user_project.project_dir.to_s, 'ann', 'Entitlements', "#{flavor_key}.entitlements")
|
|
190
|
+
entitlements_path = nil unless File.exist?(entitlements_file)
|
|
191
|
+
|
|
182
192
|
configure_build_configuration(
|
|
183
|
-
target, user_project, xcode_config, xcconfig_path,
|
|
184
|
-
icon_name
|
|
193
|
+
target, user_project, xcode_config, xcconfig_path,
|
|
194
|
+
icon_name, entitlements_path
|
|
185
195
|
)
|
|
186
196
|
end
|
|
187
197
|
|
|
@@ -191,6 +201,8 @@ module AnnFlavorCocoapods
|
|
|
191
201
|
if print_build_info
|
|
192
202
|
inject_build_info_phase(target)
|
|
193
203
|
end
|
|
204
|
+
|
|
205
|
+
inject_merge_info_plist_phase(target)
|
|
194
206
|
end
|
|
195
207
|
|
|
196
208
|
# Fixes a real pod-install failure: PBXNativeTarget#resolved_build_setting
|
|
@@ -584,9 +596,10 @@ module AnnFlavorCocoapods
|
|
|
584
596
|
# `xcodebuild` time — excluding it here is what fixes that.
|
|
585
597
|
PROJECT_LEVEL_EXCLUDED_KEYS = %w[
|
|
586
598
|
PRODUCT_BUNDLE_IDENTIFIER INFOPLIST_FILE ASSETCATALOG_COMPILER_APPICON_NAME
|
|
599
|
+
CODE_SIGN_ENTITLEMENTS
|
|
587
600
|
].freeze
|
|
588
601
|
|
|
589
|
-
def self.configure_build_configuration(target, user_project, xcode_config, xcconfig_path,
|
|
602
|
+
def self.configure_build_configuration(target, user_project, xcode_config, xcconfig_path, icon_name, entitlements_path = nil)
|
|
590
603
|
config_list = target.build_configuration_list
|
|
591
604
|
config = config_list[xcode_config]
|
|
592
605
|
|
|
@@ -612,8 +625,26 @@ module AnnFlavorCocoapods
|
|
|
612
625
|
user_project.main_group.new_reference(xcconfig_path)
|
|
613
626
|
config.base_configuration_reference = xcconfig_ref
|
|
614
627
|
|
|
615
|
-
|
|
628
|
+
# Points at the [ann-flavor] Merge Info.plist run-script phase's output
|
|
629
|
+
# (plan 038), not directly at ann/Info/Info-<flavor>.plist -- that file
|
|
630
|
+
# now holds only the flavor's info_plist: cascade delta, not a complete
|
|
631
|
+
# plist; the merge phase composes it with Runner/Info.plist (base) at
|
|
632
|
+
# build time and writes the result here.
|
|
633
|
+
config.build_settings['INFOPLIST_FILE'] = '$(DERIVED_FILE_DIR)/Info-merged.plist'
|
|
616
634
|
config.build_settings['ASSETCATALOG_COMPILER_APPICON_NAME'] = icon_name
|
|
635
|
+
# entitlements: is opt-in (unlike INFOPLIST_FILE/the icon catalog, which
|
|
636
|
+
# every flavor always has) -- only set CODE_SIGN_ENTITLEMENTS when the
|
|
637
|
+
# caller found a generated file on disk. Also explicitly clear a
|
|
638
|
+
# find-or-create'd EXISTING config's stale value when a flavor's
|
|
639
|
+
# entitlements: block was removed from annspec.yaml, rather than
|
|
640
|
+
# silently leaving Xcode signing with an entitlements file that no
|
|
641
|
+
# longer exists on disk (a build-breaking dangling reference, not
|
|
642
|
+
# merely a stale value like most other settings here).
|
|
643
|
+
if entitlements_path
|
|
644
|
+
config.build_settings['CODE_SIGN_ENTITLEMENTS'] = entitlements_path
|
|
645
|
+
else
|
|
646
|
+
config.build_settings.delete('CODE_SIGN_ENTITLEMENTS')
|
|
647
|
+
end
|
|
617
648
|
# flutter create's own stock Debug/Release configs never set
|
|
618
649
|
# MARKETING_VERSION at all (confirmed against a real project) --
|
|
619
650
|
# CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)" is present on the
|
|
@@ -744,5 +775,124 @@ module AnnFlavorCocoapods
|
|
|
744
775
|
target.build_phases.unshift(phase)
|
|
745
776
|
end
|
|
746
777
|
end
|
|
778
|
+
|
|
779
|
+
# Composes the final Info.plist Xcode actually builds against, from two
|
|
780
|
+
# layers -- Runner/Info.plist (generic/base, developer-owned) and the
|
|
781
|
+
# flavor-specific ann/Info/Info-<flavor>.plist (annspec.yaml's info_plist:
|
|
782
|
+
# cascade, opt-in -- may not exist for a flavor with no cascade) -- with
|
|
783
|
+
# the flavor layer winning on any key collision. Plan 038: since plan 035,
|
|
784
|
+
# ios_generator.dart's _generateInfoPlists used to bake a full copy of
|
|
785
|
+
# Runner/Info.plist into every flavor's generated plist at sync time; that
|
|
786
|
+
# made the generated file impossible to read as "what's actually
|
|
787
|
+
# flavor-specific" and gave nothing else (e.g. a CocoaPods plugin like
|
|
788
|
+
# ann_ads) any way to contribute Info.plist keys, since INFOPLIST_FILE
|
|
789
|
+
# pointed at the fully-resolved flavor file and Runner/Info.plist was
|
|
790
|
+
# never read again. This phase moves that composition to build time
|
|
791
|
+
# instead, so Runner/Info.plist stays a live, always-consulted base layer.
|
|
792
|
+
#
|
|
793
|
+
# Uses PlistBuddy (/usr/libexec/PlistBuddy), not python3/ruby -- PlistBuddy
|
|
794
|
+
# ships as part of Xcode itself, so this phase has no dependency on any
|
|
795
|
+
# scripting runtime beyond what Xcode already requires (OQ-1,
|
|
796
|
+
# docs/03-planning/features/038-info-plist-build-time-merge.md).
|
|
797
|
+
#
|
|
798
|
+
# Runs before_compile, ahead of Xcode's own Info.plist processing --
|
|
799
|
+
# INFOPLIST_FILE (set in configure_build_configuration) points at this
|
|
800
|
+
# phase's output, not at either source file directly.
|
|
801
|
+
def self.inject_merge_info_plist_phase(target)
|
|
802
|
+
script = <<~SHELL
|
|
803
|
+
# Injected by ann-flavor-cocoapods: compose the final Info.plist from
|
|
804
|
+
# two layers -- Runner/Info.plist (generic/base) and the flavor-
|
|
805
|
+
# specific ann/Info/Info-<flavor>.plist (annspec.yaml's info_plist:
|
|
806
|
+
# cascade) -- with the flavor layer winning on any key collision.
|
|
807
|
+
# See docs/03-planning/features/038-info-plist-build-time-merge.md.
|
|
808
|
+
PLISTBUDDY=/usr/libexec/PlistBuddy
|
|
809
|
+
BASE="${SRCROOT}/Runner/Info.plist"
|
|
810
|
+
FLAVOR_NAME="${CONFIGURATION#*-}"
|
|
811
|
+
FLAVOR_PLIST="${SRCROOT}/ann/Info/Info-${FLAVOR_NAME}.plist"
|
|
812
|
+
OUT="${DERIVED_FILE_DIR}/Info-merged.plist"
|
|
813
|
+
|
|
814
|
+
if [ ! -f "$BASE" ]; then
|
|
815
|
+
echo "error: [ann-flavor] Runner/Info.plist not found at $BASE"
|
|
816
|
+
exit 1
|
|
817
|
+
fi
|
|
818
|
+
|
|
819
|
+
# Start from a full copy of the base layer -- every key
|
|
820
|
+
# Runner/Info.plist already has is correct by default; only the
|
|
821
|
+
# flavor delta's keys need explicit merging in below.
|
|
822
|
+
cp "$BASE" "$OUT"
|
|
823
|
+
|
|
824
|
+
if [ ! -f "$FLAVOR_PLIST" ]; then
|
|
825
|
+
echo "warning: [ann-flavor] no flavor Info.plist found for '$FLAVOR_NAME' at $FLAVOR_PLIST -- using Runner/Info.plist unmerged."
|
|
826
|
+
exit 0
|
|
827
|
+
fi
|
|
828
|
+
|
|
829
|
+
# Enumerate the flavor delta's top-level keys. PlistBuddy "Print" with
|
|
830
|
+
# no key path dumps the whole dict; grep the top-level "Key = " lines
|
|
831
|
+
# (four leading spaces = depth 1 in PlistBuddy's indented dump format).
|
|
832
|
+
FLAVOR_KEYS=$("$PLISTBUDDY" -c "Print" "$FLAVOR_PLIST" | grep -E '^ [A-Za-z]' | sed 's/ =.*//' | sed 's/^ *//')
|
|
833
|
+
|
|
834
|
+
for KEY in $FLAVOR_KEYS; do
|
|
835
|
+
# OQ-2: warn (non-fatal) only on a genuine collision -- Runner/Info.plist
|
|
836
|
+
# already had this key, with a different value, before the flavor delta
|
|
837
|
+
# is applied. A net-new key (not previously in Runner/Info.plist) is not
|
|
838
|
+
# a collision and stays silent -- that's the expected, common case.
|
|
839
|
+
# Compared via PlistBuddy's human-readable Print output, which is
|
|
840
|
+
# good enough for equality-detection purposes even though it can't
|
|
841
|
+
# reliably tell types apart (see the VALUE_XML extraction below,
|
|
842
|
+
# which is what actually determines the merged value/type).
|
|
843
|
+
BASE_VALUE=$("$PLISTBUDDY" -c "Print :$KEY" "$OUT" 2>/dev/null)
|
|
844
|
+
BASE_HAD_KEY=$?
|
|
845
|
+
FLAVOR_VALUE=$("$PLISTBUDDY" -c "Print :$KEY" "$FLAVOR_PLIST")
|
|
846
|
+
|
|
847
|
+
if [ "$BASE_HAD_KEY" -eq 0 ] && [ "$BASE_VALUE" != "$FLAVOR_VALUE" ]; then
|
|
848
|
+
echo "[ann-flavor] Info.plist: '$KEY' overridden by flavor value ($FLAVOR_NAME) -- Runner/Info.plist's value ignored for this build."
|
|
849
|
+
fi
|
|
850
|
+
|
|
851
|
+
# Extract the flavor value's own XML fragment (e.g. <string>x</string>,
|
|
852
|
+
# <true/>, <integer>42</integer>, <array>...</array>) via PlistBuddy's
|
|
853
|
+
# -x (XML) output, scoped to just this key, stripping the <plist
|
|
854
|
+
# version="1.0">...</plist> wrapper that -x always adds. This
|
|
855
|
+
# preserves the flavor delta's real plist type -- Print's
|
|
856
|
+
# human-readable output alone can't distinguish an integer 42 from
|
|
857
|
+
# the string "42", or a bool true from the string "true", so a
|
|
858
|
+
# scalar-vs-composite TYPE guess from Print was unreliable and has
|
|
859
|
+
# been replaced with this approach (verified against a real
|
|
860
|
+
# PlistBuddy: bool/int/real/string/array/dict all round-trip
|
|
861
|
+
# correctly this way, plan 038 STEP-02).
|
|
862
|
+
VALUE_XML=$("$PLISTBUDDY" -x -c "Print :$KEY" "$FLAVOR_PLIST" | sed -n '/<plist version/,/<\\/plist>/p' | sed '1d;$d')
|
|
863
|
+
|
|
864
|
+
"$PLISTBUDDY" -c "Delete :$KEY" "$OUT" >/dev/null 2>&1
|
|
865
|
+
FRAGMENT=$(mktemp /tmp/ann-flavor-plist-fragment.XXXXXX)
|
|
866
|
+
cat > "$FRAGMENT" <<XMLEOF
|
|
867
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
868
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
869
|
+
<plist version="1.0">
|
|
870
|
+
<dict>
|
|
871
|
+
<key>$KEY</key>
|
|
872
|
+
$VALUE_XML
|
|
873
|
+
</dict>
|
|
874
|
+
</plist>
|
|
875
|
+
XMLEOF
|
|
876
|
+
"$PLISTBUDDY" -c "Merge \\"$FRAGMENT\\"" "$OUT"
|
|
877
|
+
rm -f "$FRAGMENT"
|
|
878
|
+
done
|
|
879
|
+
SHELL
|
|
880
|
+
|
|
881
|
+
# Find-or-update in place, rather than delete+recreate -- same
|
|
882
|
+
# idempotency rationale as inject_build_info_phase above.
|
|
883
|
+
existing = target.build_phases.find { |p| p.respond_to?(:name) && p.name == '[ann-flavor] Merge Info.plist' }
|
|
884
|
+
phase = existing || target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
|
|
885
|
+
phase.name = '[ann-flavor] Merge Info.plist'
|
|
886
|
+
phase.shell_path = '/bin/sh'
|
|
887
|
+
phase.shell_script = script
|
|
888
|
+
phase.show_env_vars_in_log = '0'
|
|
889
|
+
# Declares this phase's output so Xcode's build system understands the
|
|
890
|
+
# dependency (same technique already used for the Firebase-copy phase's
|
|
891
|
+
# output_paths) -- suppresses "input file not found" for INFOPLIST_FILE
|
|
892
|
+
# referencing a path nothing else produces until this phase runs.
|
|
893
|
+
phase.output_paths = ['$(DERIVED_FILE_DIR)/Info-merged.plist']
|
|
894
|
+
|
|
895
|
+
target.build_phases.unshift(phase) unless existing
|
|
896
|
+
end
|
|
747
897
|
end
|
|
748
898
|
end
|
|
@@ -86,7 +86,7 @@ module AnnFlavorCore
|
|
|
86
86
|
|
|
87
87
|
IosDefault = Struct.new(
|
|
88
88
|
:id, :name, :version_name, :version_code, :main_file,
|
|
89
|
-
:admob, :icon, :credentials, :firebase, :build_types, :custom, :dart_defines, :info_plist, :sdk,
|
|
89
|
+
:admob, :icon, :credentials, :firebase, :build_types, :custom, :dart_defines, :info_plist, :entitlements, :sdk,
|
|
90
90
|
keyword_init: true
|
|
91
91
|
) do
|
|
92
92
|
def self.defaults = new(build_types: {}, custom: {}, dart_defines: DartDefines.defaults)
|
|
@@ -94,7 +94,7 @@ module AnnFlavorCore
|
|
|
94
94
|
|
|
95
95
|
IosFlavor = Struct.new(
|
|
96
96
|
:id, :id_suffix, :name, :name_suffix, :version_name, :version_code,
|
|
97
|
-
:main_file, :admob, :icon, :firebase, :stores, :credentials, :build_types, :custom, :dart_defines, :info_plist,
|
|
97
|
+
:main_file, :admob, :icon, :firebase, :stores, :credentials, :build_types, :custom, :dart_defines, :info_plist, :entitlements,
|
|
98
98
|
keyword_init: true
|
|
99
99
|
) do
|
|
100
100
|
def self.defaults = new(id_suffix: '', name_suffix: '', build_types: {}, custom: {}, dart_defines: DartDefines.defaults)
|
|
@@ -160,7 +160,7 @@ module AnnFlavorCore
|
|
|
160
160
|
:id_suffix, :name_suffix,
|
|
161
161
|
:firebase, :auth, :admob,
|
|
162
162
|
:minify_enabled, :shrink_resources, :lint_check_release_builds,
|
|
163
|
-
:ndk_version, :ndk_debug_symbol_level, :ndk_abi_filters, :custom, :dart_defines, :info_plist,
|
|
163
|
+
:ndk_version, :ndk_debug_symbol_level, :ndk_abi_filters, :custom, :dart_defines, :info_plist, :entitlements,
|
|
164
164
|
keyword_init: true
|
|
165
165
|
) do
|
|
166
166
|
def self.defaults = new(id_suffix: '', name_suffix: '', ndk_abi_filters: [], custom: {}, dart_defines: DartDefines.defaults)
|
|
@@ -213,6 +213,7 @@ module AnnFlavorCore
|
|
|
213
213
|
:effective_custom,
|
|
214
214
|
:effective_dart_defines,
|
|
215
215
|
:effective_info_plist,
|
|
216
|
+
:effective_entitlements,
|
|
216
217
|
keyword_init: true
|
|
217
218
|
)
|
|
218
219
|
end
|
|
@@ -163,6 +163,7 @@ module AnnFlavorCore
|
|
|
163
163
|
custom: parse_custom_config(h(m, 'custom')),
|
|
164
164
|
dart_defines: parse_dart_defines(h(m, 'dart_defines')),
|
|
165
165
|
info_plist: m['info_plist'],
|
|
166
|
+
entitlements: m['entitlements'],
|
|
166
167
|
sdk: (parse_ios_sdk(h(m, 'sdk')) unless h(m, 'sdk').empty?),
|
|
167
168
|
)
|
|
168
169
|
end
|
|
@@ -189,6 +190,7 @@ module AnnFlavorCore
|
|
|
189
190
|
custom: parse_custom_config(h(m, 'custom')),
|
|
190
191
|
dart_defines: parse_dart_defines(h(m, 'dart_defines')),
|
|
191
192
|
info_plist: m['info_plist'],
|
|
193
|
+
entitlements: m['entitlements'],
|
|
192
194
|
)
|
|
193
195
|
end
|
|
194
196
|
|
|
@@ -321,6 +323,7 @@ module AnnFlavorCore
|
|
|
321
323
|
custom: parse_custom_config(h(v, 'custom')),
|
|
322
324
|
dart_defines: parse_dart_defines(h(v, 'dart_defines')),
|
|
323
325
|
info_plist: v['info_plist'],
|
|
326
|
+
entitlements: v['entitlements'],
|
|
324
327
|
)
|
|
325
328
|
end
|
|
326
329
|
end
|
|
@@ -119,6 +119,9 @@ module AnnFlavorCore
|
|
|
119
119
|
# in the consuming plugin, not in the core).
|
|
120
120
|
effective_info_plist: flavor.build_types[build_type]&.info_plist || flavor.info_plist ||
|
|
121
121
|
defaults.build_types[build_type]&.info_plist || defaults.info_plist,
|
|
122
|
+
# Same whole-value most-specific-wins rule as effective_info_plist above.
|
|
123
|
+
effective_entitlements: flavor.build_types[build_type]&.entitlements || flavor.entitlements ||
|
|
124
|
+
defaults.build_types[build_type]&.entitlements || defaults.entitlements,
|
|
122
125
|
)
|
|
123
126
|
end
|
|
124
127
|
|
|
@@ -21,12 +21,13 @@ module AnnFlavorCore
|
|
|
21
21
|
# Fields whose value is a free-form Hash (arbitrary user-declared keys are data,
|
|
22
22
|
# not schema) -- exempted from unknown-key checking entirely, at any level.
|
|
23
23
|
#
|
|
24
|
-
# info_plist
|
|
25
|
-
# so even when
|
|
26
|
-
# controls, never our own schema
|
|
27
|
-
# custom/dart_defines, and deliberately
|
|
28
|
-
# no single fixed struct type to
|
|
29
|
-
|
|
24
|
+
# info_plist and entitlements are additionally a union (an inline Hash OR a
|
|
25
|
+
# plain file-path String), so even when their value IS a Hash, its keys are
|
|
26
|
+
# raw Info.plist/entitlement keys the user controls, never our own schema
|
|
27
|
+
# fields -- same free-form treatment as custom/dart_defines, and deliberately
|
|
28
|
+
# NOT in RECURSION_TARGETS since there is no single fixed struct type to
|
|
29
|
+
# recurse into.
|
|
30
|
+
FREE_FORM_FIELDS = %i[custom dart_defines info_plist entitlements].freeze
|
|
30
31
|
|
|
31
32
|
# (containing_struct, field_name) => target_struct — only the "does this field
|
|
32
33
|
# recurse, and into what" relationship; the valid-keys-within-that-struct question
|