Skip to content

Commit 476c6ff

Browse files
[AND-285] Open API Code Gen V2 Integration (#1296)
* Reformat open api generated code Reformat StreamVideoClient Add api file after generating new open api code Exclude auto gen files from spotless Fix script generated code Add generated code Update the script to generate open api kotlin code Add script to generate open api kotlin code * Revert the changes from stream-video-android-core/build.gradle.kts * minor changes in ClosedCaptionManager * Add some changes in UT * Add missing moshi adapters * Add api dump * Skipping AudioRoomTest to pass in the CI * Rename package name from org.openapitools.client to io.getstream.android.video.generated * Update the generate open api script * Fix issues in renaming the package names * Fix linting * Fix linting * Fix linting * Fix UT * Exclude auto generated classes from kover * Ignore autogenerated from kover and sonar * Ignore autogenerated from kover and sonar * Ignore model class from kover * Ignore model class from kover * remove comments * ignore classes from sonarqube * ignore classes from sonarqube --------- Co-authored-by: Aleksandar Apostolov <[email protected]>
1 parent 28fa825 commit 476c6ff

File tree

410 files changed

+17774
-20530
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

410 files changed

+17774
-20530
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
apply(plugin = "io.github.gradle-nexus.publish-plugin")
22
apply(plugin = "org.jetbrains.dokka")
33
apply(from = "${rootDir}/scripts/sonar.gradle")
4+
apply(from = "${rootDir}/scripts/open-api-code-gen.gradle.kts")
45

56
buildscript {
67
repositories {

demo-app/src/main/kotlin/io/getstream/video/android/ui/call/CallScreen.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ import androidx.compose.ui.unit.IntSize
6666
import androidx.compose.ui.unit.dp
6767
import androidx.compose.ui.window.Popup
6868
import androidx.lifecycle.compose.collectAsStateWithLifecycle
69+
import io.getstream.android.video.generated.models.OwnCapability
70+
import io.getstream.android.video.generated.models.TranscriptionSettingsResponse
6971
import io.getstream.chat.android.ui.common.state.messages.list.MessageItemState
7072
import io.getstream.video.android.BuildConfig
7173
import io.getstream.video.android.R
@@ -115,8 +117,6 @@ import kotlinx.coroutines.delay
115117
import kotlinx.coroutines.flow.collectLatest
116118
import kotlinx.coroutines.flow.map
117119
import kotlinx.coroutines.launch
118-
import org.openapitools.client.models.OwnCapability
119-
import org.openapitools.client.models.TranscriptionSettingsResponse
120120

121121
@Composable
122122
fun CallScreen(

demo-app/src/main/kotlin/io/getstream/video/android/ui/closedcaptions/ClosedCaptionUi.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ import androidx.compose.ui.platform.LocalInspectionMode
3939
import androidx.compose.ui.tooling.preview.Preview
4040
import androidx.compose.ui.unit.dp
4141
import androidx.lifecycle.compose.collectAsStateWithLifecycle
42+
import io.getstream.android.video.generated.models.CallClosedCaption
4243
import io.getstream.video.android.core.Call
43-
import org.openapitools.client.models.CallClosedCaption
4444

4545
/**
4646
* A set of composables and supporting classes for displaying and customizing closed captions in a call.

demo-app/src/main/kotlin/io/getstream/video/android/ui/closedcaptions/ClosedCaptionUiState.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
package io.getstream.video.android.ui.closedcaptions
1818

19-
import org.openapitools.client.models.TranscriptionSettingsResponse
19+
import io.getstream.android.video.generated.models.TranscriptionSettingsResponse
2020

2121
sealed class ClosedCaptionUiState {
2222
/**

demo-app/src/main/kotlin/io/getstream/video/android/ui/menu/transcriptions/TranscriptionUiStateManager.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@
1616

1717
package io.getstream.video.android.ui.menu.transcriptions
1818

19+
import io.getstream.android.video.generated.models.CallSettingsResponse
20+
import io.getstream.android.video.generated.models.TranscriptionSettingsResponse
1921
import io.getstream.video.android.ui.menu.TranscriptionAvailableUiState
2022
import io.getstream.video.android.ui.menu.TranscriptionDisabledUiState
2123
import io.getstream.video.android.ui.menu.TranscriptionStoppedUiState
2224
import io.getstream.video.android.ui.menu.TranscriptionUiState
23-
import org.openapitools.client.models.CallSettingsResponse
24-
import org.openapitools.client.models.TranscriptionSettingsResponse
2525

2626
class TranscriptionUiStateManager(
2727
private val isTranscribing: Boolean,

generate_openapi_v2.sh

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
# Default values
6+
REPO_URL="[email protected]:GetStream/chat.git"
7+
REFERENCE_TYPE="branch"
8+
REFERENCE_VALUE="feature/rahullohra/kotlin_open_api_generator"
9+
API_SERVICE_CLASS_NAME="ApiService"
10+
MODEL_PACKAGE="org.openapitools.autogenerated.client.models"
11+
API_SERVICE_PACKAGE="org.openapitools.autogenerated.client.apis"
12+
MODEL_DIR="models"
13+
API_SERVICE_DIR="apis"
14+
MOSHI_ADAPTER_DIR="infrastructure"
15+
MOSHI_ADAPTER_PACKAGE="org.openapitools.autogenerated.client.infrastructure"
16+
CLASSES_TO_SKIP="PrivacySettingsResponse,PrivacySettings"
17+
KEEP_CLASSES="WSAuthMessageRequest.kt"
18+
OUTPUT_CLIENT_PATH="./stream-video-android-core/src/main/kotlin/org/openapitools/client"
19+
20+
# Parse key-value arguments
21+
for arg in "$@"; do
22+
case $arg in
23+
--repo-url=*)
24+
REPO_URL="${arg#*=}"
25+
shift
26+
;;
27+
--ref-type=*)
28+
REFERENCE_TYPE="${arg#*=}"
29+
shift
30+
;;
31+
--ref-value=*)
32+
REFERENCE_VALUE="${arg#*=}"
33+
shift
34+
;;
35+
--source-path=*)
36+
SOURCE_PATH="${arg#*=}"
37+
shift
38+
;;
39+
--output-spec=*)
40+
OUTPUT_SPEC_PATH="${arg#*=}"
41+
shift
42+
;;
43+
--output-client=*)
44+
OUTPUT_CLIENT_PATH="${arg#*=}"
45+
shift
46+
;;
47+
--model-package-name=*)
48+
MODEL_PACKAGE="${arg#*=}"
49+
shift
50+
;;
51+
--model-dir=*)
52+
MODEL_DIR="${arg#*=}"
53+
shift
54+
;;
55+
--api-service-dir=*)
56+
API_SERVICE_DIR="${arg#*=}"
57+
shift
58+
;;
59+
--api-service-package-name=*)
60+
API_SERVICE_PACKAGE="${arg#*=}"
61+
shift
62+
;;
63+
--api-service-class-name=*)
64+
API_SERVICE_CLASS_NAME="${arg#*=}"
65+
shift
66+
;;
67+
--moshi-adapters-dir=*)
68+
MOSHI_ADAPTER_DIR="${arg#*=}"
69+
shift
70+
;;
71+
--moshi-adapters-package-name=*)
72+
MOSHI_ADAPTER_PACKAGE="${arg#*=}"
73+
shift
74+
;;
75+
--classes-to-skip=*)
76+
CLASSES_TO_SKIP="${arg#*=}"
77+
shift
78+
;;
79+
--keep-classes=*)
80+
KEEP_CLASSES="${arg#*=}"
81+
shift
82+
;;
83+
*)
84+
echo "❌ ERROR: Unknown argument: $arg"
85+
exit 1
86+
;;
87+
esac
88+
done
89+
90+
# Define working directories
91+
PROJECT_ROOT="$(dirname "$(realpath "$0")")/"
92+
BUILD_DIR="$PROJECT_ROOT/build"
93+
CLONE_DIR="$BUILD_DIR/openapi-generator-repo"
94+
PROGRAM_PATH="$CLONE_DIR/cmd/chat-manager"
95+
SPEC_FILE="$CLONE_DIR/releases/video-openapi-clientside.yaml"
96+
OUTPUT_DIR="$CLONE_DIR/output"
97+
SOURCE_PATH=CLONE_DIR
98+
OUTPUT_SPEC_PATH="$CLONE_DIR/releases/video-openapi-clientside"
99+
OUTPUT_CLIENT_ABSOLUTE_PATH="$PROJECT_ROOT$OUTPUT_CLIENT_PATH"
100+
101+
# Set environment variables
102+
export APP_CONFIG_FILE="configs/test.yaml"
103+
104+
#mkdir -p $OUTPUT_CLIENT_PATH //Create and delete files here TODO Rahul
105+
106+
# Step 1: Delete/Create directory, and keep classes
107+
if [[ ! -d "$OUTPUT_CLIENT_PATH" ]]; then
108+
echo "Error: Directory $OUTPUT_CLIENT_PATH does not exist."
109+
# Function to create a directory if it doesn't exist
110+
create_directory() {
111+
local DIR_PATH=$OUTPUT_CLIENT_PATH
112+
113+
if [ -z $DIR_PATH ]; then
114+
echo "Usage: create_directory <directory_path>"
115+
return 1
116+
fi
117+
118+
if [ ! -d "$DIR_PATH" ]; then
119+
echo "Directory does not exist. Creating: $DIR_PATH"
120+
mkdir -p $DIR_PATH
121+
echo "Directory created successfully."
122+
else
123+
echo "Directory already exists: $DIR_PATH"
124+
fi
125+
}
126+
create_directory $OUTPUT_CLIENT_PATH
127+
128+
else
129+
# Function to check if a file should be kept
130+
should_keep() {
131+
local file_name=$(basename "$1")
132+
for keep in "${KEEP_CLASSES[@]}"; do
133+
echo "file_name = $file_name, keep = $keep"
134+
if [[ "$file_name" == "$keep" ]]; then
135+
return 0 # File should be kept
136+
fi
137+
done
138+
return 1 # File should be deleted
139+
}
140+
141+
# Iterate through files in the directory recursively
142+
find "$OUTPUT_CLIENT_PATH" -type f | while read -r file; do
143+
if ! should_keep "$file"; then
144+
rm "$file"
145+
echo "Deleted: $file"
146+
else
147+
echo "Kept: $file"
148+
fi
149+
done
150+
151+
# Remove empty directories
152+
find "$OUTPUT_CLIENT_PATH" -type d -empty -delete
153+
154+
echo "🧹🧹Cleanup completed!"
155+
fi
156+
157+
# Step 2: Clone the repository with shallow depth
158+
echo "🚀 Cloning repository: $REPO_URL (Type: $REFERENCE_TYPE, Value: $REFERENCE_VALUE)..."
159+
rm -rf "$CLONE_DIR"
160+
git clone --depth=1 --branch "$REFERENCE_VALUE" "$REPO_URL" "$CLONE_DIR"
161+
cd "$CLONE_DIR"
162+
163+
164+
# Step 3: Checkout to the correct branch, tag, or commit
165+
if [ "$REFERENCE_TYPE" == "branch" ]; then
166+
git checkout "$REFERENCE_VALUE"
167+
elif [ "$REFERENCE_TYPE" == "tag" ]; then
168+
git checkout "tags/$REFERENCE_VALUE"
169+
elif [ "$REFERENCE_TYPE" == "commit" ]; then
170+
git checkout "$REFERENCE_VALUE"
171+
else
172+
echo "❌ ERROR: Invalid reference type '$REFERENCE_TYPE'. Use 'branch', 'tag', or 'commit'."
173+
exit 1
174+
fi
175+
176+
# Step 4: Run the Go program with OpenAPI arguments
177+
echo "⚙️ Running OpenAPI Spec Generation..."
178+
go run ./cmd/chat-manager openapi generate-spec \
179+
-products video \
180+
-version v1 \
181+
-clientside \
182+
-output "$OUTPUT_SPEC_PATH"
183+
184+
# Step 5: Generating Kt files
185+
echo "⚙️ Running OpenAPI Client Generation..."
186+
go run ./cmd/chat-manager openapi generate-client \
187+
--language kotlin \
188+
--spec "$OUTPUT_SPEC_PATH.yaml" \
189+
--api-service-class-name "$API_SERVICE_CLASS_NAME" \
190+
--api-service-package "$API_SERVICE_PACKAGE" \
191+
--api-service-dir "$API_SERVICE_DIR" \
192+
--model-package "$MODEL_PACKAGE" \
193+
--model-dir "$MODEL_DIR" \
194+
--moshi-adapters-dir "$MOSHI_ADAPTER_DIR" \
195+
--moshi-adapters-package "$MOSHI_ADAPTER_PACKAGE" \
196+
--classes-to-skip "$CLASSES_TO_SKIP" \
197+
--output "$OUTPUT_CLIENT_ABSOLUTE_PATH"
198+
199+
echo "👉 Your autogenerated files are available under $OUTPUT_CLIENT_ABSOLUTE_PATH"
200+
201+
# Step 6: Delete files
202+
#rm -rf "$CLONE_DIR"
203+
204+
echo "✅ OpenAPI Kotlin client generation completed successfully!"

scripts/coverage.gradle

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,22 @@ if (!rootProject.ext.sonar.ignoreModules.contains(name)) {
2020
warningInsteadOfFailure = true
2121
}
2222
}
23+
currentProject {
24+
instrumentation {
25+
excludedClasses.addAll(
26+
"io.getstream.android.video.generated.*",
27+
"io.getstream.video.android.core.model.*"
28+
)
29+
}
30+
}
2331
}
2432

2533
sonarqube {
2634
properties {
2735
property "sonar.junit.reportPaths", "${buildDir}/test-results/testDebugUnitTest"
2836
property "sonar.coverage.jacoco.xmlReportPaths", "${buildDir}/reports/kover/reportDebug.xml"
2937
property "sonar.sources", "src/main/kotlin"
38+
property "sonar.coverage.exclusions", "**/generated/**,**/io/getstream/video/android/core/model/**"
3039
}
3140
}
3241
}

scripts/open-api-code-gen.gradle.kts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
tasks.register<Exec>("generateOpenApiClient") {
2+
group = "Custom"
3+
description = "Generates open api client"
4+
5+
val repoUrl = project.findProperty("repoUrl") as? String ?: "[email protected]:GetStream/chat.git"
6+
val refType = project.findProperty("refType") as? String ?: "branch"
7+
val refValue = project.findProperty("refValue") as? String ?: "feature/rahullohra/kotlin_open_api_generator"
8+
9+
val modelPackageName = project.findProperty("modelPackage") as? String ?: "org.openapitools.client.models"
10+
val modelsDir = project.findProperty("modelsDir") as? String ?: "models"
11+
12+
val apiServicePackageName = project.findProperty("apiServicePackage") as? String ?: "org.openapitools.client.apis"
13+
val apiServiceClassName = project.findProperty("apiServiceClassName") as? String ?: "ProductvideoApi"
14+
val apiServiceDir = project.findProperty("apiServiceDir") as? String ?: "apis"
15+
16+
val moshiAdaptersDir = project.findProperty("moshiAdaptersDir") as? String ?: "infrastructure"
17+
val moshiAdapterPackage = project.findProperty("moshiAdapterPackageName") as? String ?: "org.openapitools.client.infrastructure"
18+
19+
val classesToSkip = project.findProperty("classesToSkip") as? String ?: "PrivacySettingsResponse,PrivacySettings,StopRTMPBroadcastsRequest"
20+
21+
// val outputSpec = project.findProperty("outputSpec") as? String ?: "./releases/video-openapi-clientside"
22+
val outputClient = project.findProperty("outputClient") as? String ?: "stream-video-android-core/src/main/kotlin/org/openapitools/client/v3"
23+
val keepClasses = project.findProperty("keepClasses") as? String ?: "WSAuthMessageRequest.kt"
24+
val buildDir = project.layout.buildDirectory.asFile.get()
25+
26+
println("outputClient = $outputClient")
27+
println("path = $path")
28+
println("buildDir = $buildDir")
29+
println("workingDir = $workingDir")
30+
println("projectDir = ${projectDir}")
31+
println("project root dir = ${project.rootDir}")
32+
println("Keep Classes = ${keepClasses}")
33+
34+
// return@register
35+
36+
workingDir = project.rootDir
37+
val scriptFile = file("${project.rootDir}/generate_openapi_v2.sh")
38+
39+
// Make sure the script exists
40+
if (!scriptFile.exists()) {
41+
throw GradleException("❌ ERROR: Script not found at ${scriptFile.absolutePath}")
42+
}
43+
44+
// Ensure the script has execute permission
45+
scriptFile.setExecutable(true)
46+
47+
commandLine("sh", scriptFile.absolutePath,
48+
"--repo-url=$repoUrl",
49+
"--ref-type=$refType",
50+
"--ref-value=$refValue",
51+
"--model-package-name=$modelPackageName",
52+
"--model-dir=$modelsDir",
53+
"--api-service-package-name=$apiServicePackageName",
54+
"--api-service-class-name=$apiServiceClassName",
55+
"--api-service-dir=$apiServiceDir",
56+
"--moshi-adapters-dir=$moshiAdaptersDir",
57+
"--moshi-adapters-package-name=$moshiAdapterPackage",
58+
"--classes-to-skip=$classesToSkip",
59+
"--keep-classes=$keepClasses",
60+
"--output-client=$outputClient",
61+
)
62+
63+
doLast {
64+
println("✅ OpenAPI Kotlin client generation completed via Gradle!")
65+
}
66+
}

0 commit comments

Comments
 (0)