-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdi-images.go
140 lines (120 loc) · 4.44 KB
/
di-images.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import(
"fmt"
"bytes"
"strings"
)
type Image struct {
Id string
ParentId string
RepoTags []string
VirtualSize int64
Size int64
Created int64
}
/********************************************************************************
* PRINT IMAGES TREE FUNCTIONS
********************************************************************************/
func printImages(images []Image, byParent map[string][]Image, noTrunc bool, incremental bool) string {
var buffer bytes.Buffer
initialPrefix := ""
printAsTree(&buffer, images, byParent, noTrunc, incremental, initialPrefix)
return buffer.String()
}
func printAsTree(buffer *bytes.Buffer, images []Image, byParent map[string][]Image, shouldTruncate bool, incremental bool, prefix string) {
var length = len(images)
if length > 1 {
for idx, image := range images {
var nextPrefix string = ""
if (idx + 1) == length {
printTreeNode(buffer, image, shouldTruncate, incremental, prefix + "└─")
nextPrefix = " "
} else {
printTreeNode(buffer, image, shouldTruncate, incremental, prefix + "├─")
nextPrefix = "│ "
}
if subimages, exists := byParent[image.Id]; exists {
printAsTree(buffer, subimages, byParent, shouldTruncate, incremental, prefix + nextPrefix)
}
}
} else {
for _, image := range images {
printTreeNode(buffer, image, shouldTruncate, incremental, prefix + "└─")
if subimages, exists := byParent[image.Id]; exists {
printAsTree(buffer, subimages, byParent, shouldTruncate, incremental, prefix + " ")
}
}
}
}
func printTreeNode(buffer *bytes.Buffer, image Image, shouldTruncate bool, incremental bool, prefix string) {
var imageID string
if shouldTruncate {
imageID = truncateId(image.Id)
} else {
imageID = image.Id
}
var size int64
if incremental {
size = image.VirtualSize
} else {
size = image.Size
}
buffer.WriteString(fmt.Sprintf("%s %s -- Virtual Size: %s", prefix, imageID, convertToHumanReadableSize(size)))
if image.RepoTags[0] != "<none>:<none>" {
buffer.WriteString(fmt.Sprintf(" Tags: %s\n", strings.Join(image.RepoTags, ", ")))
} else {
buffer.WriteString(fmt.Sprintf("\n"))
}
}
/********************************************************************************
* UTILITY FUNCTIONS
********************************************************************************/
func collectRoots(images *[]Image) []Image {
var roots []Image
for _, image := range *images {
if image.ParentId == "" {
roots = append(roots, image)
}
}
return roots
}
func collectChildren(images *[]Image) map[string][]Image {
var imagesByParent = make(map[string][]Image)
for _, image := range *images {
if children, exists := imagesByParent[image.ParentId]; exists {
imagesByParent[image.ParentId] = append(children, image)
} else {
imagesByParent[image.ParentId] = []Image{image}
}
}
return imagesByParent
}
func filterOnlyLabeledImages(images *[]Image, byParent *map[string][]Image) (filteredImages []Image, filteredChildren map[string][]Image) {
for i := 0; i < len(*images); i++ {
// image should visible
// 1. it has a label
// 2. it is root
// 3. it is a node
visible := ((*images)[i].RepoTags[0] != "<none>:<none>") ||
((*images)[i].ParentId == "") ||
(len((*byParent)[(*images)[i].Id]) > 1)
if visible {
filteredImages = append(filteredImages, (*images)[i])
} else {
// change childs parent id
// if items are filtered with only one child
for j := 0; j < len(filteredImages); j++ {
if (filteredImages[j].ParentId == (*images)[i].Id) {
filteredImages[j].ParentId = (*images)[i].ParentId
}
}
for j := 0; j < len(*images); j++ {
if ((*images)[j].ParentId == (*images)[i].Id) {
(*images)[j].ParentId = (*images)[i].ParentId
}
}
}
}
filteredChildren = collectChildren(&filteredImages)
return filteredImages, filteredChildren
}