diff --git a/src/main/kotlin/app/git/RemotesManager.kt b/src/main/kotlin/app/git/RemotesManager.kt deleted file mode 100644 index b1a72ee..0000000 --- a/src/main/kotlin/app/git/RemotesManager.kt +++ /dev/null @@ -1,48 +0,0 @@ -package app.git - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import org.eclipse.jgit.api.Git -import org.eclipse.jgit.api.RemoteSetUrlCommand -import org.eclipse.jgit.lib.Ref -import org.eclipse.jgit.transport.RemoteConfig -import org.eclipse.jgit.transport.URIish -import javax.inject.Inject - -class RemotesManager @Inject constructor() { - suspend fun loadRemotes(git: Git, allRemoteBranches: List) = withContext(Dispatchers.IO) { - val remotes = git.remoteList() - .call() - - return@withContext remotes.map { remoteConfig -> - val remoteBranches = allRemoteBranches.filter { branch -> - branch.name.startsWith("refs/remotes/${remoteConfig.name}") - } - RemoteInfo(remoteConfig, remoteBranches) - } - } - - suspend fun deleteRemote(git: Git, remoteName: String) = withContext(Dispatchers.IO) { - git.remoteRemove() - .setRemoteName(remoteName) - .call() - } - - suspend fun addRemote(git: Git, remoteName: String, fetchUri: String) = withContext(Dispatchers.IO) { - git.remoteAdd() - .setName(remoteName) - .setUri(URIish(fetchUri)) - .call() - } - - suspend fun updateRemote(git: Git, remoteName: String, uri: String, uriType: RemoteSetUrlCommand.UriType) = - withContext(Dispatchers.IO) { - git.remoteSetUrl() - .setRemoteName(remoteName) - .setRemoteUri(URIish(uri)) - .setUriType(uriType) - .call() - } -} - -data class RemoteInfo(val remoteConfig: RemoteConfig, val branchesList: List) \ No newline at end of file diff --git a/src/main/kotlin/app/git/branches/DeleteLocallyRemoteBranches.kt b/src/main/kotlin/app/git/branches/DeleteLocallyRemoteBranchesUseCase.kt similarity index 86% rename from src/main/kotlin/app/git/branches/DeleteLocallyRemoteBranches.kt rename to src/main/kotlin/app/git/branches/DeleteLocallyRemoteBranchesUseCase.kt index 9672c85..b8faa83 100644 --- a/src/main/kotlin/app/git/branches/DeleteLocallyRemoteBranches.kt +++ b/src/main/kotlin/app/git/branches/DeleteLocallyRemoteBranchesUseCase.kt @@ -5,7 +5,7 @@ import kotlinx.coroutines.withContext import org.eclipse.jgit.api.Git import javax.inject.Inject -class DeleteLocallyRemoteBranches @Inject constructor() { +class DeleteLocallyRemoteBranchesUseCase @Inject constructor() { suspend operator fun invoke(git: Git, branches: List): List = withContext(Dispatchers.IO) { git .branchDelete() diff --git a/src/main/kotlin/app/git/remotes/AddRemoteUseCase.kt b/src/main/kotlin/app/git/remotes/AddRemoteUseCase.kt new file mode 100644 index 0000000..ab35c73 --- /dev/null +++ b/src/main/kotlin/app/git/remotes/AddRemoteUseCase.kt @@ -0,0 +1,16 @@ +package app.git.remotes + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.transport.URIish +import javax.inject.Inject + +class AddRemoteUseCase @Inject constructor() { + suspend operator fun invoke(git: Git, remoteName: String, fetchUri: String): Unit = withContext(Dispatchers.IO) { + git.remoteAdd() + .setName(remoteName) + .setUri(URIish(fetchUri)) + .call() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/git/remotes/DeleteRemoteUseCase.kt b/src/main/kotlin/app/git/remotes/DeleteRemoteUseCase.kt new file mode 100644 index 0000000..7a353b3 --- /dev/null +++ b/src/main/kotlin/app/git/remotes/DeleteRemoteUseCase.kt @@ -0,0 +1,14 @@ +package app.git.remotes + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import javax.inject.Inject + +class DeleteRemoteUseCase @Inject constructor() { + suspend operator fun invoke(git: Git, remoteName: String): Unit = withContext(Dispatchers.IO) { + git.remoteRemove() + .setRemoteName(remoteName) + .call() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/git/remotes/GetRemotesUseCase.kt b/src/main/kotlin/app/git/remotes/GetRemotesUseCase.kt new file mode 100644 index 0000000..2ce86be --- /dev/null +++ b/src/main/kotlin/app/git/remotes/GetRemotesUseCase.kt @@ -0,0 +1,22 @@ +package app.git.remotes + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.lib.Ref +import javax.inject.Inject + +class GetRemotesUseCase @Inject constructor() { + suspend operator fun invoke(git: Git, allRemoteBranches: List): List = + withContext(Dispatchers.IO) { + val remotes = git.remoteList() + .call() + + return@withContext remotes.map { remoteConfig -> + val remoteBranches = allRemoteBranches.filter { branch -> + branch.name.startsWith("refs/remotes/${remoteConfig.name}") + } + RemoteInfo(remoteConfig, remoteBranches) + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/git/remotes/RemoteInfo.kt b/src/main/kotlin/app/git/remotes/RemoteInfo.kt new file mode 100644 index 0000000..58a8ab0 --- /dev/null +++ b/src/main/kotlin/app/git/remotes/RemoteInfo.kt @@ -0,0 +1,6 @@ +package app.git.remotes + +import org.eclipse.jgit.lib.Ref +import org.eclipse.jgit.transport.RemoteConfig + +data class RemoteInfo(val remoteConfig: RemoteConfig, val branchesList: List) \ No newline at end of file diff --git a/src/main/kotlin/app/git/remotes/UpdateRemoteUseCase.kt b/src/main/kotlin/app/git/remotes/UpdateRemoteUseCase.kt new file mode 100644 index 0000000..c1f8555 --- /dev/null +++ b/src/main/kotlin/app/git/remotes/UpdateRemoteUseCase.kt @@ -0,0 +1,19 @@ +package app.git.remotes + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import org.eclipse.jgit.api.RemoteSetUrlCommand +import org.eclipse.jgit.transport.URIish +import javax.inject.Inject + +class UpdateRemoteUseCase @Inject constructor() { + suspend operator fun invoke(git: Git, remoteName: String, uri: String, uriType: RemoteSetUrlCommand.UriType): Unit = + withContext(Dispatchers.IO) { + git.remoteSetUrl() + .setRemoteName(remoteName) + .setRemoteUri(URIish(uri)) + .setUriType(uriType) + .call() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/git/repository/InitLocalRepositoryUseCase.kt b/src/main/kotlin/app/git/repository/InitLocalRepositoryUseCase.kt new file mode 100644 index 0000000..b6eb991 --- /dev/null +++ b/src/main/kotlin/app/git/repository/InitLocalRepositoryUseCase.kt @@ -0,0 +1,18 @@ +package app.git.repository + +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.eclipse.jgit.api.Git +import java.io.File +import javax.inject.Inject + +private const val INITIAL_BRANCH_NAME = "main" + +class InitLocalRepositoryUseCase @Inject constructor() { + suspend operator fun invoke(repoDir: File): Unit = withContext(Dispatchers.IO) { + Git.init() + .setInitialBranch(INITIAL_BRANCH_NAME) + .setDirectory(repoDir) + .call() + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/git/RepositoryManager.kt b/src/main/kotlin/app/git/repository/OpenRepositoryUseCase.kt similarity index 53% rename from src/main/kotlin/app/git/RepositoryManager.kt rename to src/main/kotlin/app/git/repository/OpenRepositoryUseCase.kt index 5555269..3a3d6f7 100644 --- a/src/main/kotlin/app/git/RepositoryManager.kt +++ b/src/main/kotlin/app/git/repository/OpenRepositoryUseCase.kt @@ -1,21 +1,14 @@ -package app.git +package app.git.repository import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext -import org.eclipse.jgit.api.Git import org.eclipse.jgit.lib.Repository import org.eclipse.jgit.storage.file.FileRepositoryBuilder import java.io.File import javax.inject.Inject -private const val INITIAL_BRANCH_NAME = "main" - -class RepositoryManager @Inject constructor() { - suspend fun getRepositoryState(git: Git) = withContext(Dispatchers.IO) { - return@withContext git.repository.repositoryState - } - - fun openRepository(directory: File): Repository { +class OpenRepositoryUseCase @Inject constructor() { + suspend operator fun invoke(directory: File): Repository = withContext(Dispatchers.IO) { val gitDirectory = if (directory.name == ".git") { directory } else { @@ -27,16 +20,9 @@ class RepositoryManager @Inject constructor() { } val builder = FileRepositoryBuilder() - return builder.setGitDir(gitDirectory) + return@withContext builder.setGitDir(gitDirectory) .readEnvironment() // scan environment GIT_* variables .findGitDir() // scan up the file system tree .build() } - - suspend fun initLocalRepo(repoDir: File): Unit = withContext(Dispatchers.IO) { - Git.init() - .setInitialBranch(INITIAL_BRANCH_NAME) - .setDirectory(repoDir) - .call() - } } \ No newline at end of file diff --git a/src/main/kotlin/app/viewmodels/RemotesViewModel.kt b/src/main/kotlin/app/viewmodels/RemotesViewModel.kt index b8b14d4..826458b 100644 --- a/src/main/kotlin/app/viewmodels/RemotesViewModel.kt +++ b/src/main/kotlin/app/viewmodels/RemotesViewModel.kt @@ -2,9 +2,10 @@ package app.viewmodels import app.exceptions.InvalidRemoteUrlException import app.git.* -import app.git.branches.DeleteLocallyRemoteBranches +import app.git.branches.DeleteLocallyRemoteBranchesUseCase import app.git.branches.GetRemoteBranchesUseCase import app.git.remote_operations.DeleteRemoteBranchUseCase +import app.git.remotes.* import app.ui.dialogs.RemoteWrapper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow @@ -16,11 +17,14 @@ import org.eclipse.jgit.lib.Ref import javax.inject.Inject class RemotesViewModel @Inject constructor( - private val remotesManager: RemotesManager, - private val deleteRemoteBranchUseCase: DeleteRemoteBranchUseCase, private val tabState: TabState, + private val deleteRemoteBranchUseCase: DeleteRemoteBranchUseCase, private val getRemoteBranchesUseCase: GetRemoteBranchesUseCase, - private val deleteLocallyRemoteBranchesUseCase: DeleteLocallyRemoteBranches, + private val getRemotesUseCase: GetRemotesUseCase, + private val deleteRemoteUseCase: DeleteRemoteUseCase, + private val addRemoteUseCase: AddRemoteUseCase, + private val updateRemoteUseCase: UpdateRemoteUseCase, + private val deleteLocallyRemoteBranchesUseCase: DeleteLocallyRemoteBranchesUseCase ) : ExpandableViewModel() { private val _remotes = MutableStateFlow>(listOf()) val remotes: StateFlow> @@ -31,7 +35,8 @@ class RemotesViewModel @Inject constructor( .call() val allRemoteBranches = getRemoteBranchesUseCase(git) - remotesManager.loadRemotes(git, allRemoteBranches) + getRemotesUseCase(git, allRemoteBranches) + val remoteInfoList = remotes.map { remoteConfig -> val remoteBranches = allRemoteBranches.filter { branch -> branch.name.startsWith("refs/remotes/${remoteConfig.name}") @@ -74,7 +79,7 @@ class RemotesViewModel @Inject constructor( refreshType = if (isNew) RefreshType.REMOTES else RefreshType.ALL_DATA, showError = true, ) { git -> - remotesManager.deleteRemote(git, remoteName) + deleteRemoteUseCase(git, remoteName) val remoteBranches = getRemoteBranchesUseCase(git) val remoteToDeleteBranchesNames = remoteBranches.filter { @@ -99,7 +104,7 @@ class RemotesViewModel @Inject constructor( throw InvalidRemoteUrlException("Invalid empty push URI") } - remotesManager.addRemote(git, selectedRemoteConfig.remoteName, selectedRemoteConfig.fetchUri) + addRemoteUseCase(git, selectedRemoteConfig.remoteName, selectedRemoteConfig.fetchUri) updateRemote(selectedRemoteConfig) // Sets both, fetch and push uri } @@ -117,14 +122,14 @@ class RemotesViewModel @Inject constructor( throw InvalidRemoteUrlException("Invalid empty push URI") } - remotesManager.updateRemote( + updateRemoteUseCase( git = git, remoteName = selectedRemoteConfig.remoteName, uri = selectedRemoteConfig.fetchUri, uriType = RemoteSetUrlCommand.UriType.FETCH ) - remotesManager.updateRemote( + updateRemoteUseCase( git = git, remoteName = selectedRemoteConfig.remoteName, uri = selectedRemoteConfig.pushUri, diff --git a/src/main/kotlin/app/viewmodels/TabViewModel.kt b/src/main/kotlin/app/viewmodels/TabViewModel.kt index fe0207c..cfd02ff 100644 --- a/src/main/kotlin/app/viewmodels/TabViewModel.kt +++ b/src/main/kotlin/app/viewmodels/TabViewModel.kt @@ -5,6 +5,9 @@ import app.ErrorsManager import app.credentials.CredentialsState import app.credentials.CredentialsStateManager import app.git.* +import app.git.repository.GetRepositoryStateUseCase +import app.git.repository.InitLocalRepositoryUseCase +import app.git.repository.OpenRepositoryUseCase import app.logging.printLog import app.models.AuthorInfoSimple import app.newErrorNow @@ -43,11 +46,13 @@ class TabViewModel @Inject constructor( val stashesViewModel: StashesViewModel, val commitChangesViewModel: CommitChangesViewModel, val cloneViewModel: CloneViewModel, + private val getRepositoryStateUseCase: GetRepositoryStateUseCase, + private val initLocalRepositoryUseCase: InitLocalRepositoryUseCase, + private val openRepositoryUseCase: OpenRepositoryUseCase, private val diffViewModelProvider: Provider, private val rebaseInteractiveViewModelProvider: Provider, private val historyViewModelProvider: Provider, private val authorViewModelProvider: Provider, - private val repositoryManager: RepositoryManager, private val tabState: TabState, val appStateManager: AppStateManager, private val fileChangesWatcher: FileChangesWatcher, @@ -167,7 +172,7 @@ class TabViewModel @Inject constructor( _repositorySelectionStatus.value = RepositorySelectionStatus.Opening(directory.absolutePath) - val repository: Repository = repositoryManager.openRepository(directory) + val repository: Repository = openRepositoryUseCase(directory) try { repository.workTree // test if repository is valid @@ -188,7 +193,7 @@ class TabViewModel @Inject constructor( } private suspend fun loadRepositoryState(git: Git) = withContext(Dispatchers.IO) { - val newRepoState = repositoryManager.getRepositoryState(git) + val newRepoState = getRepositoryStateUseCase(git) printLog(TAG, "Refreshing repository state $newRepoState") _repositoryState.value = newRepoState @@ -364,7 +369,7 @@ class TabViewModel @Inject constructor( showError = true, ) { val repoDir = File(dir) - repositoryManager.initLocalRepo(repoDir) + initLocalRepositoryUseCase(repoDir) openRepository(repoDir) }