Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decouple Azure Devops from git-plugin and prepare for other Git providers #30

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3606479
Introduce a provider package and move Azure code there
MartinKanters Jun 20, 2023
3ca9229
Implemented an interface as GitProvider and ensured Azure is not call…
MartinKanters Jun 20, 2023
78c3bfc
Made URL Factory part of the GitProvider
MartinKanters Jun 20, 2023
1de89fc
Made command tests independent of Azure Devops
MartinKanters Jun 20, 2023
aa39625
Removed azure devops from test method names
MartinKanters Jun 20, 2023
06552f1
Removed dependency on plugin config in command
MartinKanters Jun 20, 2023
0a262a9
Removed unused configurations
MartinKanters Jun 20, 2023
aba7ab6
Removed unused configurations - fixed tests
MartinKanters Jun 20, 2023
0530946
Moved the pluginConfiguration to azure package and renamed it
MartinKanters Jun 20, 2023
4a347dd
Removed generic DTO for the creation of a pull request
MartinKanters Jun 20, 2023
70e5501
Fixed typo in package name
MartinKanters Jun 20, 2023
4b6adbc
Tested the specifics in the Azure Devops Provider
MartinKanters Jun 20, 2023
a28cfbb
Used named imports to make the code clearer
MartinKanters Jun 20, 2023
6df9441
Let the GitUrlFactory return URLs instead of Strings
MartinKanters Jul 12, 2023
43243f7
Removed duplicate function for resolving the URL for the pull request
MartinKanters Jul 12, 2023
85ecc12
Removed unnecessary create prefix and url suffix in the gitUrlFactory
MartinKanters Jul 12, 2023
09f94a8
Fixed code smell by making the GitDomainConvertible a functional inte…
MartinKanters Jul 12, 2023
f6a7d33
Removed AzDo specific code in generic Git Domain (class Branch)
MartinKanters Jul 12, 2023
6029bec
Removed AzDo specific code in generic Git Domain (class Pipeline)
MartinKanters Jul 12, 2023
6602913
Updated Kotlin and RET-plugin version and making use of the new Brows…
MartinKanters Jul 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@ package io.rabobank.ret.git.plugin.command

import io.rabobank.ret.IntelliSearch
import io.rabobank.ret.RetContext
import io.rabobank.ret.git.plugin.azure.AzureDevopsClient
import io.rabobank.ret.git.plugin.azure.Pipeline
import io.rabobank.ret.git.plugin.azure.PipelineRun
import io.rabobank.ret.git.plugin.azure.PullRequest
import io.rabobank.ret.git.plugin.config.PluginConfig
import io.rabobank.ret.git.plugin.provider.Pipeline
import io.rabobank.ret.git.plugin.provider.PipelineRun
import io.rabobank.ret.git.plugin.provider.PullRequest
import io.rabobank.ret.git.plugin.output.OutputHandler
import io.rabobank.ret.git.plugin.provider.GitProvider
import io.rabobank.ret.picocli.mixin.ContextAwareness
import io.rabobank.ret.util.RegexUtils.DIGITS_PATTERN
import picocli.CommandLine.Command
Expand All @@ -17,8 +16,7 @@ import picocli.CommandLine.ScopeType

@Command(name = "autocomplete", hidden = true)
class AutoCompleteCommand(
private val azureDevopsClient: AzureDevopsClient,
private val pluginConfig: PluginConfig,
private val gitProvider: GitProvider,
private val intelliSearch: IntelliSearch,
private val outputHandler: OutputHandler,
private val retContext: RetContext,
Expand All @@ -32,11 +30,11 @@ class AutoCompleteCommand(

@Command(name = "git-pipeline")
fun printPipelines(@Option(names = ["--word", "-w"]) word: String?) {
val pipelines = azureDevopsClient.getAllPipelines()
val pipelines = gitProvider.getAllPipelines()

outputHandler.listPipelines(
pipelines.value.filter { it.matches(word) }
.sortedWith(compareBy({ it.folder }, { it.name })),
pipelines.filter { it.matches(word) }
.sortedWith(compareBy({ it.container }, { it.name })),
)
}

Expand All @@ -55,21 +53,21 @@ class AutoCompleteCommand(
getPipelineByUniqueName(pipelineIdFlag).id.toString()
}

val pipelineRuns = azureDevopsClient.getPipelineRuns(pipelineId)
val pipelineRuns = gitProvider.getPipelineRuns(pipelineId)

outputHandler.listPipelineRuns(
pipelineRuns.value.filter { it.matches(word) }
pipelineRuns.filter { it.matches(word) }
.sortedByDescending { it.createdDate }
.take(TOP_20_PIPELINES),
)
}

@Command(name = "git-repository")
fun printRepositories(@Option(names = ["--word", "-w"]) word: String?) {
val repositories = azureDevopsClient.getAllRepositories()
val repositories = gitProvider.getAllRepositories()

outputHandler.listRepositories(
repositories.value.filter {
repositories.filter {
word == null || intelliSearch.matches(word, it.name)
},
)
Expand All @@ -85,7 +83,7 @@ class AutoCompleteCommand(

repository?.let { repo ->
outputHandler.listBranches(
azureDevopsClient.getAllRefs(repo, "heads/").value
gitProvider.getAllRefs(repo, "heads/")
.filter { word == null || intelliSearch.matches(word, it.shortName) },
)
} ?: outputHandler.error("No repository could be determined")
Expand All @@ -106,14 +104,14 @@ class AutoCompleteCommand(
)
filterRepository: String? = null,
) {
val prs = azureDevopsClient.getAllPullRequests().value
.filter { !notReviewed || !it.reviewers.any { r -> r.uniqueName.equals(pluginConfig.email, true) } }
val prs = if (!notReviewed) gitProvider.getAllPullRequests() else gitProvider.getPullRequestsNotReviewedByUser()
val filteredPrs = prs
.filter { it.isFromRepository(filterRepository) }
val filteredPrs = prs.filter {
word == null ||
intelliSearch.matches(word, it.title) ||
intelliSearch.matches(word, it.repository.name)
}
.filter {
word == null ||
intelliSearch.matches(word, it.title) ||
intelliSearch.matches(word, it.repository.name)
}
outputHandler.listPRs(filteredPrs)
}

Expand All @@ -127,15 +125,15 @@ class AutoCompleteCommand(
private fun Pipeline.matches(value: String?): Boolean =
value == null ||
intelliSearch.matches(value, name) ||
intelliSearch.matches(value, cleanedFolder) ||
intelliSearch.matches(value, container) ||
intelliSearch.matches(value, uniqueName)

private fun PipelineRun.matches(word: String?): Boolean =
word == null || intelliSearch.matches(word, id.toString()) || intelliSearch.matches(word, name) ||
intelliSearch.matches(word, state.toString()) || intelliSearch.matches(word, result.toString())

private fun getPipelineByUniqueName(pipelineIdFlag: String) =
requireNotNull(azureDevopsClient.getAllPipelines().value.firstOrNull { it.uniqueName == pipelineIdFlag }) {
requireNotNull(gitProvider.getAllPipelines().firstOrNull { it.uniqueName == pipelineIdFlag }) {
"Could not find pipeline id by <folder>\\<pipeline-name> combination: '$pipelineIdFlag'"
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package io.rabobank.ret.git.plugin.command

import io.rabobank.ret.git.plugin.azure.AzureDevopsClient
import io.rabobank.ret.git.plugin.azure.AzureDevopsUrlFactory
import io.rabobank.ret.git.plugin.provider.GitProvider
import io.rabobank.ret.util.BrowserUtils
import io.rabobank.ret.util.RegexUtils.DIGITS_PATTERN
import picocli.CommandLine.Command
Expand All @@ -12,9 +11,8 @@ import picocli.CommandLine.Parameters
description = ["Open a recent pipeline run"],
)
class PipelineCommand(
private val azureDevopsUrlFactory: AzureDevopsUrlFactory,
private val browserUtils: BrowserUtils,
private val azureDevopsClient: AzureDevopsClient,
private val gitProvider: GitProvider,
) {

@Command(name = "open", description = ["Open the pipeline dashboard, or a specific pipeline or run"])
Expand All @@ -32,21 +30,21 @@ class PipelineCommand(
completionCandidates = PipelineRunCompletionCandidates::class,
) pipelineRunId: String?,
) {
val url = if (pipelineId == null) azureDevopsUrlFactory.createPipelineDashboardUrl()
val url = if (pipelineId == null) gitProvider.urlFactory.pipelineDashboard()
else if (pipelineRunId == null) {
val resolvedPipelineId = if (pipelineId.matches(DIGITS_PATTERN)) {
pipelineId
} else {
getPipelineByUniqueName(pipelineId).id.toString()
}
azureDevopsUrlFactory.createPipelineUrl(resolvedPipelineId)
} else azureDevopsUrlFactory.createPipelineRunUrl(pipelineRunId)
gitProvider.urlFactory.pipeline(resolvedPipelineId)
} else gitProvider.urlFactory.pipelineRun(pipelineRunId)

browserUtils.openUrl(url)
}

private fun getPipelineByUniqueName(pipelineId: String?) =
requireNotNull(azureDevopsClient.getAllPipelines().value.firstOrNull { it.uniqueName == pipelineId }) {
requireNotNull(gitProvider.getAllPipelines().firstOrNull { it.uniqueName == pipelineId }) {
"Could not find pipeline id by <folder>\\<pipeline-name> combination: '$pipelineId'"
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
package io.rabobank.ret.git.plugin.command

import io.rabobank.ret.RetContext
import io.rabobank.ret.git.plugin.azure.AzureDevopsClient
import io.rabobank.ret.git.plugin.azure.AzureDevopsUrlFactory
import io.rabobank.ret.git.plugin.azure.CreatePullRequest
import io.rabobank.ret.git.plugin.output.OutputHandler
import io.rabobank.ret.git.plugin.provider.GitProvider
import io.rabobank.ret.picocli.mixin.ContextAwareness
import io.rabobank.ret.util.BrowserUtils
import org.jboss.resteasy.reactive.ClientWebApplicationException
Expand All @@ -20,8 +18,7 @@ import picocli.CommandLine.ScopeType
description = ["Create a pull request"],
)
class PullRequestCreateCommand(
private val azureDevopsClient: AzureDevopsClient,
private val azureDevopsUrlFactory: AzureDevopsUrlFactory,
private val gitProvider: GitProvider,
private val browserUtils: BrowserUtils,
private val outputHandler: OutputHandler,
private val retContext: RetContext,
Expand Down Expand Up @@ -64,32 +61,26 @@ class PullRequestCreateCommand(
if (!noPrompt) {
val branch = if (autofillBranchRequired(filterRepository, providedBranch, contextBranch)) sourceBranch else null

val prCreateURL = azureDevopsUrlFactory.createPullRequestCreateUrl(repositoryName, branch)
val prCreateURL = gitProvider.urlFactory.pullRequestCreate(repositoryName, branch)
browserUtils.openUrl(prCreateURL)
} else {
requireNotNull(sourceBranch) { "Could not determine branch from context. Please provide the branch." }
val repository = azureDevopsClient.getRepositoryById(repositoryName)
val repository = gitProvider.getRepositoryById(repositoryName)
val defaultBranch = requireNotNull(repository.defaultBranch) { "No default branch available." }

require(defaultBranch != sourceBranch) {
"Could not create PR. Source branch is the same as the default branch."
}

val createPullRequest = CreatePullRequest(
"refs/heads/$sourceBranch",
defaultBranch,
"Merge $sourceBranch into ${repository.defaultBranch}",
"PR created by RET using `ret pr create --no-prompt`.",
)

try {
val createPullRequestResponse = azureDevopsClient.createPullRequest(
val createPullRequestResponse = gitProvider.createPullRequest(
repositoryName,
"6.0",
createPullRequest,
"refs/heads/$sourceBranch",
defaultBranch,
"Merge $sourceBranch into ${repository.defaultBranch}",
"PR created by RET using `ret pr create --no-prompt`.",
)
val pullRequestUrl =
azureDevopsUrlFactory.pullRequestUrl(repositoryName, createPullRequestResponse.pullRequestId)
val pullRequestUrl = gitProvider.urlFactory.pullRequest(repositoryName, createPullRequestResponse.pullRequestId).toString()
outputHandler.println(pullRequestUrl)
} catch (e: ClientWebApplicationException) {
val message = if (e.response.status == CONFLICT) "A pull request for this branch already exists!"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package io.rabobank.ret.git.plugin.command

import io.quarkus.logging.Log
import io.rabobank.ret.git.plugin.azure.AzureDevopsClient
import io.rabobank.ret.git.plugin.azure.AzureDevopsUrlFactory
import io.rabobank.ret.git.plugin.output.OutputHandler
import io.rabobank.ret.git.plugin.provider.GitProvider
import io.rabobank.ret.picocli.mixin.ContextAwareness
import io.rabobank.ret.util.BrowserUtils
import org.jboss.resteasy.reactive.ClientWebApplicationException
Expand All @@ -19,8 +18,7 @@ import picocli.CommandLine.ScopeType
description = ["Navigate to a pull request in Git"],
)
class PullRequestOpenCommand(
GuusdeWit marked this conversation as resolved.
Show resolved Hide resolved
private val azureDevopsClient: AzureDevopsClient,
private val azureDevopsUrlFactory: AzureDevopsUrlFactory,
private val gitProvider: GitProvider,
private val browserUtils: BrowserUtils,
private val outputHandler: OutputHandler,
) : Runnable {
Expand All @@ -46,8 +44,8 @@ class PullRequestOpenCommand(

override fun run() {
try {
val pullRequest = azureDevopsClient.getPullRequestById(pullRequestId)
val prURL = azureDevopsUrlFactory.createPullRequestUrl(pullRequest.repository.name, pullRequest.id)
val pullRequest = gitProvider.getPullRequestById(pullRequestId)
val prURL = gitProvider.urlFactory.pullRequest(pullRequest.repository.name, pullRequest.id)

browserUtils.openUrl(prURL)
} catch (e: ClientWebApplicationException) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package io.rabobank.ret.git.plugin.command

import io.rabobank.ret.RetContext
import io.rabobank.ret.git.plugin.azure.AzureDevopsClient
import io.rabobank.ret.git.plugin.azure.AzureDevopsUrlFactory
import io.rabobank.ret.git.plugin.provider.GitProvider
import io.rabobank.ret.picocli.mixin.ContextAwareness
import io.rabobank.ret.util.BrowserUtils
import picocli.CommandLine.Command
Expand All @@ -14,8 +13,7 @@ import picocli.CommandLine.Parameters
description = ["List all repositories"],
)
class RepositoryCommand(
private val azureDevopsClient: AzureDevopsClient,
private val azureDevopsUrlFactory: AzureDevopsUrlFactory,
private val gitProvider: GitProvider,
private val browserUtils: BrowserUtils,
private val retContext: RetContext,
) {
Expand All @@ -26,7 +24,7 @@ class RepositoryCommand(
fun openRepositoryInBrowser(
@Parameters(
arity = "0..1",
description = ["Repository name to open in Azure DevOps"],
description = ["Repository name to open in the browser"],
paramLabel = "<repository>",
completionCandidates = RepositoryCompletionCandidates::class,
) repositoryName: String?,
Expand All @@ -35,11 +33,12 @@ class RepositoryCommand(
"No repository provided and ret cannot get repository from context."
}

val repositories = azureDevopsClient.getAllRepositories().value
val repositories = gitProvider.getAllRepositories()

require(repositories.any { it.name == repository }) { "No repository found with name $repository." }

browserUtils.openUrl(azureDevopsUrlFactory.createRepositoryUrl(repository))
val url = gitProvider.urlFactory.repository(repository)
browserUtils.openUrl(url)
}
}

Expand Down
Loading