mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
Merge pull request #91801 from liggitt/kubectl-explain
Improve kubectl explain formatting-preservation
This commit is contained in:
commit
0281b85640
@ -41,6 +41,7 @@ go_test(
|
||||
deps = [
|
||||
"//staging/src/k8s.io/apimachinery/pkg/api/meta/testrestmapper:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/kubectl/pkg/util/openapi/testing:go_default_library",
|
||||
],
|
||||
|
@ -19,6 +19,7 @@ package explain
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
@ -103,22 +104,75 @@ func (l *line) Add(word string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
var bullet = regexp.MustCompile(`^(\d+\.?|-|\*)\s`)
|
||||
|
||||
func shouldStartNewLine(lastWord, str string) bool {
|
||||
// preserve line breaks ending in :
|
||||
if strings.HasSuffix(lastWord, ":") {
|
||||
return true
|
||||
}
|
||||
|
||||
// preserve code blocks
|
||||
if strings.HasPrefix(str, " ") {
|
||||
return true
|
||||
}
|
||||
str = strings.TrimSpace(str)
|
||||
// preserve empty lines
|
||||
if len(str) == 0 {
|
||||
return true
|
||||
}
|
||||
// preserve lines that look like they're starting lists
|
||||
if bullet.MatchString(str) == true {
|
||||
return true
|
||||
}
|
||||
// otherwise combine
|
||||
return false
|
||||
}
|
||||
|
||||
func wrapString(str string, wrap int) []string {
|
||||
words := strings.Fields(str)
|
||||
wrapped := []string{}
|
||||
l := line{wrap: wrap}
|
||||
|
||||
for _, word := range words {
|
||||
if !l.Add(word) {
|
||||
// track the last word added to the current line
|
||||
lastWord := ""
|
||||
flush := func() {
|
||||
if !l.Empty() {
|
||||
lastWord = ""
|
||||
wrapped = append(wrapped, l.String())
|
||||
l = line{wrap: wrap}
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over the lines in the original description
|
||||
for _, str := range strings.Split(str, "\n") {
|
||||
// preserve code blocks and blockquotes as-is
|
||||
if strings.HasPrefix(str, " ") {
|
||||
flush()
|
||||
wrapped = append(wrapped, str)
|
||||
continue
|
||||
}
|
||||
|
||||
// preserve empty lines after the first line, since they can separate logical sections
|
||||
if len(wrapped) > 0 && len(strings.TrimSpace(str)) == 0 {
|
||||
flush()
|
||||
wrapped = append(wrapped, "")
|
||||
continue
|
||||
}
|
||||
|
||||
// flush if we should start a new line
|
||||
if shouldStartNewLine(lastWord, str) {
|
||||
flush()
|
||||
}
|
||||
words := strings.Fields(str)
|
||||
for _, word := range words {
|
||||
lastWord = word
|
||||
if !l.Add(word) {
|
||||
panic("Couldn't add to empty line.")
|
||||
flush()
|
||||
if !l.Add(word) {
|
||||
panic("Couldn't add to empty line.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !l.Empty() {
|
||||
wrapped = append(wrapped, l.String())
|
||||
}
|
||||
flush()
|
||||
return wrapped
|
||||
}
|
||||
|
@ -19,6 +19,8 @@ package explain
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/diff"
|
||||
)
|
||||
|
||||
func TestFormatterWrite(t *testing.T) {
|
||||
@ -54,6 +56,30 @@ func TestFormatterWrappedWrite(t *testing.T) {
|
||||
f.Indent(10).WriteWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi at turpis faucibus, gravida dolor ut, fringilla velit.")
|
||||
// Test long words (especially urls) on their own line.
|
||||
f.Indent(20).WriteWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit. ThisIsAVeryLongWordThatDoesn'tFitOnALineOnItsOwn. Morbi at turpis faucibus, gravida dolor ut, fringilla velit.")
|
||||
// Test content that includes newlines, bullet points, and blockquotes/code blocks
|
||||
f.Indent(4).WriteWrapped(`
|
||||
This is an
|
||||
introductory paragraph
|
||||
that should end
|
||||
up on a continuous line.
|
||||
|
||||
Example:
|
||||
Example text on its own line
|
||||
|
||||
List:
|
||||
1. Item with
|
||||
wrapping text
|
||||
11. Another
|
||||
item with wrapping text
|
||||
* Bullet item
|
||||
with wrapping text
|
||||
- Dash item
|
||||
with wrapping text
|
||||
|
||||
base64(
|
||||
code goes here
|
||||
and here
|
||||
)`)
|
||||
|
||||
want := `Lorem ipsum dolor sit amet, consectetur adipiscing
|
||||
elit. Morbi at turpis faucibus, gravida dolor ut,
|
||||
@ -68,10 +94,26 @@ fringilla velit.
|
||||
Morbi at turpis faucibus,
|
||||
gravida dolor ut, fringilla
|
||||
velit.
|
||||
This is an introductory paragraph that should
|
||||
end up on a continuous line.
|
||||
|
||||
Example:
|
||||
Example text on its own line
|
||||
|
||||
List:
|
||||
1. Item with wrapping text
|
||||
11. Another item with wrapping text
|
||||
* Bullet item with wrapping text
|
||||
- Dash item with wrapping text
|
||||
|
||||
base64(
|
||||
code goes here
|
||||
and here
|
||||
)
|
||||
`
|
||||
|
||||
if buf.String() != want {
|
||||
t.Errorf("Got:\n%v\nWant:\n%v\n", buf.String(), want)
|
||||
t.Errorf("Diff:\n%s", diff.StringDiff(buf.String(), want))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user