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