github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/testutil/fakecontext/context.go (about)

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