Auto-commit after successful build: update app gameplay/UI, improve build setup
Changed files:\napp/build.gradle.kts app/src/main/java/com/kawomi/githugandroid/GameModels.kt app/src/main/java/com/kawomi/githugandroid/GitRuntime.kt
This commit is contained in:
@@ -11,8 +11,8 @@ android {
|
|||||||
applicationId = "com.kawomi.githugandroid"
|
applicationId = "com.kawomi.githugandroid"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 56
|
versionCode = 59
|
||||||
versionName = "0.1.55"
|
versionName = "0.1.58"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ data class RepoState(
|
|||||||
val commits: List<CommitNode> = emptyList(),
|
val commits: List<CommitNode> = emptyList(),
|
||||||
val headBranch: String = "master",
|
val headBranch: String = "master",
|
||||||
val branches: Map<String, Int> = emptyMap(),
|
val branches: Map<String, Int> = emptyMap(),
|
||||||
|
val currentDir: String = ".",
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Level(
|
data class Level(
|
||||||
@@ -75,6 +76,7 @@ val RepoStateSaver = listSaver<RepoState, Any>(
|
|||||||
state.files.flatMap { listOf(it.name, it.content, it.staged.toString(), it.tracked.toString()) },
|
state.files.flatMap { listOf(it.name, it.content, it.staged.toString(), it.tracked.toString()) },
|
||||||
state.commits.flatMap { listOf(it.id, it.message) },
|
state.commits.flatMap { listOf(it.id, it.message) },
|
||||||
state.branches.flatMap { listOf(it.key, it.value.toString()) },
|
state.branches.flatMap { listOf(it.key, it.value.toString()) },
|
||||||
|
state.currentDir,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
restore = { saved ->
|
restore = { saved ->
|
||||||
@@ -97,7 +99,8 @@ val RepoStateSaver = listSaver<RepoState, Any>(
|
|||||||
commits = commitParts.chunked(2).map {
|
commits = commitParts.chunked(2).map {
|
||||||
CommitNode(it[0] as String, it[1] as String)
|
CommitNode(it[0] as String, it[1] as String)
|
||||||
},
|
},
|
||||||
branches = branchParts.chunked(2).associate { (it[0] as String) to (it[1] as String).toInt() }
|
branches = branchParts.chunked(2).associate { (it[0] as String) to (it[1] as String).toInt() },
|
||||||
|
currentDir = saved[5] as String,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -105,19 +108,17 @@ val RepoStateSaver = listSaver<RepoState, Any>(
|
|||||||
object GitSandboxEngine {
|
object GitSandboxEngine {
|
||||||
fun commandReferenceLines(): List<String> = listOf(
|
fun commandReferenceLines(): List<String> = listOf(
|
||||||
"Available sandbox commands:",
|
"Available sandbox commands:",
|
||||||
" git init",
|
" git ",
|
||||||
" git status",
|
|
||||||
" git add <file>",
|
|
||||||
" git add .",
|
|
||||||
" git commit -m \"message\"",
|
|
||||||
" git commit -am \"message\"",
|
|
||||||
" git log",
|
|
||||||
" git branch <name>",
|
|
||||||
" git checkout <name>",
|
|
||||||
" ls",
|
" ls",
|
||||||
" touch <file>",
|
" touch <file>",
|
||||||
" help",
|
" help",
|
||||||
" git help",
|
" pwd ",
|
||||||
|
" cat <file>",
|
||||||
|
" touch <file>",
|
||||||
|
" mkdir <directory>",
|
||||||
|
" cd <directory>",
|
||||||
|
" rm <file>",
|
||||||
|
" echo <message>",
|
||||||
)
|
)
|
||||||
|
|
||||||
fun execute(repo: RepoState, command: String): Pair<RepoState, List<String>> {
|
fun execute(repo: RepoState, command: String): Pair<RepoState, List<String>> {
|
||||||
|
|||||||
@@ -62,16 +62,20 @@ class GitRepositoryRuntime(private val context: Context) {
|
|||||||
prepareLevel(level)
|
prepareLevel(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
val tokens = GitSandboxEngine.tokenizeCommand(command)
|
val sandboxRoot = sandbox.canonicalFile
|
||||||
if (tokens.isEmpty()) return inspectSandbox(level) to emptyList()
|
val workingDir = File(sandboxRoot, currentRepo.currentDir).canonicalFile
|
||||||
|
.takeIf { it.path.startsWith(sandboxRoot.path) } ?: sandboxRoot
|
||||||
|
|
||||||
val output = when (tokens.first()) {
|
val tokens = GitSandboxEngine.tokenizeCommand(command)
|
||||||
"git" -> runGit(nativeGit, sandbox, tokens.drop(1)).outputLines
|
if (tokens.isEmpty()) return inspectSandbox(level).copy(currentDir = currentRepo.currentDir) to emptyList()
|
||||||
"help", "?" -> commandReferenceLines()
|
|
||||||
else -> executeHelperCommand(sandbox, tokens)
|
val result = when (tokens.first()) {
|
||||||
|
"git" -> currentRepo to runGit(nativeGit, workingDir, tokens.drop(1)).outputLines
|
||||||
|
"help", "?" -> currentRepo to commandReferenceLines()
|
||||||
|
else -> executeHelperCommand(sandboxRoot, workingDir, currentRepo, tokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
return inspectSandbox(level) to output
|
return inspectSandbox(level).copy(currentDir = result.first.currentDir) to result.second
|
||||||
}
|
}
|
||||||
|
|
||||||
fun commandReferenceLines(): List<String> {
|
fun commandReferenceLines(): List<String> {
|
||||||
@@ -84,49 +88,64 @@ class GitRepositoryRuntime(private val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun executeHelperCommand(workingDir: File, tokens: List<String>): List<String> {
|
private fun executeHelperCommand(sandboxRoot: File, workingDir: File, currentRepo: RepoState, tokens: List<String>): Pair<RepoState, List<String>> {
|
||||||
return when (tokens.first()) {
|
return when (tokens.first()) {
|
||||||
"ls" -> workingDir.listFiles()
|
"ls" -> currentRepo to workingDir.listFiles()
|
||||||
?.filterNot { it.name == ".git" }
|
?.filterNot { it.name == ".git" }
|
||||||
?.sortedBy { it.name }
|
?.sortedBy { it.name }
|
||||||
?.map { it.name }
|
?.map { it.name }
|
||||||
.orEmpty()
|
.orEmpty()
|
||||||
"pwd" -> listOf("/sandbox/${workingDir.name}")
|
"pwd" -> currentRepo to listOf(
|
||||||
|
"/sandbox" + if (workingDir == sandboxRoot) "" else "/${workingDir.relativeTo(sandboxRoot).path}"
|
||||||
|
)
|
||||||
"cat" -> {
|
"cat" -> {
|
||||||
val target = tokens.getOrNull(1) ?: return listOf("usage: cat <file>")
|
val target = tokens.getOrNull(1) ?: return currentRepo to listOf("usage: cat <file>")
|
||||||
val file = File(workingDir, target)
|
val file = File(workingDir, target)
|
||||||
if (!file.exists() || file.isDirectory) listOf("cat: $target: No such file")
|
if (!file.exists() || file.isDirectory) currentRepo to listOf("cat: $target: No such file")
|
||||||
else file.readLines().ifEmpty { listOf("") }
|
else currentRepo to file.readLines().ifEmpty { listOf("") }
|
||||||
}
|
}
|
||||||
"touch" -> {
|
"touch" -> {
|
||||||
val target = tokens.getOrNull(1) ?: return listOf("usage: touch <file>")
|
val target = tokens.getOrNull(1) ?: return currentRepo to listOf("usage: touch <file>")
|
||||||
val file = File(workingDir, target)
|
val file = File(workingDir, target)
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
listOf("$target already exists")
|
currentRepo to listOf("$target already exists")
|
||||||
} else {
|
} else {
|
||||||
file.parentFile?.mkdirs()
|
file.parentFile?.mkdirs()
|
||||||
file.writeText("")
|
file.writeText("")
|
||||||
emptyList()
|
currentRepo to emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"mkdir" -> {
|
"mkdir" -> {
|
||||||
val target = tokens.getOrNull(1) ?: return listOf("usage: mkdir <dir>")
|
val target = tokens.getOrNull(1) ?: return currentRepo to listOf("usage: mkdir <dir>")
|
||||||
val dir = File(workingDir, target)
|
val dir = File(workingDir, target)
|
||||||
if (dir.exists()) listOf("mkdir: $target: File exists") else {
|
if (dir.exists()) currentRepo to listOf("mkdir: $target: File exists") else {
|
||||||
dir.mkdirs()
|
dir.mkdirs()
|
||||||
emptyList()
|
currentRepo to emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"cd" -> {
|
||||||
|
val target = tokens.getOrNull(1) ?: return currentRepo to listOf("usage: cd <dir>")
|
||||||
|
val dir = File(workingDir, target).canonicalFile
|
||||||
|
when {
|
||||||
|
!dir.exists() -> currentRepo to listOf("cd: $target: does not exist")
|
||||||
|
!dir.isDirectory -> currentRepo to listOf("cd: $target: Not a directory")
|
||||||
|
!dir.path.startsWith(sandboxRoot.path) -> currentRepo to listOf("cd: $target: Permission denied")
|
||||||
|
else -> {
|
||||||
|
val relativeDir = sandboxRoot.toPath().relativize(dir.toPath()).toString().ifEmpty { "." }
|
||||||
|
currentRepo.copy(currentDir = relativeDir) to emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"rm" -> {
|
"rm" -> {
|
||||||
val target = tokens.getOrNull(1) ?: return listOf("usage: rm <path>")
|
val target = tokens.getOrNull(1) ?: return currentRepo to listOf("usage: rm <path>")
|
||||||
val file = File(workingDir, target)
|
val file = File(workingDir, target)
|
||||||
if (!file.exists()) listOf("rm: $target: No such file or directory") else {
|
if (!file.exists()) currentRepo to listOf("rm: $target: No such file or directory") else {
|
||||||
file.deleteRecursively()
|
file.deleteRecursively()
|
||||||
emptyList()
|
currentRepo to emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"echo" -> listOf(tokens.drop(1).joinToString(" "))
|
"echo" -> currentRepo to listOf(tokens.drop(1).joinToString(" "))
|
||||||
else -> listOf("Command not supported in prototype runtime. Try a git command or helper command.")
|
else -> currentRepo to listOf("Command not supported in prototype runtime. Try a git command or helper command.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user