Speed up runtime state refresh
This commit is contained in:
@@ -679,6 +679,7 @@ maybe_run_operation() {
|
|||||||
local should_compile_android_git="false"
|
local should_compile_android_git="false"
|
||||||
local should_bundle_manpages="false"
|
local should_bundle_manpages="false"
|
||||||
local should_run_emulator="false"
|
local should_run_emulator="false"
|
||||||
|
local should_clean_gradle="false"
|
||||||
|
|
||||||
case "$mode" in
|
case "$mode" in
|
||||||
--build)
|
--build)
|
||||||
@@ -706,6 +707,12 @@ maybe_run_operation() {
|
|||||||
artifact_label="debug unit tests"
|
artifact_label="debug unit tests"
|
||||||
should_compile_host_git="true"
|
should_compile_host_git="true"
|
||||||
;;
|
;;
|
||||||
|
--clean-test)
|
||||||
|
gradle_task="testDebugUnitTest"
|
||||||
|
artifact_label="clean debug unit tests"
|
||||||
|
should_compile_host_git="true"
|
||||||
|
should_clean_gradle="true"
|
||||||
|
;;
|
||||||
--test-emulator)
|
--test-emulator)
|
||||||
gradle_task="connectedDebugAndroidTest"
|
gradle_task="connectedDebugAndroidTest"
|
||||||
artifact_label="debug instrumentation tests on Android emulator"
|
artifact_label="debug instrumentation tests on Android emulator"
|
||||||
@@ -755,7 +762,11 @@ maybe_run_operation() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
log "Running $artifact_label with --no-daemon"
|
log "Running $artifact_label with --no-daemon"
|
||||||
|
if [ "$should_clean_gradle" = "true" ]; then
|
||||||
|
"$PROJECT_DIR/gradlew" --no-daemon clean "$gradle_task"
|
||||||
|
else
|
||||||
"$PROJECT_DIR/gradlew" --no-daemon "$gradle_task"
|
"$PROJECT_DIR/gradlew" --no-daemon "$gradle_task"
|
||||||
|
fi
|
||||||
|
|
||||||
if [ -n "$artifact_source" ] && [ -f "$artifact_source" ]; then
|
if [ -n "$artifact_source" ] && [ -f "$artifact_source" ]; then
|
||||||
log "Renaming $(basename "$artifact_source") to $(basename "$artifact_target")"
|
log "Renaming $(basename "$artifact_source") to $(basename "$artifact_target")"
|
||||||
@@ -777,11 +788,12 @@ maybe_run_operation() {
|
|||||||
|
|
||||||
print_usage() {
|
print_usage() {
|
||||||
cat <<EOF_USAGE
|
cat <<EOF_USAGE
|
||||||
Usage: bash ./AndroidProjectTooling.sh [--build | --build-release-aab | --test | --test-emulator | --compile-git]
|
Usage: bash ./AndroidProjectTooling.sh [--build | --build-release-aab | --test | --clean-test | --test-emulator | --compile-git]
|
||||||
|
|
||||||
--build Set up the environment and build the debug APK
|
--build Set up the environment and build the debug APK
|
||||||
--build-release-aab Set up the environment and build a release Android App Bundle (AAB)
|
--build-release-aab Set up the environment and build a release Android App Bundle (AAB)
|
||||||
--test Set up the environment, compile host Git, and run the debug JVM unit tests with it
|
--test Set up the environment, compile host Git, and run the debug JVM unit tests with it
|
||||||
|
--clean-test Set up the environment, clean Gradle outputs, and run the debug JVM unit tests
|
||||||
--test-emulator Set up an Android emulator and run debug instrumentation tests on it
|
--test-emulator Set up an Android emulator and run debug instrumentation tests on it
|
||||||
--compile-git Compile Git for the development host and all Android target ABIs
|
--compile-git Compile Git for the development host and all Android target ABIs
|
||||||
EOF_USAGE
|
EOF_USAGE
|
||||||
@@ -789,7 +801,7 @@ EOF_USAGE
|
|||||||
|
|
||||||
validate_args() {
|
validate_args() {
|
||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
""|--build|--build-release-aab|--test|--test-emulator|--compile-git)
|
""|--build|--build-release-aab|--test|--clean-test|--test-emulator|--compile-git)
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Unknown argument: $1" >&2
|
echo "Unknown argument: $1" >&2
|
||||||
@@ -835,6 +847,7 @@ main() {
|
|||||||
log "To set up and build in one step: bash ./AndroidProjectTooling.sh --build"
|
log "To set up and build in one step: bash ./AndroidProjectTooling.sh --build"
|
||||||
log "To set up and build a release AAB in one step: bash ./AndroidProjectTooling.sh --build-release-aab"
|
log "To set up and build a release AAB in one step: bash ./AndroidProjectTooling.sh --build-release-aab"
|
||||||
log "To set up and run unit tests with compiled host Git: bash ./AndroidProjectTooling.sh --test"
|
log "To set up and run unit tests with compiled host Git: bash ./AndroidProjectTooling.sh --test"
|
||||||
|
log "To clean and run unit tests with compiled host Git: bash ./AndroidProjectTooling.sh --clean-test"
|
||||||
log "To set up and run instrumentation tests on an emulator: bash ./AndroidProjectTooling.sh --test-emulator"
|
log "To set up and run instrumentation tests on an emulator: bash ./AndroidProjectTooling.sh --test-emulator"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ Available commands:
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `bash ./AndroidProjectTooling.sh` | Provision or refresh the local Android/JDK toolchain only. | Toolchain under `./jdk` and `./android-sdk` |
|
| `bash ./AndroidProjectTooling.sh` | Provision or refresh the local Android/JDK toolchain only. | Toolchain under `./jdk` and `./android-sdk` |
|
||||||
| `bash ./AndroidProjectTooling.sh --test` | Compile host Git, set `GITHUG_TEST_GIT_BINARY`, and run JVM unit tests. | Test reports under `app/build/reports/` |
|
| `bash ./AndroidProjectTooling.sh --test` | Compile host Git, set `GITHUG_TEST_GIT_BINARY`, and run JVM unit tests. | Test reports under `app/build/reports/` |
|
||||||
|
| `bash ./AndroidProjectTooling.sh --clean-test` | Compile host Git, clean Gradle outputs, set `GITHUG_TEST_GIT_BINARY`, and run JVM unit tests. | Fresh test reports under `app/build/reports/` |
|
||||||
| `bash ./AndroidProjectTooling.sh --test-emulator` | Install emulator packages if needed, create/start the project test AVD, compile Android Git, and run debug instrumentation tests. | Instrumentation reports under `app/build/reports/androidTests/` |
|
| `bash ./AndroidProjectTooling.sh --test-emulator` | Install emulator packages if needed, create/start the project test AVD, compile Android Git, and run debug instrumentation tests. | Instrumentation reports under `app/build/reports/androidTests/` |
|
||||||
| `bash ./AndroidProjectTooling.sh --build` | Build the debug APK. | `app/build/outputs/apk/debug/githug-android-debug-v<versionCode>.apk` |
|
| `bash ./AndroidProjectTooling.sh --build` | Build the debug APK. | `app/build/outputs/apk/debug/githug-android-debug-v<versionCode>.apk` |
|
||||||
| `bash ./AndroidProjectTooling.sh --build-release-aab` | Build the release Android App Bundle. | `app/build/outputs/bundle/release/githug-android-release-v<versionCode>.aab` |
|
| `bash ./AndroidProjectTooling.sh --build-release-aab` | Build the release Android App Bundle. | `app/build/outputs/bundle/release/githug-android-release-v<versionCode>.aab` |
|
||||||
@@ -112,6 +113,7 @@ Options:
|
|||||||
| Command | Purpose | Output |
|
| Command | Purpose | Output |
|
||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
| `bash ./AndroidProjectTooling.sh --test` | Ensure the host Git binary is current, then run tests with it. | `build/host-git/libgit.so` and test reports |
|
| `bash ./AndroidProjectTooling.sh --test` | Ensure the host Git binary is current, then run tests with it. | `build/host-git/libgit.so` and test reports |
|
||||||
|
| `bash ./AndroidProjectTooling.sh --clean-test` | Ensure the host Git binary is current, clean Gradle outputs, then run tests with it. | `build/host-git/libgit.so` and fresh test reports |
|
||||||
| `bash ./AndroidProjectTooling.sh --test-emulator` | Ensure Android ABI Git binaries are current, then run instrumentation tests on the project AVD. | Android `libgit.so` binaries and instrumentation reports |
|
| `bash ./AndroidProjectTooling.sh --test-emulator` | Ensure Android ABI Git binaries are current, then run instrumentation tests on the project AVD. | Android `libgit.so` binaries and instrumentation reports |
|
||||||
| `bash ./AndroidProjectTooling.sh --compile-git` | Ensure host Git and Android ABI Git binaries are current. | Host and Android outputs |
|
| `bash ./AndroidProjectTooling.sh --compile-git` | Ensure host Git and Android ABI Git binaries are current. | Host and Android outputs |
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ android {
|
|||||||
applicationId = "solutions.tretter.githugandroid"
|
applicationId = "solutions.tretter.githugandroid"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 35
|
targetSdk = 35
|
||||||
versionCode = 172
|
versionCode = 173
|
||||||
versionName = "0.1.171"
|
versionName = "0.1.172"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
|
|||||||
@@ -22,4 +22,21 @@ class GitRepositoryRuntimeInstrumentedTest {
|
|||||||
assertTrue(updatedRepo.initialized)
|
assertTrue(updatedRepo.initialized)
|
||||||
assertTrue(level.validator(updatedRepo, "git init"))
|
assertTrue(level.validator(updatedRepo, "git init"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun nativeGitRuntimeCompletesConfigLevelOnDevice() {
|
||||||
|
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
|
val runtime = GitRepositoryRuntime(context)
|
||||||
|
val level = configLevel()
|
||||||
|
|
||||||
|
assertTrue(runtime.unavailableMessage(), runtime.isNativeGitAvailable())
|
||||||
|
|
||||||
|
val repo = runtime.prepareLevel(level)
|
||||||
|
val (namedRepo, _) = runtime.execute(level, repo, "git config user.name GitHug")
|
||||||
|
val (configuredRepo, _) = runtime.execute(level, namedRepo, "git config user.email githug@example.com")
|
||||||
|
|
||||||
|
assertTrue(configuredRepo.config["user.name"].orEmpty().isNotBlank())
|
||||||
|
assertTrue(configuredRepo.config["user.email"].orEmpty().isNotBlank())
|
||||||
|
assertTrue(level.validator(configuredRepo, "git config user.email githug@example.com"))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,16 +6,21 @@ internal class GitRepositoryInspector(
|
|||||||
private val nativeGit: () -> File,
|
private val nativeGit: () -> File,
|
||||||
private val runGit: (File, File, List<String>, Map<String, String>) -> ProcessExecutionResult,
|
private val runGit: (File, File, List<String>, Map<String, String>) -> ProcessExecutionResult,
|
||||||
) {
|
) {
|
||||||
|
fun inspectConfig(sandbox: File, currentDir: String = "."): Map<String, String> {
|
||||||
|
val git = nativeGit()
|
||||||
|
val workingDir = File(sandbox, currentDir).canonicalFile
|
||||||
|
.takeIf { it.path == sandbox.canonicalPath || it.path.startsWith(sandbox.canonicalPath + File.separator) }
|
||||||
|
?: sandbox
|
||||||
|
val repositoryRoot = repositoryRoot(sandbox, workingDir) ?: sandbox
|
||||||
|
return readConfig(git, repositoryRoot)
|
||||||
|
}
|
||||||
|
|
||||||
fun inspect(sandbox: File, currentDir: String = "."): RepoState {
|
fun inspect(sandbox: File, currentDir: String = "."): RepoState {
|
||||||
val git = nativeGit()
|
val git = nativeGit()
|
||||||
val workingDir = File(sandbox, currentDir).canonicalFile
|
val workingDir = File(sandbox, currentDir).canonicalFile
|
||||||
.takeIf { it.path == sandbox.canonicalPath || it.path.startsWith(sandbox.canonicalPath + File.separator) }
|
.takeIf { it.path == sandbox.canonicalPath || it.path.startsWith(sandbox.canonicalPath + File.separator) }
|
||||||
?: sandbox
|
?: sandbox
|
||||||
val repositoryRoot = generateSequence(workingDir) { directory ->
|
val repositoryRoot = repositoryRoot(sandbox, workingDir)
|
||||||
directory.parentFile?.takeIf {
|
|
||||||
it.path == sandbox.canonicalPath || it.path.startsWith(sandbox.canonicalPath + File.separator)
|
|
||||||
}
|
|
||||||
}.firstOrNull { File(it, ".git").exists() }
|
|
||||||
val inspectionRoot = repositoryRoot ?: sandbox
|
val inspectionRoot = repositoryRoot ?: sandbox
|
||||||
val filesOnDisk = inspectionRoot.walkTopDown()
|
val filesOnDisk = inspectionRoot.walkTopDown()
|
||||||
.filter { it.isFile && !it.relativeTo(inspectionRoot).path.startsWith(".git/") }
|
.filter { it.isFile && !it.relativeTo(inspectionRoot).path.startsWith(".git/") }
|
||||||
@@ -54,8 +59,6 @@ internal class GitRepositoryInspector(
|
|||||||
val remoteResult = run(git, inspectionRoot, listOf("remote", "-v"))
|
val remoteResult = run(git, inspectionRoot, listOf("remote", "-v"))
|
||||||
val headResult = run(git, inspectionRoot, listOf("branch", "--show-current"))
|
val headResult = run(git, inspectionRoot, listOf("branch", "--show-current"))
|
||||||
val exactTagResult = run(git, inspectionRoot, listOf("describe", "--tags", "--exact-match"))
|
val exactTagResult = run(git, inspectionRoot, listOf("describe", "--tags", "--exact-match"))
|
||||||
val userNameResult = run(git, inspectionRoot, listOf("config", "--get", "user.name"))
|
|
||||||
val userEmailResult = run(git, inspectionRoot, listOf("config", "--get", "user.email"))
|
|
||||||
val stashResult = run(git, inspectionRoot, listOf("stash", "list", "--format=%gd"))
|
val stashResult = run(git, inspectionRoot, listOf("stash", "list", "--format=%gd"))
|
||||||
val submodules = inspectSubmodules(git, inspectionRoot)
|
val submodules = inspectSubmodules(git, inspectionRoot)
|
||||||
val maintenanceActions = buildSet {
|
val maintenanceActions = buildSet {
|
||||||
@@ -68,14 +71,7 @@ internal class GitRepositoryInspector(
|
|||||||
?.readLines()
|
?.readLines()
|
||||||
?.count { it.isNotBlank() }
|
?.count { it.isNotBlank() }
|
||||||
?: 0
|
?: 0
|
||||||
val config = buildMap {
|
val config = readConfig(git, inspectionRoot)
|
||||||
userNameResult.outputLines.firstOrNull()
|
|
||||||
?.takeIf { userNameResult.exitCode == 0 && it.isNotBlank() }
|
|
||||||
?.let { put("user.name", it) }
|
|
||||||
userEmailResult.outputLines.firstOrNull()
|
|
||||||
?.takeIf { userEmailResult.exitCode == 0 && it.isNotBlank() }
|
|
||||||
?.let { put("user.email", it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val commits = if (logResult.exitCode == 0) {
|
val commits = if (logResult.exitCode == 0) {
|
||||||
logResult.outputLines.filter { it.isNotBlank() }.mapNotNull { line ->
|
logResult.outputLines.filter { it.isNotBlank() }.mapNotNull { line ->
|
||||||
@@ -185,6 +181,28 @@ internal class GitRepositoryInspector(
|
|||||||
environment: Map<String, String> = emptyMap(),
|
environment: Map<String, String> = emptyMap(),
|
||||||
): ProcessExecutionResult = runGit(binary, workingDir, arguments, environment)
|
): ProcessExecutionResult = runGit(binary, workingDir, arguments, environment)
|
||||||
|
|
||||||
|
private fun repositoryRoot(sandbox: File, workingDir: File): File? {
|
||||||
|
val sandboxPath = sandbox.canonicalPath
|
||||||
|
return generateSequence(workingDir) { directory ->
|
||||||
|
directory.parentFile?.takeIf {
|
||||||
|
it.path == sandboxPath || it.path.startsWith(sandboxPath + File.separator)
|
||||||
|
}
|
||||||
|
}.firstOrNull { File(it, ".git").exists() }
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun readConfig(git: File, inspectionRoot: File): Map<String, String> {
|
||||||
|
val userNameResult = run(git, inspectionRoot, listOf("config", "--get", "user.name"))
|
||||||
|
val userEmailResult = run(git, inspectionRoot, listOf("config", "--get", "user.email"))
|
||||||
|
return buildMap {
|
||||||
|
userNameResult.outputLines.firstOrNull()
|
||||||
|
?.takeIf { userNameResult.exitCode == 0 && it.isNotBlank() }
|
||||||
|
?.let { put("user.name", it) }
|
||||||
|
userEmailResult.outputLines.firstOrNull()
|
||||||
|
?.takeIf { userEmailResult.exitCode == 0 && it.isNotBlank() }
|
||||||
|
?.let { put("user.email", it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun inspectRemoteRefs(git: File, inspectionRoot: File, remoteLines: List<String>): RemoteRefs {
|
private fun inspectRemoteRefs(git: File, inspectionRoot: File, remoteLines: List<String>): RemoteRefs {
|
||||||
val remotes = remoteLines.mapNotNull { line ->
|
val remotes = remoteLines.mapNotNull { line ->
|
||||||
val parts = line.trim().split(Regex("\\s+"))
|
val parts = line.trim().split(Regex("\\s+"))
|
||||||
|
|||||||
@@ -128,8 +128,8 @@ class GitRepositoryRuntime private constructor(
|
|||||||
?: helperCommands.execute(sandboxRoot, workingDir, currentRepo, expandedTokens)
|
?: helperCommands.execute(sandboxRoot, workingDir, currentRepo, expandedTokens)
|
||||||
}
|
}
|
||||||
|
|
||||||
val inspectedRepo = inspectSandbox(level, result.first.currentDir).copy(currentDir = result.first.currentDir)
|
val refreshedRepo = refreshRepoAfterCommand(level, currentRepo, result.first, expandedTokens)
|
||||||
return inspectedRepo to result.second
|
return refreshedRepo to result.second
|
||||||
}
|
}
|
||||||
|
|
||||||
fun completionCandidates(level: Level, currentRepo: RepoState, directoriesOnly: Boolean): List<String> {
|
fun completionCandidates(level: Level, currentRepo: RepoState, directoriesOnly: Boolean): List<String> {
|
||||||
@@ -236,6 +236,72 @@ class GitRepositoryRuntime private constructor(
|
|||||||
private fun inspectSandbox(level: Level, currentDir: String = "."): RepoState =
|
private fun inspectSandbox(level: Level, currentDir: String = "."): RepoState =
|
||||||
repositoryInspector.inspect(sandboxDir(level), currentDir)
|
repositoryInspector.inspect(sandboxDir(level), currentDir)
|
||||||
|
|
||||||
|
private fun refreshRepoAfterCommand(
|
||||||
|
level: Level,
|
||||||
|
previousRepo: RepoState,
|
||||||
|
commandRepo: RepoState,
|
||||||
|
tokens: List<String>,
|
||||||
|
): RepoState {
|
||||||
|
if (tokens.isEmpty()) return previousRepo
|
||||||
|
if (!commandNeedsStateRefresh(tokens)) return commandRepo
|
||||||
|
if (tokens.isGitConfigCommand()) {
|
||||||
|
return commandRepo.copy(
|
||||||
|
config = repositoryInspector.inspectConfig(sandboxDir(level), commandRepo.currentDir),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return inspectSandbox(level, commandRepo.currentDir).copy(currentDir = commandRepo.currentDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun commandNeedsStateRefresh(tokens: List<String>): Boolean {
|
||||||
|
return when (tokens.firstOrNull()) {
|
||||||
|
"git" -> tokens.gitCommandNeedsStateRefresh()
|
||||||
|
"sh" -> true
|
||||||
|
"touch", "mkdir", "md", "rm", "del" -> true
|
||||||
|
"echo" -> tokens.any { it == ">" || it == ">>" }
|
||||||
|
else -> tokens.firstOrNull()?.startsWith("./") == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<String>.gitCommandNeedsStateRefresh(): Boolean {
|
||||||
|
val command = drop(1).firstOrNull { it != "-C" && !it.startsWith("--git-dir=") && !it.startsWith("--work-tree=") }
|
||||||
|
?: return false
|
||||||
|
return when (command) {
|
||||||
|
"init",
|
||||||
|
"config",
|
||||||
|
"add",
|
||||||
|
"stage",
|
||||||
|
"rm",
|
||||||
|
"mv",
|
||||||
|
"commit",
|
||||||
|
"commit-tree",
|
||||||
|
"checkout",
|
||||||
|
"switch",
|
||||||
|
"restore",
|
||||||
|
"branch",
|
||||||
|
"tag",
|
||||||
|
"remote",
|
||||||
|
"fetch",
|
||||||
|
"pull",
|
||||||
|
"push",
|
||||||
|
"merge",
|
||||||
|
"rebase",
|
||||||
|
"reset",
|
||||||
|
"revert",
|
||||||
|
"stash",
|
||||||
|
"cherry-pick",
|
||||||
|
"repack",
|
||||||
|
"submodule",
|
||||||
|
"update-ref",
|
||||||
|
"read-tree",
|
||||||
|
-> true
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun List<String>.isGitConfigCommand(): Boolean {
|
||||||
|
return firstOrNull() == "git" && drop(1).firstOrNull { !it.startsWith("-") } == "config"
|
||||||
|
}
|
||||||
|
|
||||||
private fun nativeGitBinary(): File? {
|
private fun nativeGitBinary(): File? {
|
||||||
return nativeGitOverride
|
return nativeGitOverride
|
||||||
?.takeIf { it.exists() && it.canExecute() }
|
?.takeIf { it.exists() && it.canExecute() }
|
||||||
|
|||||||
@@ -258,6 +258,48 @@ class GitSandboxEngineTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun nativeConfigLevelSolvesAfterSettingNameAndEmail() {
|
||||||
|
val git = testGitBinary()
|
||||||
|
assumeTrue(git.exists() && git.canExecute())
|
||||||
|
val root = Files.createTempDirectory("githug-config-level").toFile()
|
||||||
|
try {
|
||||||
|
val runtime = GitRepositoryRuntime(root, git)
|
||||||
|
val level = configLevel()
|
||||||
|
val repo = runtime.prepareLevel(level)
|
||||||
|
|
||||||
|
val (namedRepo, _) = runtime.execute(level, repo, "git config user.name GitHug")
|
||||||
|
val (configuredRepo, _) = runtime.execute(level, namedRepo, "git config user.email githug@example.com")
|
||||||
|
|
||||||
|
assertEquals("GitHug", configuredRepo.config["user.name"])
|
||||||
|
assertEquals("githug@example.com", configuredRepo.config["user.email"])
|
||||||
|
assertTrue(level.validator(configuredRepo, "git config user.email githug@example.com"))
|
||||||
|
} finally {
|
||||||
|
root.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun nativeReadOnlyHelperCommandsDoNotRefreshAwayTransientState() {
|
||||||
|
val git = testGitBinary()
|
||||||
|
assumeTrue(git.exists() && git.canExecute())
|
||||||
|
val root = Files.createTempDirectory("githug-read-only-helper").toFile()
|
||||||
|
try {
|
||||||
|
val runtime = GitRepositoryRuntime(root, git)
|
||||||
|
val level = configLevel()
|
||||||
|
val repo = runtime.prepareLevel(level).copy(
|
||||||
|
maintenanceActions = setOf("transient-marker"),
|
||||||
|
)
|
||||||
|
|
||||||
|
val (listedRepo, output) = runtime.execute(level, repo, "ls")
|
||||||
|
|
||||||
|
assertTrue(".git" in output)
|
||||||
|
assertEquals(setOf("transient-marker"), listedRepo.maintenanceActions)
|
||||||
|
} finally {
|
||||||
|
root.deleteRecursively()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun nativeGitExecAliasesRefreshWhenBinaryChanges() {
|
fun nativeGitExecAliasesRefreshWhenBinaryChanges() {
|
||||||
val git = testGitBinary()
|
val git = testGitBinary()
|
||||||
|
|||||||
Reference in New Issue
Block a user