This fix ignore some functions in the Go template when header is
redendered, so that `--format "{{truncate .ID 1}}"` will still
be able to redener the header correctly.
Additional test cases have been added to the unit test.
Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
... | ... |
@@ -226,6 +226,14 @@ size: 0B |
226 | 226 |
Context{Format: NewContainerFormat("{{.Image}}", false, true)}, |
227 | 227 |
"ubuntu\nubuntu\n", |
228 | 228 |
}, |
229 |
+ // Special headers for customerized table format |
|
230 |
+ { |
|
231 |
+ Context{Format: NewContainerFormat(`table {{truncate .ID 5}}\t{{json .Image}} {{.RunningFor}}/{{title .Status}}/{{pad .Ports 2 2}}.{{upper .Names}} {{lower .Status}}`, false, true)}, |
|
232 |
+ `CONTAINER ID IMAGE CREATED/STATUS/ PORTS .NAMES STATUS |
|
233 |
+conta "ubuntu" 24 hours ago//.FOOBAR_BAZ |
|
234 |
+conta "ubuntu" 24 hours ago//.FOOBAR_BAR |
|
235 |
+`, |
|
236 |
+ }, |
|
229 | 237 |
} |
230 | 238 |
|
231 | 239 |
for _, testcase := range cases { |
... | ... |
@@ -2,13 +2,8 @@ package formatter |
2 | 2 |
|
3 | 3 |
import ( |
4 | 4 |
"bytes" |
5 |
- //"encoding/json" |
|
6 |
- //"strings" |
|
7 | 5 |
"testing" |
8 |
- //"time" |
|
9 | 6 |
|
10 |
- //"github.com/docker/docker/api/types" |
|
11 |
- //"github.com/docker/docker/pkg/stringid" |
|
12 | 7 |
"github.com/docker/docker/pkg/testutil/assert" |
13 | 8 |
) |
14 | 9 |
|
... | ... |
@@ -44,10 +39,6 @@ VOLUME NAME LINKS SIZE |
44 | 44 |
} |
45 | 45 |
|
46 | 46 |
for _, testcase := range cases { |
47 |
- //networks := []types.NetworkResource{ |
|
48 |
- // {ID: "networkID1", Name: "foobar_baz", Driver: "foo", Scope: "local", Created: timestamp1}, |
|
49 |
- // {ID: "networkID2", Name: "foobar_bar", Driver: "bar", Scope: "local", Created: timestamp2}, |
|
50 |
- //} |
|
51 | 47 |
out := bytes.NewBufferString("") |
52 | 48 |
testcase.context.Output = out |
53 | 49 |
testcase.context.Write() |
... | ... |
@@ -73,7 +73,7 @@ func (c *Context) postFormat(tmpl *template.Template, subContext subContext) { |
73 | 73 |
if c.Format.IsTable() { |
74 | 74 |
t := tabwriter.NewWriter(c.Output, 20, 1, 3, ' ', 0) |
75 | 75 |
buffer := bytes.NewBufferString("") |
76 |
- tmpl.Execute(buffer, subContext.FullHeader()) |
|
76 |
+ tmpl.Funcs(templates.HeaderFunctions).Execute(buffer, subContext.FullHeader()) |
|
77 | 77 |
buffer.WriteTo(t) |
78 | 78 |
t.Write([]byte("\n")) |
79 | 79 |
c.buffer.WriteTo(t) |
... | ... |
@@ -76,20 +76,6 @@ func ImageWrite(ctx ImageContext, images []types.ImageSummary) error { |
76 | 76 |
render := func(format func(subContext subContext) error) error { |
77 | 77 |
return imageFormat(ctx, images, format) |
78 | 78 |
} |
79 |
- imageCtx := imageContext{} |
|
80 |
- imageCtx.header = map[string]string{ |
|
81 |
- "ID": imageIDHeader, |
|
82 |
- "Repository": repositoryHeader, |
|
83 |
- "Tag": tagHeader, |
|
84 |
- "Digest": digestHeader, |
|
85 |
- "CreatedSince": createdSinceHeader, |
|
86 |
- "CreatedAt": createdAtHeader, |
|
87 |
- "Size": sizeHeader, |
|
88 |
- "Containers": containersHeader, |
|
89 |
- "VirtualSize": sizeHeader, |
|
90 |
- "SharedSize": sharedSizeHeader, |
|
91 |
- "UniqueSize": uniqueSizeHeader, |
|
92 |
- } |
|
93 | 79 |
return ctx.Write(newImageContext(), render) |
94 | 80 |
} |
95 | 81 |
|
... | ... |
@@ -22,6 +22,28 @@ var basicFunctions = template.FuncMap{ |
22 | 22 |
"truncate": truncateWithLength, |
23 | 23 |
} |
24 | 24 |
|
25 |
+// HeaderFunctions are used to created headers of a table. |
|
26 |
+// This is a replacement of basicFunctions for header generation |
|
27 |
+// because we want the header to remain intact. |
|
28 |
+// Some functions like `split` are irrevelant so not added. |
|
29 |
+var HeaderFunctions = template.FuncMap{ |
|
30 |
+ "json": func(v string) string { |
|
31 |
+ return v |
|
32 |
+ }, |
|
33 |
+ "title": func(v string) string { |
|
34 |
+ return v |
|
35 |
+ }, |
|
36 |
+ "lower": func(v string) string { |
|
37 |
+ return v |
|
38 |
+ }, |
|
39 |
+ "upper": func(v string) string { |
|
40 |
+ return v |
|
41 |
+ }, |
|
42 |
+ "truncate": func(v string, l int) string { |
|
43 |
+ return v |
|
44 |
+ }, |
|
45 |
+} |
|
46 |
+ |
|
25 | 47 |
// Parse creates a new anonymous template with the basic functions |
26 | 48 |
// and parses the given format. |
27 | 49 |
func Parse(format string) (*template.Template, error) { |