2017-01-14 12:34:22 -02:00
|
|
|
package git
|
|
|
|
|
2017-01-29 21:55:32 -02:00
|
|
|
import (
|
2020-09-21 14:47:51 -03:00
|
|
|
"fmt"
|
2020-01-31 19:38:56 +01:00
|
|
|
"os"
|
2018-08-20 23:18:43 -03:00
|
|
|
"os/exec"
|
2020-07-06 16:09:22 -04:00
|
|
|
"strconv"
|
2017-01-29 21:55:32 -02:00
|
|
|
"strings"
|
2020-07-06 16:09:22 -04:00
|
|
|
"time"
|
2017-01-29 21:55:32 -02:00
|
|
|
|
2017-06-22 00:09:14 -03:00
|
|
|
"github.com/apex/log"
|
2020-01-31 19:38:56 +01:00
|
|
|
|
2017-08-19 12:47:04 -03:00
|
|
|
"github.com/goreleaser/goreleaser/internal/git"
|
2018-09-12 14:18:01 -03:00
|
|
|
"github.com/goreleaser/goreleaser/internal/pipe"
|
2018-08-14 23:50:20 -03:00
|
|
|
"github.com/goreleaser/goreleaser/pkg/context"
|
2017-01-29 21:55:32 -02:00
|
|
|
)
|
2017-01-14 12:34:22 -02:00
|
|
|
|
2020-05-26 00:48:10 -03:00
|
|
|
// Pipe that sets up git state.
|
2017-01-14 12:34:22 -02:00
|
|
|
type Pipe struct{}
|
|
|
|
|
2017-12-02 19:53:19 -02:00
|
|
|
func (Pipe) String() string {
|
|
|
|
return "getting and validating git state"
|
2017-01-14 12:34:22 -02:00
|
|
|
}
|
|
|
|
|
2020-05-26 00:48:10 -03:00
|
|
|
// Run the pipe.
|
2018-02-25 20:17:45 -03:00
|
|
|
func (Pipe) Run(ctx *context.Context) error {
|
2018-08-20 23:18:43 -03:00
|
|
|
if _, err := exec.LookPath("git"); err != nil {
|
|
|
|
return ErrNoGit
|
|
|
|
}
|
2018-02-25 20:17:45 -03:00
|
|
|
info, err := getInfo(ctx)
|
2017-01-14 12:34:22 -02:00
|
|
|
if err != nil {
|
2018-02-25 20:17:45 -03:00
|
|
|
return err
|
2017-01-14 12:34:22 -02:00
|
|
|
}
|
2018-02-25 20:17:45 -03:00
|
|
|
ctx.Git = info
|
|
|
|
log.Infof("releasing %s, commit %s", info.CurrentTag, info.Commit)
|
2018-12-13 10:09:36 -02:00
|
|
|
ctx.Version = strings.TrimPrefix(ctx.Git.CurrentTag, "v")
|
2018-02-25 20:17:45 -03:00
|
|
|
return validate(ctx)
|
|
|
|
}
|
|
|
|
|
2018-11-07 22:04:49 -02:00
|
|
|
// nolint: gochecknoglobals
|
2018-03-01 20:42:47 -03:00
|
|
|
var fakeInfo = context.GitInfo{
|
2020-11-18 19:50:31 +01:00
|
|
|
Branch: "none",
|
2018-10-03 17:44:31 -03:00
|
|
|
CurrentTag: "v0.0.0",
|
|
|
|
Commit: "none",
|
|
|
|
ShortCommit: "none",
|
|
|
|
FullCommit: "none",
|
2018-03-01 20:42:47 -03:00
|
|
|
}
|
|
|
|
|
2018-02-25 20:17:45 -03:00
|
|
|
func getInfo(ctx *context.Context) (context.GitInfo, error) {
|
|
|
|
if !git.IsRepo() && ctx.Snapshot {
|
2018-03-01 20:42:47 -03:00
|
|
|
log.Warn("accepting to run without a git repo because this is a snapshot")
|
|
|
|
return fakeInfo, nil
|
2018-02-25 20:17:45 -03:00
|
|
|
}
|
|
|
|
if !git.IsRepo() {
|
|
|
|
return context.GitInfo{}, ErrNotRepository
|
|
|
|
}
|
2019-01-19 18:05:15 -02:00
|
|
|
info, err := getGitInfo()
|
2018-02-25 20:17:45 -03:00
|
|
|
if err != nil && ctx.Snapshot {
|
2018-03-01 20:42:47 -03:00
|
|
|
log.WithError(err).Warn("ignoring errors because this is a snapshot")
|
|
|
|
if info.Commit == "" {
|
|
|
|
info = fakeInfo
|
|
|
|
}
|
2018-02-25 20:17:45 -03:00
|
|
|
return info, nil
|
|
|
|
}
|
|
|
|
return info, err
|
|
|
|
}
|
|
|
|
|
2019-01-19 18:05:15 -02:00
|
|
|
func getGitInfo() (context.GitInfo, error) {
|
2020-11-18 19:50:31 +01:00
|
|
|
branch, err := getBranch()
|
|
|
|
if err != nil {
|
|
|
|
return context.GitInfo{}, fmt.Errorf("couldn't get current branch: %w", err)
|
|
|
|
}
|
2018-10-03 17:44:31 -03:00
|
|
|
short, err := getShortCommit()
|
|
|
|
if err != nil {
|
2020-09-21 14:47:51 -03:00
|
|
|
return context.GitInfo{}, fmt.Errorf("couldn't get current commit: %w", err)
|
2018-10-03 17:44:31 -03:00
|
|
|
}
|
|
|
|
full, err := getFullCommit()
|
2018-02-25 20:17:45 -03:00
|
|
|
if err != nil {
|
2020-09-21 14:47:51 -03:00
|
|
|
return context.GitInfo{}, fmt.Errorf("couldn't get current commit: %w", err)
|
2017-01-14 14:06:57 -02:00
|
|
|
}
|
2020-07-06 16:09:22 -04:00
|
|
|
date, err := getCommitDate()
|
|
|
|
if err != nil {
|
2020-09-21 14:47:51 -03:00
|
|
|
return context.GitInfo{}, fmt.Errorf("couldn't get commit date: %w", err)
|
2020-07-06 16:09:22 -04:00
|
|
|
}
|
2018-10-04 09:38:19 -03:00
|
|
|
url, err := getURL()
|
|
|
|
if err != nil {
|
2020-09-21 14:47:51 -03:00
|
|
|
return context.GitInfo{}, fmt.Errorf("couldn't get remote URL: %w", err)
|
2018-10-04 09:38:19 -03:00
|
|
|
}
|
2018-02-25 20:17:45 -03:00
|
|
|
tag, err := getTag()
|
2019-10-21 09:09:11 -03:00
|
|
|
if err != nil {
|
2018-02-25 20:17:45 -03:00
|
|
|
return context.GitInfo{
|
2020-11-18 19:50:31 +01:00
|
|
|
Branch: branch,
|
2019-01-19 17:37:42 -02:00
|
|
|
Commit: full,
|
2018-10-03 17:44:31 -03:00
|
|
|
FullCommit: full,
|
|
|
|
ShortCommit: short,
|
2020-07-06 16:09:22 -04:00
|
|
|
CommitDate: date,
|
2018-10-04 09:38:19 -03:00
|
|
|
URL: url,
|
2018-10-03 17:44:31 -03:00
|
|
|
CurrentTag: "v0.0.0",
|
2018-02-25 20:17:45 -03:00
|
|
|
}, ErrNoTag
|
2017-05-01 10:39:57 -03:00
|
|
|
}
|
2018-02-25 20:17:45 -03:00
|
|
|
return context.GitInfo{
|
2020-11-18 19:50:31 +01:00
|
|
|
Branch: branch,
|
2018-10-03 17:44:31 -03:00
|
|
|
CurrentTag: tag,
|
2019-01-19 17:37:42 -02:00
|
|
|
Commit: full,
|
2018-10-03 17:44:31 -03:00
|
|
|
FullCommit: full,
|
|
|
|
ShortCommit: short,
|
2020-07-06 16:09:22 -04:00
|
|
|
CommitDate: date,
|
2018-10-04 09:38:19 -03:00
|
|
|
URL: url,
|
2018-02-25 20:17:45 -03:00
|
|
|
}, nil
|
2017-05-01 10:39:57 -03:00
|
|
|
}
|
|
|
|
|
2018-02-25 20:17:45 -03:00
|
|
|
func validate(ctx *context.Context) error {
|
2018-02-24 17:59:08 -03:00
|
|
|
if ctx.Snapshot {
|
2018-09-12 14:18:01 -03:00
|
|
|
return pipe.ErrSnapshotEnabled
|
2018-03-08 08:42:33 -03:00
|
|
|
}
|
|
|
|
if ctx.SkipValidate {
|
2018-09-12 14:18:01 -03:00
|
|
|
return pipe.ErrSkipValidateEnabled
|
2018-02-24 17:59:08 -03:00
|
|
|
}
|
2020-12-22 15:04:51 +01:00
|
|
|
out, err := git.Run("status", "--porcelain")
|
|
|
|
if strings.TrimSpace(out) != "" || err != nil {
|
|
|
|
return ErrDirty{status: out}
|
2017-04-15 16:11:47 -03:00
|
|
|
}
|
2020-12-22 15:04:51 +01:00
|
|
|
_, err = git.Clean(git.Run("describe", "--exact-match", "--tags", "--match", ctx.Git.CurrentTag))
|
2017-05-01 10:57:37 -03:00
|
|
|
if err != nil {
|
2018-06-19 15:53:14 -03:00
|
|
|
return ErrWrongRef{
|
|
|
|
commit: ctx.Git.Commit,
|
|
|
|
tag: ctx.Git.CurrentTag,
|
|
|
|
}
|
2017-04-15 16:11:47 -03:00
|
|
|
}
|
|
|
|
return nil
|
2017-01-14 12:34:22 -02:00
|
|
|
}
|
2017-04-15 13:05:54 -03:00
|
|
|
|
2020-11-18 19:50:31 +01:00
|
|
|
func getBranch() (string, error) {
|
|
|
|
return git.Clean(git.Run("rev-parse", "--abbrev-ref", "HEAD", "--quiet"))
|
|
|
|
}
|
|
|
|
|
2020-07-06 16:09:22 -04:00
|
|
|
func getCommitDate() (time.Time, error) {
|
|
|
|
ct, err := git.Clean(git.Run("show", "--format='%ct'", "HEAD", "--quiet"))
|
|
|
|
if err != nil {
|
|
|
|
return time.Time{}, err
|
|
|
|
}
|
|
|
|
if ct == "" {
|
|
|
|
return time.Time{}, nil
|
|
|
|
}
|
|
|
|
i, err := strconv.ParseInt(ct, 10, 64)
|
|
|
|
if err != nil {
|
|
|
|
return time.Time{}, err
|
|
|
|
}
|
|
|
|
t := time.Unix(i, 0).UTC()
|
|
|
|
return t, nil
|
|
|
|
}
|
|
|
|
|
2018-10-03 17:44:31 -03:00
|
|
|
func getShortCommit() (string, error) {
|
2020-01-30 19:20:36 -08:00
|
|
|
return git.Clean(git.Run("show", "--format='%h'", "HEAD", "--quiet"))
|
2018-10-03 17:44:31 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
func getFullCommit() (string, error) {
|
2020-01-30 19:20:36 -08:00
|
|
|
return git.Clean(git.Run("show", "--format='%H'", "HEAD", "--quiet"))
|
2018-02-25 20:17:45 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
func getTag() (string, error) {
|
2020-09-08 10:11:59 -03:00
|
|
|
var tag string
|
|
|
|
var err error
|
|
|
|
for _, fn := range []func() (string, error){
|
|
|
|
func() (string, error) {
|
|
|
|
return os.Getenv("GORELEASER_CURRENT_TAG"), nil
|
|
|
|
},
|
|
|
|
func() (string, error) {
|
|
|
|
return git.Clean(git.Run("tag", "--points-at", "HEAD", "--sort", "-version:creatordate"))
|
|
|
|
},
|
|
|
|
func() (string, error) {
|
|
|
|
return git.Clean(git.Run("describe", "--tags", "--abbrev=0"))
|
|
|
|
},
|
|
|
|
} {
|
|
|
|
tag, err = fn()
|
|
|
|
if tag != "" || err != nil {
|
|
|
|
return tag, err
|
|
|
|
}
|
2020-01-31 19:38:56 +01:00
|
|
|
}
|
|
|
|
|
2020-09-08 10:11:59 -03:00
|
|
|
return tag, err
|
2017-04-23 16:33:44 -03:00
|
|
|
}
|
2018-10-04 09:38:19 -03:00
|
|
|
|
|
|
|
func getURL() (string, error) {
|
|
|
|
return git.Clean(git.Run("ls-remote", "--get-url"))
|
|
|
|
}
|