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

GetRepositoryInfo for Azure Repos #116

Merged
merged 2 commits into from
Aug 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
41 changes: 34 additions & 7 deletions vcsclient/azurerepos.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/jfrog/froggit-go/vcsutils"
"github.com/jfrog/gofrog/datastructures"
"github.com/microsoft/azure-devops-go-api/azuredevops"
"github.com/microsoft/azure-devops-go-api/azuredevops/core"
"github.com/microsoft/azure-devops-go-api/azuredevops/git"
"io"
"net/http"
Expand Down Expand Up @@ -114,16 +115,16 @@ func (client *AzureReposClient) DownloadRepository(ctx context.Context, owner, r
return err
}
client.logger.Info(successfulRepoExtraction)
repoInfo, err := client.GetRepositoryInfo(ctx, owner, repository)
if err != nil {
return err
}
httpsCloneUrl := repoInfo.CloneInfo.HTTP
// Generate .git folder with remote details
return vcsutils.CreateDotGitFolderWithRemote(
localPath,
vcsutils.RemoteName,
client.GetGitRemoteURL(owner, repository))
}

// GetGitRemoteURL on Azure Repos
func (client *AzureReposClient) GetGitRemoteURL(owner, repository string) string {
return fmt.Sprintf("https://%s@%s/%s/_git/%s", owner, strings.TrimPrefix(client.connectionDetails.BaseUrl, "https://"), client.vcsInfo.Project, repository)
httpsCloneUrl)
}

func (client *AzureReposClient) sendDownloadRepoRequest(ctx context.Context, repository string, branch string) (res *http.Response, err error) {
Expand Down Expand Up @@ -405,7 +406,33 @@ func (client *AzureReposClient) AddSshKeyToRepository(ctx context.Context, owner

// GetRepositoryInfo on Azure Repos
func (client *AzureReposClient) GetRepositoryInfo(ctx context.Context, owner, repository string) (RepositoryInfo, error) {
return RepositoryInfo{}, getUnsupportedInAzureError("get repository info")
azureReposGitClient, err := client.buildAzureReposClient(ctx)
if err != nil {
return RepositoryInfo{}, err
}
response, err := azureReposGitClient.GetRepository(ctx, git.GetRepositoryArgs{
RepositoryId: &repository,
Project: &client.vcsInfo.Project,
})
if err != nil {
return RepositoryInfo{}, fmt.Errorf("an error occured while retrieving <%s/%s/%s> repository info:\n%s", owner, client.vcsInfo.Project, repository, err.Error())
}
if response == nil {
return RepositoryInfo{}, fmt.Errorf("failed to retreive <%s/%s/%s> repository info, received empty response", owner, client.vcsInfo.Project, repository)
}
if response.Project == nil {
return RepositoryInfo{}, fmt.Errorf("failed to retreive <%s/%s/%s> repository info, received empty project info", owner, client.vcsInfo.Project, repository)
}

visibility := Private
visibilityFromResponse := *response.Project.Visibility
if visibilityFromResponse == core.ProjectVisibilityValues.Public {
visibility = Public
}
return RepositoryInfo{
CloneInfo: CloneInfo{HTTP: *response.RemoteUrl, SSH: *response.SshUrl},
RepositoryVisibility: visibility,
}, nil
}

// GetCommitBySha on Azure Repos
Expand Down
75 changes: 45 additions & 30 deletions vcsclient/azurerepos_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestAzureRepos_ListRepositories(t *testing.T) {
jsonRes, err := json.Marshal(res)
assert.NoError(t, err)
ctx := context.Background()
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true, jsonRes, "listRepositories", createAzureReposHandler)
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true, jsonRes, "getRepository", createAzureReposHandler)
defer cleanUp()
reposMap, err := client.ListRepositories(ctx)
assert.NoError(t, err)
Expand Down Expand Up @@ -92,7 +92,7 @@ func TestAzureRepos_TestDownloadRepository(t *testing.T) {
repo1,
branch1)
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true,
repoFile, downloadURL, createAzureReposHandler)
repoFile, downloadURL, createGetRepositoryAzureReposHandler)
defer cleanUp()
err = client.DownloadRepository(ctx, "", repo1, branch1, dir)
assert.NoError(t, err)
Expand Down Expand Up @@ -449,11 +449,11 @@ func TestAzureReposClient_CreateLabel(t *testing.T) {
assert.Error(t, client.CreateLabel(ctx, owner, repo1, LabelInfo{}))
}

func TestAzureReposClient_GetRepositoryInfo(t *testing.T) {
func TestAzureReposClient_GetRepositoryEnvironmentInfo(t *testing.T) {
ctx := context.Background()
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true, "", "unsupportedTest", createAzureReposHandler)
defer cleanUp()
_, err := client.GetRepositoryInfo(ctx, owner, repo1)
_, err := client.GetRepositoryEnvironmentInfo(ctx, owner, repo1, "")
assert.Error(t, err)
}

Expand Down Expand Up @@ -547,19 +547,22 @@ func TestAzureReposClient_SetCommitStatus(t *testing.T) {
assert.Error(t, err)
}

func TestAzureReposClient_GetLabel(t *testing.T) {
func TestAzureReposClient_GetRepositoryInfo(t *testing.T) {
ctx := context.Background()
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true, "", "unsupportedTest", createAzureReposHandler)
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true, "", "/_apis/ResourceAreas/getRepository", createGetRepositoryAzureReposHandler)
defer cleanUp()
_, err := client.GetLabel(ctx, owner, repo1, "")
assert.Error(t, err)
repositoryInfo, err := client.GetRepositoryInfo(ctx, "jfrog", "froggit-go")
assert.NoError(t, err)
assert.Equal(t, repositoryInfo.CloneInfo.HTTP, "https://jfrog@dev.azure.com/jfrog/froggit-go/_git/froggit-go")
omerzi marked this conversation as resolved.
Show resolved Hide resolved
assert.Equal(t, repositoryInfo.CloneInfo.SSH, "git@ssh.dev.azure.com:v3/jfrog/froggit-go/froggit-go")
assert.Equal(t, repositoryInfo.RepositoryVisibility, Public)
}

func TestAzureReposClient_GetRepositoryEnvironmentInfo(t *testing.T) {
func TestAzureReposClient_GetLabel(t *testing.T) {
ctx := context.Background()
client, cleanUp := createServerAndClient(t, vcsutils.AzureRepos, true, "", "unsupportedTest", createAzureReposHandler)
defer cleanUp()
_, err := client.GetRepositoryEnvironmentInfo(ctx, owner, repo1, envName)
_, err := client.GetLabel(ctx, owner, repo1, "")
assert.Error(t, err)
}

Expand Down Expand Up @@ -719,6 +722,38 @@ func createAzureReposHandler(t *testing.T, expectedURI string, response []byte,
}
}

func createGetRepositoryAzureReposHandler(t *testing.T, expectedURI string, response []byte, expectedStatusCode int) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
base64Token := base64.StdEncoding.EncodeToString([]byte(":" + token))
assert.Equal(t, "Basic "+base64Token, r.Header.Get("Authorization"))
if r.RequestURI == "/_apis" {
omerzi marked this conversation as resolved.
Show resolved Hide resolved
jsonVal, err := os.ReadFile(filepath.Join("./", "testdata", "azurerepos", "resourcesResponse.json"))
assert.NoError(t, err)
_, err = w.Write(jsonVal)
assert.NoError(t, err)
return
} else if r.RequestURI == "/_apis/ResourceAreas" {
jsonVal := `{"value": [],"count": 0}`
_, err := w.Write([]byte(jsonVal))
assert.NoError(t, err)
return
} else if r.RequestURI == "/_apis/ResourceAreas/getRepository" {
jsonVal := `{"id":"23d122fb-c6c1-4f03-8117-a10a08f8b0d6","name":"froggit-go","url":"https://dev.azure.com/jfrog/638e3921-f5e3-46e6-a11f-a139cb9bd511/_apis/git/repositories/23d122fb-c6c1-4f03-8117-a10a08f8b0d6","project":{"id":"638e3921-f5e3-46e6-a11f-a139cb9bd511","name":"froggit-go","visibility":"public"},"defaultBranch":"refs/heads/main","remoteUrl":"https://jfrog@dev.azure.com/jfrog/froggit-go/_git/froggit-go","sshUrl":"git@ssh.dev.azure.com:v3/jfrog/froggit-go/froggit-go","isDisabled":false,"isInMaintenance":false}`
_, err := w.Write([]byte(jsonVal))
assert.NoError(t, err)
return
}

if !strings.Contains(expectedURI, "bad^endpoint") {
assert.Contains(t, r.RequestURI, expectedURI)
w.WriteHeader(expectedStatusCode)
_, err := w.Write(response)
assert.NoError(t, err)
return
}
w.WriteHeader(http.StatusNotFound)
}
}
func createBadAzureReposClient(t *testing.T, response []byte) (VcsClient, func()) {
client, cleanUp := createServerAndClient(
t,
Expand All @@ -732,23 +767,3 @@ func createBadAzureReposClient(t *testing.T, response []byte) (VcsClient, func()
createAzureReposHandler)
return client, cleanUp
}

func TestAzureReposClient_GetGitRemoteUrl(t *testing.T) {
testCase := struct {
name string
apiEndpoint string
owner string
repo string
expectedResult string
}{
name: "Azure Repos Cloud",
apiEndpoint: "https://dev.azure.com/my-org",
owner: "my-org",
repo: "my-repo",
expectedResult: "https://my-org@dev.azure.com/my-org/project/_git/my-repo",
}
info := VcsInfo{APIEndpoint: testCase.apiEndpoint, Project: "project"}
client, err := NewAzureReposClient(info, nil)
assert.NoError(t, err)
assert.Equal(t, testCase.expectedResult, client.GetGitRemoteURL(testCase.owner, testCase.repo))
}
12 changes: 5 additions & 7 deletions vcsclient/bitbucketcloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,14 +274,12 @@ func (client *BitbucketCloudClient) DownloadRepository(ctx context.Context, owne
return err
}
client.logger.Info(successfulRepoExtraction)
repositoryInfo, err := client.GetRepositoryInfo(ctx, owner, repository)
if err != nil {
return err
}
// Generate .git folder with remote details
return vcsutils.CreateDotGitFolderWithRemote(localPath, "origin",
client.GetGitRemoteURL(owner, repository))
}

// GetGitRemoteURL on Bitbucket Cloud
func (client *BitbucketCloudClient) GetGitRemoteURL(owner, repository string) string {
return vcsutils.GetGenericGitRemoteUrl(client.vcsInfo.APIEndpoint, owner, repository)
return vcsutils.CreateDotGitFolderWithRemote(localPath, "origin", repositoryInfo.CloneInfo.HTTP)
}

// CreatePullRequest on Bitbucket cloud
Expand Down
20 changes: 0 additions & 20 deletions vcsclient/bitbucketcloud_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,26 +151,6 @@ func TestBitbucketCloud_CreatePullRequest(t *testing.T) {
assert.NoError(t, err)
}

func TestBitbucketCloudClient_GetGitRemoteUrl(t *testing.T) {
testCase := struct {
name string
apiEndpoint string
owner string
repo string
expectedResult string
}{
name: "Bitbucket Cloud",
apiEndpoint: "https://bitbucket.org",
owner: "my-org",
repo: "my-repo",
expectedResult: "https://bitbucket.org/my-org/my-repo.git",
}
info := VcsInfo{APIEndpoint: testCase.apiEndpoint}
client, err := NewBitbucketCloudClient(info, nil)
assert.NoError(t, err)
assert.Equal(t, testCase.expectedResult, client.GetGitRemoteURL(testCase.owner, testCase.repo))
}

func TestBitbucketCloudClient_UpdatePullRequest(t *testing.T) {
ctx := context.Background()
prId := 3
Expand Down
11 changes: 5 additions & 6 deletions vcsclient/bitbucketserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,16 +266,15 @@ func (client *BitbucketServerClient) DownloadRepository(ctx context.Context, own
return err
}
client.logger.Info(successfulRepoExtraction)
repositoryInfo, err := client.GetRepositoryInfo(ctx, owner, repository)
if err != nil {
return err
}
// Generate .git folder with remote details
return vcsutils.CreateDotGitFolderWithRemote(
localPath,
vcsutils.RemoteName,
client.GetGitRemoteURL(owner, repository))
}

// GetGitRemoteURL on Bitbucket Server
func (client *BitbucketServerClient) GetGitRemoteURL(owner, repository string) string {
return vcsutils.GetGenericGitRemoteUrl(fmt.Sprintf("%s/scm", strings.TrimSuffix(client.vcsInfo.APIEndpoint, "/rest")), owner, repository)
repositoryInfo.CloneInfo.HTTP)
}

// CreatePullRequest on Bitbucket server
Expand Down
39 changes: 17 additions & 22 deletions vcsclient/bitbucketserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func TestBitbucketServer_DownloadRepository(t *testing.T) {
assert.NoError(t, err)

client, cleanUp := createServerAndClient(t, vcsutils.BitbucketServer, false, repoFile,
fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s/archive?format=tgz", owner, repo1), createBitbucketServerHandler)
fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s/archive?format=tgz", owner, repo1), createBitbucketServerDownloadRepositoryHandler)
defer cleanUp()
err = client.DownloadRepository(ctx, owner, repo1, "", dir)
assert.NoError(t, err)
Expand Down Expand Up @@ -718,6 +718,22 @@ func createBitbucketServerHandler(t *testing.T, expectedURI string, response []b
}
}

func createBitbucketServerDownloadRepositoryHandler(t *testing.T, expectedURI string, response []byte, expectedStatusCode int) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
if r.RequestURI == "/rest/api/1.0/projects/jfrog/repos/repo-1" {
repositoryResponse, err := os.ReadFile(filepath.Join("testdata", "bitbucketserver", "repository_response.json"))
assert.NoError(t, err)
_, err = w.Write(repositoryResponse)
assert.NoError(t, err)
}
w.WriteHeader(expectedStatusCode)
_, err := w.Write(response)
assert.NoError(t, err)
assert.Contains(t, expectedURI, r.RequestURI)
assert.Equal(t, "Bearer "+token, r.Header.Get("Authorization"))
}
}

func createBitbucketServerListRepositoriesHandler(t *testing.T, _ string, _ []byte, expectedStatusCode int) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var responseObj interface{}
Expand Down Expand Up @@ -834,24 +850,3 @@ func createBadBitbucketServerClient(t *testing.T) VcsClient {
assert.NoError(t, err)
return client
}

func TestBitbucketServerClient_GetGitRemoteUrl(t *testing.T) {
testCase := struct {
name string
apiEndpoint string
owner string
repo string
expectedResult string
}{
name: "Bitbucket On-Premises",
apiEndpoint: "https://git.example.com",
owner: "my-org",
repo: "my-repo",
expectedResult: "https://git.example.com/scm/my-org/my-repo.git",
}
info := VcsInfo{APIEndpoint: testCase.apiEndpoint}
client, err := NewBitbucketServerClient(info, nil)
assert.NoError(t, err)
assert.Equal(t, testCase.expectedResult, client.GetGitRemoteURL(testCase.owner, testCase.repo))

}
17 changes: 5 additions & 12 deletions vcsclient/github.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,6 @@ import (
"golang.org/x/oauth2"
)

const (
GitHubApiVersion = "/api/v3"
GitHubCloudBaseUrl = "https://github.com"
)

// GitHubClient API version 3
type GitHubClient struct {
vcsInfo VcsInfo
Expand Down Expand Up @@ -251,17 +246,15 @@ func (client *GitHubClient) DownloadRepository(ctx context.Context, owner, repos
return
}

repositoryInfo, err := client.GetRepositoryInfo(ctx, owner, repository)
if err != nil {
return err
}
client.logger.Info(successfulRepoExtraction)
err = vcsutils.CreateDotGitFolderWithRemote(localPath, vcsutils.RemoteName, client.GetGitRemoteURL(owner, repository))
err = vcsutils.CreateDotGitFolderWithRemote(localPath, vcsutils.RemoteName, repositoryInfo.CloneInfo.HTTP)
return
}

// GetGitRemoteURL on GitHub
func (client *GitHubClient) GetGitRemoteURL(owner, repository string) string {
baseUrl := vcsutils.GetBaseURLFromApiEndpoint(client.vcsInfo.APIEndpoint, GitHubCloudBaseUrl, GitHubApiVersion)
return vcsutils.GetGenericGitRemoteUrl(baseUrl, owner, repository)
}

// CreatePullRequest on GitHub
func (client *GitHubClient) CreatePullRequest(ctx context.Context, owner, repository, sourceBranch, targetBranch,
title, description string) error {
Expand Down
Loading
Loading