From 1ea1a5749e048400390ad4e73a63968f430696cf Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Thu, 18 Oct 2018 14:45:50 -0400 Subject: [PATCH] docker-ex: something like `docker images` with emoji digest Signed-off-by: Vincent Batts --- docker-ex/main.go | 110 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docker-ex/main.go diff --git a/docker-ex/main.go b/docker-ex/main.go new file mode 100644 index 0000000..1144112 --- /dev/null +++ b/docker-ex/main.go @@ -0,0 +1,110 @@ +package main + +import ( + "encoding/hex" + "encoding/json" + "flag" + "fmt" + "io" + "os" + "os/exec" + "strings" + + esum "github.com/emojisum/emojisum/emoji" +) + +var ( + flJson = flag.Bool("json", false, "output json (no emoji)") + formatOutput = ` +{ + "repo": "{{.Repository}}", + "id": "{{.ID}}", + "digest": "{{.Digest}}", + "tag": "{{.Tag}}", + "createdSince": "{{.CreatedSince}}", + "createdAt": "{{.CreatedAt}}", + "size": "{{.Size}}" +} +` +) + +func main() { + flag.Parse() + args := []string{"images", "--digests", fmt.Sprintf("--format=%s", formatOutput)} + args = append(args, flag.Args()...) + cmd := exec.Command("docker", args...) + + if !*flJson { + pR, pW := io.Pipe() + cmd.Stdout = pW + jR := json.NewDecoder(pR) + go func() { + for { + it := ImageThing{} + err := jR.Decode(&it) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + var digest, d, h string + var name string + + if it.Tag == "" { + name = it.Repo + } else { + name = fmt.Sprintf("%s:%s", it.Repo, it.Tag) + } + + if strings.Contains(it.Digest, ":") { + chunks := strings.SplitN(it.Digest, ":", 2) + h = chunks[0] + d, err = emojiFromHexString(chunks[1]) + if err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } + digest = fmt.Sprintf("%s:%s", h, d) + } else { + digest = "" + } + + fmt.Printf("%s (id %s) %s\n", name, it.ID, digest) + } + }() + } else { + cmd.Stdout = os.Stdout + } + + cmd.Stdin = os.Stdin + cmd.Stderr = os.Stderr + cmd.Run() +} + +func emojiFromHexString(s string) (string, error) { + d, err := hex.DecodeString(s) + if err != nil { + return "", err + } + + var ret string + for _, b := range d { + for _, e := range esum.Map(b) { + // use the first colon notation word and continue + if esum.IsCodepoint(e) { + ret = ret + esum.CodepointToUnicode(e) + break + } + } + } + return ret, nil +} + +type ImageThing struct { + Repo string + ID string + Digest string + Tag string + CreateSince string + CreateAt string + Size string +}