asdf/internal/git/git_test.go
Trevor Brown b9e79e6456 feat(golang-rewrite): misc. version improvements part 2
* Remove old commands from help output
* Add message to `asdf update` command
* Explain why `asdf global` and `asdf local` have been removed
* Add reference argument to `git.Repoer.Clone` method
* Update `asdf plugin test` command to install specific ref of plugin if provided
* Update `asdf plugin update` command to run pre and post plugin update hooks, and `post-plugin-update` plugin callback
* Enable `plugin_update_command.bats` tests
2024-12-18 11:32:04 -05:00

229 lines
5.7 KiB
Go

package git
import (
"os"
"path/filepath"
"testing"
"github.com/asdf-vm/asdf/repotest"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/stretchr/testify/assert"
)
func TestRepoClone(t *testing.T) {
t.Run("when repo name is valid but URL is invalid prints an error", func(t *testing.T) {
repo := NewRepo(t.TempDir())
err := repo.Clone("foobar", "")
assert.ErrorContains(t, err, "unable to clone plugin: repository not found")
})
t.Run("clones provided Git URL to repo directory when URL is valid", func(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
repo := NewRepo(directory)
err := repo.Clone(repoDir, "")
assert.Nil(t, err)
// Assert repo directory contains Git repo with bin directory
_, err = os.ReadDir(directory + "/.git")
assert.Nil(t, err)
entries, err := os.ReadDir(directory + "/bin")
assert.Nil(t, err)
assert.Equal(t, 12, len(entries))
})
t.Run("when repo name and URL are valid but ref is invalid prints an error", func(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
repo := NewRepo(directory)
err := repo.Clone(repoDir, "non-existent")
assert.ErrorContains(t, err, "unable to clone plugin: reference not found")
})
t.Run("clones a provided Git URL and checks out a specific ref when URL is valid and ref is provided", func(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
repo := NewRepo(directory)
err := repo.Clone(repoDir, "master")
assert.Nil(t, err)
// Assert repo directory contains Git repo with bin directory
_, err = os.ReadDir(directory + "/.git")
assert.Nil(t, err)
entries, err := os.ReadDir(directory + "/bin")
assert.Nil(t, err)
assert.Equal(t, 12, len(entries))
})
}
func TestRepoHead(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
repo := NewRepo(directory)
err := repo.Clone(repoDir, "")
assert.Nil(t, err)
head, err := repo.Head()
assert.Nil(t, err)
assert.NotZero(t, head)
}
func TestRepoRemoteURL(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
repo := NewRepo(directory)
err := repo.Clone(repoDir, "")
assert.Nil(t, err)
url, err := repo.RemoteURL()
assert.Nil(t, err)
assert.NotZero(t, url)
}
func TestRepoUpdate(t *testing.T) {
repoDir := generateRepo(t)
directory := t.TempDir()
repo := NewRepo(directory)
err := repo.Clone(repoDir, "")
assert.Nil(t, err)
t.Run("returns error when repo with name does not exist", func(t *testing.T) {
nonexistantPath := filepath.Join(directory, "nonexistant")
nonexistantRepo := NewRepo(nonexistantPath)
updatedToRef, _, _, err := nonexistantRepo.Update("")
assert.NotNil(t, err)
assert.Equal(t, updatedToRef, "")
expectedErrMsg := "unable to open plugin Git repository: repository does not exist"
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("returns error when repo repo does not exist", func(t *testing.T) {
badRepoName := "badrepo"
badRepoDir := filepath.Join(directory, badRepoName)
err := os.MkdirAll(badRepoDir, 0o777)
assert.Nil(t, err)
badRepo := NewRepo(badRepoDir)
updatedToRef, _, _, err := badRepo.Update("")
assert.NotNil(t, err)
assert.Equal(t, updatedToRef, "")
expectedErrMsg := "unable to open plugin Git repository: repository does not exist"
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("does not return error when repo is already updated", func(t *testing.T) {
// update repo twice to test already updated case
updatedToRef, _, _, err := repo.Update("")
assert.Nil(t, err)
updatedToRef2, _, _, err := repo.Update("")
assert.Nil(t, err)
assert.Equal(t, updatedToRef, updatedToRef2)
})
t.Run("updates repo when repo when repo exists", func(t *testing.T) {
latestHash, err := getCurrentCommit(directory)
assert.Nil(t, err)
_, err = checkoutPreviousCommit(directory)
assert.Nil(t, err)
updatedToRef, _, _, err := repo.Update("")
assert.Nil(t, err)
assert.Equal(t, "refs/heads/master", updatedToRef)
currentHash, err := getCurrentCommit(directory)
assert.Nil(t, err)
assert.Equal(t, latestHash, currentHash)
})
t.Run("Returns error when specified ref does not exist", func(t *testing.T) {
ref := "non-existant"
updatedToRef, _, _, err := repo.Update(ref)
assert.Equal(t, updatedToRef, "")
expectedErrMsg := "couldn't find remote ref \"non-existant\""
assert.ErrorContains(t, err, expectedErrMsg)
})
t.Run("updates repo to ref when repo with name and ref exist", func(t *testing.T) {
ref := "master"
hash, err := getCommit(directory, ref)
assert.Nil(t, err)
updatedToRef, _, newHash, err := repo.Update(ref)
assert.Nil(t, err)
assert.Equal(t, "master", updatedToRef)
// Check that repo was updated to ref
latestHash, err := getCurrentCommit(directory)
assert.Nil(t, err)
assert.Equal(t, hash, latestHash)
assert.Equal(t, newHash, latestHash)
})
}
func getCurrentCommit(path string) (string, error) {
return getCommit(path, "HEAD")
}
func getCommit(path, revision string) (string, error) {
repo, err := git.PlainOpen(path)
if err != nil {
return "", err
}
hash, err := repo.ResolveRevision(plumbing.Revision(revision))
return hash.String(), err
}
func checkoutPreviousCommit(path string) (string, error) {
repo, err := git.PlainOpen(path)
if err != nil {
return "", err
}
previousHash, err := repo.ResolveRevision(plumbing.Revision("HEAD~"))
if err != nil {
return "", err
}
worktree, err := repo.Worktree()
if err != nil {
return "", err
}
err = worktree.Reset(&git.ResetOptions{Commit: *previousHash})
if err != nil {
return "", err
}
return previousHash.String(), nil
}
func generateRepo(t *testing.T) string {
t.Helper()
tempDir := t.TempDir()
path, err := repotest.GeneratePlugin("dummy_plugin", tempDir, "lua")
assert.Nil(t, err)
return path
}