Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Fraser Davidson committed Nov 6, 2023
1 parent 225ed29 commit 3fc7b22
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 42 deletions.
1 change: 1 addition & 0 deletions azuredevops/artifacts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package azuredevops
17 changes: 17 additions & 0 deletions azuredevops/azuredevops.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package azuredevops

import (
"context"
"encoding/base64"
"fmt"
"strings"

"github.com/microsoft/azure-devops-go-api/azuredevops"
)
Expand All @@ -22,3 +24,18 @@ func NewAzureDevOps(organisationName string, personalAccessToken string) *AzureD
ctx: ctx,
}
}

func (a *AzureDevOps) GetPAT() (*string, error) {
authString := a.connection.AuthorizationString
if !strings.Contains(authString, "Basic") {
return nil, fmt.Errorf("authorization string does not contain basic auth")
}
bytes, err := base64.StdEncoding.DecodeString(strings.TrimLeft(authString, "Basic "))
if err != nil {
return nil, err
}
usernamePassword := string(bytes)
password := strings.Split(usernamePassword, ":")

return &password[1], nil
}
2 changes: 1 addition & 1 deletion azuredevops/project.go → azuredevops/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func (a *AzureDevOps) getProjectUUID(projectName string) (*uuid.UUID, error) {
return nil, err
}

for _, project := range *&projects.Value {
for _, project := range projects.Value {
if *project.Name == projectName {
return project.Id, nil
}
Expand Down
1 change: 1 addition & 0 deletions azuredevops/core_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package azuredevops
1 change: 1 addition & 0 deletions azuredevops/git_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package azuredevops
File renamed without changes.
1 change: 1 addition & 0 deletions azuredevops/location_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package azuredevops
86 changes: 47 additions & 39 deletions azuredevops/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package azuredevops
import (
"fmt"
"os"
"path/filepath"

egit "github.com/frontierdigital/utils/git/external_git"
"github.com/frontierdigital/utils/output"
"github.com/microsoft/azure-devops-go-api/azuredevops/git"
"golang.org/x/exp/slices"
)
Expand Down Expand Up @@ -41,21 +39,8 @@ func (a *AzureDevOps) GetRepository(projectName string, name string) (*git.GitRe
return &(*repositories)[repositoryIdx], nil
}

// configureRepository configures a repository
func configureRepository(repo *egit.ExternalGit, gitEmail string, gitUsername string) error {
err := repo.SetConfig("user.email", gitEmail)
if err != nil {
return err
}
err = repo.SetConfig("user.name", gitUsername)
if err != nil {
return err
}
return nil
}

// createRepositoryIfNotExists creates a repository if it does not exist
func createRepositoryIfNotExists(a *AzureDevOps, projectName string, repoName string, gitEmail string, gitUsername string, adoPat string) (*git.GitRepository, *string, error) {
func (a *AzureDevOps) createRepositoryIfNotExists(projectName string, repoName string, gitEmail string, gitUsername string) (*git.GitRepository, *string, error) {
client, err := git.NewClient(a.ctx, a.connection)
if err != nil {
return nil, nil, err
Expand All @@ -69,22 +54,16 @@ func createRepositoryIfNotExists(a *AzureDevOps, projectName string, repoName st
r, err := client.GetRepository(a.ctx, getRepositoryArgs)

if err == nil {
repoPath, err := os.MkdirTemp("", "")
if err != nil {
return nil, nil, err
}
repo := egit.NewGit(repoPath)
err = repo.CloneOverHttp(*r.RemoteUrl, adoPat, "x-oauth-basic")
if err != nil {
return nil, nil, err
}
err = configureRepository(repo, gitEmail, gitUsername)
repoPath, err := a.checkoutAndConfigure(*r.RemoteUrl, gitEmail, gitUsername)
if err != nil {
return nil, nil, err
}
return r, &repoPath, nil

return r, repoPath, nil
}

// TODO: Check that err is a GitRepositoryNotFound error

createRepositoryArgs := git.CreateRepositoryArgs{
GitRepositoryToCreate: &git.GitRepositoryCreateOptions{
Name: &repoName,
Expand All @@ -93,39 +72,70 @@ func createRepositoryIfNotExists(a *AzureDevOps, projectName string, repoName st
}

r, err = client.CreateRepository(a.ctx, createRepositoryArgs)
if err != nil {
return nil, nil, err
}

repoPath, err := a.initRepository(*r.RemoteUrl, gitEmail, gitUsername)
if err != nil {
return nil, nil, err
}

localPath, err := initRepository("frontierdigital", projectName, repoName, gitEmail, gitUsername, adoPat)
return r, repoPath, nil
}

func (a *AzureDevOps) checkoutAndConfigure(remoteUrl string, gitEmail string, gitUsername string) (*string, error) {
repoPath, err := os.MkdirTemp("", "")
if err != nil {
return nil, nil, err
return nil, err
}

return r, localPath, nil
repo := egit.NewGit(repoPath)
pat, err := a.GetPAT()
if err != nil {
return nil, err
}

err = repo.CloneOverHttp(remoteUrl, *pat, "x-oauth-basic")
if err != nil {
return nil, err
}

err = repo.Configure(gitEmail, gitUsername)
if err != nil {
return nil, err
}

repoPath = repo.GetRepositoryPath()

return &repoPath, nil
}

// initRepository creates a main branch
func initRepository(organisationName string, projectName string, repoName string, gitEmail string, gitUsername string, adoPat string) (*string, error) {
repoUrl := fmt.Sprintf("https://dev.azure.com/%s/%s/_git/%s", organisationName, projectName, repoName)

func (a *AzureDevOps) initRepository(remoteUrl string, gitEmail string, gitUsername string) (*string, error) {
repoPath, err := os.MkdirTemp("", "")
if err != nil {
return nil, err
}

repo := egit.NewGit(repoPath)
err = repo.CloneOverHttp(repoUrl, adoPat, "x-oauth-basic")

pat, err := a.GetPAT()
if err != nil {
return nil, err
}
err = configureRepository(repo, gitEmail, gitUsername)

err = repo.CloneOverHttp(remoteUrl, *pat, "x-oauth-basic")
if err != nil {
return nil, err
}

file, err := os.Create(filepath.Join(repoPath, "README.md"))
err = repo.Configure(gitEmail, gitUsername)
if err != nil {
return nil, err
}

file, err := os.Create(repo.GetFilePath("README.md"))
if err != nil {
return nil, err
}
Expand All @@ -136,7 +146,7 @@ func initRepository(organisationName string, projectName string, repoName string
return nil, err
}

commitMessage := "Initial Commit"
commitMessage := "Initial commit."
_, err = repo.Commit(commitMessage)
if err != nil {
return nil, err
Expand All @@ -147,7 +157,5 @@ func initRepository(organisationName string, projectName string, repoName string
return nil, err
}

output.PrintlnfInfo("Pushed.")

return &repoPath, nil
}
6 changes: 4 additions & 2 deletions azuredevops/wiki.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
)

// CreateWikiIfNotExists creates a code wiki if it does not exist.
func (a *AzureDevOps) CreateWikiIfNotExists(projectName string, wikiName string, gitEmail string, gitUsername string, adoPat string) (*string, error) {
func (a *AzureDevOps) CreateWikiIfNotExists(projectName string, wikiName string, gitEmail string, gitUsername string) (*string, error) {
client, err := wiki.NewClient(a.ctx, a.connection)
if err != nil {
return nil, err
Expand All @@ -17,7 +17,7 @@ func (a *AzureDevOps) CreateWikiIfNotExists(projectName string, wikiName string,
WikiIdentifier: &wikiName,
}

r, localPath, err := createRepositoryIfNotExists(a, projectName, wikiName, gitEmail, gitUsername, adoPat)
r, localPath, err := a.createRepositoryIfNotExists(projectName, wikiName, gitEmail, gitUsername)
if err != nil {
return nil, err
}
Expand All @@ -28,6 +28,8 @@ func (a *AzureDevOps) CreateWikiIfNotExists(projectName string, wikiName string,
return localPath, nil
}

// TODO: Check that this is a WikiNotFoundError

projectId, err := a.getProjectUUID(projectName)
if err != nil {
return nil, err
Expand Down
15 changes: 15 additions & 0 deletions git/external_git/config.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
package external_git

// Configure configures the repository
func (g *ExternalGit) Configure(gitEmail string, gitUsername string) error {
err := g.SetConfig("user.email", gitEmail)
if err != nil {
return err
}

err = g.SetConfig("user.name", gitUsername)
if err != nil {
return err
}

return nil
}

// SetConfig sets the value for the given key
func (g *ExternalGit) SetConfig(key string, value string) error {
_, err := g.Exec("config", "--local", key, value)
Expand Down
3 changes: 3 additions & 0 deletions git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ package git

type Git interface {
Add(path string) error
AddAll() error
Checkout(branchName string, create bool) error
CloneOverHttp(url string, username string, password string) error
Commit(message string) (string, error)
Configure(gitEmail string, gitUsername string) error
GetFilePath(filePath string) string
GetRepositoryPath() string
Push(force bool) error
SetConfig(key string, value string) error
}

0 comments on commit 3fc7b22

Please sign in to comment.