github.com/tomsquest/goreleaser@v0.34.3-0.20171008022654-7d6ef4d338b3/pipeline/git/git.go (about) 1 // Package git implements the Pipe interface getting and validating the 2 // current git repository state 3 package git 4 5 import ( 6 "bytes" 7 "fmt" 8 "regexp" 9 "strings" 10 "text/template" 11 "time" 12 13 "github.com/apex/log" 14 "github.com/goreleaser/goreleaser/context" 15 "github.com/goreleaser/goreleaser/internal/git" 16 "github.com/goreleaser/goreleaser/pipeline" 17 ) 18 19 // Pipe for brew deployment 20 type Pipe struct{} 21 22 // Description of the pipe 23 func (Pipe) Description() string { 24 return "Getting and validating git state" 25 } 26 27 // Run the pipe 28 func (Pipe) Run(ctx *context.Context) (err error) { 29 tag, commit, err := getInfo() 30 if err != nil { 31 return 32 } 33 if tag == "" && !ctx.Snapshot { 34 return ErrNoTag 35 } 36 ctx.Git = context.GitInfo{ 37 CurrentTag: tag, 38 Commit: commit, 39 } 40 log.Infof("releasing %s, commit %s", tag, commit) 41 if err = setLog(ctx, tag, commit); err != nil { 42 return 43 } 44 if err = setVersion(ctx, tag, commit); err != nil { 45 return 46 } 47 if !ctx.Validate { 48 return pipeline.Skip("--skip-validate is set") 49 } 50 return validate(ctx, commit, tag) 51 } 52 53 func setVersion(ctx *context.Context, tag, commit string) (err error) { 54 if ctx.Snapshot { 55 snapshotName, err := getSnapshotName(ctx, tag, commit) 56 if err != nil { 57 return fmt.Errorf("failed to generate snapshot name: %s", err.Error()) 58 } 59 ctx.Version = snapshotName 60 return nil 61 } 62 // removes usual `v` prefix 63 ctx.Version = strings.TrimPrefix(tag, "v") 64 return 65 } 66 67 func setLog(ctx *context.Context, tag, commit string) (err error) { 68 if ctx.ReleaseNotes != "" { 69 return 70 } 71 var log string 72 if tag == "" { 73 log, err = getChangelog(commit) 74 } else { 75 log, err = getChangelog(tag) 76 } 77 if err != nil { 78 return err 79 } 80 ctx.ReleaseNotes = fmt.Sprintf("## Changelog\n\n%v", log) 81 return nil 82 } 83 84 type snapshotNameData struct { 85 Commit string 86 Tag string 87 Timestamp int64 88 } 89 90 func getSnapshotName(ctx *context.Context, tag, commit string) (string, error) { 91 tmpl, err := template.New("snapshot").Parse(ctx.Config.Snapshot.NameTemplate) 92 var out bytes.Buffer 93 if err != nil { 94 return "", err 95 } 96 var data = snapshotNameData{ 97 Commit: commit, 98 Tag: tag, 99 Timestamp: time.Now().Unix(), 100 } 101 err = tmpl.Execute(&out, data) 102 return out.String(), err 103 } 104 105 func validate(ctx *context.Context, commit, tag string) error { 106 out, err := git.Run("status", "--porcelain") 107 if strings.TrimSpace(out) != "" || err != nil { 108 return ErrDirty{out} 109 } 110 if ctx.Snapshot { 111 return nil 112 } 113 if !regexp.MustCompile("^[0-9.]+").MatchString(ctx.Version) { 114 return ErrInvalidVersionFormat{ctx.Version} 115 } 116 _, err = cleanGit("describe", "--exact-match", "--tags", "--match", tag) 117 if err != nil { 118 return ErrWrongRef{commit, tag} 119 } 120 return nil 121 } 122 123 func getChangelog(tag string) (string, error) { 124 prev, err := previous(tag) 125 if err != nil { 126 return "", err 127 } 128 if !prev.Tag { 129 return gitLog(prev.SHA, tag) 130 } 131 return gitLog(fmt.Sprintf("%v..%v", prev.SHA, tag)) 132 } 133 134 func gitLog(refs ...string) (string, error) { 135 var args = []string{"log", "--pretty=oneline", "--abbrev-commit"} 136 args = append(args, refs...) 137 return git.Run(args...) 138 } 139 140 func getInfo() (tag, commit string, err error) { 141 tag, err = cleanGit("describe", "--tags", "--abbrev=0") 142 if err != nil { 143 log.WithError(err).Info("failed to retrieve current tag") 144 } 145 commit, err = cleanGit("show", "--format='%H'", "HEAD") 146 return 147 } 148 149 func previous(tag string) (result ref, err error) { 150 result.Tag = true 151 result.SHA, err = cleanGit("describe", "--tags", "--abbrev=0", tag+"^") 152 if err != nil { 153 result.Tag = false 154 result.SHA, err = cleanGit("rev-list", "--max-parents=0", "HEAD") 155 } 156 return 157 } 158 159 type ref struct { 160 Tag bool 161 SHA string 162 }