Unwind PasswordRepository's confusing control flow (#1686)

* Cleanup PasswordRepository

* Tear out nonsensical logic for getRepository
This commit is contained in:
Harsh Shandilya 2022-01-27 09:22:15 +05:30 committed by GitHub
parent d89d500319
commit 2d607c78e7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 26 additions and 75 deletions

View file

@ -4,8 +4,6 @@
*/ */
package dev.msfjarvis.aps.data.repo package dev.msfjarvis.aps.data.repo
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.core.content.edit import androidx.core.content.edit
import com.github.michaelbull.result.getOrElse import com.github.michaelbull.result.getOrElse
import com.github.michaelbull.result.onFailure import com.github.michaelbull.result.onFailure
@ -18,77 +16,19 @@ import dev.msfjarvis.aps.util.extensions.unsafeLazy
import dev.msfjarvis.aps.util.settings.PasswordSortOrder import dev.msfjarvis.aps.util.settings.PasswordSortOrder
import dev.msfjarvis.aps.util.settings.PreferenceKeys import dev.msfjarvis.aps.util.settings.PreferenceKeys
import java.io.File import java.io.File
import java.nio.file.Files
import java.nio.file.LinkOption
import org.eclipse.jgit.api.Git import org.eclipse.jgit.api.Git
import org.eclipse.jgit.lib.Repository import org.eclipse.jgit.lib.Repository
import org.eclipse.jgit.storage.file.FileRepositoryBuilder import org.eclipse.jgit.storage.file.FileRepositoryBuilder
import org.eclipse.jgit.transport.RefSpec import org.eclipse.jgit.transport.RefSpec
import org.eclipse.jgit.transport.RemoteConfig import org.eclipse.jgit.transport.RemoteConfig
import org.eclipse.jgit.transport.URIish import org.eclipse.jgit.transport.URIish
import org.eclipse.jgit.util.FS
import org.eclipse.jgit.util.FS_POSIX_Java6
object PasswordRepository { object PasswordRepository {
@RequiresApi(Build.VERSION_CODES.O) var repository: Repository? = null
private class FS_POSIX_Java6_with_optional_symlinks : FS_POSIX_Java6() {
override fun supportsSymlinks() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
override fun isSymLink(file: File) = Files.isSymbolicLink(file.toPath())
override fun readSymLink(file: File) = Files.readSymbolicLink(file.toPath()).toString()
override fun createSymLink(source: File, target: String) {
val sourcePath = source.toPath()
if (Files.exists(sourcePath, LinkOption.NOFOLLOW_LINKS)) Files.delete(sourcePath)
Files.createSymbolicLink(sourcePath, File(target).toPath())
}
}
@RequiresApi(Build.VERSION_CODES.O)
private class Java7FSFactory : FS.FSFactory() {
override fun detect(cygwinUsed: Boolean?): FS {
return FS_POSIX_Java6_with_optional_symlinks()
}
}
private var repository: Repository? = null
private val settings by unsafeLazy { Application.instance.sharedPrefs } private val settings by unsafeLazy { Application.instance.sharedPrefs }
private val filesDir private val filesDir
get() = Application.instance.filesDir get() = Application.instance.filesDir
/**
* Returns the git repository
*
* @param localDir needed only on the creation
* @return the git repository
*/
fun getRepository(localDir: File?): Repository? {
if (repository == null && localDir != null) {
val builder = FileRepositoryBuilder()
repository =
runCatching {
builder
.run {
gitDir = localDir
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
fs = Java7FSFactory().detect(null)
}
readEnvironment()
}
.build()
}
.getOrElse { e ->
e.printStackTrace()
null
}
}
return repository
}
val isInitialized: Boolean val isInitialized: Boolean
get() = repository != null get() = repository != null
@ -96,11 +36,23 @@ object PasswordRepository {
return repository?.objectDatabase?.exists() ?: false return repository?.objectDatabase?.exists() ?: false
} }
fun createRepository(localDir: File) { /**
localDir.delete() * Takes in a [repositoryDir] to initialize a Git repository with, and assigns it to [repository]
* as static state.
*/
private fun initializeRepository(repositoryDir: File) {
val builder = FileRepositoryBuilder()
repository =
runCatching { builder.setGitDir(repositoryDir).build() }.getOrElse { e ->
e.printStackTrace()
null
}
}
Git.init().setDirectory(localDir).call() fun createRepository(repositoryDir: File) {
getRepository(localDir) repositoryDir.delete()
Git.init().setDirectory(repositoryDir).call()
initializeRepository(repositoryDir)
} }
// TODO add multiple remotes support for pull/push // TODO add multiple remotes support for pull/push
@ -164,7 +116,7 @@ object PasswordRepository {
fun initialize(): Repository? { fun initialize(): Repository? {
val dir = getRepositoryDirectory() val dir = getRepositoryDirectory()
// uninitialize the repo if the dir does not exist or is absolutely empty // Un-initialize the repo if the dir does not exist or is absolutely empty
settings.edit { settings.edit {
if (!dir.exists() || !dir.isDirectory || requireNotNull(dir.listFiles()).isEmpty()) { if (!dir.exists() || !dir.isDirectory || requireNotNull(dir.listFiles()).isEmpty()) {
putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false) putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, false)
@ -172,9 +124,10 @@ object PasswordRepository {
putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, true) putBoolean(PreferenceKeys.REPOSITORY_INITIALIZED, true)
} }
} }
// Create the repository static variable in PasswordRepository
initializeRepository(dir.resolve(".git"))
// create the repository static variable in PasswordRepository return repository
return getRepository(File(dir.absolutePath + "/.git"))
} }
/** /**

View file

@ -38,8 +38,7 @@ class FolderCreationDialogFragment : DialogFragment() {
result.data?.getStringArrayExtra(OpenPgpApi.EXTRA_KEY_IDS)?.let { keyIds -> result.data?.getStringArrayExtra(OpenPgpApi.EXTRA_KEY_IDS)?.let { keyIds ->
val gpgIdentifierFile = File(newFolder, ".gpg-id") val gpgIdentifierFile = File(newFolder, ".gpg-id")
gpgIdentifierFile.writeText(keyIds.joinToString("\n")) gpgIdentifierFile.writeText(keyIds.joinToString("\n"))
val repo = PasswordRepository.getRepository(null) if (PasswordRepository.repository != null) {
if (repo != null) {
lifecycleScope.launch { lifecycleScope.launch {
val repoPath = PasswordRepository.getRepositoryDirectory().absolutePath val repoPath = PasswordRepository.getRepositoryDirectory().absolutePath
requireActivity() requireActivity()

View file

@ -78,7 +78,7 @@ class GitConfigActivity : BaseGitActivity() {
/** Sets up the UI components of the tools section. */ /** Sets up the UI components of the tools section. */
private fun setupTools() { private fun setupTools() {
val repo = PasswordRepository.getRepository(null) val repo = PasswordRepository.repository
if (repo != null) { if (repo != null) {
binding.gitHeadStatus.text = headStatusMsg(repo) binding.gitHeadStatus.text = headStatusMsg(repo)
// enable the abort button only if we're rebasing or merging // enable the abort button only if we're rebasing or merging

View file

@ -174,8 +174,7 @@ class GitServerConfigActivity : BaseGitActivity() {
} }
} }
GitSettings.UpdateConnectionSettingsResult.Valid -> { GitSettings.UpdateConnectionSettingsResult.Valid -> {
if (isClone && PasswordRepository.getRepository(null) == null) if (isClone && PasswordRepository.repository == null) PasswordRepository.initialize()
PasswordRepository.initialize()
if (!isClone) { if (!isClone) {
Snackbar.make( Snackbar.make(
binding.root, binding.root,

View file

@ -20,7 +20,7 @@ import org.eclipse.jgit.revwalk.RevCommit
private val TAG = GitLogModel::class.java.simpleName private val TAG = GitLogModel::class.java.simpleName
private fun commits(): Iterable<RevCommit> { private fun commits(): Iterable<RevCommit> {
val repo = PasswordRepository.getRepository(null) val repo = PasswordRepository.repository
if (repo == null) { if (repo == null) {
logcat(TAG, ERROR) { "Could not access git repository" } logcat(TAG, ERROR) { "Could not access git repository" }
return listOf() return listOf()

View file

@ -70,7 +70,7 @@ abstract class GitOperation(protected val callingActivity: FragmentActivity) {
GitOperationEntryPoint::class.java GitOperationEntryPoint::class.java
) )
protected val repository = PasswordRepository.getRepository(null)!! protected val repository = PasswordRepository.repository!!
protected val git = Git(repository) protected val git = Git(repository)
protected val remoteBranch = hiltEntryPoint.gitSettings().branch protected val remoteBranch = hiltEntryPoint.gitSettings().branch
private val authActivity private val authActivity