From 9df54ea7440bccbcc1823d9c4ee38681860b6c27 Mon Sep 17 00:00:00 2001 From: Almaz Ibragimov Date: Wed, 2 Oct 2024 21:45:51 +0300 Subject: [PATCH 1/4] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D1=87?= =?UTF-8?q?=D0=B0=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=84=D0=B0=D0=B9=D0=BB=D0=B0=20=D0=B2=20=D1=88=D0=B0=D0=B1?= =?UTF-8?q?=D0=BB=D0=BE=D0=BD=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20?= =?UTF-8?q?=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D1=83=D0=BA=D1=82=D1=83=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Event/DefaultEventGenerator.swift | 27 +++++++------------ .../Event/InternalEventContext.swift | 5 ++-- .../Models/Event/EventPlatform.swift | 12 ++++----- 3 files changed, 17 insertions(+), 27 deletions(-) diff --git a/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift b/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift index abbcbba..a02e3c6 100644 --- a/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift +++ b/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift @@ -49,14 +49,6 @@ final class DefaultEventGenerator: EventGenerator { } } - private func resolveInternalEventProtocol(event: InternalEvent) -> String { - if event.knownEventName == .screenShown { - return "ScreenShownEvent" - } - - return "InternalEvent" - } - private func resolveExternalEventCategory(event: ExternalEvent) -> ExternalEventContext.Category { switch event.category { case .anonymous, .applicant, .employer, .hhMobileUUID: @@ -96,24 +88,23 @@ final class DefaultEventGenerator: EventGenerator { schemaURL: URL, platform: EventPlatform ) throws { - let filename = schemaURL.deletingPathExtension().lastPathComponent.deletingSuffix("event").camelized + let fileName = schemaURL.deletingPathExtension().lastPathComponent.deletingSuffix("event").camelized - if let internalEvent = event.internal, (internalEvent.platform ?? .androidIOS) == platform { + if let internalEvent = event.internal, (internalEvent.platform ?? .iOSAndroid) == platform { try templateRenderer.renderTemplate( parameters.render.internalTemplate, - to: parameters.render.destination.appending(path: "\(filename)Event.swift"), + to: parameters.render.destination.appending(path: "\(fileName)Event.swift"), context: InternalEventContext( edition: event.edition, deprecated: event.deprecated ?? false, name: event.name, description: event.description, category: event.category, - eventName: internalEvent.event, experiment: event.experiment.map { InternalEventContext.Experiment(description: $0.description, url: $0.url.absoluteString) }, - structName: filename.appending("Event"), - protocol: resolveInternalEventProtocol(event: internalEvent), + eventName: internalEvent.event, + fileName: fileName, parameters: internalEvent.parameters.nonEmpty?.map { parameter in InternalEventContext.Parameter( name: parameter.name, @@ -131,17 +122,17 @@ final class DefaultEventGenerator: EventGenerator { ) } - if let externalEvent = event.external, (externalEvent.platform ?? .androidIOS) == platform { + if let externalEvent = event.external, (externalEvent.platform ?? .iOSAndroid) == platform { try templateRenderer.renderTemplate( parameters.render.externalTemplate, - to: parameters.render.destination.appending(path: "\(filename)ExternalEvent.swift"), + to: parameters.render.destination.appending(path: "\(fileName)ExternalEvent.swift"), context: ExternalEventContext( edition: event.edition, deprecated: event.deprecated ?? false, name: event.name, description: event.description, category: resolveExternalEventCategory(event: externalEvent), - structName: filename.appending("ExternalEvent"), + structName: fileName.appending("ExternalEvent"), action: ExternalEventContext.Action( description: externalEvent.action.description, value: externalEvent.action.value, @@ -175,7 +166,7 @@ final class DefaultEventGenerator: EventGenerator { Log.info("(\(configuration.name)) Starting code generation... πŸš€") let generarionParameters = try resolveGenerationParameters(from: configuration) - let platform = configuration.platform ?? .androidIOS + let platform = configuration.platform ?? .iOSAndroid let events: [(Event, URL)] = try enumerator .lazy diff --git a/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift b/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift index da5b187..97f755c 100644 --- a/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift +++ b/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift @@ -32,10 +32,9 @@ struct InternalEventContext: Encodable { let name: String let description: String? let category: String - let eventName: String let experiment: Experiment? - let structName: String - let `protocol`: String + let eventName: String + let fileName: String let parameters: [Parameter]? let hasParametersToInit: Bool } diff --git a/Sources/AnalyticsGen/Models/Event/EventPlatform.swift b/Sources/AnalyticsGen/Models/Event/EventPlatform.swift index 78e2f50..9a95268 100644 --- a/Sources/AnalyticsGen/Models/Event/EventPlatform.swift +++ b/Sources/AnalyticsGen/Models/Event/EventPlatform.swift @@ -5,7 +5,7 @@ enum EventPlatform: String, Decodable { // MARK: - Enumeration Cases case android = "Android" - case androidIOS = "Android/iOS" + case iOSAndroid = "Android/iOS" case iOS } @@ -20,25 +20,25 @@ extension EventPlatform: Equatable { case (.android, .android): return true - case (.android, .androidIOS): + case (.android, .iOSAndroid): return true case (.android, .iOS): return false - case (.androidIOS, .android): + case (.iOSAndroid, .android): return true - case (.androidIOS, .androidIOS): + case (.iOSAndroid, .iOSAndroid): return true - case (.androidIOS, .iOS): + case (.iOSAndroid, .iOS): return true case (.iOS, .android): return false - case (.iOS, .androidIOS): + case (.iOS, .iOSAndroid): return true case (.iOS, .iOS): From 34c1ac0e06747ced61a44fa06bec6a16408e5918 Mon Sep 17 00:00:00 2001 From: Almaz Ibragimov Date: Wed, 2 Oct 2024 22:06:36 +0300 Subject: [PATCH 2/4] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20Stencil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Package.resolved | 4 ++-- Package.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Package.resolved b/Package.resolved index 77660d9..89aeda3 100644 --- a/Package.resolved +++ b/Package.resolved @@ -96,8 +96,8 @@ "repositoryURL": "https://github.com/kylef/Stencil.git", "state": { "branch": null, - "revision": "94197b3adbbf926348ad8765476a158aa4e54f8a", - "version": "0.14.0" + "revision": "4f222ac85d673f35df29962fc4c36ccfdaf9da5b", + "version": "0.15.1" } }, { diff --git a/Package.swift b/Package.swift index f0cf487..ac16497 100644 --- a/Package.swift +++ b/Package.swift @@ -17,7 +17,7 @@ let package = Package( .package(url: "https://github.com/kylef/PathKit.git", from: "1.0.1"), .package(url: "https://github.com/onevcat/Rainbow", from: "3.0.0"), .package(url: "https://github.com/mxcl/PromiseKit", from: "6.8.0"), - .package(url: "https://github.com/kylef/Stencil.git", from: "0.13.0"), + .package(url: "https://github.com/kylef/Stencil.git", from: "0.15.1"), .package(url: "https://github.com/SwiftGen/StencilSwiftKit.git", from: "2.7.2"), .package(url: "https://github.com/almazrafi/DictionaryCoder.git", from: "1.0.4"), .package(url: "https://github.com/jpsim/Yams.git", from: "4.0.4"), From 4b8d8364bfa9e76e4e677d03e98c71bc016653dd Mon Sep 17 00:00:00 2001 From: Almaz Ibragimov Date: Thu, 3 Oct 2024 12:23:20 +0300 Subject: [PATCH 3/4] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20Stencil?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Package.resolved | 12 ++++++------ Package.swift | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Package.resolved b/Package.resolved index 89aeda3..814e63a 100644 --- a/Package.resolved +++ b/Package.resolved @@ -33,8 +33,8 @@ "repositoryURL": "https://github.com/shibapm/Komondor.git", "state": { "branch": null, - "revision": "855c74f395a4dc9e02828f58d931be6920bcbf6f", - "version": "1.0.6" + "revision": "90b087b1e39069684b1ff4bf915c2aae594f2d60", + "version": "1.1.3" } }, { @@ -42,8 +42,8 @@ "repositoryURL": "https://github.com/shibapm/PackageConfig.git", "state": { "branch": null, - "revision": "bf90dc69fa0792894b08a0b74cf34029694ae486", - "version": "0.13.0" + "revision": "58523193c26fb821ed1720dcd8a21009055c7cdb", + "version": "1.1.3" } }, { @@ -105,8 +105,8 @@ "repositoryURL": "https://github.com/SwiftGen/StencilSwiftKit.git", "state": { "branch": null, - "revision": "54cbedcdbb4334e03930adcff7343ffaf317bf0f", - "version": "2.8.0" + "revision": "20e2de5322c83df005939d9d9300fab130b49f97", + "version": "2.10.1" } }, { diff --git a/Package.swift b/Package.swift index ac16497..ff8ee3c 100644 --- a/Package.swift +++ b/Package.swift @@ -18,7 +18,7 @@ let package = Package( .package(url: "https://github.com/onevcat/Rainbow", from: "3.0.0"), .package(url: "https://github.com/mxcl/PromiseKit", from: "6.8.0"), .package(url: "https://github.com/kylef/Stencil.git", from: "0.15.1"), - .package(url: "https://github.com/SwiftGen/StencilSwiftKit.git", from: "2.7.2"), + .package(url: "https://github.com/SwiftGen/StencilSwiftKit.git", from: "2.10.1"), .package(url: "https://github.com/almazrafi/DictionaryCoder.git", from: "1.0.4"), .package(url: "https://github.com/jpsim/Yams.git", from: "4.0.4"), .package(url: "https://github.com/kylef/JSONSchema.swift.git", from: "0.5.0"), From e8e511560baa04d05c406b35d7549b0ef74c6431 Mon Sep 17 00:00:00 2001 From: Almaz Ibragimov Date: Sat, 5 Oct 2024 19:38:08 +0300 Subject: [PATCH 4/4] =?UTF-8?q?=D0=93=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=BF=D0=B0=D0=BF=D0=BA=D0=B0?= =?UTF-8?q?=D0=BC=20=D0=B8=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8?= =?UTF-8?q?=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BF=D0=B0=D1=80?= =?UTF-8?q?=D0=B0=D0=BC=D0=B5=D1=82=D1=80=D1=8B=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Event/DefaultEventGenerator.swift | 70 ++++++++++++++----- .../Event/ExternalEventContext.swift | 3 +- .../Event/InternalEventContext.swift | 3 +- Templates/ExternalEvent.stencil | 4 +- Templates/InternalEvent.stencil | 6 +- 5 files changed, 61 insertions(+), 25 deletions(-) diff --git a/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift b/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift index a02e3c6..3821e65 100644 --- a/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift +++ b/Sources/AnalyticsGen/Generators/Event/DefaultEventGenerator.swift @@ -43,9 +43,7 @@ final class DefaultEventGenerator: EventGenerator { let fileManager = FileManager.default try? fileManager.contentsOfDirectory(atPath: path).forEach { filename in - if filename.hasSuffix(.swiftExtension) { - try fileManager.removeItem(atPath: path + "/" + filename) - } + try fileManager.removeItem(atPath: path + "/" + filename) } } @@ -85,15 +83,28 @@ final class DefaultEventGenerator: EventGenerator { private func generate( parameters: GenerationParameters, event: Event, - schemaURL: URL, + targetPath: String, + schemePath: [String], platform: EventPlatform ) throws { - let fileName = schemaURL.deletingPathExtension().lastPathComponent.deletingSuffix("event").camelized + let filePath = schemePath + .dropLast() + .map { $0.camelized } + .joined(separator: "/") + + let schemeName = schemePath + .last? + .components(separatedBy: ".") + .first? + .deletingSuffix("event") ?? "" + + let schemePath = schemePath.prepending(targetPath).filter { !$0.isEmpty }.joined(separator: "/") + let renderDestination = parameters.render.destination.appending(path: filePath) if let internalEvent = event.internal, (internalEvent.platform ?? .iOSAndroid) == platform { try templateRenderer.renderTemplate( parameters.render.internalTemplate, - to: parameters.render.destination.appending(path: "\(fileName)Event.swift"), + to: renderDestination.appending(path: "\(schemeName.camelized)Event.swift"), context: InternalEventContext( edition: event.edition, deprecated: event.deprecated ?? false, @@ -104,7 +115,8 @@ final class DefaultEventGenerator: EventGenerator { InternalEventContext.Experiment(description: $0.description, url: $0.url.absoluteString) }, eventName: internalEvent.event, - fileName: fileName, + schemeName: schemeName, + schemePath: schemePath, parameters: internalEvent.parameters.nonEmpty?.map { parameter in InternalEventContext.Parameter( name: parameter.name, @@ -125,14 +137,15 @@ final class DefaultEventGenerator: EventGenerator { if let externalEvent = event.external, (externalEvent.platform ?? .iOSAndroid) == platform { try templateRenderer.renderTemplate( parameters.render.externalTemplate, - to: parameters.render.destination.appending(path: "\(fileName)ExternalEvent.swift"), + to: renderDestination.appending(path: "\(schemeName.camelized)ExternalEvent.swift"), context: ExternalEventContext( edition: event.edition, deprecated: event.deprecated ?? false, name: event.name, description: event.description, category: resolveExternalEventCategory(event: externalEvent), - structName: fileName.appending("ExternalEvent"), + schemeName: schemeName, + schemePath: schemePath, action: ExternalEventContext.Action( description: externalEvent.action.description, value: externalEvent.action.value, @@ -158,7 +171,7 @@ final class DefaultEventGenerator: EventGenerator { } } - private func generate(configuration: GeneratedConfiguration, schemasPath: URL) throws { + private func generate(configuration: GeneratedConfiguration, targetPath: String? = nil, schemasPath: URL) throws { guard let enumerator = FileManager.default.enumerator(at: schemasPath, includingPropertiesForKeys: nil) else { throw MessageError("Failed to create enumerator at \(schemasPath).") } @@ -168,20 +181,34 @@ final class DefaultEventGenerator: EventGenerator { let generarionParameters = try resolveGenerationParameters(from: configuration) let platform = configuration.platform ?? .iOSAndroid - let events: [(Event, URL)] = try enumerator + let events: [(Event, [String])] = try enumerator .lazy .compactMap { $0 as? URL } .filter { $0.pathExtension == .yamlExtension } .map { url in - Log.debug("(\(configuration.name)) Reading schema: \(url.lastPathComponent)") - let event: Event = try fileProvider.readFile(at: url.path) - return (event, url) + let basePathComponents = schemasPath.pathComponents + + let filePathComponents = url + .pathComponents + .drop(while: basePathComponents.contains(_:)) + + let filePath = filePathComponents.joined(separator: "/") + + Log.debug("(\(configuration.name)) Reading schema: \(filePath)") + + return (try fileProvider.readFile(at: url.path), Array(filePathComponents)) } try clearDestinationFolder(at: configuration.destination ?? .rootPath) - try events.forEach { event, url in - try generate(parameters: generarionParameters, event: event, schemaURL: url, platform: platform) + try events.forEach { event, schemePath in + try generate( + parameters: generarionParameters, + event: event, + targetPath: targetPath ?? "", + schemePath: schemePath, + platform: platform + ) } } @@ -245,7 +272,10 @@ final class DefaultEventGenerator: EventGenerator { }.map { repoPathURL in try self.generate( configuration: configuration, - schemasPath: gitHubConfiguration.path.map { repoPathURL.appendingPathComponent($0) } ?? repoPathURL + targetPath: gitHubConfiguration.path, + schemasPath: gitHubConfiguration.path.map { targetPath in + repoPathURL.appendingPathComponent(targetPath) + } ?? repoPathURL ) try self.saveLockfile(configurationName: configuration.name, remoteReferenceSHA: remoteReferenceSHA) @@ -354,7 +384,11 @@ final class DefaultEventGenerator: EventGenerator { ) throws -> Promise { switch configuration.source { case .local(let path): - try generate(configuration: configuration, schemasPath: URL(fileURLWithPath: path)) + try generate( + configuration: configuration, + schemasPath: URL(fileURLWithPath: path) + ) + return .value(.success) case .gitHub(let gitHubConfiguration): diff --git a/Sources/AnalyticsGen/Generators/Event/ExternalEventContext.swift b/Sources/AnalyticsGen/Generators/Event/ExternalEventContext.swift index 2b6081f..366233c 100644 --- a/Sources/AnalyticsGen/Generators/Event/ExternalEventContext.swift +++ b/Sources/AnalyticsGen/Generators/Event/ExternalEventContext.swift @@ -49,7 +49,8 @@ struct ExternalEventContext: Encodable { let name: String let description: String? let category: Category - let structName: String + let schemeName: String + let schemePath: String let action: Action let label: Label? let initialisationParameters: [Parameter] diff --git a/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift b/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift index 97f755c..48977db 100644 --- a/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift +++ b/Sources/AnalyticsGen/Generators/Event/InternalEventContext.swift @@ -34,7 +34,8 @@ struct InternalEventContext: Encodable { let category: String let experiment: Experiment? let eventName: String - let fileName: String + let schemeName: String + let schemePath: String let parameters: [Parameter]? let hasParametersToInit: Bool } diff --git a/Templates/ExternalEvent.stencil b/Templates/ExternalEvent.stencil index 6d7d6c4..e894f7a 100644 --- a/Templates/ExternalEvent.stencil +++ b/Templates/ExternalEvent.stencil @@ -1,9 +1,9 @@ {% include "FileHeader.stencil" %} +{% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} +{% set structName %}{{ schemeName|swiftIdentifier:"pretty" }}ExternalEvent{% endset %} {% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstLetter|escapeReservedKeywords }}{% endmacro %} {% macro optional types %}{% if nullable %}?{% endif %}{% endmacro %} -{% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} - import Analytics /** diff --git a/Templates/InternalEvent.stencil b/Templates/InternalEvent.stencil index 3f607bc..0159001 100644 --- a/Templates/InternalEvent.stencil +++ b/Templates/InternalEvent.stencil @@ -1,9 +1,9 @@ {% include "FileHeader.stencil" %} +{% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} +{% set structName %}{{ schemeName|swiftIdentifier:"pretty" }}Event{% endset %} {% macro propertyName name %}{{ name|swiftIdentifier:"pretty"|lowerFirstLetter|escapeReservedKeywords|replace:"Id","ID"|uppercaseSuffix:"json","Json","Hhid" }}{% endmacro %} {% macro enumName name %}{{ name|swiftIdentifier:"pretty"|escapeReservedKeywords|replace:"`Type`","EventType"|uppercasePrefix:"Hhtm" }}{% endmacro %} -{% set accessModifier %}{% if options.publicAccess %}public{% else %}internal{% endif %}{% endset %} - import Analytics /** @@ -21,7 +21,7 @@ import Analytics - **ЭкспСримСнт**: [{{ experiment.description }}]({{ experiment.url }}) {% endif %} */ -{{ accessModifier }} struct {{ structName }}: {{ protocol }} { +{{ accessModifier }} struct {{ structName }}: InternalEvent { {{ accessModifier }} var edition: [AnalyticsEventEdition] { {% if edition %}