From 1f9af76b40d800339e2ae2c0b48460c1ed9a9049 Mon Sep 17 00:00:00 2001 From: Quentin Bandera Date: Wed, 29 Oct 2025 09:23:10 +0100 Subject: [PATCH 1/4] RES-74 Ajout du multiligne sur les logs des analytics --- .../Generator/AnalyticsGenerator.swift | 117 ++++++++++-------- 1 file changed, 64 insertions(+), 53 deletions(-) diff --git a/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift b/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift index 27dbd21..ff98268 100644 --- a/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift +++ b/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift @@ -196,63 +196,74 @@ enum AnalyticsGenerator { } private static func getPrivateLogFunction() -> String { - """ - // MARK: - Private Log Methods - - private func logScreen( - name: String, - path: String, - params: [String: Any]? - ) { - guard isEnabled else { - if isDebugMode { - logger.log("Analytics disabled") - } - return + """ + // MARK: - Private Log Methods + + private func logScreen( + name: String, + path: String, + params: [String: Any]? + ) { + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") } - - managers.values.forEach { manager in + return + } + + managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 🖥️ Screen: + Name: \\(name, privacy: .public) + Path: \\(path, privacy: .public) + Params: \\(String(describing: params ?? [:]), privacy: .public) + \""") + } + + manager.logScreen( + name: name, + path: path, + params: params + ) + } + } + + private func logEvent( + name: String, + action: String, + category: String, + params: [String: Any]? + ) { + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } + + managers.values.forEach { manager in - if isDebugMode { - logger.debug("🖥️ Screen: \\(name, privacy: .public) | Path: \\(path, privacy: .public) | Params: \\(String(describing: params ?? [:]), privacy: .public)") - } - - manager.logScreen( - name: name, - path: path, - params: params - ) + if isDebugMode { + logger.debug(\""" + 📊 Event: + Name: \\(name, privacy: .public) + Action: \\(action.isEmpty ? "-" : action, privacy: .public) + Category: \\(category.isEmpty ? "-" : category, privacy: .public) + Params: \\(String(describing: params ?? [:]), privacy: .public) + \""") } + + manager.logEvent( + name: name, + action: action, + category: category, + params: params + ) } - - private func logEvent( - name: String, - action: String, - category: String, - params: [String: Any]? - ) { - guard isEnabled else { - if isDebugMode { - logger.log("Analytics disabled") - } - return - } - - managers.values.forEach { manager in - - if isDebugMode { - logger.debug("📊 Event: \\(name, privacy: .public) | Action: \\(action.isEmpty ? "-" : action, privacy: .public) | Category: \\(category.isEmpty ? "-" : category, privacy: .public) | Params: \\(String(describing: params ?? [:]), privacy: .public)") - } - - manager.logEvent( - name: name, - action: action, - category: category, - params: params - ) - } - } - """ + } + """ } private static func getAnalyticsProperties( -- 2.39.5 From 4b944ed8c7837ac0baa5fc4cdffa0f111947ca87 Mon Sep 17 00:00:00 2001 From: Quentin Bandera Date: Wed, 29 Oct 2025 09:44:19 +0100 Subject: [PATCH 2/4] RES-75 Ajouter un pretty print pour le dictionnaire des params --- .../Generated/Analytics+GenAllScript.swift | 26 +++++++++++++++++-- Sources/ResgenSwift/Analytics/Analytics.swift | 3 --- .../Generator/AnalyticsGenerator.swift | 25 +++++++++++++----- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/SampleFiles/Tags/Generated/Analytics+GenAllScript.swift b/SampleFiles/Tags/Generated/Analytics+GenAllScript.swift index 0ef2f88..ed17153 100644 --- a/SampleFiles/Tags/Generated/Analytics+GenAllScript.swift +++ b/SampleFiles/Tags/Generated/Analytics+GenAllScript.swift @@ -160,6 +160,17 @@ internal class AnalyticsManager { // MARK: - Private Log Methods + private func formattedParams(_ params: [String: Any]?) -> String { + guard let params = params, !params.isEmpty else { return "-" } + + let formattedParams = params.map { key, value in + " \(key): \(value)" + } + .joined(separator: "\n") + + return "\n" + formattedParams + } + private func logScreen( name: String, path: String, @@ -175,7 +186,12 @@ internal class AnalyticsManager { managers.values.forEach { manager in if isDebugMode { - logger.debug("🖥️ Screen: \(name, privacy: .public) | Path: \(path, privacy: .public) | Params: \(String(describing: params ?? [:]), privacy: .public)") + logger.debug(""" + 🖥️ Screen: + Name: \(name, privacy: .public) + Path: \(path, privacy: .public) + Params: \(self.formattedParams(params), privacy: .public) + """) } manager.logScreen( @@ -202,7 +218,13 @@ internal class AnalyticsManager { managers.values.forEach { manager in if isDebugMode { - logger.debug("📊 Event: \(name, privacy: .public) | Action: \(action.isEmpty ? "-" : action, privacy: .public) | Category: \(category.isEmpty ? "-" : category, privacy: .public) | Params: \(String(describing: params ?? [:]), privacy: .public)") + logger.debug(""" + 📊 Event: + Name: \(name, privacy: .public) + Action: \(action.isEmpty ? "-" : action, privacy: .public) + Category: \(category.isEmpty ? "-" : category, privacy: .public) + Params: \(self.formattedParams(params), privacy: .public) + """) } manager.logEvent( diff --git a/Sources/ResgenSwift/Analytics/Analytics.swift b/Sources/ResgenSwift/Analytics/Analytics.swift index b9b5047..293a649 100644 --- a/Sources/ResgenSwift/Analytics/Analytics.swift +++ b/Sources/ResgenSwift/Analytics/Analytics.swift @@ -38,9 +38,6 @@ struct Analytics: ParsableCommand { print("[\(Self.toolName)] Will generate analytics") - // Check requirements - guard checkRequirements() else { return } - // Parse input file let sections = AnalyticsFileParser().parse(options.inputFile, target: options.target) diff --git a/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift b/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift index ff98268..f92351d 100644 --- a/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift +++ b/Sources/ResgenSwift/Analytics/Generator/AnalyticsGenerator.swift @@ -199,6 +199,17 @@ enum AnalyticsGenerator { """ // MARK: - Private Log Methods + private func formattedParams(_ params: [String: Any]?) -> String { + guard let params = params, !params.isEmpty else { return "-" } + + let formattedParams = params.map { key, value in + " \\(key): \\(value)" + } + .joined(separator: "\\n") + + return "\\n" + formattedParams + } + private func logScreen( name: String, path: String, @@ -216,9 +227,9 @@ enum AnalyticsGenerator { if isDebugMode { logger.debug(\""" 🖥️ Screen: - Name: \\(name, privacy: .public) - Path: \\(path, privacy: .public) - Params: \\(String(describing: params ?? [:]), privacy: .public) + Name: \\(name, privacy: .public) + Path: \\(path, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) \""") } @@ -248,10 +259,10 @@ enum AnalyticsGenerator { if isDebugMode { logger.debug(\""" 📊 Event: - Name: \\(name, privacy: .public) - Action: \\(action.isEmpty ? "-" : action, privacy: .public) - Category: \\(category.isEmpty ? "-" : category, privacy: .public) - Params: \\(String(describing: params ?? [:]), privacy: .public) + Name: \\(name, privacy: .public) + Action: \\(action.isEmpty ? "-" : action, privacy: .public) + Category: \\(category.isEmpty ? "-" : category, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) \""") } -- 2.39.5 From 052f416741969c04f42c58658cd28c99b9113820 Mon Sep 17 00:00:00 2001 From: Quentin Bandera Date: Mon, 10 Nov 2025 16:01:10 +0100 Subject: [PATCH 3/4] Update jenkinsFile --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 136be57..5a66ba7 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,6 +1,6 @@ library "openiumpipeline" -env.DEVELOPER_DIR="/Applications/Xcode-16.3.0.app/Contents/Developer" +env.DEVELOPER_DIR="/Applications/Xcode-26.0.0.app/Contents/Developer" // env.SIMULATOR_DEVICE_TYPES="iPhone-14-Pro" // env.SLACK_CHANNEL = "prj-skdevkit" env.IS_PACKAGE_SWIFT=1 -- 2.39.5 From 434d42713670a51bf17849755c785025d0d088fa Mon Sep 17 00:00:00 2001 From: Quentin Bandera Date: Mon, 10 Nov 2025 17:19:13 +0100 Subject: [PATCH 4/4] fix test --- SampleFiles/resgenConfiguration.yml | 2 +- .../Analytics/AnalyticsGeneratorTests.swift | 224 ++++++++++++++---- 2 files changed, 185 insertions(+), 41 deletions(-) diff --git a/SampleFiles/resgenConfiguration.yml b/SampleFiles/resgenConfiguration.yml index efd54c0..2c76e5e 100644 --- a/SampleFiles/resgenConfiguration.yml +++ b/SampleFiles/resgenConfiguration.yml @@ -90,7 +90,7 @@ analytics: inputFile: ./Tags/sampleTags.yml target: "matomo firebase" outputFile: ./Tags/Generated/Analytics+GenAllScript.swift - visibility: public + visibility: internal # diff --git a/Tests/ResgenSwiftTests/Analytics/AnalyticsGeneratorTests.swift b/Tests/ResgenSwiftTests/Analytics/AnalyticsGeneratorTests.swift index 6faa97e..d1f03b9 100644 --- a/Tests/ResgenSwiftTests/Analytics/AnalyticsGeneratorTests.swift +++ b/Tests/ResgenSwiftTests/Analytics/AnalyticsGeneratorTests.swift @@ -234,7 +234,7 @@ final class AnalyticsGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo, sectionThree], tags: ["ios", "iosonly"], isStatic: false, - visibility: .public + visibility: .internal ) // Expect Analytics @@ -243,29 +243,32 @@ final class AnalyticsGeneratorTests: XCTestCase { import Foundation import FirebaseAnalytics + import os - \(protocolString(visibility: .public)) + \(protocolString(visibility: .internal)) \(firebaseString()) // MARK: - Traker Type - public enum TrackerType: CaseIterable { + internal enum TrackerType: CaseIterable { case firebase } // MARK: - Manager - public class AnalyticsManager { + internal class AnalyticsManager { - public static var shared = AnalyticsManager() + internal static var shared = AnalyticsManager() private init() {} // MARK: - Properties var managers: [TrackerType: AnalyticsManagerProtocol] = [:] + + private var isDebugMode: Bool = false private var isEnabled: Bool { if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { @@ -274,6 +277,8 @@ final class AnalyticsGeneratorTests: XCTestCase { true } } + + private let logger = Logger(subsystem: "resgen", category: "analytics") // MARK: - Enable Methods @@ -287,28 +292,55 @@ final class AnalyticsGeneratorTests: XCTestCase { } } - public func enableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { + internal func enableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { setAnalytics(enable: true, analytics) } - public func disableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { + internal func disableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { setAnalytics(enable: false, analytics) } - public func configure() { + internal func configure(isDebugMode: Bool = false) { + self.isDebugMode = isDebugMode managers[TrackerType.firebase] = FirebaseAnalyticsManager() } // MARK: - Private Log Methods + + private func formattedParams(_ params: [String: Any]?) -> String { + guard let params = params, !params.isEmpty else { return "-" } + + let formattedParams = params.map { key, value in + " \\(key): \\(value)" + } + .joined(separator: "\\n") + + return "\\n" + formattedParams + } private func logScreen( name: String, path: String, params: [String: Any]? ) { - guard isEnabled else { return } + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 🖥️ Screen: + Name: \\(name, privacy: .public) + Path: \\(path, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) + \""") + } + manager.logScreen( name: name, path: path, @@ -323,9 +355,25 @@ final class AnalyticsGeneratorTests: XCTestCase { category: String, params: [String: Any]? ) { - guard isEnabled else { return } + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 📊 Event: + Name: \\(name, privacy: .public) + Action: \\(action.isEmpty ? "-" : action, privacy: .public) + Category: \\(category.isEmpty ? "-" : category, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) + \""") + } + manager.logEvent( name: name, action: action, @@ -337,7 +385,7 @@ final class AnalyticsGeneratorTests: XCTestCase { // MARK: - section_one - public func logScreenS1DefOne() { + internal func logScreenS1DefOne() { logScreen( name: "s1 def one", path: "", @@ -345,7 +393,7 @@ final class AnalyticsGeneratorTests: XCTestCase { ) } - public func logEventS1DefTwo() { + internal func logEventS1DefTwo() { logEvent( name: "s1 def two", action: "", @@ -356,7 +404,7 @@ final class AnalyticsGeneratorTests: XCTestCase { // MARK: - section_two - public func logScreenS2DefOne() { + internal func logScreenS2DefOne() { logScreen( name: "s2 def one", path: "", @@ -399,7 +447,7 @@ final class AnalyticsGeneratorTests: XCTestCase { sections: [sectionOne, sectionTwo, sectionThree], tags: ["ios", "iosonly"], isStatic: false, - visibility: .package + visibility: .internal ) // Expect Analytics let expect = """ @@ -407,29 +455,32 @@ final class AnalyticsGeneratorTests: XCTestCase { import Foundation import MatomoTracker + import os - \(protocolString(visibility: .package)) + \(protocolString(visibility: .internal)) \(matomoString()) // MARK: - Traker Type - package enum TrackerType: CaseIterable { + internal enum TrackerType: CaseIterable { case matomo } // MARK: - Manager - package class AnalyticsManager { + internal class AnalyticsManager { - package static var shared = AnalyticsManager() + internal static var shared = AnalyticsManager() private init() {} // MARK: - Properties var managers: [TrackerType: AnalyticsManagerProtocol] = [:] + + private var isDebugMode: Bool = false private var isEnabled: Bool { if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { @@ -438,6 +489,8 @@ final class AnalyticsGeneratorTests: XCTestCase { true } } + + private let logger = Logger(subsystem: "resgen", category: "analytics") // MARK: - Enable Methods @@ -451,15 +504,16 @@ final class AnalyticsGeneratorTests: XCTestCase { } } - package func enableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { + internal func enableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { setAnalytics(enable: true, analytics) } - package func disableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { + internal func disableAnalytics(_ analytics: [TrackerType] = TrackerType.allCases) { setAnalytics(enable: false, analytics) } - package func configure(siteId: String, url: String) { + internal func configure(siteId: String, url: String, isDebugMode: Bool = false) { + self.isDebugMode = isDebugMode managers[TrackerType.matomo] = MatomoAnalyticsManager( siteId: siteId, url: url @@ -468,14 +522,40 @@ final class AnalyticsGeneratorTests: XCTestCase { // MARK: - Private Log Methods + private func formattedParams(_ params: [String: Any]?) -> String { + guard let params = params, !params.isEmpty else { return "-" } + + let formattedParams = params.map { key, value in + " \\(key): \\(value)" + } + .joined(separator: "\\n") + + return "\\n" + formattedParams + } + private func logScreen( name: String, path: String, params: [String: Any]? ) { - guard isEnabled else { return } - + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } + managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 🖥️ Screen: + Name: \\(name, privacy: .public) + Path: \\(path, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) + \""") + } + manager.logScreen( name: name, path: path, @@ -483,16 +563,32 @@ final class AnalyticsGeneratorTests: XCTestCase { ) } } - + private func logEvent( name: String, action: String, category: String, params: [String: Any]? ) { - guard isEnabled else { return } - + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } + managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 📊 Event: + Name: \\(name, privacy: .public) + Action: \\(action.isEmpty ? "-" : action, privacy: .public) + Category: \\(category.isEmpty ? "-" : category, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) + \""") + } + manager.logEvent( name: name, action: action, @@ -501,18 +597,18 @@ final class AnalyticsGeneratorTests: XCTestCase { ) } } - + // MARK: - section_one - - package func logScreenS1DefOne() { + + internal func logScreenS1DefOne() { logScreen( name: "s1 def one", path: "s1_def_one/", params: nil ) } - - package func logEventS1DefTwo() { + + internal func logEventS1DefTwo() { logEvent( name: "s1 def two", action: "test", @@ -520,10 +616,10 @@ final class AnalyticsGeneratorTests: XCTestCase { params: nil ) } - + // MARK: - section_two - - package func logScreenS2DefOne() { + + internal func logScreenS2DefOne() { logScreen( name: "s2 def one", path: "s2_def_one/", @@ -576,6 +672,7 @@ final class AnalyticsGeneratorTests: XCTestCase { import Foundation import MatomoTracker import FirebaseAnalytics + import os \(protocolString(visibility: .internal)) @@ -602,6 +699,8 @@ final class AnalyticsGeneratorTests: XCTestCase { // MARK: - Properties var managers: [TrackerType: AnalyticsManagerProtocol] = [:] + + private var isDebugMode: Bool = false private var isEnabled: Bool { if ProcessInfo.processInfo.environment["XCODE_RUNNING_FOR_PREVIEWS"] == "1" { @@ -610,6 +709,8 @@ final class AnalyticsGeneratorTests: XCTestCase { true } } + + private let logger = Logger(subsystem: "resgen", category: "analytics") // MARK: - Enable Methods @@ -631,7 +732,8 @@ final class AnalyticsGeneratorTests: XCTestCase { setAnalytics(enable: false, analytics) } - internal func configure(siteId: String, url: String) { + internal func configure(siteId: String, url: String, isDebugMode: Bool = false) { + self.isDebugMode = isDebugMode managers[TrackerType.matomo] = MatomoAnalyticsManager( siteId: siteId, url: url @@ -640,15 +742,41 @@ final class AnalyticsGeneratorTests: XCTestCase { } // MARK: - Private Log Methods + + private func formattedParams(_ params: [String: Any]?) -> String { + guard let params = params, !params.isEmpty else { return "-" } + + let formattedParams = params.map { key, value in + " \\(key): \\(value)" + } + .joined(separator: "\\n") + + return "\\n" + formattedParams + } private func logScreen( name: String, path: String, params: [String: Any]? ) { - guard isEnabled else { return } - + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } + managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 🖥️ Screen: + Name: \\(name, privacy: .public) + Path: \\(path, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) + \""") + } + manager.logScreen( name: name, path: path, @@ -656,16 +784,32 @@ final class AnalyticsGeneratorTests: XCTestCase { ) } } - + private func logEvent( name: String, action: String, category: String, params: [String: Any]? ) { - guard isEnabled else { return } - + guard isEnabled else { + if isDebugMode { + logger.log("Analytics disabled") + } + return + } + managers.values.forEach { manager in + + if isDebugMode { + logger.debug(\""" + 📊 Event: + Name: \\(name, privacy: .public) + Action: \\(action.isEmpty ? "-" : action, privacy: .public) + Category: \\(category.isEmpty ? "-" : category, privacy: .public) + Params: \\(self.formattedParams(params), privacy: .public) + \""") + } + manager.logEvent( name: name, action: action, -- 2.39.5