Skip to content

Commit 0ea0ee5

Browse files
committed
feat(model-client): allow deleting branches
Adds a new `deleteBranch` method to IModelClientV2 for deleting a branch from a repository in case it exists.
1 parent 25b67e6 commit 0ea0ee5

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

model-client/src/commonMain/kotlin/org/modelix/model/client2/IModelClientV2.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@ interface IModelClientV2 {
4444
suspend fun deleteRepository(repository: RepositoryId): Boolean
4545
suspend fun listBranches(repository: RepositoryId): List<BranchReference>
4646

47+
/**
48+
* Deletes a branch from a repository if it exists.
49+
*
50+
* @param branch the branch to delete
51+
* @return true if the branch existed and could be deleted, else false.
52+
*/
53+
suspend fun deleteBranch(branch: BranchReference): Boolean
54+
4755
@Deprecated("repository ID is required for permission checks")
4856
@DeprecationInfo("3.7.0", "May be removed with the next major release. Also remove the endpoint from the model-server.")
4957
suspend fun loadVersion(versionHash: String, baseVersion: IVersion?): IVersion

model-client/src/commonMain/kotlin/org/modelix/model/client2/ModelClientV2.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import io.ktor.client.plugins.ResponseException
2222
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
2323
import io.ktor.client.plugins.expectSuccess
2424
import io.ktor.client.request.HttpRequestBuilder
25+
import io.ktor.client.request.delete
2526
import io.ktor.client.request.get
2627
import io.ktor.client.request.post
2728
import io.ktor.client.request.prepareGet
@@ -168,6 +169,25 @@ class ModelClientV2(
168169
}.bodyAsText().lines().filter { it.isNotEmpty() }.map { repository.getBranchReference(it) }
169170
}
170171

172+
override suspend fun deleteBranch(branch: BranchReference): Boolean {
173+
try {
174+
return httpClient.delete {
175+
url {
176+
takeFrom(baseUrl)
177+
appendPathSegmentsEncodingSlash(
178+
"repositories",
179+
branch.repositoryId.id,
180+
"branches",
181+
branch.branchName,
182+
)
183+
}
184+
}.status == HttpStatusCode.NoContent
185+
} catch (ex: Exception) {
186+
LOG.error(ex) { ex.message }
187+
return false
188+
}
189+
}
190+
171191
@Deprecated("repository ID is required for permission checks")
172192
@DeprecationInfo("3.7.0", "May be removed with the next major release. Also remove the endpoint from the model-server.")
173193
override suspend fun loadVersion(versionHash: String, baseVersion: IVersion?): IVersion {

model-server/src/test/kotlin/org/modelix/model/server/ModelClientV2Test.kt

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.modelix.model.api.PBranch
2424
import org.modelix.model.client2.ModelClientV2
2525
import org.modelix.model.client2.runWrite
2626
import org.modelix.model.client2.runWriteOnBranch
27+
import org.modelix.model.lazy.BranchReference
2728
import org.modelix.model.lazy.CLTree
2829
import org.modelix.model.lazy.CLVersion
2930
import org.modelix.model.lazy.RepositoryId
@@ -165,6 +166,47 @@ class ModelClientV2Test {
165166
assertFalse(containsRepository)
166167
}
167168

169+
@Test
170+
fun `branches from non-existing repositories cannot be removed`() = runTest {
171+
val client = createModelClient()
172+
val repositoryId = RepositoryId(UUID.randomUUID().toString())
173+
174+
val success = client.deleteBranch(BranchReference(repositoryId, "doesntmatter"))
175+
176+
assertFalse(success)
177+
}
178+
179+
@Test
180+
fun `non-existing branches from existing repositories cannot be removed`() = runTest {
181+
val client = createModelClient()
182+
val repositoryId = RepositoryId(UUID.randomUUID().toString())
183+
client.initRepository(repositoryId)
184+
185+
val success = client.deleteBranch(BranchReference(repositoryId, "doesnotexist"))
186+
187+
assertFalse(success)
188+
}
189+
190+
@Test
191+
fun `existing branches from existing repositories can be removed`() = runTest {
192+
val client = createModelClient()
193+
val repositoryId = RepositoryId(UUID.randomUUID().toString())
194+
client.initRepository(repositoryId)
195+
val branchToDelete = BranchReference(repositoryId, "todelete")
196+
client.push(
197+
branchToDelete,
198+
requireNotNull(
199+
client.pullIfExists(BranchReference(repositoryId, "master")),
200+
) { "the master branch must always exist" },
201+
null,
202+
)
203+
204+
val success = client.deleteBranch(BranchReference(repositoryId, branchToDelete.branchName))
205+
206+
assertTrue(success)
207+
assertFalse(client.listBranches(repositoryId).contains(branchToDelete))
208+
}
209+
168210
@Test
169211
fun `pulling existing versions pulls all referenced objects`() = runTest {
170212
// Arrange

0 commit comments

Comments
 (0)