From 4e76d357100089c96827799a9756fb57e3fb2da7 Mon Sep 17 00:00:00 2001 From: Qiu Jian Date: Fri, 20 Aug 2021 09:32:19 +0800 Subject: [PATCH] fix: truncate columns longer than 512 bytes by default Set OS_MAX_COLUMN_TEXT_LENGTH=-1 to disable auto text truncation --- pkg/util/printutils/printjson.go | 37 ++++++++++++++++++++++-- pkg/util/printutils/termwidth_unix.go | 32 ++++++++++++++++++++ pkg/util/printutils/termwidth_windows.go | 34 ++++++++++++++++++++++ 3 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 pkg/util/printutils/termwidth_unix.go create mode 100644 pkg/util/printutils/termwidth_windows.go diff --git a/pkg/util/printutils/printjson.go b/pkg/util/printutils/printjson.go index 95850873b9..e9da1dadb0 100644 --- a/pkg/util/printutils/printjson.go +++ b/pkg/util/printutils/printjson.go @@ -18,6 +18,7 @@ import ( "fmt" "os" "sort" + "strconv" "strings" "yunion.io/x/jsonutils" @@ -60,10 +61,33 @@ func PrintJSONList(list *modulebase.ListResult, columns []string) { } } } - osTryTermWidth := os.Getenv("OS_TRY_TERM_WIDTH") + + const ( + OS_MAX_COLUMN_TEXT_LENGTH = "OS_MAX_COLUMN_TEXT_LENGTH" + OS_TRY_TERM_WIDTH = "OS_TRY_TERM_WIDTH" + + defaultMaxColLength = 512 + ) + maxColLength := int64(-1) + colTruncated := false tryTermWidth := false - if strings.ToLower(osTryTermWidth) == "true" { - tryTermWidth = true + screenWidth, _ := termWidth() + if screenWidth > 0 { + // the width of screen is available, which is an interactive shell + // truncate the text to make it prettier + osMaxTextLength := os.Getenv(OS_MAX_COLUMN_TEXT_LENGTH) + if len(osMaxTextLength) > 0 { + maxColLength, _ = strconv.ParseInt(osMaxTextLength, 10, 64) + if maxColLength >= 0 && maxColLength < 3 { + maxColLength = defaultMaxColLength + } + } else { + maxColLength = defaultMaxColLength + } + osTryTermWidth := os.Getenv(OS_TRY_TERM_WIDTH) + if strings.ToLower(osTryTermWidth) == "true" { + tryTermWidth = true + } } pt := prettytable.NewPrettyTableWithTryTermWidth(colsWithData, tryTermWidth) rows := make([][]string, 0) @@ -73,6 +97,10 @@ func PrintJSONList(list *modulebase.ListResult, columns []string) { v, e := obj.GetIgnoreCases(k) if e == nil { s, _ := v.GetString() + if maxColLength > 0 && int64(len(s)) > maxColLength { + s = s[0:maxColLength-3] + "..." + colTruncated = true + } row = append(row, s) } else { row = append(row, "") @@ -106,6 +134,9 @@ func PrintJSONList(list *modulebase.ListResult, columns []string) { } } fmt.Println("*** ", title, " ***") + if colTruncated { + fmt.Println(fmt.Sprintf("!!!Some text truncated, set env %s=-1 to show full text!!!", OS_MAX_COLUMN_TEXT_LENGTH)) + } } func printJSONObject(dict *jsonutils.JSONDict, cb PrintJSONObjectFunc) { diff --git a/pkg/util/printutils/termwidth_unix.go b/pkg/util/printutils/termwidth_unix.go new file mode 100644 index 0000000000..456d978f72 --- /dev/null +++ b/pkg/util/printutils/termwidth_unix.go @@ -0,0 +1,32 @@ +// Copyright 2019 Yunion + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build !windows + +package printutils + +import ( + "os" + + "golang.org/x/sys/unix" +) + +func termWidth() (int, error) { + fd := int(os.Stdout.Fd()) + wsz, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ) + if err != nil { + return -1, err + } + return int(wsz.Col), nil +} diff --git a/pkg/util/printutils/termwidth_windows.go b/pkg/util/printutils/termwidth_windows.go new file mode 100644 index 0000000000..b7b85b0ae3 --- /dev/null +++ b/pkg/util/printutils/termwidth_windows.go @@ -0,0 +1,34 @@ +// Copyright 2019 Yunion + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// +build windows + +package printutils + +import ( + "os" + + "golang.org/x/sys/windows" +) + +func termWidth() (int, error) { + var ( + h = windows.Handle(os.Stdout.Fd()) + info windows.ConsoleScreenBufferInfo + ) + if err := windows.GetConsoleScreenBufferInfo(h, &info); err != nil { + return -1, err + } + return int(info.Size.X), nil +}