mukan-ignite/ignite/pkg/xgit/xgit_test.go
Mukan Erkin Törük 26b204bd04
Some checks are pending
Docs Deploy / build_and_deploy (push) Waiting to run
Generate Docs / cli (push) Waiting to run
Generate Config Doc / cli (push) Waiting to run
Go formatting / go-formatting (push) Waiting to run
Check links / markdown-link-check (push) Waiting to run
Integration / pre-test (push) Waiting to run
Integration / test on (push) Blocked by required conditions
Integration / status (push) Blocked by required conditions
Lint / Lint Go code (push) Waiting to run
Test / test (ubuntu-latest) (push) Waiting to run
feat: fork Ignite CLI v29 as Mukan Ignite — remove cosmos-sdk restrictions
2026-05-11 03:31:37 +03:00

445 lines
12 KiB
Go

package xgit_test
import (
"context"
"fmt"
"os"
"path"
"testing"
"time"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/ignite/cli/v29/ignite/pkg/randstr"
"github.com/ignite/cli/v29/ignite/pkg/xgit"
)
func TestInitAndCommit(t *testing.T) {
tests := []struct {
name string
dirFunc func(*testing.T) string
expectDotGitFolder bool
expectedNumCommits int
expectedFilesInCommit []string
}{
{
name: "dir is not inside an existing repo",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
err := os.WriteFile(path.Join(dir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
return dir
},
expectDotGitFolder: true,
expectedNumCommits: 1,
expectedFilesInCommit: []string{"foo"},
},
{
name: "dir is inside an existing repo",
// In this repo, there's no existing commit but a standalone uncommitted
// foo file that shouldn't be included in the xgit.InitAndCommit's commit.
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
dirInsideRepo := path.Join(dir, "bar")
err = os.Mkdir(dirInsideRepo, 0o0755)
require.NoError(t, err)
err = os.WriteFile(path.Join(dirInsideRepo, "baz"), []byte("hello"), 0o755)
require.NoError(t, err)
return dirInsideRepo
},
expectDotGitFolder: false,
expectedNumCommits: 1,
expectedFilesInCommit: []string{"bar/baz"},
},
{
name: "dir is an existing repo",
dirFunc: func(t *testing.T) string {
t.Helper()
// In this repo, there's one existing commit, and an uncommitted baz file
// that must be included in the xgit.InitAndCommit's commit.
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
repo, err := git.PlainOpenWithOptions(dir, &git.PlainOpenOptions{})
require.NoError(t, err)
wt, err := repo.Worktree()
require.NoError(t, err)
_, err = wt.Add(".")
require.NoError(t, err)
_, err = wt.Commit("First commit", &git.CommitOptions{
Author: &object.Signature{},
})
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "bar"), []byte("hello"), 0o755)
require.NoError(t, err)
return dir
},
expectDotGitFolder: true,
expectedNumCommits: 2,
expectedFilesInCommit: []string{"bar"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := tt.dirFunc(t)
err := xgit.InitAndCommit(dir)
require.NoError(t, err)
_, err = os.Stat(path.Join(dir, ".git"))
require.Equal(t, tt.expectDotGitFolder, !os.IsNotExist(err))
// Assert repository commits. For that we need to open the repo and
// iterate over existing commits.
repo, err := git.PlainOpenWithOptions(dir, &git.PlainOpenOptions{
DetectDotGit: true,
})
require.NoError(t, err)
logs, err := repo.Log(&git.LogOptions{})
require.NoError(t, err)
var (
numCommits int
lastCommit *object.Commit
)
err = logs.ForEach(func(c *object.Commit) error {
if numCommits == 0 {
lastCommit = c
}
numCommits++
return nil
})
require.NoError(t, err)
require.Equal(t, tt.expectedNumCommits, numCommits)
if assert.NotNil(t, lastCommit) {
require.Equal(t, "Initialized with Ignite CLI", lastCommit.Message)
require.WithinDuration(t, time.Now(), lastCommit.Committer.When, 10*time.Second)
require.Equal(t, "Developer Experience team at Ignite", lastCommit.Author.Name)
require.Equal(t, "hello@ignite.com", lastCommit.Author.Email)
stats, err := lastCommit.Stats()
require.NoError(t, err)
var files []string
for _, s := range stats {
files = append(files, s.Name)
}
require.Equal(t, tt.expectedFilesInCommit, files)
}
})
}
}
func TestAreChangesCommitted(t *testing.T) {
tests := []struct {
name string
dirFunc func(*testing.T) string
expectedResult bool
}{
{
name: "dir is not a git repo",
dirFunc: func(t *testing.T) string {
t.Helper()
return t.TempDir()
},
expectedResult: true,
},
{
name: "dir is a empty git repo",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
return dir
},
expectedResult: true,
},
{
name: "dir is a dirty empty git repo",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
return dir
},
expectedResult: false,
},
{
name: "dir is a cleaned git repo",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
repo, err := git.PlainOpenWithOptions(dir, &git.PlainOpenOptions{})
require.NoError(t, err)
wt, err := repo.Worktree()
require.NoError(t, err)
_, err = wt.Add(".")
require.NoError(t, err)
_, err = wt.Commit("First commit", &git.CommitOptions{
Author: &object.Signature{},
})
require.NoError(t, err)
return dir
},
expectedResult: true,
},
{
name: "dir is a dirty git repo",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
repo, err := git.PlainOpenWithOptions(dir, &git.PlainOpenOptions{})
require.NoError(t, err)
wt, err := repo.Worktree()
require.NoError(t, err)
_, err = wt.Add(".")
require.NoError(t, err)
_, err = wt.Commit("First commit", &git.CommitOptions{
Author: &object.Signature{},
})
require.NoError(t, err)
err = os.WriteFile(path.Join(dir, "bar"), []byte("hello"), 0o755)
require.NoError(t, err)
return dir
},
expectedResult: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
dir := tt.dirFunc(t)
res, err := xgit.AreChangesCommitted(dir)
require.NoError(t, err)
assert.Equal(t, tt.expectedResult, res)
})
}
}
func TestClone(t *testing.T) {
// Create a folder with content
notEmptyDir := t.TempDir()
err := os.WriteFile(path.Join(notEmptyDir, ".foo"), []byte("hello"), 0o755)
require.NoError(t, err)
// Create a local git repo for all the test cases
repoDir := t.TempDir()
repo, err := git.PlainInit(repoDir, false)
require.NoError(t, err)
err = os.WriteFile(path.Join(repoDir, "foo"), []byte("hello"), 0o755)
require.NoError(t, err)
// Add a first commit
w, err := repo.Worktree()
require.NoError(t, err)
_, err = w.Add(".")
require.NoError(t, err)
commit1, err := w.Commit("commit1", &git.CommitOptions{
Author: &object.Signature{
Name: "bob",
Email: "bob@example.com",
When: time.Now(),
},
})
// Add a branch on commit1
require.NoError(t, err)
err = w.Checkout(&git.CheckoutOptions{
Branch: plumbing.NewBranchReferenceName("my-branch"),
Create: true,
})
require.NoError(t, err)
// Back to master
err = w.Checkout(&git.CheckoutOptions{Branch: plumbing.NewBranchReferenceName("master")})
require.NoError(t, err)
// Add a tag on commit1
_, err = repo.CreateTag("v1", commit1, &git.CreateTagOptions{
Tagger: &object.Signature{Name: "me"},
Message: "v1",
})
require.NoError(t, err)
// Add a second commit
err = os.WriteFile(path.Join(repoDir, "bar"), []byte("hello"), 0o755)
require.NoError(t, err)
_, err = w.Add(".")
require.NoError(t, err)
commit2, err := w.Commit("commit2", &git.CommitOptions{
Author: &object.Signature{
Name: "bob",
Email: "bob@example.com",
When: time.Now(),
},
})
require.NoError(t, err)
tests := []struct {
name string
dir string
urlRef string
expectedError string
expectedRef plumbing.Hash
}{
{
name: "fail: repo doesn't exist",
dir: t.TempDir(),
urlRef: "/tmp/not/exists",
expectedError: "repository not found",
},
{
name: "fail: target dir isn't empty",
dir: notEmptyDir,
urlRef: repoDir,
expectedError: fmt.Sprintf(`clone: target directory "%s" is not empty`, notEmptyDir),
},
{
name: "ok: target dir doesn't exists",
dir: "/tmp/not/exists/" + randstr.Runes(6),
urlRef: repoDir,
expectedRef: commit2,
},
{
name: "ok: no ref",
dir: t.TempDir(),
urlRef: repoDir,
expectedRef: commit2,
},
{
name: "ok: empty ref",
dir: t.TempDir(),
urlRef: repoDir + "@",
expectedRef: commit2,
},
{
name: "ok: with tag ref",
dir: t.TempDir(),
urlRef: repoDir + "@v1",
expectedRef: commit1,
},
{
name: "ok: with branch ref",
dir: t.TempDir(),
urlRef: repoDir + "@my-branch",
expectedRef: commit1,
},
{
name: "ok: with commit1 hash ref",
dir: t.TempDir(),
urlRef: repoDir + "@" + commit1.String(),
expectedRef: commit1,
},
{
name: "ok: with commit2 hash ref",
dir: t.TempDir(),
urlRef: repoDir + "@" + commit2.String(),
expectedRef: commit2,
},
{
name: "fail: ref not found",
dir: t.TempDir(),
urlRef: repoDir + "@what",
expectedError: "reference not found",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var (
files, _ = os.ReadDir(tt.dir)
dirWasEmpty = len(files) == 0
)
err := xgit.Clone(context.Background(), tt.urlRef, tt.dir)
if tt.expectedError != "" {
require.EqualError(t, err, tt.expectedError)
if dirWasEmpty {
// If it was empty, ensure target dir is still clean
files, _ := os.ReadDir(tt.dir)
require.Empty(t, files, "target dir should be empty in case of error")
}
return
}
require.NoError(t, err)
_, err = os.Stat(tt.dir)
require.False(t, os.IsNotExist(err), "dir %s should exist", tt.dir)
repo, err := git.PlainOpen(tt.dir)
require.NoError(t, err)
h, err := repo.Head()
require.NoError(t, err)
require.Equal(t, tt.expectedRef, h.Hash())
})
}
}
func TestIsRepository(t *testing.T) {
tests := []struct {
name string
dirFunc func(*testing.T) string
shouldFail bool
expected bool
}{
{
name: "path is a repository",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
_, err := git.PlainInit(dir, false)
require.NoError(t, err)
return dir
},
expected: true,
},
{
name: "path is not a repository",
dirFunc: func(t *testing.T) string {
t.Helper()
return t.TempDir()
},
expected: false,
},
{
name: "repository error",
dirFunc: func(t *testing.T) string {
t.Helper()
dir := t.TempDir()
err := os.Chmod(dir, 0)
require.NoError(t, err)
return dir
},
shouldFail: true,
expected: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Act
exists, err := xgit.IsRepository(tt.dirFunc(t))
// Assert
require.Equal(t, tt.expected, exists)
if tt.shouldFail {
require.Error(t, err)
} else {
require.NoError(t, err)
}
})
}
}