Repository: cli/cli
Pull request #11003 (2025-05-20 14:38:42)

Fix formatting in allowed values for `gh config --help`
Part of a fix for https://github.com/cli/cli/issues/10678


Patch:
diff --git a/go.mod b/go.mod
index bf8b033fe..f95c8a7c2 100644
--- a/go.mod
+++ b/go.mod
@@ -48,6 +48,7 @@ require (
 	github.com/spf13/cobra v1.9.1
 	github.com/spf13/pflag v1.0.6
 	github.com/stretchr/testify v1.10.0
+	github.com/yuin/goldmark v1.7.8
 	github.com/zalando/go-keyring v0.2.5
 	golang.org/x/crypto v0.37.0
 	golang.org/x/sync v0.13.0
@@ -171,7 +172,6 @@ require (
 	github.com/transparency-dev/merkle v0.0.2 // indirect
 	github.com/vbatts/tar-split v0.11.6 // indirect
 	github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
-	github.com/yuin/goldmark v1.7.8 // indirect
 	github.com/yuin/goldmark-emoji v1.0.5 // indirect
 	go.mongodb.org/mongo-driver v1.14.0 // indirect
 	go.opentelemetry.io/auto/sdk v1.1.0 // indirect
diff --git a/pkg/cmd/config/config.go b/pkg/cmd/config/config.go
index 66051f83a..92d0ca1ba 100644
--- a/pkg/cmd/config/config.go
+++ b/pkg/cmd/config/config.go
@@ -20,10 +20,10 @@ func NewCmdConfig(f *cmdutil.Factory) *cobra.Command {
 	for _, co := range config.Options {
 		longDoc.WriteString(fmt.Sprintf("- `%s`: %s", co.Key, co.Description))
 		if len(co.AllowedValues) > 0 {
-			longDoc.WriteString(fmt.Sprintf(" {%s}", strings.Join(co.AllowedValues, "|")))
+			longDoc.WriteString(fmt.Sprintf(" `{%s}`", strings.Join(co.AllowedValues, " | ")))
 		}
 		if co.DefaultValue != "" {
-			longDoc.WriteString(fmt.Sprintf(" (default %s)", co.DefaultValue))
+			longDoc.WriteString(fmt.Sprintf(" (default `%s`)", co.DefaultValue))
 		}
 		longDoc.WriteRune('\n')
 	}


Test patch:
diff --git a/pkg/cmd/root/help_test.go b/pkg/cmd/root/help_test.go
index d24a84a0d..40f333159 100644
--- a/pkg/cmd/root/help_test.go
+++ b/pkg/cmd/root/help_test.go
@@ -1,7 +1,20 @@
 package root
 
 import (
+	"fmt"
 	"testing"
+
+	"github.com/cli/cli/v2/internal/browser"
+	"github.com/cli/cli/v2/internal/config"
+	"github.com/cli/cli/v2/internal/gh"
+	"github.com/cli/cli/v2/pkg/cmdutil"
+	"github.com/cli/cli/v2/pkg/extensions"
+	"github.com/cli/cli/v2/pkg/iostreams"
+	"github.com/spf13/cobra"
+	"github.com/stretchr/testify/require"
+	"github.com/yuin/goldmark"
+	"github.com/yuin/goldmark/ast"
+	"github.com/yuin/goldmark/text"
 )
 
 func TestDedent(t *testing.T) {
@@ -44,3 +57,68 @@ func TestDedent(t *testing.T) {
 		}
 	}
 }
+
+// Since our online docs website renders pages by using the kramdown (a superset
+// of Markdown) engine, we have to check against some known quirks of the
+// syntax.
+func TestKramdownCompatibleDocs(t *testing.T) {
+	ios, _, _, _ := iostreams.Test()
+	f := &cmdutil.Factory{
+		IOStreams: ios,
+		Config:    func() (gh.Config, error) { return config.NewBlankConfig(), nil },
+		Browser:   &browser.Stub{},
+		ExtensionManager: &extensions.ExtensionManagerMock{
+			ListFunc: func() []extensions.Extension {
+				return nil
+			},
+		},
+	}
+
+	cmd, err := NewCmdRoot(f, "N/A", "")
+	require.NoError(t, err)
+
+	var walk func(*cobra.Command)
+	walk = func(cmd *cobra.Command) {
+		name := fmt.Sprintf("%q: test pipes are in code blocks", cmd.UseLine())
+		t.Run(name, func(t *testing.T) {
+			assertPipesAreInCodeBlocks(t, cmd)
+		})
+		for _, child := range cmd.Commands() {
+			walk(child)
+		}
+	}
+
+	walk(cmd)
+}
+
+// If not in a code block or a code span, kramdown treats pipes ("|") as table
+// column separators, even if there's no table header, or left/right table row
+// borders (i.e. lines starting and ending with a pipe).
+//
+// We need to assert there's no pipe in the text unless it's in a code-block or
+// code-span.
+//
+// (See https://github.com/cli/cli/issues/10348)
+func assertPipesAreInCodeBlocks(t *testing.T, cmd *cobra.Command) {
+	md := goldmark.New()
+	reader := text.NewReader([]byte(cmd.Long))
+	doc := md.Parser().Parse(reader)
+
+	var checkNode func(node ast.Node)
+	checkNode = func(node ast.Node) {
+		if node.Kind() == ast.KindCodeSpan || node.Kind() == ast.KindCodeBlock {
+			return
+		}
+
+		if node.Kind() == ast.KindText {
+			text := string(node.(*ast.Text).Segment.Value(reader.Source()))
+			require.NotContains(t, text, "|", `found pipe ("|") in plain text in %q docs`, cmd.CommandPath())
+		}
+
+		for child := node.FirstChild(); child != nil; child = child.NextSibling() {
+			checkNode(child)
+		}
+	}
+
+	checkNode(doc)
+}