Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: add script for generating new API version #WPB-11975 #3097

Merged
merged 12 commits into from
Nov 20, 2024
34 changes: 34 additions & 0 deletions network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,37 @@ android {
it.enabled = false
}
}

tasks.register<Exec>("generateNewApiVersion") {
group = "custom"
description = "Generates a new API version by calling the generate_new_api_version.sh script"

val previousApiVersion = project.findProperty("previousApiVersion") as String? ?: ""
val currentApiVersion = project.findProperty("currentApiVersion") as String? ?: ""
val newApiVersion = project.findProperty("newApiVersion") as String? ?: ""

doFirst {
if (previousApiVersion == "" || currentApiVersion == "" || newApiVersion == "") {
println(
"Usage: ./gradlew :network:generateNewApiVersion " +
"-PpreviousApiVersion=<previous> -PcurrentApiVersion=<current> -PnewApiVersion=<new>"
)
println(
"Example: ./gradlew :network:generateNewApiVersion " +
"-PpreviousApiVersion=5 -PcurrentApiVersion=6 -PnewApiVersion=7"
)
throw IllegalArgumentException(
"All parameters (previousApiVersion, " +
"currentApiVersion, newApiVersion) must be provided."
)
}
}

commandLine(
"bash",
"./../scripts/generate_new_api_version.sh",
previousApiVersion,
currentApiVersion,
newApiVersion
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*/

@file:Suppress("MagicNumber")

package com.wire.kalium.network

import com.wire.kalium.network.api.unbound.configuration.ApiVersionDTO
import com.wire.kalium.network.api.unbound.configuration.ServerConfigDTO
import com.wire.kalium.network.api.unbound.versioning.VersionInfoDTO

// They are not truly constants as set is not a primitive type, yet are treated as one in this context
@Suppress("MagicNumber")
val SupportedApiVersions = setOf(0, 1, 2, 4, 5)

// They are not truly constants as set is not a primitive type, yet are treated as one in this context
@Suppress("MagicNumber")
val DevelopmentApiVersions = setOf(6, 7)

// You can use scripts/generate_new_api_version.sh or gradle task network:generateNewApiVersion to
// bump API version and generate all needed classes

interface BackendMetaDataUtil {
fun calculateApiVersion(
versionInfoDTO: VersionInfoDTO,
Expand All @@ -45,8 +50,13 @@ object BackendMetaDataUtilImpl : BackendMetaDataUtil {
developmentApiEnabled: Boolean
): ServerConfigDTO.MetaData {

val allSupportedApiVersions = if (developmentApiEnabled) supportedApiVersions + developmentApiVersions else supportedApiVersions
val apiVersion = commonApiVersion(versionInfoDTO, allSupportedApiVersions, developmentApiEnabled)?.let { maxCommonVersion ->
val allSupportedApiVersions =
if (developmentApiEnabled) supportedApiVersions + developmentApiVersions else supportedApiVersions
val apiVersion = commonApiVersion(
versionInfoDTO,
allSupportedApiVersions,
developmentApiEnabled
)?.let { maxCommonVersion ->
ApiVersionDTO.Valid(maxCommonVersion)
} ?: run {
handleNoCommonVersion(versionInfoDTO.supported, allSupportedApiVersions)
Expand All @@ -59,16 +69,24 @@ object BackendMetaDataUtilImpl : BackendMetaDataUtil {
)
}

private fun commonApiVersion(serverVersion: VersionInfoDTO, supportedApiVersions: Set<Int>, developmentAPIEnabled: Boolean): Int? {
val serverSupportedApiVersions: List<Int> = if (developmentAPIEnabled && serverVersion.developmentSupported != null) {
serverVersion.supported + serverVersion.developmentSupported!!
} else {
serverVersion.supported
}
private fun commonApiVersion(
serverVersion: VersionInfoDTO,
supportedApiVersions: Set<Int>,
developmentAPIEnabled: Boolean
): Int? {
val serverSupportedApiVersions: List<Int> =
if (developmentAPIEnabled && serverVersion.developmentSupported != null) {
serverVersion.supported + serverVersion.developmentSupported!!
} else {
serverVersion.supported
}
return serverSupportedApiVersions.intersect(supportedApiVersions).maxOrNull()
}

private fun handleNoCommonVersion(serverVersion: List<Int>, appVersion: Set<Int>): ApiVersionDTO.Invalid {
private fun handleNoCommonVersion(
serverVersion: List<Int>,
appVersion: Set<Int>
): ApiVersionDTO.Invalid {
return serverVersion.maxOrNull()?.let { maxBEVersion ->
appVersion.maxOrNull()?.let { maxAppVersion ->
if (maxBEVersion > maxAppVersion) ApiVersionDTO.Invalid.New
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ interface AuthenticatedNetworkContainer {
kaliumLogger
)

// You can use scripts/generate_new_api_version.sh or gradle task network:generateNewApiVersion to
// bump API version and generate all needed classes
else -> error("Unsupported version: $version")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ interface UnauthenticatedNetworkContainer {
developmentApiEnabled = developmentApiEnabled
)

// You can use scripts/generate_new_api_version.sh or gradle task network:generateNewApiVersion to
// bump API version and generate all needed classes
else -> error("Unsupported version: ${serverConfigDTO.metaData.commonApiVersion.version}")
}
}
Expand Down
112 changes: 112 additions & 0 deletions scripts/generate_new_api_version.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/bin/bash

# Makes all paths relative to project root so it can be run from anywhere
parent_path=$(
cd "$(dirname "${BASH_SOURCE[0]}")" || exit
pwd -P
)
cd "$parent_path/.." || exit

if [ "$#" -ne 3 ]; then
echo "Usage: $0 <previousApiVersion> <currentApiVersion> <newApiVersion>"
echo "Example: $0 5 6 7"
exit 1
fi

# Validate that all parameters are integers
if ! [[ "$1" =~ ^[0-9]+$ && "$2" =~ ^[0-9]+$ && "$3" =~ ^[0-9]+$ ]]; then
echo "Error: All parameters must be integers."
exit 1
fi

# sometimes we have lower case (i.e. imports) sometimes upper case (i.e. class names)
previousApiVersionLower="v$1"
currentApiVersionLower="v$2"
newApiVersionLower="v$3"

previousApiVersionUpper="V$1"
currentApiVersionUpper="V$2"
newApiVersionUpper="V$3"

copy_api_files() {
local source_dir=$1
local target_dir=$2

mkdir -p "$target_dir"

for file in "$source_dir"/*.kt; do
if [[ -f "$file" ]]; then
content=$(cat "$file")
# package name changed from previous to current version
new_content=$(echo "$content" | sed "s/com\.wire\.kalium\.network\.api\.$currentApiVersionLower\./com.wire.kalium.network.api.$newApiVersionLower./g")
# class name changed from previous to current version
new_content=$(echo "$new_content" | sed "s/\(class .*\)$currentApiVersionUpper/\1$newApiVersionUpper/g")
# imports changed from previous to current version
new_content=$(echo "$new_content" | sed "s/com\.wire\.kalium\.network\.api\.$previousApiVersionLower\./com.wire.kalium.network.api.$currentApiVersionLower./g")
# imports class names changed from previous to current version
new_content=$(echo "$new_content" | sed "s/\(import com\.wire\.kalium\.network\.api\.$currentApiVersionLower\.\)\(.*\)$previousApiVersionUpper/\1\2$currentApiVersionUpper/g")
# class names in extension definition changed from previous to current version
new_content=$(echo "$new_content" | sed "s/\(: \)\(.*\)$previousApiVersionUpper/\1\2$currentApiVersionUpper/g")
# class names in inheritance changed from previous to current version
new_content=$(echo "$new_content" | sed "s/\(: \)\(.*\)$previousApiVersionUpper/\1\2$currentApiVersionUpper/g")
# Make class definitions empty inside {}
new_content=$(echo "$new_content" | perl -0777 -pe "s|({[\W\w]*\})|\2|g")
# Remove all private val or val
new_content=$(echo "$new_content" | sed "s/\(private \)*val //g")
# New file name with newApiVersion
new_filename=$(basename "$file" | sed "s/$currentApiVersionUpper/$newApiVersionUpper/g")
echo "$new_content" >"$target_dir/$new_filename"
echo "Created $new_filename"
fi
done
}

SOURCE_DIR_UNAUTH="network/src/commonMain/kotlin/com/wire/kalium/network/api/$currentApiVersionLower/unauthenticated"
TARGET_DIR_UNAUTH="network/src/commonMain/kotlin/com/wire/kalium/network/api/$newApiVersionLower/unauthenticated"

SOURCE_DIR_AUTH="network/src/commonMain/kotlin/com/wire/kalium/network/api/$currentApiVersionLower/authenticated"
TARGET_DIR_AUTH="network/src/commonMain/kotlin/com/wire/kalium/network/api/$newApiVersionLower/authenticated"

copy_api_files "$SOURCE_DIR_UNAUTH" "$TARGET_DIR_UNAUTH"
copy_api_files "$SOURCE_DIR_AUTH" "$TARGET_DIR_AUTH"

copy_container_files() {
local source_file="$1"
local target_file="${source_file//$currentApiVersionUpper/$newApiVersionUpper}"
target_file="${target_file//$currentApiVersionLower/$newApiVersionLower}"
if [[ -f "$source_file" ]]; then
mkdir -p "$(dirname "$target_file")"

# Read the content of the file
content=$(cat "$source_file")

# Perform replacements on the content
new_content="${content//$currentApiVersionUpper/$newApiVersionUpper}"
new_content="${new_content//$currentApiVersionLower/$newApiVersionLower}"

# Save the modified content back to the target file
echo "$new_content" >"$target_file"

echo "Created $target_file"
else
exit 1
fi
}

copy_container_files "network/src/commonMain/kotlin/com/wire/kalium/network/api/$currentApiVersionLower/authenticated/networkContainer/AuthenticatedNetworkContainer$currentApiVersionUpper.kt"
copy_container_files "network/src/commonMain/kotlin/com/wire/kalium/network/api/$currentApiVersionLower/unauthenticated/networkContainer/UnauthenticatedNetworkContainer$currentApiVersionUpper.kt"

echo

# Add the new API version to DevelopmentApiVersions if it does not already contain it
if ! grep -q "$3" network/src/commonMain/kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt; then
sed -i '' "s/\(val DevelopmentApiVersions = setOf(.*\))/\1, $3)/" network/src/commonMain/kotlin/com/wire/kalium/network/BackendMetaDataUtil.kt
echo "Added $3 to DevelopmentApiVersions in BackendMetaDataUtil.kt"
else
echo "$3 is already in DevelopmentApiVersions in BackendMetaDataUtil.kt"
fi

echo "!!!!!!!"
echo "You must add the new API version to the list of supported API versions in the AuthenticatedNetworkContainer.create() and UnauthenticatedNetworkContainer.create() methods."
echo "Check the generated files for unused parameters."
echo "!!!!!!!"
Loading