ann-flavor-cocoapods 0.1.7 → 0.1.8
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 +63 -0
- data/ann-flavor-cocoapods.gemspec +2 -0
- data/exe/ann-ios-flavorize +83 -0
- data/lib/ann_flavor_cocoapods/podfile_helper.rb +119 -10
- data/lib/ann_flavor_cocoapods/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 65ffc39f0153491522ad751cd067acb59e600473c1aa7ac049b23656f9faafb9
|
|
4
|
+
data.tar.gz: 18ff13f0444baec5a01211ef9f8fb30beae617d55d8d274b74ca297b0966cd89
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9d9db39720735e4d45b88369421bb0f18739dd857d18528370a408e706d71b1765790aff0190c9525b1979202a2b1bed1491df16522c135b482e9810a537485f
|
|
7
|
+
data.tar.gz: d57728fec0711d043df83d72a9ea0766e297568baff91f59ffdc464076d6dedb7e18f4523d39d3836b7e920dbde7d430f0e246ce103b8492011d05d394447df4
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.8
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **DEF-017**: `ann-ios-flavorize setup` CLI command for iOS-only (non-Flutter)
|
|
7
|
+
projects. Checks `annspec.yaml` exists, patches `ios/Podfile` with
|
|
8
|
+
`plugin 'ann-ios-flavorize'`, and prints next-step guidance. Idempotent —
|
|
9
|
+
safe to run multiple times. Install via `gem 'ann-flavor-cocoapods'` in your
|
|
10
|
+
Gemfile, then run `bundle exec ann-ios-flavorize setup`.
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- **DEF-014**: `configure_firebase` now injects build phases in `project_id` mode
|
|
14
|
+
(no `config_file` set). The plist source is derived from
|
|
15
|
+
`lib/generated/firebase/GoogleService-Info-{flavor}-{buildType}.plist`.
|
|
16
|
+
Previously no build phases were injected, causing the Crashlytics dSYM upload
|
|
17
|
+
run script to fail with a missing plist error.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 0.1.7
|
|
22
|
+
|
|
23
|
+
**Backwards-compatibility shims removed** — the deprecated `firebase.file` fallback
|
|
24
|
+
and `firebase_token_file` are no longer accepted. Specs must use `config_file` and
|
|
25
|
+
`service_account` directly.
|
|
26
|
+
|
|
27
|
+
**`service_account` support** — the `service_account` field is read from the spec
|
|
28
|
+
and exported as `GOOGLE_APPLICATION_CREDENTIALS` when invoking Firebase CLI commands.
|
|
29
|
+
|
|
30
|
+
## 0.1.6
|
|
31
|
+
|
|
32
|
+
**`enabled: false` support** — when `annspec.yaml` sets `enabled: false`, the
|
|
33
|
+
CocoaPods plugin skips all configuration silently.
|
|
34
|
+
|
|
35
|
+
**Improved error messages** — field validation errors now include the exact YAML path
|
|
36
|
+
and a fix hint.
|
|
37
|
+
|
|
38
|
+
## 0.1.5
|
|
39
|
+
|
|
40
|
+
**Breaking: `annai_app:` root key renamed to `app:`** — `annspec.yaml` files using
|
|
41
|
+
the old `annai_app:` root key must be updated.
|
|
42
|
+
|
|
43
|
+
## 0.1.4
|
|
44
|
+
|
|
45
|
+
**Firebase `config_file` support** — the podfile helper now reads the `config_file`
|
|
46
|
+
field. The old `file` field is accepted with a deprecation warning; support will be
|
|
47
|
+
removed in a future version.
|
|
48
|
+
|
|
49
|
+
**Firebase `path` / `firebase_app_id` / `build_target` removed** — replaced by
|
|
50
|
+
`config_file` and `project_id`.
|
|
51
|
+
|
|
52
|
+
## 0.1.3
|
|
53
|
+
|
|
54
|
+
**Schema restructure** — credentials and sdk fields reorganised to match the updated
|
|
55
|
+
`annspec.yaml` structure.
|
|
56
|
+
|
|
57
|
+
## 0.1.2
|
|
58
|
+
|
|
59
|
+
Documentation and sync-workflow updates. No user-facing behaviour changes.
|
|
60
|
+
|
|
61
|
+
## 0.1.1
|
|
62
|
+
|
|
63
|
+
Initial release.
|
|
@@ -13,6 +13,8 @@ Gem::Specification.new do |spec|
|
|
|
13
13
|
spec.license = "MIT"
|
|
14
14
|
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec)/}) }
|
|
16
|
+
spec.bindir = "exe"
|
|
17
|
+
spec.executables = ["ann-ios-flavorize"]
|
|
16
18
|
spec.require_paths = ["lib"]
|
|
17
19
|
|
|
18
20
|
spec.add_dependency "cocoapods", ">= 1.12"
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'ann_flavor_cocoapods'
|
|
5
|
+
|
|
6
|
+
HELP = <<~HELP
|
|
7
|
+
ann-ios-flavorize — iOS-only setup for ann-flavor-cocoapods
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
bundle exec ann-ios-flavorize setup [--project DIR]
|
|
11
|
+
|
|
12
|
+
Commands:
|
|
13
|
+
setup Patch ios/Podfile to add the ann-ios-flavorize plugin line.
|
|
14
|
+
Run once per project; idempotent on subsequent runs.
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
--project DIR Project root directory (default: current directory)
|
|
18
|
+
--help Show this help
|
|
19
|
+
HELP
|
|
20
|
+
|
|
21
|
+
def run(argv)
|
|
22
|
+
command = nil
|
|
23
|
+
root = Dir.pwd
|
|
24
|
+
|
|
25
|
+
i = 0
|
|
26
|
+
while i < argv.length
|
|
27
|
+
case argv[i]
|
|
28
|
+
when 'setup'
|
|
29
|
+
command = :setup
|
|
30
|
+
when '--project'
|
|
31
|
+
i += 1
|
|
32
|
+
root = argv[i] || Dir.pwd
|
|
33
|
+
when '--help', '-h'
|
|
34
|
+
puts HELP
|
|
35
|
+
exit 0
|
|
36
|
+
end
|
|
37
|
+
i += 1
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if command.nil?
|
|
41
|
+
puts HELP
|
|
42
|
+
exit 1
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
case command
|
|
46
|
+
when :setup
|
|
47
|
+
run_setup(root)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def run_setup(root)
|
|
52
|
+
annspec = File.join(root, 'annspec.yaml')
|
|
53
|
+
unless File.exist?(annspec)
|
|
54
|
+
warn "✗ annspec.yaml not found in #{root}"
|
|
55
|
+
warn " Run ann-ios-flavorize from your Flutter project root, or use --project <dir>."
|
|
56
|
+
exit 1
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
podfile_path = File.join(root, 'ios', 'Podfile')
|
|
60
|
+
unless File.exist?(podfile_path)
|
|
61
|
+
warn "✗ ios/Podfile not found in #{root}"
|
|
62
|
+
warn " Create an iOS Flutter project first, then re-run this command."
|
|
63
|
+
exit 1
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
plugin_line = "plugin 'ann-ios-flavorize'"
|
|
67
|
+
content = File.read(podfile_path)
|
|
68
|
+
|
|
69
|
+
if content.include?(plugin_line)
|
|
70
|
+
puts "✓ ios/Podfile already has #{plugin_line} — nothing to do."
|
|
71
|
+
puts "Next: run `bundle exec pod install`"
|
|
72
|
+
return
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
patched = "# Added by ann-flavor-cocoapods — multi-flavor iOS build configuration\n" \
|
|
76
|
+
"#{plugin_line}\n" + content
|
|
77
|
+
File.write(podfile_path, patched)
|
|
78
|
+
|
|
79
|
+
puts "✓ Podfile patched — #{plugin_line} added"
|
|
80
|
+
puts "Next: run `bundle exec pod install`"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
run(ARGV)
|
|
@@ -2,29 +2,67 @@ require_relative 'spec_loader'
|
|
|
2
2
|
|
|
3
3
|
module AnnFlavorCocoapods
|
|
4
4
|
module PodfileHelper
|
|
5
|
-
# Call inside your Podfile to wire per-flavor Firebase
|
|
5
|
+
# Call inside your Podfile's post_install hook to wire per-flavor Firebase
|
|
6
|
+
# GoogleService-Info.plist into the Xcode build.
|
|
6
7
|
#
|
|
7
8
|
# Example Podfile usage:
|
|
8
9
|
# require 'ann_flavor_cocoapods'
|
|
9
|
-
#
|
|
10
|
+
# post_install do |installer|
|
|
11
|
+
# AnnFlavorCocoapods::PodfileHelper.configure_firebase(installer)
|
|
12
|
+
# end
|
|
10
13
|
#
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
# For each iOS flavor that has config_file set, this injects two build phases
|
|
15
|
+
# into the Runner target (or the matching umbrella target):
|
|
16
|
+
# - A pre-build shell script that copies the correct plist to
|
|
17
|
+
# ${SRCROOT}/Runner/GoogleService-Info.plist at build time.
|
|
18
|
+
# - A post-build shell script that removes the copied file so the workspace
|
|
19
|
+
# stays clean and a mis-matched plist cannot accidentally survive.
|
|
20
|
+
#
|
|
21
|
+
# Gate: only runs when integrations.firebase is true in annspec.yaml.
|
|
22
|
+
#
|
|
23
|
+
def self.configure_firebase(installer, project_root: Dir.pwd)
|
|
24
|
+
spec = SpecLoader.load(project_root)
|
|
25
|
+
|
|
26
|
+
# integrations.firebase must be explicitly enabled (REQ-FIRE-00010).
|
|
27
|
+
return unless spec.dig('app', 'integrations', 'firebase') == true
|
|
28
|
+
|
|
13
29
|
flavors = SpecLoader.ios_flavors(spec)
|
|
14
30
|
default = SpecLoader.ios_default(spec)
|
|
15
31
|
|
|
32
|
+
# Build a map: configuration_name → config_file path.
|
|
33
|
+
# Xcode configuration names are capitalized: Release-<flavor>, Debug-<flavor>.
|
|
34
|
+
config_map = {}
|
|
16
35
|
flavors.each do |flavor_key, flavor_cfg|
|
|
17
36
|
merged = default.merge(flavor_cfg || {})
|
|
18
37
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
38
|
+
default_build_types = default.dig('build_types') || {}
|
|
39
|
+
flavor_build_types = (flavor_cfg || {}).dig('build_types') || {}
|
|
40
|
+
build_types = default_build_types.merge(flavor_build_types)
|
|
41
|
+
|
|
42
|
+
%w[release debug].each do |bt|
|
|
43
|
+
bt_fb = build_types.dig(bt, 'firebase') || {}
|
|
44
|
+
fb_file = bt_fb['config_file']
|
|
45
|
+
project_id = bt_fb['project_id']
|
|
23
46
|
|
|
24
|
-
|
|
47
|
+
if fb_file.nil? && project_id
|
|
48
|
+
# project_id mode — derive plist from stable generated path.
|
|
49
|
+
fb_file = "lib/generated/firebase/GoogleService-Info-#{flavor_key}-#{bt}.plist"
|
|
50
|
+
end
|
|
25
51
|
|
|
26
|
-
|
|
52
|
+
next unless fb_file
|
|
53
|
+
|
|
54
|
+
# Map Xcode config name (e.g. "Release-ledger_in") → plist path
|
|
55
|
+
xcode_config = "#{bt.capitalize}-#{flavor_key}"
|
|
56
|
+
config_map[xcode_config] = fb_file
|
|
57
|
+
|
|
58
|
+
warn_if_static_plist(project_root, xcode_config, fb_file)
|
|
59
|
+
end
|
|
27
60
|
end
|
|
61
|
+
|
|
62
|
+
return if config_map.empty?
|
|
63
|
+
return if installer.nil?
|
|
64
|
+
|
|
65
|
+
inject_build_phases(installer, project_root, config_map)
|
|
28
66
|
end
|
|
29
67
|
|
|
30
68
|
# Returns the bundle ID for a given flavor key, merging defaults.
|
|
@@ -61,5 +99,76 @@ module AnnFlavorCocoapods
|
|
|
61
99
|
bt_suffix = build_types.dig(build_type.to_s, 'id_suffix') || ''
|
|
62
100
|
"#{base}#{id_suffix}#{bt_suffix}"
|
|
63
101
|
end
|
|
102
|
+
|
|
103
|
+
private
|
|
104
|
+
|
|
105
|
+
# Warn if a static GoogleService-Info.plist already exists in the project; a
|
|
106
|
+
# higher-priority static file would shadow the one we copy at build time.
|
|
107
|
+
def self.warn_if_static_plist(project_root, xcode_config, config_file)
|
|
108
|
+
static_path = File.join(project_root, 'ios', 'Runner', 'GoogleService-Info.plist')
|
|
109
|
+
if File.exist?(static_path)
|
|
110
|
+
puts "ann-flavor-cocoapods WARNING: A static GoogleService-Info.plist exists at " \
|
|
111
|
+
"ios/Runner/GoogleService-Info.plist. It will be overwritten at build time " \
|
|
112
|
+
"for configuration '#{xcode_config}' (source: #{config_file}). " \
|
|
113
|
+
"Remove the static file to silence this warning."
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# Injects pre-build and post-build shell script phases into the Runner (or
|
|
118
|
+
# umbrella) target for every native target that matches the project.
|
|
119
|
+
def self.inject_build_phases(installer, project_root, config_map)
|
|
120
|
+
# Build the per-config shell that selects the right source file.
|
|
121
|
+
# Uses a case statement keyed on $CONFIGURATION (Xcode build setting).
|
|
122
|
+
case_body = config_map.map do |xcode_config, plist_path|
|
|
123
|
+
" #{xcode_config}) SRC_PLIST=\"${SRCROOT}/../#{plist_path}\" ;;"
|
|
124
|
+
end.join("\n")
|
|
125
|
+
|
|
126
|
+
pre_build_script = <<~SHELL
|
|
127
|
+
# Injected by ann-flavor-cocoapods: copy per-flavor GoogleService-Info.plist
|
|
128
|
+
case "$CONFIGURATION" in
|
|
129
|
+
#{case_body}
|
|
130
|
+
*) echo "ann-flavor-cocoapods: no Firebase plist for $CONFIGURATION"; exit 0 ;;
|
|
131
|
+
esac
|
|
132
|
+
DEST="${SRCROOT}/Runner/GoogleService-Info.plist"
|
|
133
|
+
if [ ! -f "$SRC_PLIST" ]; then
|
|
134
|
+
echo "ann-flavor-cocoapods ERROR: Firebase plist not found: $SRC_PLIST"
|
|
135
|
+
exit 1
|
|
136
|
+
fi
|
|
137
|
+
cp "$SRC_PLIST" "$DEST"
|
|
138
|
+
echo "ann-flavor-cocoapods: copied $SRC_PLIST -> $DEST"
|
|
139
|
+
SHELL
|
|
140
|
+
|
|
141
|
+
post_build_script = <<~SHELL
|
|
142
|
+
# Injected by ann-flavor-cocoapods: remove copied GoogleService-Info.plist after build
|
|
143
|
+
DEST="${SRCROOT}/Runner/GoogleService-Info.plist"
|
|
144
|
+
rm -f "$DEST"
|
|
145
|
+
echo "ann-flavor-cocoapods: removed $DEST"
|
|
146
|
+
SHELL
|
|
147
|
+
|
|
148
|
+
installer.pods_project.targets.each do |target|
|
|
149
|
+
next unless target.name == 'Pods-Runner'
|
|
150
|
+
|
|
151
|
+
# Avoid duplicate injection on repeated pod install runs.
|
|
152
|
+
next if target.build_phases.any? { |p| p.respond_to?(:shell_script) &&
|
|
153
|
+
p.shell_script.include?('ann-flavor-cocoapods: copy per-flavor') }
|
|
154
|
+
|
|
155
|
+
pre = target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
|
|
156
|
+
pre.name = '[ann-flavor] Copy Firebase plist'
|
|
157
|
+
pre.shell_path = '/bin/sh'
|
|
158
|
+
pre.shell_script = pre_build_script
|
|
159
|
+
pre.show_env_vars_in_log = '0'
|
|
160
|
+
target.build_phases.unshift(pre)
|
|
161
|
+
|
|
162
|
+
post = target.project.new(Xcodeproj::Project::Object::PBXShellScriptBuildPhase)
|
|
163
|
+
post.name = '[ann-flavor] Remove Firebase plist'
|
|
164
|
+
post.shell_path = '/bin/sh'
|
|
165
|
+
post.shell_script = post_build_script
|
|
166
|
+
post.show_env_vars_in_log = '0'
|
|
167
|
+
target.build_phases << post
|
|
168
|
+
|
|
169
|
+
puts "ann-flavor-cocoapods: injected Firebase build phases into #{target.name} " \
|
|
170
|
+
"(#{config_map.size} configuration(s))"
|
|
171
|
+
end
|
|
172
|
+
end
|
|
64
173
|
end
|
|
65
174
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ann-flavor-cocoapods
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ANN Solutions
|
|
8
8
|
autorequire:
|
|
9
|
-
bindir:
|
|
9
|
+
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-07-
|
|
11
|
+
date: 2026-07-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: cocoapods
|
|
@@ -55,14 +55,17 @@ dependencies:
|
|
|
55
55
|
description:
|
|
56
56
|
email:
|
|
57
57
|
- support@annaibrands.com
|
|
58
|
-
executables:
|
|
58
|
+
executables:
|
|
59
|
+
- ann-ios-flavorize
|
|
59
60
|
extensions: []
|
|
60
61
|
extra_rdoc_files: []
|
|
61
62
|
files:
|
|
62
63
|
- ".gitignore"
|
|
64
|
+
- CHANGELOG.md
|
|
63
65
|
- Gemfile
|
|
64
66
|
- Rakefile
|
|
65
67
|
- ann-flavor-cocoapods.gemspec
|
|
68
|
+
- exe/ann-ios-flavorize
|
|
66
69
|
- lib/ann_flavor_cocoapods.rb
|
|
67
70
|
- lib/ann_flavor_cocoapods/podfile_helper.rb
|
|
68
71
|
- lib/ann_flavor_cocoapods/spec_loader.rb
|