diff --git a/.github/workflows/update_versions.yml b/.github/workflows/update_versions.yml new file mode 100644 index 0000000..4ef3c68 --- /dev/null +++ b/.github/workflows/update_versions.yml @@ -0,0 +1,47 @@ +# This is a basic workflow that is manually triggered + +name: Update Versions + +# Controls when the action will run. Workflow runs when manually triggered using the UI +# or API. +on: + workflow_dispatch: + # Inputs the workflow accepts. + inputs: + version: + description: 'New version to use for the Target extension. Example: 4.0.2' + required: true + + branch: + description: 'Branch to be used when updating versions' + required: true + + core-dependency: + description: 'If a version is provided, update AEPCore dependency in podspec and Package.swift' + required: false + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + update-versions: + runs-on: macos-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + + - name: Checkout + uses: actions/checkout@v3.1.0 + with: + ref: ${{ github.event.inputs.branch }} + + - name: Update AEPTarget + run: (sh ./Script/update-versions.sh -n Target -v ${{ github.event.inputs.version }} -d "AEPCore ${{ github.event.inputs.core-dependency }}") + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v4.2.3 + with: + token: ${{ github.token }} + commit-message: Updating version to ${{ github.event.inputs.version }}. + branch: version-${{ github.event.inputs.version }}-update + delete-branch: true + title: Updating version to ${{ github.event.inputs.version }} + body: Updating version to ${{ github.event.inputs.version }} diff --git a/AEPTarget.podspec b/AEPTarget.podspec index e077721..de3e7da 100644 --- a/AEPTarget.podspec +++ b/AEPTarget.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "AEPTarget" - s.version = "4.0.1" + s.version = "4.0.2" s.summary = "Experience Platform Target extension for Adobe Experience Platform Mobile SDK. Written and maintained by Adobe." s.description = <<-DESC The Experience Platform Target extension provides APIs that allow use of the Target product in the Adobe Experience Platform SDK. diff --git a/AEPTarget.xcodeproj/project.pbxproj b/AEPTarget.xcodeproj/project.pbxproj index 8a5babd..613cc0e 100644 --- a/AEPTarget.xcodeproj/project.pbxproj +++ b/AEPTarget.xcodeproj/project.pbxproj @@ -1174,7 +1174,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 4.0.1; + MARKETING_VERSION = 4.0.2; PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.target; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1205,7 +1205,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 4.0.1; + MARKETING_VERSION = 4.0.2; PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.target; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/AEPTarget.xcodeproj/xcshareddata/xcschemes/AEPTargetDemoApp.xcscheme b/AEPTarget.xcodeproj/xcshareddata/xcschemes/AEPTargetDemoApp.xcscheme index cc228d1..d476db1 100644 --- a/AEPTarget.xcodeproj/xcshareddata/xcschemes/AEPTargetDemoApp.xcscheme +++ b/AEPTarget.xcodeproj/xcshareddata/xcschemes/AEPTargetDemoApp.xcscheme @@ -44,6 +44,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + enableAddressSanitizer = "YES" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" @@ -60,6 +61,13 @@ ReferencedContainer = "container:AEPTarget.xcodeproj"> + + + + String { + guard let eventHubData = eventHubData else { + return "" + } + + let coreVersion = eventHubData[TargetConstants.EventHub.SharedState.Keys.VERSION] as? String ?? "unknown" + + // sdkVersion is a combination of Mobile Core+Target SDK version + return "\(coreVersion)+\(TargetConstants.EXTENSION_VERSION)" + } + + private func getSdkInfo(eventHubData: [String: Any]?) -> String { + let sdkBase = TargetConstants.HEADER_X_EXC_SDK_BASE_TARGET_MOBILE_IOS + + guard let eventHubData = eventHubData else { + return sdkBase + } + + guard let wrapper = eventHubData[TargetConstants.EventHub.SharedState.Keys.WRAPPER] as? [String: Any], + let wrapperFriendlyName = wrapper[TargetConstants.EventHub.SharedState.Keys.WRAPPER_FRIENDLY_NAME] as? String, + wrapperFriendlyName != "None" + else { + return sdkBase + } + + // sdkInfo is of the format AdobeTargetMobile-iOS- + return "\(sdkBase)-\(wrapperFriendlyName)" + } + /// Prepares for the target requests and checks whether a target request can be sent. /// - returns: error indicating why the request can't be sent, nil otherwise private func prepareForTargetRequest() -> String? { @@ -667,8 +696,6 @@ public class Target: NSObject, Extension { return "Failed to generate request parameter(JSON) for target delivery API call" } - let headers = [TargetConstants.HEADER_CONTENT_TYPE: TargetConstants.HEADER_CONTENT_TYPE_JSON] - guard let clientCode = targetState.clientCode else { return "Missing client code" } @@ -677,7 +704,13 @@ public class Target: NSObject, Extension { return "Failed to generate the url for target API call" } + let eventHubSharedState = getSharedState(extensionName: TargetConstants.EventHub.EXTENSION_NAME, event: event)?.value let timeout = targetState.networkTimeout + let headers = [ + TargetConstants.HEADER_CONTENT_TYPE: TargetConstants.HEADER_CONTENT_TYPE_JSON, + TargetConstants.HEADER_X_EXC_SDK: getSdkInfo(eventHubData: eventHubSharedState), + TargetConstants.HEADER_X_EXC_SDK_VERSION: getSdkVersion(eventHubData: eventHubSharedState), + ] // https://developers.adobetarget.com/api/delivery-api/#tag/Delivery-API let request = NetworkRequest(url: url, httpMethod: .post, connectPayload: requestJson, httpHeaders: headers, connectTimeout: timeout, readTimeout: timeout) @@ -903,8 +936,13 @@ public class Target: NSObject, Extension { return } + let eventHubSharedState = getSharedState(extensionName: TargetConstants.EventHub.EXTENSION_NAME, event: event)?.value let timeout = targetState.networkTimeout - let headers = [TargetConstants.HEADER_CONTENT_TYPE: TargetConstants.HEADER_CONTENT_TYPE_JSON] + let headers = [ + TargetConstants.HEADER_CONTENT_TYPE: TargetConstants.HEADER_CONTENT_TYPE_JSON, + TargetConstants.HEADER_X_EXC_SDK: getSdkInfo(eventHubData: eventHubSharedState), + TargetConstants.HEADER_X_EXC_SDK_VERSION: getSdkVersion(eventHubData: eventHubSharedState), + ] // https://developers.adobetarget.com/api/delivery-api/#tag/Delivery-API let request = NetworkRequest(url: url, httpMethod: .post, connectPayload: requestJson, httpHeaders: headers, connectTimeout: timeout, readTimeout: timeout) @@ -916,8 +954,9 @@ public class Target: NSObject, Extension { Log.debug(label: Target.LOG_TAG, "handleRawRequest - Target response is received with code: \(connection.responseCode ?? -1) and data: \(connection.responseString ?? "").") self.targetState.updateSessionTimestamp() self.processTargetRawResponse(event: event, isContentRequest: isContentRequest, connection: connection) + + self.startEvents() } - startEvents() } /// Processes the network response after the Target delivery API call for raw request. diff --git a/AEPTarget/Sources/TargetConstants.swift b/AEPTarget/Sources/TargetConstants.swift index fa70e3a..ae41e3e 100644 --- a/AEPTarget/Sources/TargetConstants.swift +++ b/AEPTarget/Sources/TargetConstants.swift @@ -15,14 +15,17 @@ import Foundation enum TargetConstants { static let EXTENSION_NAME = "com.adobe.module.target" static let FRIENDLY_NAME = "Target" - static let EXTENSION_VERSION = "4.0.1" + static let EXTENSION_VERSION = "4.0.2" static let DATASTORE_NAME = EXTENSION_NAME static let DEFAULT_SESSION_TIMEOUT: Int = 30 * 60 // 30 mins static let DELIVERY_API_URL_BASE = "https://%@/rest/v1/delivery/?client=%@&sessionId=%@" static let EDGE_HOST_BASE = "mboxedge%@" static let API_URL_HOST_BASE = "%@.tt.omtrdc.net" static let HEADER_CONTENT_TYPE = "Content-Type" + static let HEADER_X_EXC_SDK = "X-EXC-SDK" + static let HEADER_X_EXC_SDK_VERSION = "X-EXC-SDK-Version" static let HEADER_CONTENT_TYPE_JSON = "application/json" + static let HEADER_X_EXC_SDK_BASE_TARGET_MOBILE_IOS = "AdobeTargetMobile-iOS" static let A4T_ACTION_NAME = "AnalyticsForTarget" static let MAP_TO_CONTEXT_DATA_KEYS: [String: String] = [ @@ -234,6 +237,17 @@ enum TargetConstants { } } + enum EventHub { + static let EXTENSION_NAME = "com.adobe.module.eventhub" + enum SharedState { + enum Keys { + static let VERSION = "version" + static let WRAPPER = "wrapper" + static let WRAPPER_FRIENDLY_NAME = "friendlyName" + } + } + } + enum Identity { static let EXTENSION_NAME = "com.adobe.module.identity" enum SharedState { diff --git a/AEPTarget/Sources/TargetState.swift b/AEPTarget/Sources/TargetState.swift index a865621..92c120f 100644 --- a/AEPTarget/Sources/TargetState.swift +++ b/AEPTarget/Sources/TargetState.swift @@ -15,11 +15,31 @@ import Foundation /// Represents the state of the `Target` extension class TargetState { - private(set) var prefetchedMboxJsonDicts = [String: [String: Any]]() - private(set) var loadedMboxJsonDicts = [String: [String: Any]]() - private(set) var notifications = [Notification]() + private let queue: DispatchQueue = .init(label: "com.adobe.targetstate.queue") - private(set) var storedConfigurationSharedState: [String: Any]? + private var _prefetchedMboxJsonDicts: [String: [String: Any]] = [:] + private(set) var prefetchedMboxJsonDicts: [String: [String: Any]] { + get { queue.sync { self._prefetchedMboxJsonDicts } } + set { queue.async { self._prefetchedMboxJsonDicts = newValue } } + } + + private var _loadedMboxJsonDicts: [String: [String: Any]] = [:] + private(set) var loadedMboxJsonDicts: [String: [String: Any]] { + get { queue.sync { self._loadedMboxJsonDicts } } + set { queue.async { self._loadedMboxJsonDicts = newValue } } + } + + private var _notifications: [Notification] = [] + private(set) var notifications: [Notification] { + get { queue.sync { self._notifications } } + set { queue.async { self._notifications = newValue } } + } + + private var _storedConfigurationSharedState: [String: Any]? + private(set) var storedConfigurationSharedState: [String: Any]? { + get { queue.sync { self._storedConfigurationSharedState } } + set { queue.async { self._storedConfigurationSharedState = newValue } } + } private(set) var thirdPartyId: String? private(set) var tntId: String? diff --git a/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift b/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift index 0658fa9..9b1f240 100644 --- a/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift +++ b/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift @@ -185,6 +185,12 @@ class TargetIntegrationTests: XCTestCase { mockNetworkService.mock { request in Log.debug(label: self.T_LOG_TAG, "request url is: \(request.url.absoluteString)") if request.url.absoluteString.contains("https://amsdk.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + if let payloadDictionary = try? JSONSerialization.jsonObject(with: request.connectPayload, options: .allowFragments) as? [String: Any] { Log.debug(label: self.T_LOG_TAG, "request payload is: \n \(self.prettify(payloadDictionary))") @@ -407,6 +413,12 @@ class TargetIntegrationTests: XCTestCase { ServiceProvider.shared.networkService = mockNetworkService mockNetworkService.mock { request in if request.url.absoluteString.contains("https://amsdk.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + return (data: responseString.data(using: .utf8), response: validResponse, error: nil) } return nil @@ -1093,6 +1105,12 @@ class TargetIntegrationTests: XCTestCase { ServiceProvider.shared.networkService = mockNetworkService mockNetworkService.mock { request in if request.url.absoluteString.contains("https://amsdk.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + let connectPayloadString = String(decoding: request.connectPayload, as: UTF8.self) if connectPayloadString.contains("ADCKKBC") { targetRequestExpectation.fulfill() @@ -1219,6 +1237,12 @@ class TargetIntegrationTests: XCTestCase { ServiceProvider.shared.networkService = mockNetworkService mockNetworkService.mock { request in if request.url.absoluteString.contains("https://amsdk.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + let connectPayloadString = String(decoding: request.connectPayload, as: UTF8.self) if connectPayloadString.contains("ADCKKBC") { targetRequestExpectation.fulfill() @@ -1662,6 +1686,12 @@ class TargetIntegrationTests: XCTestCase { ServiceProvider.shared.networkService = mockNetworkService mockNetworkService.mock { request in if request.url.absoluteString.contains("https://acopprod3.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + return (data: responseString.data(using: .utf8), response: validResponse, error: nil) } return nil @@ -1802,6 +1832,12 @@ class TargetIntegrationTests: XCTestCase { ServiceProvider.shared.networkService = mockNetworkService mockNetworkService.mock { request in if request.url.absoluteString.contains("https://acopprod3.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + return (data: responseString.data(using: .utf8), response: validResponse, error: nil) } return nil @@ -1954,6 +1990,12 @@ class TargetIntegrationTests: XCTestCase { ServiceProvider.shared.networkService = mockNetworkService mockNetworkService.mock { request in if request.url.absoluteString.contains("https://acopprod3.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + return (data: responseString.data(using: .utf8), response: validResponse, error: nil) } @@ -2096,6 +2138,12 @@ class TargetIntegrationTests: XCTestCase { } if request.url.absoluteString.contains("https://mboxedge35.tt.omtrdc.net/rest/v1/delivery/?client=acopprod3&sessionId=") { + // verify request headers + let coreVersion = self.getLastValidSharedState("com.adobe.module.eventhub")?.value?["version"] ?? "unknown" + let requestHeaders: [String: String] = request.httpHeaders + XCTAssertEqual("AdobeTargetMobile-iOS", requestHeaders["X-EXC-SDK"]) + XCTAssertEqual("\(coreVersion)+\(TargetTestConstants.EXTENSION_VERSION)", requestHeaders["X-EXC-SDK-Version"]) + targetNotificationExpectation.fulfill() return nil } diff --git a/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift b/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift index 2493a71..3d8d7b8 100644 --- a/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift +++ b/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift @@ -11,6 +11,7 @@ */ enum TargetTestConstants { + static let EXTENSION_VERSION = "4.0.2" // preview parameters static let PREVIEW_MESSAGE_ID = "target-preview-message-id" static let PREVIEW_PARAMETERS = "at_preview_params" diff --git a/Makefile b/Makefile index a593c6d..b4aa3d9 100644 --- a/Makefile +++ b/Makefile @@ -87,3 +87,7 @@ test-podspec: pod-lint: (pod lib lint --allow-warnings --verbose --swift-version=5.1) + +# used to test update-versions.sh script locally +test-update-version: + (sh ./Script/update-versions.sh -n Target -v 9.9.9 -d "AEPCore 9.9.3") diff --git a/Podfile.lock b/Podfile.lock index e162a3e..f981056 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -5,17 +5,17 @@ PODS: - AEPAssurance (4.0.0): - AEPCore (>= 4.0.0) - AEPServices (>= 4.0.0) - - AEPCore (4.0.0): + - AEPCore (4.1.0): - AEPRulesEngine (>= 4.0.0) - - AEPServices (>= 4.0.0) - - AEPIdentity (4.0.0): - - AEPCore (>= 4.0.0) - - AEPLifecycle (4.0.0): - - AEPCore (>= 4.0.0) + - AEPServices (>= 4.1.0) + - AEPIdentity (4.1.0): + - AEPCore (>= 4.1.0) + - AEPLifecycle (4.1.0): + - AEPCore (>= 4.1.0) - AEPRulesEngine (4.0.0) - - AEPServices (4.0.0) - - AEPSignal (4.0.0): - - AEPCore (>= 4.0.0) + - AEPServices (4.1.0) + - AEPSignal (4.1.0): + - AEPCore (>= 4.1.0) - SwiftLint (0.52.0) - SwiftyJSON (5.0.1) @@ -45,12 +45,12 @@ SPEC REPOS: SPEC CHECKSUMS: AEPAnalytics: a510eb9653fac7f913965ad4291c8d51f74ffdcd AEPAssurance: 4fa3138ddd7308c1f9923570f4d2b0b8526a916f - AEPCore: dd7cd69696c768c610e6adc0307032985a381c7e - AEPIdentity: 45ee1c3717e08ff3ca60930caf4a869d60d7bf08 - AEPLifecycle: 59be1b5381d8ec4939ece43516ea7d2de4aaba65 + AEPCore: 20fb832a7467b25ca4aca186c0a5a1e3c0c6abc3 + AEPIdentity: 88671626d6043a488896ee7d71483a8bcec80739 + AEPLifecycle: 97693ea99ef9deb818b726a4e429ef96abb1353e AEPRulesEngine: 458450a34922823286ead045a0c2bd8c27e224c6 - AEPServices: ca493988df250d84fda050124ff7549bcc43c65f - AEPSignal: b2b332adf4d8a9af6a1b57f5dd8c2e1ea6d5c112 + AEPServices: d94555679870311d2f1391c5d7a5de590fd1f3c0 + AEPSignal: 9152e68bae462276f57ac63666e879cc7ff7c302 SwiftLint: 13280e21cdda6786ad908dc6e416afe5acd1fcb7 SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e diff --git a/Script/update-versions.sh b/Script/update-versions.sh new file mode 100755 index 0000000..af6ab6f --- /dev/null +++ b/Script/update-versions.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +# make this script executable from terminal: +# chmod 755 update-versions.sh + +set -e # Any subsequent(*) commands which fail will cause the shell script to exit immediately + +ROOT_DIR=$(git rev-parse --show-toplevel) +LINE="================================================================================" +VERSION_REGEX="[0-9]+\.[0-9]+\.[0-9]+" +DEPENDENCIES=none + +# make a "dictionary" to help us find the correct spm repo per dependency (if necessary) +# IMPORTANT - this will be used in a regex search so escape special chars +# usage : +# getRepo AEPCore + +declare "repos_AEPCore=https:\/\/github\.com\/adobe\/aepsdk-core-ios\.git" + +getRepo() { + local extensionName=$1 + local url="repos_$extensionName" + echo "${!url}" +} + +help() +{ + echo "" + echo "Usage: $0 -n EXTENSION_NAME -v NEW_VERSION -d \"PODSPEC_DEPENDENCY_1, PODSPEC_DEPENDENCY_2\"" + echo "" + echo -e " -n\t- Name of the extension getting a version update. \n\t Example: Edge, Analytics\n" + echo -e " -v\t- New version to use for the extension. \n\t Example: 4.0.2\n" + echo -e " -d (optional)\t- Dependency(ies) that require updating in the extension's podspec and Package.swift file. \n\t Example: -d \"AEPCore 4.0.2\" (update the dependency on AEPCore to version 4.0.2 or newer)\n" + exit 1 # Exit script after printing help +} + +while getopts "n:v:d:" opt +do + case "$opt" in + n ) NAME="$OPTARG" ;; + v ) NEW_VERSION="$OPTARG" ;; + d ) DEPENDENCIES="$OPTARG" ;; + ? ) help ;; # Print help in case parameter is non-existent + esac +done + +# Print help in case parameters are empty +if [ -z "$NAME" ] || [ -z "$NEW_VERSION" ] +then + echo "********** USAGE ERROR **********" + echo "Some or all of the parameters are empty. See usage below:"; + help +fi + +PODSPEC_FILE=$ROOT_DIR"/AEP"$NAME.podspec +SPM_FILE=$ROOT_DIR/Package.swift + +# Begin script in case all parameters are correct +echo "" +echo "$LINE" +echo "Changing version of AEP$NAME to $NEW_VERSION with the following minimum version dependencies: $DEPENDENCIES" +echo "$LINE" + +# Replace extension version in podspec +echo "Changing value of 's.version' to '$NEW_VERSION' in '$PODSPEC_FILE'" +sed -i '' -E "/^ *s.version/{s/$VERSION_REGEX/$NEW_VERSION/;}" $PODSPEC_FILE + +# Replace dependencies in podspec and Package.swift +if [ "$DEPENDENCIES" != "none" ]; then + IFS="," + dependenciesArray=($(echo "$DEPENDENCIES")) + + IFS=" " + for dependency in "${dependenciesArray[@]}"; do + dependencyArray=(${dependency// / }) + dependencyName=${dependencyArray[0]} + dependencyVersion=${dependencyArray[1]} + + if [ "$dependencyVersion" != "" ]; then + echo "Changing value of 's.dependency' for '$dependencyName' to '>= $dependencyVersion' in '$PODSPEC_FILE'" + sed -i '' -E "/^ *s.dependency +'$dependencyName'/{s/$VERSION_REGEX/$dependencyVersion/;}" $PODSPEC_FILE + + spmRepoUrl=$(getRepo $dependencyName) + if [ "$spmRepoUrl" != "" ]; then + echo "Changing value of '.upToNextMajor(from:)' for '$spmRepoUrl' to '$dependencyVersion' in '$SPM_FILE'" + sed -i '' -E "/$spmRepoUrl\", \.upToNextMajor/{s/$VERSION_REGEX/$dependencyVersion/;}" $SPM_FILE + fi + fi + done +fi + +# Replace version in Constants file +CONSTANTS_FILE=$ROOT_DIR"/AEP$NAME/Sources/"$NAME"Constants.swift" +echo "Changing value of 'EXTENSION_VERSION' to '$NEW_VERSION' in '$CONSTANTS_FILE'" +sed -i '' -E "/^ +static let EXTENSION_VERSION/{s/$VERSION_REGEX/$NEW_VERSION/;}" $CONSTANTS_FILE + +# Replace version in TestConstants file +TEST_CONSTANTS_FILE=$ROOT_DIR"/AEP$NAME/Tests/TestHelpers/"$NAME"TestConstants.swift" +echo "Changing value of 'EXTENSION_VERSION' to '$NEW_VERSION' in '$TEST_CONSTANTS_FILE'" +sed -i '' -E "/^ +static let EXTENSION_VERSION/{s/$VERSION_REGEX/$NEW_VERSION/;}" $TEST_CONSTANTS_FILE + +# Replace marketing versions in project.pbxproj +PROJECT_PBX_FILE=$ROOT_DIR"/AEP$NAME.xcodeproj/project.pbxproj" +echo "Changing value of 'MARKETING_VERSION' to '$NEW_VERSION' in '$PROJECT_PBX_FILE'" +sed -i '' -E "/^\t+MARKETING_VERSION = /{s/$VERSION_REGEX/$NEW_VERSION/;}" $PROJECT_PBX_FILE \ No newline at end of file