@@ -16,6 +16,10 @@ import (
1616
1717const GitCommitMessagePreviousVersion = "Bumps from"
1818
19+ // stdin is shared across all prompts. Creating a fresh bufio.Reader per prompt
20+ // discards read-ahead input, which breaks piped stdin and typed-ahead answers.
21+ var stdin = bufio .NewReader (os .Stdin )
22+
1923func NewCommand (name string , args ... string ) * exec.Cmd {
2024 _ , _ = fmt .Fprintf (os .Stderr , "$ %s %s\n " , name , strings .Join (args , " " ))
2125 ec := exec .Command (name , args ... )
@@ -43,9 +47,8 @@ func GitTagRelease(dir string, annotate, dry bool, nextVersion semver.Version, p
4347 Check (NewCommandIn (dir , "git" , gitArgs ... ).Run ())
4448
4549 if annotate {
46- tag := NewCommandIn (dir , "git" , "tag" , fmt .Sprintf ("v%s" , nextVersion .String ()), "-a" )
47- tag .Stdin = os .Stdin
48- Check (tag .Run ())
50+ message := promptTagMessage (nextVersion )
51+ Check (NewCommandIn (dir , "git" , "tag" , fmt .Sprintf ("v%s" , nextVersion .String ()), "-a" , "-m" , message ).Run ())
4952 } else {
5053 Check (NewCommandIn (dir , "git" , "tag" , fmt .Sprintf ("v%s" , nextVersion .String ())).Run ())
5154 }
@@ -64,11 +67,34 @@ func GitClone(repo string) string {
6467 return dest
6568}
6669
70+ // promptTagMessage reads the annotated tag message from stdin. Opening
71+ // $EDITOR instead is not safe here: handing the inherited terminal to vim
72+ // mid-run can leave the terminal in a broken state and subsequent stdin
73+ // reads fail with EOF.
74+ func promptTagMessage (version semver.Version ) string {
75+ fmt .Printf ("Enter the tag message for v%s. Finish with an empty line:\n > " , version .String ())
76+ var lines []string
77+ for {
78+ line , err := stdin .ReadString ('\n' )
79+ Check (err )
80+
81+ line = strings .TrimRight (line , "\r \n " )
82+ if line == "" {
83+ if len (lines ) > 0 {
84+ return strings .Join (lines , "\n " )
85+ }
86+ fmt .Print ("The tag message must not be empty.\n > " )
87+ continue
88+ }
89+ lines = append (lines , line )
90+ fmt .Print ("> " )
91+ }
92+ }
93+
6794func Confirm (message string , args ... interface {}) {
6895 for {
69- reader := bufio .NewReader (os .Stdin )
7096 fmt .Printf ("%s [y/n] " , fmt .Sprintf (message , args ... ))
71- answer , err := reader .ReadString ('\n' )
97+ answer , err := stdin .ReadString ('\n' )
7298 Check (err )
7399
74100 answer = strings .TrimSpace (answer )
0 commit comments