github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/testutil/fakecontext/context.go (about)

     1  package fakecontext // import "github.com/docker/docker/testutil/fakecontext"
     2  
     3  import (
     4  	"bytes"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"github.com/docker/docker/pkg/archive"
    11  )
    12  
    13  // New creates a fake build context
    14  func New(t testing.TB, dir string, modifiers ...func(*Fake) error) *Fake {
    15  	t.Helper()
    16  	fakeContext := &Fake{Dir: dir}
    17  	if dir == "" {
    18  		if err := newDir(fakeContext); err != nil {
    19  			t.Fatal(err)
    20  		}
    21  	}
    22  
    23  	for _, modifier := range modifiers {
    24  		if err := modifier(fakeContext); err != nil {
    25  			t.Fatal(err)
    26  		}
    27  	}
    28  
    29  	return fakeContext
    30  }
    31  
    32  func newDir(fake *Fake) error {
    33  	tmp, err := os.MkdirTemp("", "fake-context")
    34  	if err != nil {
    35  		return err
    36  	}
    37  	if err := os.Chmod(tmp, 0755); err != nil {
    38  		return err
    39  	}
    40  	fake.Dir = tmp
    41  	return nil
    42  }
    43  
    44  // WithFile adds the specified file (with content) in the build context
    45  func WithFile(name, content string) func(*Fake) error {
    46  	return func(ctx *Fake) error {
    47  		return ctx.Add(name, content)
    48  	}
    49  }
    50  
    51  // WithDockerfile adds the specified content as Dockerfile in the build context
    52  func WithDockerfile(content string) func(*Fake) error {
    53  	return WithFile("Dockerfile", content)
    54  }
    55  
    56  // WithFiles adds the specified files in the build context, content is a string
    57  func WithFiles(files map[string]string) func(*Fake) error {
    58  	return func(fakeContext *Fake) error {
    59  		for file, content := range files {
    60  			if err := fakeContext.Add(file, content); err != nil {
    61  				return err
    62  			}
    63  		}
    64  		return nil
    65  	}
    66  }
    67  
    68  // WithBinaryFiles adds the specified files in the build context, content is binary
    69  func WithBinaryFiles(files map[string]*bytes.Buffer) func(*Fake) error {
    70  	return func(fakeContext *Fake) error {
    71  		for file, content := range files {
    72  			if err := fakeContext.Add(file, content.String()); err != nil {
    73  				return err
    74  			}
    75  		}
    76  		return nil
    77  	}
    78  }
    79  
    80  // Fake creates directories that can be used as a build context
    81  type Fake struct {
    82  	Dir string
    83  }
    84  
    85  // Add a file at a path, creating directories where necessary
    86  func (f *Fake) Add(file, content string) error {
    87  	return f.addFile(file, []byte(content))
    88  }
    89  
    90  func (f *Fake) addFile(file string, content []byte) error {
    91  	fp := filepath.Join(f.Dir, filepath.FromSlash(file))
    92  	dirpath := filepath.Dir(fp)
    93  	if dirpath != "." {
    94  		if err := os.MkdirAll(dirpath, 0755); err != nil {
    95  			return err
    96  		}
    97  	}
    98  	return os.WriteFile(fp, content, 0644)
    99  }
   100  
   101  // Delete a file at a path
   102  func (f *Fake) Delete(file string) error {
   103  	fp := filepath.Join(f.Dir, filepath.FromSlash(file))
   104  	return os.RemoveAll(fp)
   105  }
   106  
   107  // Close deletes the context
   108  func (f *Fake) Close() error {
   109  	return os.RemoveAll(f.Dir)
   110  }
   111  
   112  // AsTarReader returns a ReadCloser with the contents of Dir as a tar archive.
   113  func (f *Fake) AsTarReader(t testing.TB) io.ReadCloser {
   114  	t.Helper()
   115  	reader, err := archive.TarWithOptions(f.Dir, &archive.TarOptions{})
   116  	if err != nil {
   117  		t.Fatalf("Failed to create tar from %s: %s", f.Dir, err)
   118  	}
   119  	return reader
   120  }