From cb8496d6b278312495c14ffa4c4b74e976932f52 Mon Sep 17 00:00:00 2001
From: Garth Kidd <garth@garthk.com>
Date: Sun, 17 Jan 2016 15:18:47 +1100
Subject: [PATCH 1/2] Ensure SEE ALSO list has no leading comma, fixing #229

---
 doc/man_docs.go | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/doc/man_docs.go b/doc/man_docs.go
index f21d839..a98674b 100644
--- a/doc/man_docs.go
+++ b/doc/man_docs.go
@@ -188,10 +188,12 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
 	}
 	if hasSeeAlso(cmd) {
 		fmt.Fprintf(buf, "# SEE ALSO\n")
+		seealsos := make([]string, 0)
 		if cmd.HasParent() {
 			parentPath := cmd.Parent().CommandPath()
 			dashParentPath := strings.Replace(parentPath, " ", "-", -1)
-			fmt.Fprintf(buf, "**%s(%s)**", dashParentPath, header.Section)
+			seealso := fmt.Sprintf("**%s(%s)**", dashParentPath, header.Section)
+			seealsos = append(seealsos, seealso)
 			cmd.VisitParents(func(c *cobra.Command) {
 				if c.DisableAutoGenTag {
 					cmd.DisableAutoGenTag = c.DisableAutoGenTag
@@ -200,16 +202,14 @@ func genMan(cmd *cobra.Command, header *GenManHeader) []byte {
 		}
 		children := cmd.Commands()
 		sort.Sort(byName(children))
-		for i, c := range children {
+		for _, c := range children {
 			if !c.IsAvailableCommand() || c.IsHelpCommand() {
 				continue
 			}
-			if cmd.HasParent() || i > 0 {
-				fmt.Fprintf(buf, ", ")
-			}
-			fmt.Fprintf(buf, "**%s-%s(%s)**", dashCommandName, c.Name(), header.Section)
+			seealso := fmt.Sprintf("**%s-%s(%s)**", dashCommandName, c.Name(), header.Section)
+			seealsos = append(seealsos, seealso)
 		}
-		fmt.Fprintf(buf, "\n")
+		fmt.Fprintf(buf, "%s\n", strings.Join(seealsos, ", "))
 	}
 	if !cmd.DisableAutoGenTag {
 		fmt.Fprintf(buf, "# HISTORY\n%s Auto generated by spf13/cobra\n", header.Date.Format("2-Jan-2006"))

From 57f473263ef491b4b3693e8a5df7af0bd4a28094 Mon Sep 17 00:00:00 2001
From: Garth Kidd <garth@garthk.com>
Date: Thu, 21 Jan 2016 12:06:00 +1100
Subject: [PATCH 2/2] Add explicit doc.GenMan SEE ALSO test covering #229

---
 doc/man_docs_test.go | 65 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/doc/man_docs_test.go b/doc/man_docs_test.go
index 3083125..51eba36 100644
--- a/doc/man_docs_test.go
+++ b/doc/man_docs_test.go
@@ -1,11 +1,14 @@
 package doc
 
 import (
+	"bufio"
 	"bytes"
 	"fmt"
 	"os"
 	"strings"
 	"testing"
+
+	"github.com/spf13/cobra"
 )
 
 var _ = fmt.Println
@@ -95,3 +98,65 @@ func TestGenManNoGenTag(t *testing.T) {
 	unexpected := translate("#HISTORY")
 	checkStringOmits(t, found, unexpected)
 }
+
+func TestGenManSeeAlso(t *testing.T) {
+	noop := func(cmd *cobra.Command, args []string) {}
+
+	top := &cobra.Command{Use: "top", Run: noop}
+	aaa := &cobra.Command{Use: "aaa", Run: noop, Hidden: true} // #229
+	bbb := &cobra.Command{Use: "bbb", Run: noop}
+	ccc := &cobra.Command{Use: "ccc", Run: noop}
+	top.AddCommand(aaa, bbb, ccc)
+
+	out := new(bytes.Buffer)
+	header := &GenManHeader{}
+	if err := GenMan(top, header, out); err != nil {
+		t.Fatal(err)
+	}
+
+	scanner := bufio.NewScanner(out)
+
+	if err := AssertLineFound(scanner, ".SH SEE ALSO"); err != nil {
+		t.Fatal(fmt.Errorf("Couldn't find SEE ALSO section header: %s", err.Error()))
+	}
+
+	if err := AssertNextLineEquals(scanner, ".PP"); err != nil {
+		t.Fatal(fmt.Errorf("First line after SEE ALSO wasn't break-indent: %s", err.Error()))
+	}
+
+	if err := AssertNextLineEquals(scanner, `\fBtop\-bbb(1)\fP, \fBtop\-ccc(1)\fP`); err != nil {
+		t.Fatal(fmt.Errorf("Second line after SEE ALSO wasn't correct: %s", err.Error()))
+	}
+}
+
+func AssertLineFound(scanner *bufio.Scanner, expectedLine string) error {
+	for scanner.Scan() {
+		line := scanner.Text()
+		if line == expectedLine {
+			return nil
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		return fmt.Errorf("AssertLineFound: scan failed: %s", err.Error())
+	}
+
+	return fmt.Errorf("AssertLineFound: hit EOF before finding %#v", expectedLine)
+}
+
+func AssertNextLineEquals(scanner *bufio.Scanner, expectedLine string) error {
+	if scanner.Scan() {
+		line := scanner.Text()
+		if line == expectedLine {
+			return nil
+		} else {
+			return fmt.Errorf("AssertNextLineEquals: got %#v, not %#v", line, expectedLine)
+		}
+	}
+
+	if err := scanner.Err(); err != nil {
+		return fmt.Errorf("AssertNextLineEquals: scan failed: %s", err.Error())
+	}
+
+	return fmt.Errorf("AssertNextLineEquals: hit EOF before finding %#v", expectedLine)
+}