#!/usr/bin/env ruby # configure_xcode.rb — stamped fresh from template on every build (see gitea.service.ts) # # 1. Adds GoogleService-Info.plist to the Xcode target if present (xcodeproj gem) # 2. Scans Swift sources for Firebase imports and injects matching products into # CapApp-SPM/Package.swift — the correct approach for Capacitor SPM projects # where all native linking goes through CapApp-SPM, not App.xcodeproj directly. require 'xcodeproj' PROJECT_PATH = 'ios/App/App.xcodeproj' TARGET_NAME = 'App' PLIST_SRC = 'ios/App/App/GoogleService-Info.plist' CAP_APP_SPM = 'ios/App/CapApp-SPM/Package.swift' # ── 1. GoogleService-Info.plist ─────────────────────────────────────────────── if File.exist?(PLIST_SRC) project = Xcodeproj::Project.open(PROJECT_PATH) target = project.targets.find { |t| t.name == TARGET_NAME } if target app_group = project.main_group['App'] unless app_group&.files&.find { |f| f.path == 'GoogleService-Info.plist' } file_ref = app_group.new_reference('GoogleService-Info.plist') target.resources_build_phase.add_file_reference(file_ref) project.save puts "Added GoogleService-Info.plist to target" end end end # ── 2. Scan Swift sources for Firebase imports ──────────────────────────────── swift_files = Dir['ios/App/App/**/*.swift'] firebase_imports = swift_files .flat_map { |f| File.readlines(f) rescue [] } .grep(/^\s*import\s+Firebase\w+/) .map { |l| l.strip.split(/\s+/).last } .uniq .sort if firebase_imports.empty? puts "No Firebase imports found — skipping CapApp-SPM update" exit 0 end puts "Firebase imports detected: #{firebase_imports.join(', ')}" unless File.exist?(CAP_APP_SPM) warn "WARNING: #{CAP_APP_SPM} not found — was cap sync run?" exit 0 end # ── 3. Detect firebase-ios-sdk URL and version from node_modules ────────────── # Read from the ACTUAL node_modules on this build machine (populated by npm install) # so the version we inject matches what @capacitor-firebase/* already resolved. firebase_url = nil firebase_version = nil Dir['node_modules/@capacitor-firebase/**/Package.swift', 'node_modules/@capacitor/push-notifications/**/Package.swift'].each do |f| content = File.read(f) rescue next url_m = content.match(/\.package\(url:\s*"(https:\/\/github\.com\/firebase\/firebase-ios-sdk[^"]*)"/) ver_m = content.match(/firebase-ios-sdk[^)]+from:\s*"(\d+)\.(\d+)\.(\d+)"/) next unless url_m && ver_m firebase_url = url_m[1] major = ver_m[1].to_i firebase_version = "#{major}.0.0" puts "Detected firebase-ios-sdk from #{f}: url=#{firebase_url} → using from: \"#{firebase_version}\"" break end # Fallback — should rarely be needed unless firebase_url firebase_url = 'https://github.com/firebase/firebase-ios-sdk.git' firebase_version = '11.0.0' puts "Could not detect firebase-ios-sdk version from node_modules — using fallback #{firebase_version}" end firebase_pkg = 'firebase-ios-sdk' lines = File.read(CAP_APP_SPM).split("\n") # ── 4. Inject firebase-ios-sdk as a direct package dependency if missing ────── # Normalise URL check to handle both with and without .git suffix firebase_url_base = firebase_url.sub(/\.git$/, '') unless lines.any? { |l| l.include?(firebase_url_base) } last_pkg_idx = lines.rindex { |l| l.include?('.package(') } if last_pkg_idx lines[last_pkg_idx] = lines[last_pkg_idx].rstrip lines[last_pkg_idx] += ',' unless lines[last_pkg_idx].end_with?(',') lines.insert(last_pkg_idx + 1, " .package(url: \"#{firebase_url}\", from: \"#{firebase_version}\")") puts "Added #{firebase_pkg} to CapApp-SPM package dependencies" else warn "WARNING: no .package( line found in #{CAP_APP_SPM} — cannot inject dependency" end end # ── 5. Inject each detected product into the target dependencies if missing ─── firebase_imports.each do |product| next if product == 'Firebase' # umbrella import — not a linkable SPM product product_str = ".product(name: \"#{product}\", package: \"#{firebase_pkg}\")" next if lines.any? { |l| l.include?(product_str) } last_prod_idx = lines.rindex { |l| l.include?('.product(') } if last_prod_idx lines[last_prod_idx] = lines[last_prod_idx].rstrip lines[last_prod_idx] += ',' unless lines[last_prod_idx].end_with?(',') lines.insert(last_prod_idx + 1, " #{product_str}") puts "Added #{product} to CapApp-SPM target dependencies" else warn "WARNING: no .product( line found in #{CAP_APP_SPM} — cannot inject #{product}" end end File.write(CAP_APP_SPM, lines.join("\n")) puts "CapApp-SPM/Package.swift updated"