// Package source provides pipes to take care of using the correct source files. // For the releasing process we need the files of the tag we are releasing. package source import ( "bytes" "errors" "fmt" "log" "os/exec" "github.com/goreleaser/goreleaser/context" ) // Pipe to use the latest Git tag as source. type Pipe struct { dirty bool wrongBranch bool } // Description of the pipe func (p *Pipe) Description() string { return "Using source from latest tag" } // Run uses the latest tag as source. // Uncommitted changes are stashed. func (p *Pipe) Run(ctx *context.Context) error { cmd := exec.Command("git", "diff-index", "--quiet", "HEAD", "--") err := cmd.Run() dirty := err != nil if dirty { log.Println("Stashing changes") if err = run("git", "stash", "--include-untracked", "--quiet"); err != nil { return fmt.Errorf("failed stashing changes: %v", err) } } p.dirty = dirty cmd = exec.Command("git", "describe", "--exact-match", "--match", ctx.Git.CurrentTag) err = cmd.Run() wrongBranch := err != nil if wrongBranch { log.Println("Checking out tag") if err = run("git", "checkout", ctx.Git.CurrentTag); err != nil { return fmt.Errorf("failed changing branch: %v", err) } } p.wrongBranch = wrongBranch return nil } // Clean switches back to the original branch and restores changes. func (p *Pipe) Clean(ctx *context.Context) { if p.wrongBranch { log.Println("Checking out original branch") if err := run("git", "checkout", "-"); err != nil { log.Println("failed changing branch: ", err.Error()) } } if p.dirty { log.Println("Popping stashed changes") if err := run("git", "stash", "pop"); err != nil { log.Println("failed popping stashed changes:", err.Error()) } } } func run(bin string, args ...string) error { cmd := exec.Command(bin, args...) var out bytes.Buffer cmd.Stdout = &out cmd.Stderr = &out err := cmd.Run() if err != nil { return errors.New(out.String()) } return nil }