118 lines
3 KiB
Go
118 lines
3 KiB
Go
|
package container
|
||
|
|
||
|
import (
|
||
|
"archive/tar"
|
||
|
"context"
|
||
|
"io"
|
||
|
"path/filepath"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/go-git/go-billy/v5"
|
||
|
"github.com/go-git/go-billy/v5/memfs"
|
||
|
git "github.com/go-git/go-git/v5"
|
||
|
"github.com/go-git/go-git/v5/plumbing/cache"
|
||
|
"github.com/go-git/go-git/v5/plumbing/format/gitignore"
|
||
|
"github.com/go-git/go-git/v5/plumbing/format/index"
|
||
|
"github.com/go-git/go-git/v5/storage/filesystem"
|
||
|
"github.com/stretchr/testify/assert"
|
||
|
)
|
||
|
|
||
|
type memoryFs struct {
|
||
|
billy.Filesystem
|
||
|
}
|
||
|
|
||
|
func (mfs *memoryFs) walk(root string, fn filepath.WalkFunc) error {
|
||
|
dir, err := mfs.ReadDir(root)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
for i := 0; i < len(dir); i++ {
|
||
|
filename := filepath.Join(root, dir[i].Name())
|
||
|
err = fn(filename, dir[i], nil)
|
||
|
if dir[i].IsDir() {
|
||
|
if err == filepath.SkipDir {
|
||
|
err = nil
|
||
|
} else if err := mfs.walk(filename, fn); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func (mfs *memoryFs) Walk(root string, fn filepath.WalkFunc) error {
|
||
|
stat, err := mfs.Lstat(root)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
err = fn(strings.Join([]string{root, "."}, string(filepath.Separator)), stat, nil)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return mfs.walk(root, fn)
|
||
|
}
|
||
|
|
||
|
func (mfs *memoryFs) OpenGitIndex(path string) (*index.Index, error) {
|
||
|
f, _ := mfs.Filesystem.Chroot(filepath.Join(path, ".git"))
|
||
|
storage := filesystem.NewStorage(f, cache.NewObjectLRUDefault())
|
||
|
i, err := storage.Index()
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
return i, nil
|
||
|
}
|
||
|
|
||
|
func (mfs *memoryFs) Open(path string) (io.ReadCloser, error) {
|
||
|
return mfs.Filesystem.Open(path)
|
||
|
}
|
||
|
|
||
|
func (mfs *memoryFs) Readlink(path string) (string, error) {
|
||
|
return mfs.Filesystem.Readlink(path)
|
||
|
}
|
||
|
|
||
|
func TestIgnoredTrackedfile(t *testing.T) {
|
||
|
fs := memfs.New()
|
||
|
_ = fs.MkdirAll("mygitrepo/.git", 0777)
|
||
|
dotgit, _ := fs.Chroot("mygitrepo/.git")
|
||
|
worktree, _ := fs.Chroot("mygitrepo")
|
||
|
repo, _ := git.Init(filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()), worktree)
|
||
|
f, _ := worktree.Create(".gitignore")
|
||
|
_, _ = f.Write([]byte(".*\n"))
|
||
|
f.Close()
|
||
|
// This file shouldn't be in the tar
|
||
|
f, _ = worktree.Create(".env")
|
||
|
_, _ = f.Write([]byte("test=val1\n"))
|
||
|
f.Close()
|
||
|
w, _ := repo.Worktree()
|
||
|
// .gitignore is in the tar after adding it to the index
|
||
|
_, _ = w.Add(".gitignore")
|
||
|
|
||
|
tmpTar, _ := fs.Create("temp.tar")
|
||
|
tw := tar.NewWriter(tmpTar)
|
||
|
ps, _ := gitignore.ReadPatterns(worktree, []string{})
|
||
|
ignorer := gitignore.NewMatcher(ps)
|
||
|
fc := &fileCollector{
|
||
|
Fs: &memoryFs{Filesystem: fs},
|
||
|
Ignorer: ignorer,
|
||
|
SrcPath: "mygitrepo",
|
||
|
SrcPrefix: "mygitrepo" + string(filepath.Separator),
|
||
|
Handler: &tarCollector{
|
||
|
TarWriter: tw,
|
||
|
},
|
||
|
}
|
||
|
err := fc.Fs.Walk("mygitrepo", fc.collectFiles(context.Background(), []string{}))
|
||
|
assert.NoError(t, err, "successfully collect files")
|
||
|
tw.Close()
|
||
|
_, _ = tmpTar.Seek(0, io.SeekStart)
|
||
|
tr := tar.NewReader(tmpTar)
|
||
|
h, err := tr.Next()
|
||
|
assert.NoError(t, err, "tar must not be empty")
|
||
|
assert.Equal(t, ".gitignore", h.Name)
|
||
|
_, err = tr.Next()
|
||
|
assert.ErrorIs(t, err, io.EOF, "tar must only contain one element")
|
||
|
}
|