Move native level setups into level files
- Delete NativeLevelFixtures.kt and make native repository setup an optional property of each Level. - Move every existing native setup into its corresponding level file so setup, validation, and tests stay together. - Add the missing Blame native setup with config.rb history and a Spider Man password commit. - Add a native runtime regression that verifies `git blame config.rb` identifies Spider Man on the password line. - Verify the full JVM test suite using the compiled host Git runtime.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package solutions.tretter.githugandroid
|
||||
|
||||
import androidx.compose.runtime.saveable.listSaver
|
||||
import java.io.File
|
||||
|
||||
enum class PlayMode(val label: String) {
|
||||
CLI_ONLY("CLI ONLY"),
|
||||
@@ -46,6 +47,7 @@ data class Level(
|
||||
val commandSuggestions: List<String>,
|
||||
val validator: (RepoState, String) -> Boolean,
|
||||
val setup: () -> RepoState,
|
||||
val nativeSetup: (NativeLevelSetup.() -> Boolean)? = null,
|
||||
val testCases: List<LevelTestCase> = emptyList(),
|
||||
)
|
||||
|
||||
@@ -54,6 +56,91 @@ data class LevelTestCase(
|
||||
val commands: List<String>,
|
||||
)
|
||||
|
||||
class NativeLevelSetup internal constructor(
|
||||
internal val sandbox: File,
|
||||
private val runGit: (File, List<String>) -> Int,
|
||||
) {
|
||||
fun resetFiles() {
|
||||
sandbox.listFiles()
|
||||
?.filterNot { it.name == ".git" }
|
||||
?.forEach { it.deleteRecursively() }
|
||||
git("checkout", "-B", "master")
|
||||
}
|
||||
|
||||
fun git(vararg arguments: String): Int = runGit(sandbox, arguments.toList())
|
||||
|
||||
fun git(directory: File, vararg arguments: String): Int = runGit(directory, arguments.toList())
|
||||
|
||||
fun initRepo(directory: File) {
|
||||
directory.mkdirs()
|
||||
val initResult = git(directory, "init", "-b", "master")
|
||||
if (initResult != 0) {
|
||||
git(directory, "init")
|
||||
git(directory, "checkout", "-B", "master")
|
||||
}
|
||||
git(directory, "config", "receive.denyCurrentBranch", "ignore")
|
||||
}
|
||||
|
||||
fun write(path: String, content: String = "") {
|
||||
File(sandbox, path).apply {
|
||||
parentFile?.mkdirs()
|
||||
writeText(content)
|
||||
}
|
||||
}
|
||||
|
||||
fun append(path: String, content: String) {
|
||||
File(sandbox, path).appendText(content)
|
||||
}
|
||||
|
||||
fun add(vararg paths: String) {
|
||||
git("add", *paths)
|
||||
}
|
||||
|
||||
fun commit(message: String, author: String? = null) {
|
||||
if (author == null) {
|
||||
git("commit", "-m", message)
|
||||
} else {
|
||||
git("commit", "--author", author, "-m", message)
|
||||
}
|
||||
}
|
||||
|
||||
fun addCommit(message: String, vararg paths: String, author: String? = null) {
|
||||
add(*paths)
|
||||
commit(message, author)
|
||||
}
|
||||
|
||||
fun writeIn(directory: File, path: String, content: String = "") {
|
||||
File(directory, path).apply {
|
||||
parentFile?.mkdirs()
|
||||
writeText(content)
|
||||
}
|
||||
}
|
||||
|
||||
fun addCommitIn(directory: File, message: String, vararg paths: String) {
|
||||
git(directory, "add", *paths)
|
||||
git(directory, "commit", "-m", message)
|
||||
}
|
||||
|
||||
fun siblingRepo(name: String): File {
|
||||
val directory = File(sandbox.parentFile ?: sandbox, "${sandbox.name}-$name")
|
||||
directory.deleteRecursively()
|
||||
initRepo(directory)
|
||||
return directory
|
||||
}
|
||||
|
||||
fun checkoutNew(branch: String) {
|
||||
git("checkout", "-b", branch)
|
||||
}
|
||||
|
||||
fun checkout(branch: String) {
|
||||
git("checkout", branch)
|
||||
}
|
||||
|
||||
fun tag(name: String) {
|
||||
git("tag", "-f", name)
|
||||
}
|
||||
}
|
||||
|
||||
fun sampleLevels(): List<Level> = allGithugLevels()
|
||||
|
||||
val RepoStateSaver = listSaver<RepoState, Any>(
|
||||
|
||||
Reference in New Issue
Block a user