From cd9da59718239d92ae6923e29fa2ed7a8e8d7a14 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Wed, 29 Mar 2023 03:32:09 -0500 Subject: [PATCH 1/3] Added test command for consistent output --- cmd/zrok/shareTest.go | 97 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 cmd/zrok/shareTest.go diff --git a/cmd/zrok/shareTest.go b/cmd/zrok/shareTest.go new file mode 100644 index 00000000..1e959c10 --- /dev/null +++ b/cmd/zrok/shareTest.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "strings" + + tea "github.com/charmbracelet/bubbletea" + "github.com/muesli/reflow/wordwrap" + "github.com/openziti/zrok/tui" + "github.com/spf13/cobra" +) + +var testA = "[13.845] DEBUG sdk-golang/ziti/edge/impl. (*edgeConn) .Accept: {edgeSeq= [2] vid=[invalid- vid-size-of-0-bytes] connId= [2147483694] type= [EdgeDataType] chSeq= [7]} receivedddddd 567 bytes (msg type: 60786)" + +var testB = "[] Hello this is a test to see if word wrapping works propery. {Need to pad space. WhathappensifIputareallylongwordwithnobreakswillitcutthewordorwillitproperlyloverflow and then (a new line)} ()ß" + +func init() { + testCmd.AddCommand(newShareTestCommand().cmd) +} + +type shareTestCommand struct { + headless bool + cmd *cobra.Command +} + +func newShareTestCommand() *shareTestCommand { + cmd := &cobra.Command{ + Use: "share ", + Short: "Share a target resource publicly", + Args: cobra.ExactArgs(1), + } + command := &shareTestCommand{cmd: cmd} + cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") + + cmd.Run = command.run + return command +} + +func (cmd *shareTestCommand) run(_ *cobra.Command, args []string) { + w := 167 + if !cmd.headless { + mdl := newShareModel("token", []string{"Endpoints"}, "shareMode", "backendMode") + prg := tea.NewProgram(mdl, tea.WithAltScreen()) + mdl.prg = prg + + go func() { + mdl.Write([]byte(testA)) + mdl.Write([]byte(testB)) + }() + + if _, err := prg.Run(); err != nil { + tui.Error("An error occurred", err) + } + } else { + for i := w; i >= 0; i = i - 10 { + fmt.Println("-----------------------------") + fmt.Printf("Width: %d\n", i) + out, n := plainTextRender(i, testA) + fmt.Println(out) + fmt.Printf("Expected lines: %d\n", n) + fmt.Println("-----------------------------") + } + } +} + +func plainTextRender(width int, logs ...string) (string, int) { + var splitLines []string + for _, line := range logs { + wrapped := wordwrap.String(line, width) + + wrappedLines := strings.Split(wrapped, "\n") + for _, wrappedLine := range wrappedLines { + splitLine := strings.ReplaceAll(wrappedLine, "\n", "") + if splitLine != "" { + splitLines = append(splitLines, splitLine) + } + } + } + maxRows := shareLogStyle.GetHeight() + maxRows = 999 + startRow := 0 + if len(splitLines) > maxRows { + startRow = len(splitLines) - maxRows + } + out := "" + n := 0 + for i := startRow; i < len(splitLines); i++ { + outLine := splitLines[i] + n++ + if i < len(splitLines)-1 { + outLine += "\n" + } + out += outLine + } + return out, n + +} From 2791b7d835fb50b087b93c9956169148ff5d2f80 Mon Sep 17 00:00:00 2001 From: Cam Otts Date: Tue, 4 Apr 2023 09:21:33 -0500 Subject: [PATCH 2/3] added manual wrapping to be done after reflow package --- cmd/zrok/shareTest.go | 97 ------------------------------------------- cmd/zrok/shareTui.go | 42 ++++++++++++++++++- 2 files changed, 40 insertions(+), 99 deletions(-) delete mode 100644 cmd/zrok/shareTest.go diff --git a/cmd/zrok/shareTest.go b/cmd/zrok/shareTest.go deleted file mode 100644 index 1e959c10..00000000 --- a/cmd/zrok/shareTest.go +++ /dev/null @@ -1,97 +0,0 @@ -package main - -import ( - "fmt" - "strings" - - tea "github.com/charmbracelet/bubbletea" - "github.com/muesli/reflow/wordwrap" - "github.com/openziti/zrok/tui" - "github.com/spf13/cobra" -) - -var testA = "[13.845] DEBUG sdk-golang/ziti/edge/impl. (*edgeConn) .Accept: {edgeSeq= [2] vid=[invalid- vid-size-of-0-bytes] connId= [2147483694] type= [EdgeDataType] chSeq= [7]} receivedddddd 567 bytes (msg type: 60786)" - -var testB = "[] Hello this is a test to see if word wrapping works propery. {Need to pad space. WhathappensifIputareallylongwordwithnobreakswillitcutthewordorwillitproperlyloverflow and then (a new line)} ()ß" - -func init() { - testCmd.AddCommand(newShareTestCommand().cmd) -} - -type shareTestCommand struct { - headless bool - cmd *cobra.Command -} - -func newShareTestCommand() *shareTestCommand { - cmd := &cobra.Command{ - Use: "share ", - Short: "Share a target resource publicly", - Args: cobra.ExactArgs(1), - } - command := &shareTestCommand{cmd: cmd} - cmd.Flags().BoolVar(&command.headless, "headless", false, "Disable TUI and run headless") - - cmd.Run = command.run - return command -} - -func (cmd *shareTestCommand) run(_ *cobra.Command, args []string) { - w := 167 - if !cmd.headless { - mdl := newShareModel("token", []string{"Endpoints"}, "shareMode", "backendMode") - prg := tea.NewProgram(mdl, tea.WithAltScreen()) - mdl.prg = prg - - go func() { - mdl.Write([]byte(testA)) - mdl.Write([]byte(testB)) - }() - - if _, err := prg.Run(); err != nil { - tui.Error("An error occurred", err) - } - } else { - for i := w; i >= 0; i = i - 10 { - fmt.Println("-----------------------------") - fmt.Printf("Width: %d\n", i) - out, n := plainTextRender(i, testA) - fmt.Println(out) - fmt.Printf("Expected lines: %d\n", n) - fmt.Println("-----------------------------") - } - } -} - -func plainTextRender(width int, logs ...string) (string, int) { - var splitLines []string - for _, line := range logs { - wrapped := wordwrap.String(line, width) - - wrappedLines := strings.Split(wrapped, "\n") - for _, wrappedLine := range wrappedLines { - splitLine := strings.ReplaceAll(wrappedLine, "\n", "") - if splitLine != "" { - splitLines = append(splitLines, splitLine) - } - } - } - maxRows := shareLogStyle.GetHeight() - maxRows = 999 - startRow := 0 - if len(splitLines) > maxRows { - startRow = len(splitLines) - maxRows - } - out := "" - n := 0 - for i := startRow; i < len(splitLines); i++ { - outLine := splitLines[i] - n++ - if i < len(splitLines)-1 { - outLine += "\n" - } - out += outLine - } - return out, n - -} diff --git a/cmd/zrok/shareTui.go b/cmd/zrok/shareTui.go index 42da905a..123b8868 100644 --- a/cmd/zrok/shareTui.go +++ b/cmd/zrok/shareTui.go @@ -2,16 +2,20 @@ package main import ( "fmt" + "strings" + "time" + tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/muesli/reflow/wordwrap" "github.com/openziti/zrok/endpoints" - "strings" - "time" ) const shareTuiBacklog = 256 +var wordwrapCharacters = " -" +var wordwrapBreakpoints = map[rune]bool{' ': true, '-': true} + type shareModel struct { shrToken string frontendDescriptions []string @@ -144,6 +148,7 @@ func (m *shareModel) renderRequests() string { } } } + requestLines = wrap(requestLines, m.width-2) maxRows := shareRequestsStyle.GetHeight() startRow := 0 if len(requestLines) > maxRows { @@ -183,6 +188,7 @@ func (m *shareModel) renderLog() string { } } } + splitLines = wrap(splitLines, m.width-2) maxRows := shareLogStyle.GetHeight() startRow := 0 if len(splitLines) > maxRows { @@ -211,6 +217,38 @@ func (m *shareModel) Write(p []byte) (n int, err error) { return len(p), nil } +func wrap(lines []string, width int) []string { + ret := make([]string, 0) + for _, line := range lines { + if width <= 0 || len(line) <= width { + ret = append(ret, line) + continue + } + for i := 0; i <= len(line); { + max := i + width + if max > len(line) { + max = len(line) + } + if line[i:max] == "" { + continue + } + nextI := i + width + if max < len(line)-1 { + if !wordwrapBreakpoints[rune(line[max])] || !wordwrapBreakpoints[rune(line[max+1])] { + lastSpace := strings.LastIndexAny(line[:max], wordwrapCharacters) + if lastSpace > -1 { + max = lastSpace + nextI = lastSpace + } + } + } + ret = append(ret, strings.TrimSpace(line[i:max])) + i = nextI + } + } + return ret +} + var shareHeaderStyle = lipgloss.NewStyle(). BorderStyle(lipgloss.RoundedBorder()). BorderForeground(lipgloss.Color("63")). From 807b3b7148c3363a2fc06a0621bd4830aa3ad39b Mon Sep 17 00:00:00 2001 From: Michael Quigley Date: Tue, 25 Apr 2023 15:17:09 -0400 Subject: [PATCH 3/3] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8de8ddb8..4337ac39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# v0.3.7 + +FIX: Improved TUI word-wrapping (https://github.com/openziti/zrok/issues/180) + # v0.3.6 CHANGE: Additional change to support branch builds (for CI purposes) and additional containerization efforts around k8s.