Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the CLI #2

Merged
merged 3 commits into from May 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 31 additions & 0 deletions .gitignore
@@ -0,0 +1,31 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so

# Folders
_obj
_test

# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out

*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*

_testmain.go

*.exe
*.test
*.prof
/ksuid

# Emacs
*~

# govendor
/vendor/*/
128 changes: 105 additions & 23 deletions cmd/ksuid/main.go
@@ -1,23 +1,84 @@
package main

import (
"bytes"
"encoding/hex"
"flag"
"fmt"
"html/template"
"io"
"os"
"strings"
"time"

"github.com/segmentio/ksuid"
)

const usage = `
Usage: ksuid <ksuid>
ksuid
ksuid --help
var (
count int
format string
tpltxt string
verbose bool
)

Generates and inspects KSUIDs
`
func init() {
flag.IntVar(&count, "n", 1, "Number of KSUIDs to generate when called with no other arguments.")
flag.StringVar(&format, "f", "inspect", "One of inspect, time, timestamp, payload, raw, or template.")
flag.StringVar(&tpltxt, "t", "", "The Go template used to format the output.")
flag.BoolVar(&verbose, "v", false, "Turn on verbose mode.")
}

func main() {
flag.Parse()
args := flag.Args()

const inspectFormat = `
var print func(ksuid.KSUID)
switch format {
case "inspect":
print = printInspect
case "time":
print = printTime
case "timestamp":
print = printTimestamp
case "payload":
print = printPayload
case "raw":
print = printRaw
case "template":
print = printTemplate
default:
fmt.Println("Bad formatting function:", format)
os.Exit(1)
}

if len(args) == 0 {
for i := 0; i < count; i++ {
fmt.Println(ksuid.New())
}
os.Exit(0)
}

var ids []ksuid.KSUID
for _, arg := range args {
id, err := ksuid.Parse(arg)
if err != nil {
fmt.Printf("Error when parsing %q: %s\n\n", arg, err)
flag.PrintDefaults()
os.Exit(1)
}
ids = append(ids, id)
}

for _, id := range ids {
if verbose {
fmt.Printf("%s: ", id)
}
print(id)
}
}

func printInspect(id ksuid.KSUID) {
const inspectFormat = `
REPRESENTATION:

String: %v
Expand All @@ -30,26 +91,47 @@ COMPONENTS:
Payload: %v

`

func main() {
if len(os.Args) < 2 {
fmt.Println(ksuid.New())
os.Exit(0)
}

id, err := ksuid.Parse(os.Args[1])
if err != nil {
fmt.Println("Error when parsing: ", err)
fmt.Println()
fmt.Println(usage)
os.Exit(1)
}

fmt.Printf(inspectFormat,
id.String(),
strings.ToUpper(hex.EncodeToString(id.Bytes())),
id.Time(),
id.Timestamp(),
strings.ToUpper(hex.EncodeToString(id.Payload())))
strings.ToUpper(hex.EncodeToString(id.Payload())),
)
}

func printTime(id ksuid.KSUID) {
fmt.Println(id.Time())
}

func printTimestamp(id ksuid.KSUID) {
fmt.Println(id.Timestamp())
}

func printPayload(id ksuid.KSUID) {
os.Stdout.Write(id.Payload())
}

func printRaw(id ksuid.KSUID) {
os.Stdout.Write(id.Bytes())
}

func printTemplate(id ksuid.KSUID) {
b := &bytes.Buffer{}
t := template.Must(template.New("").Parse(tpltxt))
t.Execute(b, struct {
String string
Raw string
Time time.Time
Timestamp uint32
Payload string
}{
String: id.String(),
Raw: strings.ToUpper(hex.EncodeToString(id.Bytes())),
Time: id.Time(),
Timestamp: id.Timestamp(),
Payload: strings.ToUpper(hex.EncodeToString(id.Payload())),
})
b.WriteByte('\n')
io.Copy(os.Stdout, b)
}