github.1485827954.workers.dev/nektos/act@v0.2.63/pkg/filecollector/file_collector_test.go (about) 1 package filecollector 2 3 import ( 4 "archive/tar" 5 "context" 6 "io" 7 "path/filepath" 8 "strings" 9 "testing" 10 11 "github.com/go-git/go-billy/v5" 12 "github.com/go-git/go-billy/v5/memfs" 13 git "github.com/go-git/go-git/v5" 14 "github.com/go-git/go-git/v5/plumbing/cache" 15 "github.com/go-git/go-git/v5/plumbing/format/gitignore" 16 "github.com/go-git/go-git/v5/plumbing/format/index" 17 "github.com/go-git/go-git/v5/storage/filesystem" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 type memoryFs struct { 22 billy.Filesystem 23 } 24 25 func (mfs *memoryFs) walk(root string, fn filepath.WalkFunc) error { 26 dir, err := mfs.ReadDir(root) 27 if err != nil { 28 return err 29 } 30 for i := 0; i < len(dir); i++ { 31 filename := filepath.Join(root, dir[i].Name()) 32 err = fn(filename, dir[i], nil) 33 if dir[i].IsDir() { 34 if err == filepath.SkipDir { 35 err = nil 36 } else if err := mfs.walk(filename, fn); err != nil { 37 return err 38 } 39 } 40 if err != nil { 41 return err 42 } 43 } 44 return nil 45 } 46 47 func (mfs *memoryFs) Walk(root string, fn filepath.WalkFunc) error { 48 stat, err := mfs.Lstat(root) 49 if err != nil { 50 return err 51 } 52 err = fn(strings.Join([]string{root, "."}, string(filepath.Separator)), stat, nil) 53 if err != nil { 54 return err 55 } 56 return mfs.walk(root, fn) 57 } 58 59 func (mfs *memoryFs) OpenGitIndex(path string) (*index.Index, error) { 60 f, _ := mfs.Filesystem.Chroot(filepath.Join(path, ".git")) 61 storage := filesystem.NewStorage(f, cache.NewObjectLRUDefault()) 62 i, err := storage.Index() 63 if err != nil { 64 return nil, err 65 } 66 return i, nil 67 } 68 69 func (mfs *memoryFs) Open(path string) (io.ReadCloser, error) { 70 return mfs.Filesystem.Open(path) 71 } 72 73 func (mfs *memoryFs) Readlink(path string) (string, error) { 74 return mfs.Filesystem.Readlink(path) 75 } 76 77 func TestIgnoredTrackedfile(t *testing.T) { 78 fs := memfs.New() 79 _ = fs.MkdirAll("mygitrepo/.git", 0o777) 80 dotgit, _ := fs.Chroot("mygitrepo/.git") 81 worktree, _ := fs.Chroot("mygitrepo") 82 repo, _ := git.Init(filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()), worktree) 83 f, _ := worktree.Create(".gitignore") 84 _, _ = f.Write([]byte(".*\n")) 85 f.Close() 86 // This file shouldn't be in the tar 87 f, _ = worktree.Create(".env") 88 _, _ = f.Write([]byte("test=val1\n")) 89 f.Close() 90 w, _ := repo.Worktree() 91 // .gitignore is in the tar after adding it to the index 92 _, _ = w.Add(".gitignore") 93 94 tmpTar, _ := fs.Create("temp.tar") 95 tw := tar.NewWriter(tmpTar) 96 ps, _ := gitignore.ReadPatterns(worktree, []string{}) 97 ignorer := gitignore.NewMatcher(ps) 98 fc := &FileCollector{ 99 Fs: &memoryFs{Filesystem: fs}, 100 Ignorer: ignorer, 101 SrcPath: "mygitrepo", 102 SrcPrefix: "mygitrepo" + string(filepath.Separator), 103 Handler: &TarCollector{ 104 TarWriter: tw, 105 }, 106 } 107 err := fc.Fs.Walk("mygitrepo", fc.CollectFiles(context.Background(), []string{})) 108 assert.NoError(t, err, "successfully collect files") 109 tw.Close() 110 _, _ = tmpTar.Seek(0, io.SeekStart) 111 tr := tar.NewReader(tmpTar) 112 h, err := tr.Next() 113 assert.NoError(t, err, "tar must not be empty") 114 assert.Equal(t, ".gitignore", h.Name) 115 _, err = tr.Next() 116 assert.ErrorIs(t, err, io.EOF, "tar must only contain one element") 117 } 118 119 func TestSymlinks(t *testing.T) { 120 fs := memfs.New() 121 _ = fs.MkdirAll("mygitrepo/.git", 0o777) 122 dotgit, _ := fs.Chroot("mygitrepo/.git") 123 worktree, _ := fs.Chroot("mygitrepo") 124 repo, _ := git.Init(filesystem.NewStorage(dotgit, cache.NewObjectLRUDefault()), worktree) 125 // This file shouldn't be in the tar 126 f, err := worktree.Create(".env") 127 assert.NoError(t, err) 128 _, err = f.Write([]byte("test=val1\n")) 129 assert.NoError(t, err) 130 f.Close() 131 err = worktree.Symlink(".env", "test.env") 132 assert.NoError(t, err) 133 134 w, err := repo.Worktree() 135 assert.NoError(t, err) 136 137 // .gitignore is in the tar after adding it to the index 138 _, err = w.Add(".env") 139 assert.NoError(t, err) 140 _, err = w.Add("test.env") 141 assert.NoError(t, err) 142 143 tmpTar, _ := fs.Create("temp.tar") 144 tw := tar.NewWriter(tmpTar) 145 ps, _ := gitignore.ReadPatterns(worktree, []string{}) 146 ignorer := gitignore.NewMatcher(ps) 147 fc := &FileCollector{ 148 Fs: &memoryFs{Filesystem: fs}, 149 Ignorer: ignorer, 150 SrcPath: "mygitrepo", 151 SrcPrefix: "mygitrepo" + string(filepath.Separator), 152 Handler: &TarCollector{ 153 TarWriter: tw, 154 }, 155 } 156 err = fc.Fs.Walk("mygitrepo", fc.CollectFiles(context.Background(), []string{})) 157 assert.NoError(t, err, "successfully collect files") 158 tw.Close() 159 _, _ = tmpTar.Seek(0, io.SeekStart) 160 tr := tar.NewReader(tmpTar) 161 h, err := tr.Next() 162 files := map[string]tar.Header{} 163 for err == nil { 164 files[h.Name] = *h 165 h, err = tr.Next() 166 } 167 168 assert.Equal(t, ".env", files[".env"].Name) 169 assert.Equal(t, "test.env", files["test.env"].Name) 170 assert.Equal(t, ".env", files["test.env"].Linkname) 171 assert.ErrorIs(t, err, io.EOF, "tar must be read cleanly to EOF") 172 }