github.com/dnephin/dobi@v0.15.0/tasks/image/image.go (about) 1 package image 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/dnephin/dobi/config" 8 "github.com/dnephin/dobi/logging" 9 "github.com/dnephin/dobi/tasks/context" 10 "github.com/dnephin/dobi/tasks/task" 11 "github.com/dnephin/dobi/tasks/types" 12 "github.com/docker/docker/pkg/jsonmessage" 13 "github.com/docker/docker/pkg/term" 14 docker "github.com/fsouza/go-dockerclient" 15 log "github.com/sirupsen/logrus" 16 ) 17 18 // Task creates a Docker image 19 type Task struct { 20 types.NoStop 21 name task.Name 22 config *config.ImageConfig 23 runFunc runFunc 24 } 25 26 // Name returns the name of the task 27 func (t *Task) Name() task.Name { 28 return t.name 29 } 30 31 func (t *Task) logger() *log.Entry { 32 return logging.ForTask(t) 33 } 34 35 // Repr formats the task for logging 36 func (t *Task) Repr() string { 37 return fmt.Sprintf("%s %s", t.name.Format("image"), t.config.Image) 38 } 39 40 // Run builds or pulls an image if it is out of date 41 func (t *Task) Run(ctx *context.ExecuteContext, depsModified bool) (bool, error) { 42 return t.runFunc(ctx, t, depsModified) 43 } 44 45 // ForEachTag runs a function for each tag 46 func (t *Task) ForEachTag(ctx *context.ExecuteContext, each func(string) error) error { 47 if len(t.config.Tags) == 0 { 48 return each(GetImageName(ctx, t.config)) 49 } 50 51 for _, tag := range t.config.Tags { 52 imageTag := t.config.Image + ":" + tag 53 // If the tag is already a complete image name then use it directly 54 if _, hasTag := docker.ParseRepositoryTag(tag); hasTag != "" { 55 imageTag = tag 56 } 57 58 if err := each(imageTag); err != nil { 59 return err 60 } 61 } 62 return nil 63 } 64 65 // Stream json output to a terminal 66 func Stream(out io.Writer, streamer func(out io.Writer) error) error { 67 outFd, isTTY := term.GetFdInfo(out) 68 rpipe, wpipe := io.Pipe() 69 defer rpipe.Close() // nolint: errcheck 70 71 errChan := make(chan error) 72 73 go func() { 74 err := jsonmessage.DisplayJSONMessagesStream(rpipe, out, outFd, isTTY, nil) 75 errChan <- err 76 }() 77 78 err := streamer(wpipe) 79 wpipe.Close() // nolint: errcheck 80 if err != nil { 81 <-errChan 82 return err 83 } 84 return <-errChan 85 }