diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 3151cd9..59f4e64 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -19,8 +19,8 @@ android { applicationId = "solutions.tretter.githugandroid" minSdk = 26 targetSdk = 35 - versionCode = 136 - versionName = "0.1.135" + versionCode = 137 + versionName = "0.1.136" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables.useSupportLibrary = true diff --git a/app/src/main/java/solutions/tretter/githugandroid/GitRuntime.kt b/app/src/main/java/solutions/tretter/githugandroid/GitRuntime.kt index 3ac20e9..aafe956 100644 --- a/app/src/main/java/solutions/tretter/githugandroid/GitRuntime.kt +++ b/app/src/main/java/solutions/tretter/githugandroid/GitRuntime.kt @@ -852,6 +852,7 @@ class GitRepositoryRuntime private constructor( } else { File(binary.parentFile ?: binary.absoluteFile.parentFile ?: sandboxesRoot, "git-exec") } + refreshGitExecDirectoryIfNeeded(directory, binary) directory.mkdirs() File(directory, "git").also { alias -> @@ -870,7 +871,27 @@ class GitRepositoryRuntime private constructor( return directory } + private fun refreshGitExecDirectoryIfNeeded(directory: File, binary: File) { + val fingerprint = buildString { + append(binary.absolutePath) + append('\n') + append(binary.length()) + append('\n') + append(binary.lastModified()) + } + val stamp = File(directory, ".binary-fingerprint") + val previousFingerprint = stamp.takeIf { it.isFile }?.readText() + if (previousFingerprint != fingerprint) { + directory.deleteRecursively() + } + directory.mkdirs() + stamp.writeText(fingerprint) + } + private fun createGitAlias(binary: File, alias: File) { + if (alias.exists() || Files.isSymbolicLink(alias.toPath())) { + alias.delete() + } if (context != null) { try { Os.symlink(binary.absolutePath, alias.absolutePath) diff --git a/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt b/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt index c85a902..802523b 100644 --- a/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt +++ b/app/src/test/java/solutions/tretter/githugandroid/GitSandboxEngineTest.kt @@ -185,6 +185,37 @@ class GitSandboxEngineTest { } } + @Test + fun nativeGitExecAliasesRefreshWhenBinaryChanges() { + val git = testGitBinary() + assumeTrue(git.exists() && git.canExecute()) + val root = Files.createTempDirectory("githug-exec-refresh").toFile() + try { + val firstGit = File(root, "first-git").also { git.copyTo(it); it.setExecutable(true) } + val secondGit = File(root, "second-git").also { git.copyTo(it); it.setExecutable(true) } + val level = level( + id = "exec-refresh-test", + title = "Exec Refresh Test", + description = "", + hints = emptyList(), + commandSuggestions = emptyList(), + setup = { RepoState(initialized = true) }, + validator = { _, _ -> false }, + ) + + GitRepositoryRuntime(root, firstGit).prepareLevel(level) + val alias = File(root, "git-exec/git") + assertTrue(alias.exists()) + assertTrue(File(root, "git-exec/.binary-fingerprint").readText().contains(firstGit.absolutePath)) + + GitRepositoryRuntime(root, secondGit).prepareLevel(level) + assertTrue(alias.exists()) + assertTrue(File(root, "git-exec/.binary-fingerprint").readText().contains(secondGit.absolutePath)) + } finally { + root.deleteRecursively() + } + } + @Test fun nativePushLevelHasDivergedStatusAndRebasesCleanly() { val git = testGitBinary()