Browse Source

Merge pull request #25568 from thaJeztah/enhance-string-truncate

Implement stringutils.Ellipsis()
Vincent Demeester 9 năm trước cách đây
mục cha
commit
64f83cee43

+ 2 - 2
api/client/formatter/container.go

@@ -124,7 +124,7 @@ func (c *containerContext) Command() string {
 	c.addHeader(commandHeader)
 	command := c.c.Command
 	if c.trunc {
-		command = stringutils.Truncate(command, 20)
+		command = stringutils.Ellipsis(command, 20)
 	}
 	return strconv.Quote(command)
 }
@@ -200,7 +200,7 @@ func (c *containerContext) Mounts() string {
 			name = m.Name
 		}
 		if c.trunc {
-			name = stringutils.Truncate(name, 15)
+			name = stringutils.Ellipsis(name, 15)
 		}
 		mounts = append(mounts, name)
 	}

+ 2 - 2
api/client/formatter/container_test.go

@@ -60,12 +60,12 @@ func TestContainerPsContext(t *testing.T) {
 		{types.Container{
 			Mounts: []types.MountPoint{
 				{
-					Name:   "733908409c91817de8e92b0096373245f329f19a88e2c849f02460e9b3d1c203",
+					Name:   "this-is-a-long-volume-name-and-will-be-truncated-if-trunc-is-set",
 					Driver: "local",
 					Source: "/a/path",
 				},
 			},
-		}, true, "733908409c91817", mountsHeader, ctx.Mounts},
+		}, true, "this-is-a-lo...", mountsHeader, ctx.Mounts},
 		{types.Container{
 			Mounts: []types.MountPoint{
 				{

+ 2 - 2
api/client/image/history.go

@@ -79,8 +79,8 @@ func runHistory(dockerCli *client.DockerCli, opts historyOptions) error {
 	for _, entry := range history {
 		imageID = entry.ID
 		createdBy = strings.Replace(entry.CreatedBy, "\t", " ", -1)
-		if opts.noTrunc == false {
-			createdBy = stringutils.Truncate(createdBy, 45)
+		if !opts.noTrunc {
+			createdBy = stringutils.Ellipsis(createdBy, 45)
 			imageID = stringid.TruncateID(entry.ID)
 		}
 

+ 2 - 2
api/client/image/search.go

@@ -109,8 +109,8 @@ func runSearch(dockerCli *client.DockerCli, opts searchOptions) error {
 		}
 		desc := strings.Replace(res.Description, "\n", " ", -1)
 		desc = strings.Replace(desc, "\r", " ", -1)
-		if !opts.noTrunc && len(desc) > 45 {
-			desc = stringutils.Truncate(desc, 42) + "..."
+		if !opts.noTrunc {
+			desc = stringutils.Ellipsis(desc, 45)
 		}
 		fmt.Fprintf(w, "%s\t%s\t%d\t", res.Name, desc, res.StarCount)
 		if res.IsOfficial {

+ 2 - 2
api/client/plugin/list.go

@@ -51,8 +51,8 @@ func runList(dockerCli *client.DockerCli, opts listOptions) error {
 	for _, p := range plugins {
 		desc := strings.Replace(p.Manifest.Description, "\n", " ", -1)
 		desc = strings.Replace(desc, "\r", " ", -1)
-		if !opts.noTrunc && len(desc) > 45 {
-			desc = stringutils.Truncate(desc, 42) + "..."
+		if !opts.noTrunc {
+			desc = stringutils.Ellipsis(desc, 45)
 		}
 
 		fmt.Fprintf(w, "%s\t%s\t%s\t%v\n", p.Name, p.Tag, desc, p.Active)

+ 16 - 2
pkg/stringutils/stringutils.go

@@ -32,12 +32,26 @@ func GenerateRandomASCIIString(n int) string {
 	return string(res)
 }
 
+// Ellipsis truncates a string to fit within maxlen, and appends ellipsis (...).
+// For maxlen of 3 and lower, no ellipsis is appended.
+func Ellipsis(s string, maxlen int) string {
+	r := []rune(s)
+	if len(r) <= maxlen {
+		return s
+	}
+	if maxlen <= 3 {
+		return string(r[:maxlen])
+	}
+	return string(r[:maxlen-3]) + "..."
+}
+
 // Truncate truncates a string to maxlen.
 func Truncate(s string, maxlen int) string {
-	if len(s) <= maxlen {
+	r := []rune(s)
+	if len(r) <= maxlen {
 		return s
 	}
-	return s[:maxlen]
+	return string(r[:maxlen])
 }
 
 // InSlice tests whether a string is contained in a slice of strings or not.

+ 24 - 8
pkg/stringutils/stringutils_test.go

@@ -57,24 +57,40 @@ func TestGenerateRandomAsciiStringIsAscii(t *testing.T) {
 	}
 }
 
+func TestEllipsis(t *testing.T) {
+	str := "t🐳ststring"
+	newstr := Ellipsis(str, 3)
+	if newstr != "t🐳s" {
+		t.Fatalf("Expected t🐳s, got %s", newstr)
+	}
+	newstr = Ellipsis(str, 8)
+	if newstr != "t🐳sts..." {
+		t.Fatalf("Expected tests..., got %s", newstr)
+	}
+	newstr = Ellipsis(str, 20)
+	if newstr != "t🐳ststring" {
+		t.Fatalf("Expected t🐳ststring, got %s", newstr)
+	}
+}
+
 func TestTruncate(t *testing.T) {
-	str := "teststring"
+	str := "t🐳ststring"
 	newstr := Truncate(str, 4)
-	if newstr != "test" {
-		t.Fatalf("Expected test, got %s", newstr)
+	if newstr != "t🐳st" {
+		t.Fatalf("Expected t🐳st, got %s", newstr)
 	}
 	newstr = Truncate(str, 20)
-	if newstr != "teststring" {
-		t.Fatalf("Expected teststring, got %s", newstr)
+	if newstr != "t🐳ststring" {
+		t.Fatalf("Expected t🐳ststring, got %s", newstr)
 	}
 }
 
 func TestInSlice(t *testing.T) {
-	slice := []string{"test", "in", "slice"}
+	slice := []string{"t🐳st", "in", "slice"}
 
-	test := InSlice(slice, "test")
+	test := InSlice(slice, "t🐳st")
 	if !test {
-		t.Fatalf("Expected string test to be in slice")
+		t.Fatalf("Expected string t🐳st to be in slice")
 	}
 	test = InSlice(slice, "SLICE")
 	if !test {