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  }