Skip to content

Commit

Permalink
Refactor for full in-memory support
Browse files Browse the repository at this point in the history
The refactoring achieves a few goals:
- Support for fully in-memory execution, without the need of extracting
tgz files into disk.
- Removal of the deprecated check.v1 dependency.

Signed-off-by: Paulo Gomes <[email protected]>
  • Loading branch information
pjbgf committed Apr 8, 2024
1 parent c0d4342 commit 414d44e
Show file tree
Hide file tree
Showing 11 changed files with 304 additions and 280 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ jobs:

runs-on: ${{ matrix.platform }}
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install Go
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}

- name: Checkout code
uses: actions/checkout@v4
go-version: ${{ matrix.go-version }}

- name: Test
run: make test
101 changes: 28 additions & 73 deletions fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,11 @@ import (
"testing"

"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git-fixtures/v4/internal/embedfs"
"github.com/go-git/go-git-fixtures/v4/internal/tgz"
"gopkg.in/check.v1"
)

var (
files = make(map[string]string)
Filesystem = osfs.New(os.TempDir())
)
var Filesystem = embedfs.New(&data)

//go:embed data
var data embed.FS
Expand Down Expand Up @@ -231,35 +227,8 @@ func (f *Fixture) Is(tag string) bool {
return false
}

func (f *Fixture) file(path string) (billy.File, error) {
if fpath, ok := files[path]; ok {
return Filesystem.Open(fpath)
}

bytes, err := data.ReadFile("data/" + path)
if err != nil {
return nil, err
}

file, err := Filesystem.TempFile("", "go-git-fixtures")
if err != nil {
return nil, err
}

if _, err := file.Write(bytes); err != nil {
return nil, err
}

if err := file.Close(); err != nil {
return nil, err
}

files[path] = file.Name()
return Filesystem.Open(file.Name())
}

func (f *Fixture) Packfile() billy.File {
file, err := f.file(fmt.Sprintf("pack-%s.pack", f.PackfileHash))
file, err := Filesystem.Open(fmt.Sprintf("data/pack-%s.pack", f.PackfileHash))
if err != nil {
panic(err)
}
Expand All @@ -268,7 +237,7 @@ func (f *Fixture) Packfile() billy.File {
}

func (f *Fixture) Idx() billy.File {
file, err := f.file(fmt.Sprintf("pack-%s.idx", f.PackfileHash))
file, err := Filesystem.Open(fmt.Sprintf("data/pack-%s.idx", f.PackfileHash))
if err != nil {
panic(err)
}
Expand All @@ -277,7 +246,7 @@ func (f *Fixture) Idx() billy.File {
}

func (f *Fixture) Rev() billy.File {
file, err := f.file(fmt.Sprintf("pack-%s.rev", f.PackfileHash))
file, err := Filesystem.Open(fmt.Sprintf("data/pack-%s.rev", f.PackfileHash))
if err != nil {
panic(err)
}
Expand All @@ -287,18 +256,23 @@ func (f *Fixture) Rev() billy.File {

// DotGit creates a new temporary directory and unpacks the repository .git
// directory into it. Multiple calls to DotGit returns different directories.
func (f *Fixture) DotGit() billy.Filesystem {
func (f *Fixture) DotGit(opts ...Option) billy.Filesystem {
o := newOptions()
for _, opt := range opts {
opt(o)
}

if f.DotGitHash == "" && f.WorktreeHash != "" {
fs, _ := f.Worktree().Chroot(".git")
fs, _ := f.Worktree(opts...).Chroot(".git")
return fs.(billy.Filesystem)
}

file, err := f.file(fmt.Sprintf("git-%s.tgz", f.DotGitHash))
file, err := Filesystem.Open(fmt.Sprintf("data/git-%s.tgz", f.DotGitHash))
if err != nil {
panic(err)
}

fs, err, _ := tgz.Extract(Filesystem, file.Name())
fs, err := tgz.Extract(file, o.fsFactory)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -332,13 +306,18 @@ func EnsureIsBare(fs billy.Filesystem) error {
return err
}

func (f *Fixture) Worktree() billy.Filesystem {
file, err := f.file(fmt.Sprintf("worktree-%s.tgz", f.WorktreeHash))
func (f *Fixture) Worktree(opts ...Option) billy.Filesystem {
o := newOptions()
for _, opt := range opts {
opt(o)
}

file, err := Filesystem.Open(fmt.Sprintf("data/worktree-%s.tgz", f.WorktreeHash))
if err != nil {
panic(err)
}

fs, err, _ := tgz.Extract(Filesystem, file.Name())
fs, err := tgz.Extract(file, o.fsFactory)
if err != nil {
panic(err)
}
Expand All @@ -348,15 +327,6 @@ func (f *Fixture) Worktree() billy.Filesystem {

type Fixtures []*Fixture

// Deprecated as part of removing check from the code base.
// Use Run instead.
func (g Fixtures) Test(c *check.C, test func(*Fixture)) {
for _, f := range g {
c.Logf("executing test at %s %s", f.URL, f.Tags)
test(f)
}
}

// Run calls test within a t.Run for each fixture in g.
func (g Fixtures) Run(t *testing.T, test func(*testing.T, *Fixture)) {
for _, f := range g {
Expand All @@ -368,11 +338,14 @@ func (g Fixtures) Run(t *testing.T, test func(*testing.T, *Fixture)) {
}

func (g Fixtures) One() *Fixture {
if len(g) == 0 {
return nil
}
return g[0]
}

func (g Fixtures) ByTag(tag string) Fixtures {
r := make(Fixtures, 0)
r := make(Fixtures, 0, len(g))
for _, f := range g {
if f.Is(tag) {
r = append(r, f)
Expand All @@ -383,7 +356,7 @@ func (g Fixtures) ByTag(tag string) Fixtures {
}

func (g Fixtures) ByURL(url string) Fixtures {
r := make(Fixtures, 0)
r := make(Fixtures, 0, len(g))
for _, f := range g {
if f.URL == url {
r = append(r, f)
Expand All @@ -394,7 +367,7 @@ func (g Fixtures) ByURL(url string) Fixtures {
}

func (g Fixtures) Exclude(tag string) Fixtures {
r := make(Fixtures, 0)
r := make(Fixtures, 0, len(g))
for _, f := range g {
if !f.Is(tag) {
r = append(r, f)
Expand All @@ -403,21 +376,3 @@ func (g Fixtures) Exclude(tag string) Fixtures {

return r
}

// Clean cleans all the temporal files created
func Clean() error {
for fname, f := range files {
if err := Filesystem.Remove(f); err != nil {
return err
}
delete(files, fname)
}
return nil
}

type Suite struct{}

// Deprecated as part of removing check from the code base.
func (s *Suite) TearDownSuite(c *check.C) {
Clean()
}
53 changes: 53 additions & 0 deletions fixtures_options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package fixtures

import (
"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/osfs"
"github.com/go-git/go-git-fixtures/v4/internal/tgz"
)

const (
useDefaultTempDir = ""
tmpPrefix = "tmp-tgz-"
)

type Option func(*options)

type options struct {
fsFactory func() (billy.Filesystem, error)
}

func newOptions() *options {
return &options{
fsFactory: tgz.MemFactory,
}
}

// WithMemFS returns the option of using memfs for the fs created for Fixtures.
func WithMemFS() Option {
return func(o *options) {
o.fsFactory = tgz.MemFactory
}
}

// WithTargetDir returns the option of using an OS-based filesystem based on a target dir.
// The target dir will be based on the name returned from dirName, which aligns with tempdir
// functions in different testing frameworks (e.g. t.TempDir, c.MkDir).
//
// The caller is responsible for removing the dir from disk. Therefore, it is recommended
// to delegate that to the testing framework:
//
// Go:
//
// WithTargetDir(t.TempDir)
//
// Check Framework:
//
// WithTargetDir(c.Mkdir)
func WithTargetDir(dirName func() string) Option {
return func(o *options) {
o.fsFactory = func() (billy.Filesystem, error) {
return osfs.New(dirName(), osfs.WithChrootOS()), nil
}
}
}
28 changes: 20 additions & 8 deletions fixtures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,15 @@ import (
)

func TestDotGit(t *testing.T) {
fs := Basic().One().DotGit()
fs := Basic().One().DotGit(WithTargetDir(t.TempDir))
files, err := fs.ReadDir("/")
assert.NoError(t, err)
assert.True(t, len(files) > 1)

fs = Basic().One().DotGit(WithMemFS())
files, err = fs.ReadDir("/")
assert.NoError(t, err)
assert.True(t, len(files) > 1)
}

func TestEmbeddedFiles(t *testing.T) {
Expand All @@ -26,14 +31,22 @@ func TestEmbeddedFiles(t *testing.T) {
}

if f.WorktreeHash != "" {
if f.Worktree() == nil {
assert.Fail(t, "failed to get worktree", i)
if f.Worktree(WithMemFS()) == nil {
assert.Fail(t, "[mem] failed to get worktree", i)
}

if f.Worktree(WithTargetDir(t.TempDir)) == nil {
assert.Fail(t, "[tempdir] failed to get worktree", i)
}
}

if f.DotGitHash != "" {
if f.DotGit() == nil {
assert.Fail(t, "failed to get dotgit", i)
if f.DotGit(WithMemFS()) == nil {
assert.Fail(t, "[mem] failed to get dotgit", i)
}

if f.DotGit(WithTargetDir(t.TempDir)) == nil {
assert.Fail(t, "[tempdir] failed to get dotgit", i)
}
}
}
Expand All @@ -42,7 +55,6 @@ func TestEmbeddedFiles(t *testing.T) {
func TestRevFiles(t *testing.T) {
f := ByTag("packfile-sha256").One()

if f.Rev() == nil {
assert.Fail(t, "failed to get rev file")
}
assert.NotNil(t, f)
assert.NotNil(t, f.Rev(), "failed to get rev file")
}
4 changes: 0 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@ go 1.20
require (
github.com/go-git/go-billy/v5 v5.5.0
github.com/stretchr/testify v1.9.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
)

require (
github.com/cyphar/filepath-securejoin v0.2.4 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
golang.org/x/sys v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
10 changes: 0 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,25 +1,16 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
Expand All @@ -28,6 +19,5 @@ golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Loading

0 comments on commit 414d44e

Please sign in to comment.