Skip to content

Commit

Permalink
Get rid of type aliases
Browse files Browse the repository at this point in the history
 - This converts `CloneAndProcessDirectoryAction`, `GitRepositoryProcessor`,
   and `CloneResult` into classes/interfaces.
 - Additionally, `fetch()` now returns a `Flux<TestSuiteValidationResult>`
   instead of `Mono<Unit>`.
 - Related: #1096
  • Loading branch information
0x6675636b796f75676974687562 committed Mar 7, 2023
1 parent 2fa8b61 commit 4df2a8c
Show file tree
Hide file tree
Showing 7 changed files with 270 additions and 91 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.saveourtool.save.preprocessor.common

import com.saveourtool.save.entities.GitDto
import com.saveourtool.save.preprocessor.service.GitPreprocessorService
import org.reactivestreams.Publisher

/**
* Uses [GitPreprocessorService] to clone and process a repository.
*/
fun interface CloneAndProcessDirectoryAction<T : Publisher<*>> {
/**
* Clones and processes a repository identified by [gitDto].
*
* @param gitDto the _Git_ URL along with optional credentials.
* @param branchOrTagOrCommit either a branch name, or a tag name, or a
* commit hash.
* @param repositoryProcessor the custom process action.
* @return a custom [Publisher] returned by [repositoryProcessor].
*/
fun GitPreprocessorService.cloneAndProcessDirectoryAsync(
gitDto: GitDto,
branchOrTagOrCommit: String,
repositoryProcessor: GitRepositoryProcessor<T>,
): T
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.saveourtool.save.preprocessor.common

import com.saveourtool.save.preprocessor.utils.GitCommitInfo
import java.nio.file.Path

/**
* The result of running `git clone`.
*
* @property directory the local directory the repository has been cloned into.
* @property gitCommitInfo the _Git_ commit metadata.
*/
data class CloneResult(
val directory: Path,
val gitCommitInfo: GitCommitInfo,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.saveourtool.save.preprocessor.common

import org.reactivestreams.Publisher

/**
* Asynchronously processes a local _Git_ repository.
*/
fun interface GitRepositoryProcessor<T : Publisher<*>> {
/**
* Processes the cloned _Git_ repository, returning a `Mono` or a `Flux`.
*
* @param cloneResult the local directory along with _Git_ metadata.
* @return the result of the processing as a custom [Publisher].
*/
fun processAsync(cloneResult: CloneResult): T
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class AwesomeBenchmarksDownloadController(
gitPreprocessorService.cloneBranchAndProcessDirectory(
gitDto,
branch
) { repositoryDir: Path, _ ->
) { (repositoryDir: Path) ->
log.info("Awesome-benchmarks were downloaded to ${repositoryDir.absolutePathString()}")
processDirectoryAndCleanUp(repositoryDir)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.saveourtool.save.preprocessor.controllers

import com.saveourtool.save.entities.GitDto
import com.saveourtool.save.preprocessor.common.CloneAndProcessDirectoryAction
import com.saveourtool.save.preprocessor.common.GitRepositoryProcessor
import com.saveourtool.save.preprocessor.service.GitPreprocessorService
import com.saveourtool.save.preprocessor.service.GitRepositoryProcessor
import com.saveourtool.save.preprocessor.service.TestDiscoveringService
import com.saveourtool.save.preprocessor.service.TestsPreprocessorToBackendBridge
import com.saveourtool.save.preprocessor.utils.GitCommitInfo
import com.saveourtool.save.request.TestsSourceFetchRequest
import com.saveourtool.save.test.TestSuiteValidationResult
import com.saveourtool.save.test.TestsSourceSnapshotDto
import com.saveourtool.save.testsuite.TestSuitesSourceFetchMode
import com.saveourtool.save.utils.*
Expand All @@ -18,6 +20,7 @@ import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import reactor.core.publisher.Flux
import reactor.core.publisher.Mono
import reactor.kotlin.core.publisher.switchIfEmpty
import reactor.kotlin.core.util.function.component1
Expand All @@ -27,8 +30,6 @@ import java.nio.file.Path

import kotlin.io.path.div

typealias CloneAndProcessDirectoryAction = GitPreprocessorService.(GitDto, String, GitRepositoryProcessor<Unit>) -> Mono<Unit>

/**
* Preprocessor's controller for [com.saveourtool.save.entities.TestSuitesSource]
*/
Expand All @@ -48,41 +49,50 @@ class TestSuitesPreprocessorController(
@PostMapping("/fetch")
fun fetch(
@RequestBody request: TestsSourceFetchRequest,
): Mono<Unit> = fetchTestSuites(
request = request,
cloneAndProcessDirectoryAction = when (request.mode) {
TestSuitesSourceFetchMode.BY_BRANCH -> GitPreprocessorService::cloneBranchAndProcessDirectory
TestSuitesSourceFetchMode.BY_COMMIT -> GitPreprocessorService::cloneCommitAndProcessDirectory
TestSuitesSourceFetchMode.BY_TAG -> GitPreprocessorService::cloneTagAndProcessDirectory
}
)
): Flux<TestSuiteValidationResult> {
@Suppress("TYPE_ALIAS")
val cloneAndProcessDirectoryAction: GitPreprocessorService.(GitDto, String, GitRepositoryProcessor<Flux<TestSuiteValidationResult>>) -> Flux<TestSuiteValidationResult> =
when (request.mode) {
TestSuitesSourceFetchMode.BY_BRANCH -> GitPreprocessorService::cloneBranchAndProcessDirectoryMany
TestSuitesSourceFetchMode.BY_COMMIT -> GitPreprocessorService::cloneCommitAndProcessDirectoryMany
TestSuitesSourceFetchMode.BY_TAG -> GitPreprocessorService::cloneTagAndProcessDirectoryMany
}

return fetchTestSuites(
request = request,
cloneAndProcessDirectoryAction = cloneAndProcessDirectoryAction
)
}

@NonBlocking
@Suppress("TYPE_ALIAS")
private fun fetchTestSuites(
request: TestsSourceFetchRequest,
cloneAndProcessDirectoryAction: CloneAndProcessDirectoryAction,
): Mono<Unit> = gitPreprocessorService.cloneAndProcessDirectoryAction(
request.source.gitDto,
request.version
) { repositoryDirectory, gitCommitInfo ->
testsPreprocessorToBackendBridge.findTestsSourceSnapshot(request.source.requiredId(), gitCommitInfo.id)
.switchIfEmpty {
doFetchTests(repositoryDirectory, gitCommitInfo, request)
}
.flatMap { snapshot ->
testsPreprocessorToBackendBridge.saveTestsSourceVersion(request.createVersion(snapshot))
}.doOnNext { isSaved: Boolean ->
log.info {
val messagePrefix = "Tests from ${request.source.gitDto.url}"
val status = when {
isSaved -> "saved"
else -> "not saved: the snapshot already exists"
}
val messageSuffix = "(version \"${request.version}\"; commit ${gitCommitInfo.id})."

"$messagePrefix $status $messageSuffix"
cloneAndProcessDirectoryAction: CloneAndProcessDirectoryAction<Flux<TestSuiteValidationResult>>,
): Flux<TestSuiteValidationResult> = with(cloneAndProcessDirectoryAction) {
gitPreprocessorService.cloneAndProcessDirectoryAsync(
request.source.gitDto,
request.version
) { (repositoryDirectory, gitCommitInfo) ->
testsPreprocessorToBackendBridge.findTestsSourceSnapshot(request.source.requiredId(), gitCommitInfo.id)
.switchIfEmpty {
doFetchTests(repositoryDirectory, gitCommitInfo, request)
}
}.thenReturn(Unit)
.flatMap { snapshot ->
testsPreprocessorToBackendBridge.saveTestsSourceVersion(request.createVersion(snapshot))
}.doOnNext { isSaved: Boolean ->
log.info {
val messagePrefix = "Tests from ${request.source.gitDto.url}"
val status = when {
isSaved -> "saved"
else -> "not saved: the snapshot already exists"
}
val messageSuffix = "(version \"${request.version}\"; commit ${gitCommitInfo.id})."

"$messagePrefix $status $messageSuffix"
}
}.thenMany(Flux.empty())
}
}

@NonBlocking
Expand Down
Loading

0 comments on commit 4df2a8c

Please sign in to comment.