Skip to content

Commit

Permalink
recursively look for parent files of changed API specifications
Browse files Browse the repository at this point in the history
  • Loading branch information
harikrishnan83 committed May 29, 2024
1 parent e03c262 commit 13805eb
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import java.io.File
import java.util.concurrent.Callable

@Component
@Command(name = "backwardCompatibilityCheck",
mixinStandardHelpOptions = true,
description = ["Checks backward compatibility of a directory across the current HEAD and the main branch"])
class BackwardCompatibilityCheckCommand(
@Command(
name = "backwardCompatibilityCheck",
mixinStandardHelpOptions = true,
description = ["Checks backward compatibility of a directory across the current HEAD and the main branch"]
)
open class BackwardCompatibilityCheckCommand(
private val gitCommand: GitCommand,
) : Callable<Unit> {

Expand All @@ -29,7 +31,7 @@ class BackwardCompatibilityCheckCommand(

override fun call() {
val filesChangedInCurrentBranch: Set<String> = getOpenAPISpecFilesChangedInCurrentBranch()
if(filesChangedInCurrentBranch.isEmpty()) exitWithMessage("$newLine OpenAPI spec files were changed, skipping the check.$newLine")
if (filesChangedInCurrentBranch.isEmpty()) exitWithMessage("$newLine OpenAPI spec files were changed, skipping the check.$newLine")

val filesReferringToChangedSchemaFiles = filesReferringToChangedSchemaFiles(filesChangedInCurrentBranch)

Expand All @@ -42,15 +44,15 @@ class BackwardCompatibilityCheckCommand(

val result = runBackwardCompatibilityCheckFor(filesToCheck)

if(result == FAILED) {
if (result == FAILED) {
exitWithMessage("$newLine Verdict: FAIL, backward incompatible changes were found.")
}
println("$newLine Verdict: PASS, all changes were backward compatible")
}

private fun runBackwardCompatibilityCheckFor(files: Set<String>): String {
val currentBranch = gitCommand.currentBranch()
val currentTreeish = if(currentBranch == HEAD) gitCommand.detachedHEAD() else currentBranch
val currentTreeish = if (currentBranch == HEAD) gitCommand.detachedHEAD() else currentBranch

try {
val failures = files.mapIndexed { index, specFilePath ->
Expand All @@ -74,7 +76,11 @@ class BackwardCompatibilityCheckCommand(
SUCCESS
} else {
println("$newLine ${backwardCompatibilityResult.report().prependIndent(MARGIN_SPACE)}")
println("$newLine *** The file $specFilePath is NOT backward compatible. ***$newLine".prependIndent(MARGIN_SPACE))
println(
"$newLine *** The file $specFilePath is NOT backward compatible. ***$newLine".prependIndent(
MARGIN_SPACE
)
)
FAILED
}
}.filter { it == FAILED }
Expand All @@ -85,7 +91,10 @@ class BackwardCompatibilityCheckCommand(
}
}

private fun logFilesToBeCheckedForBackwardCompatibility(changedFiles : Set<String>, filesReferringToChangedFiles: Set<String>) {
private fun logFilesToBeCheckedForBackwardCompatibility(
changedFiles: Set<String>,
filesReferringToChangedFiles: Set<String>
) {
println("Checking backward compatibility of the following files: $newLine")
println("Files that have changed - ")
changedFiles.forEach { println(it) }
Expand All @@ -98,31 +107,35 @@ class BackwardCompatibilityCheckCommand(
println()
}

private fun filesReferringToChangedSchemaFiles(schemaFiles : Set<String>): Set<String> {
if(schemaFiles.isEmpty()) return emptySet()
internal fun filesReferringToChangedSchemaFiles(schemaFiles: Set<String>): Set<String> {
if (schemaFiles.isEmpty()) return emptySet()

val schemaFileBaseNames = schemaFiles.map { File(it).name }
return allOpenApiSpecFiles().filter {
val result = allOpenApiSpecFiles().filter {
it.readText().let { specContent ->
schemaFileBaseNames.any { schemaFileBaseName -> schemaFileBaseName in specContent }
}
}.map { it.path }.toSet()

return result.flatMap {
filesReferringToChangedSchemaFiles(setOf(it)).ifEmpty { setOf(it) }
}.toSet()
}

private fun allOpenApiSpecFiles(): List<File> {
internal fun allOpenApiSpecFiles(): List<File> {
return File(".").walk().toList().filterNot {
".git" in it.path
}.filter { it.isFile && it.isOpenApiSpec() }
}

private fun getOpenAPISpecFilesChangedInCurrentBranch(): Set<String> {
return gitCommand.getFilesChangeInCurrentBranch().filter {
File(it).exists() && File(it).isOpenApiSpec()
File(it).exists() && File(it).isOpenApiSpec()
}.toSet()
}

private fun File.isOpenApiSpec(): Boolean {
if(this.extension !in CONTRACT_EXTENSIONS) return false
if (this.extension !in CONTRACT_EXTENSIONS) return false
return OpenApiSpecification.isParsable(this.path)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package application

import io.mockk.every
import io.mockk.mockk
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import java.io.File

class BackwardCompatibilityCheckCommandTest {

@Test
fun `filesReferringToChangedSchemaFiles returns empty set when input is empty`() {
val command = BackwardCompatibilityCheckCommand(mockk())
val result = command.filesReferringToChangedSchemaFiles(emptySet())
assertTrue(result.isEmpty())
}

@Test
fun `filesReferringToChangedSchemaFiles returns empty set when no files refer to changed schema files`() {
val command = BackwardCompatibilityCheckCommand(mockk(relaxed = true))
every { command.allOpenApiSpecFiles() } returns listOf(
File("file1.yaml").apply { writeText("content1") },
File("file2.yaml").apply { writeText("content2") }
)
val result = command.filesReferringToChangedSchemaFiles(setOf("file3.yaml"))
assertTrue(result.isEmpty())
}

@Test
fun `filesReferringToChangedSchemaFiles returns set of files that refer to changed schema files`() {
val command = mockk<BackwardCompatibilityCheckCommand>(relaxed = true)
every { command.allOpenApiSpecFiles() } returns listOf(
File("file1.yaml").apply { writeText("file3.yaml") },
File("file2.yaml").apply { writeText("file4.yaml") }
)
val result = command.filesReferringToChangedSchemaFiles(setOf("file3.yaml"))
assertEquals(setOf("file1.yaml"), result)
}
}

0 comments on commit 13805eb

Please sign in to comment.