package fakecontext // import "github.com/docker/docker/testutil/fakecontext" import ( "bytes" "io" "os" "path/filepath" "testing" "github.com/docker/docker/pkg/archive" ) // New creates a fake build context func New(t testing.TB, dir string, modifiers ...func(*Fake) error) *Fake { t.Helper() fakeContext := &Fake{Dir: dir} if dir == "" { if err := newDir(fakeContext); err != nil { t.Fatal(err) } } for _, modifier := range modifiers { if err := modifier(fakeContext); err != nil { t.Fatal(err) } } return fakeContext } func newDir(fake *Fake) error { tmp, err := os.MkdirTemp("", "fake-context") if err != nil { return err } if err := os.Chmod(tmp, 0o755); err != nil { return err } fake.Dir = tmp return nil } // WithFile adds the specified file (with content) in the build context func WithFile(name, content string) func(*Fake) error { return func(ctx *Fake) error { return ctx.Add(name, content) } } // WithDockerfile adds the specified content as Dockerfile in the build context func WithDockerfile(content string) func(*Fake) error { return WithFile("Dockerfile", content) } // WithFiles adds the specified files in the build context, content is a string func WithFiles(files map[string]string) func(*Fake) error { return func(fakeContext *Fake) error { for file, content := range files { if err := fakeContext.Add(file, content); err != nil { return err } } return nil } } // WithBinaryFiles adds the specified files in the build context, content is binary func WithBinaryFiles(files map[string]*bytes.Buffer) func(*Fake) error { return func(fakeContext *Fake) error { for file, content := range files { if err := fakeContext.Add(file, content.String()); err != nil { return err } } return nil } } // Fake creates directories that can be used as a build context type Fake struct { Dir string } // Add a file at a path, creating directories where necessary func (f *Fake) Add(file, content string) error { return f.addFile(file, []byte(content)) } func (f *Fake) addFile(file string, content []byte) error { fp := filepath.Join(f.Dir, filepath.FromSlash(file)) dirpath := filepath.Dir(fp) if dirpath != "." { if err := os.MkdirAll(dirpath, 0o755); err != nil { return err } } return os.WriteFile(fp, content, 0o644) } // Delete a file at a path func (f *Fake) Delete(file string) error { fp := filepath.Join(f.Dir, filepath.FromSlash(file)) return os.RemoveAll(fp) } // Close deletes the context func (f *Fake) Close() error { return os.RemoveAll(f.Dir) } // AsTarReader returns a ReadCloser with the contents of Dir as a tar archive. func (f *Fake) AsTarReader(t testing.TB) io.ReadCloser { t.Helper() reader, err := archive.TarWithOptions(f.Dir, &archive.TarOptions{}) if err != nil { t.Fatalf("Failed to create tar from %s: %s", f.Dir, err) } return reader }