github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/docker/api.go (about) 1 package docker 2 3 import ( 4 "bytes" 5 "fmt" 6 "io" 7 "os/exec" 8 "sync" 9 10 "github.com/caarlos0/log" 11 "github.com/goreleaser/goreleaser/internal/gio" 12 "github.com/goreleaser/goreleaser/internal/logext" 13 "github.com/goreleaser/goreleaser/pkg/context" 14 ) 15 16 var ( 17 manifesters = map[string]manifester{} 18 imagers = map[string]imager{} 19 lock sync.Mutex 20 ) 21 22 func registerManifester(use string, impl manifester) { 23 lock.Lock() 24 defer lock.Unlock() 25 manifesters[use] = impl 26 } 27 28 func registerImager(use string, impl imager) { 29 lock.Lock() 30 defer lock.Unlock() 31 imagers[use] = impl 32 } 33 34 // imager is something that can build and push docker images. 35 type imager interface { 36 Build(ctx *context.Context, root string, images, flags []string) error 37 Push(ctx *context.Context, image string, flags []string) (digest string, err error) 38 } 39 40 // manifester is something that can create and push docker manifests. 41 type manifester interface { 42 Create(ctx *context.Context, manifest string, images, flags []string) error 43 Push(ctx *context.Context, manifest string, flags []string) (digest string, err error) 44 } 45 46 // nolint: unparam 47 func runCommand(ctx *context.Context, dir, binary string, args ...string) error { 48 /* #nosec */ 49 cmd := exec.CommandContext(ctx, binary, args...) 50 cmd.Dir = dir 51 cmd.Env = append(ctx.Env.Strings(), cmd.Environ()...) 52 53 var b bytes.Buffer 54 w := gio.Safe(&b) 55 cmd.Stderr = io.MultiWriter(logext.NewWriter(), w) 56 cmd.Stdout = io.MultiWriter(logext.NewWriter(), w) 57 58 log. 59 WithField("cmd", append([]string{binary}, args[0])). 60 WithField("cwd", dir). 61 WithField("args", args[1:]).Debug("running") 62 if err := cmd.Run(); err != nil { 63 return fmt.Errorf("%w: %s", err, b.String()) 64 } 65 return nil 66 } 67 68 func runCommandWithOutput(ctx *context.Context, dir, binary string, args ...string) ([]byte, error) { 69 /* #nosec */ 70 cmd := exec.CommandContext(ctx, binary, args...) 71 cmd.Dir = dir 72 cmd.Env = append(ctx.Env.Strings(), cmd.Environ()...) 73 74 var b bytes.Buffer 75 w := gio.Safe(&b) 76 cmd.Stderr = io.MultiWriter(logext.NewWriter(), w) 77 78 log. 79 WithField("cmd", append([]string{binary}, args[0])). 80 WithField("cwd", dir). 81 WithField("args", args[1:]). 82 Debug("running") 83 out, err := cmd.Output() 84 if out != nil { 85 // regardless of command success, always print stdout for backward-compatibility with runCommand() 86 _, _ = io.MultiWriter(logext.NewWriter(), w).Write(out) 87 } 88 if err != nil { 89 return nil, fmt.Errorf("%w: %s", err, b.String()) 90 } 91 92 return out, nil 93 }