feat: Add custom help text
parent
40c62216ec
commit
9d2245f72e
3
Makefile
3
Makefile
|
@ -1,9 +1,8 @@
|
|||
DOGGO-BIN := doggo.bin
|
||||
|
||||
HASH := $(shell git rev-parse --short HEAD)
|
||||
COMMIT_DATE := $(shell git show -s --format=%ci ${HASH})
|
||||
BUILD_DATE := $(shell date '+%Y-%m-%d %H:%M:%S')
|
||||
VERSION := ${HASH} (${COMMIT_DATE})
|
||||
VERSION := ${HASH}
|
||||
|
||||
.PHONY: build
|
||||
build: ## Build the doggo binary
|
||||
|
|
22
TODO.md
22
TODO.md
|
@ -1,4 +1,4 @@
|
|||
# doggo - v1.0 Milestone
|
||||
# doggo - Initial Release Milestone
|
||||
|
||||
## Resolver
|
||||
- [x] Create a DNS Resolver struct
|
||||
|
@ -6,20 +6,22 @@
|
|||
- [x] Add a resolve method
|
||||
- [x] Make it separate from Hub
|
||||
- [x] Parse output into separate fields
|
||||
- [ ] Test IPv6
|
||||
- [ ] Test IPv6/IPv4 only options
|
||||
- [x] Add DOH support
|
||||
- [x] Add DOT support
|
||||
- [x] Add DNS protocol on TCP mode support.
|
||||
- [ ] Error on NXDomain (Realted upstream [bug](https://github.com/miekg/dns/issues/1198))
|
||||
- [ ] Support all DNS records?
|
||||
- [x] Major records supported
|
||||
|
||||
## CLI Features
|
||||
- [ ] `digfile`
|
||||
- [x] `ndots` support
|
||||
- [ ] `ndots` support
|
||||
- [x] `search list` support
|
||||
- [x] JSON output
|
||||
- [x] Colorized output
|
||||
- [x] Table output
|
||||
- [ ] Parsing options free-form
|
||||
- [x] Parsing options free-form
|
||||
- [x] Remove urfave/cli in favour of `flag`
|
||||
|
||||
## CLI Grunt
|
||||
|
@ -27,15 +29,27 @@
|
|||
- [x] Neatly package them to load args in different functions
|
||||
- [x] Upper case is not mandatory for query type/classes
|
||||
- [x] Output
|
||||
- [ ] Custom Help Text
|
||||
- [x] Add examples
|
||||
- [ ] Colorize
|
||||
- [ ] Add different commands
|
||||
- [x] Add client transport options
|
||||
- [ ] Fix an issue while loading free form args, where the same records are being added twice
|
||||
|
||||
## Tests
|
||||
|
||||
## Documentation
|
||||
|
||||
- [ ] Mkdocs init project
|
||||
- [ ] Custom Index (Landing Page)
|
||||
|
||||
## Release Checklist
|
||||
- [ ] Goreleaser
|
||||
- [ ] Snap
|
||||
- [ ] Homebrew
|
||||
- [ ] ARM
|
||||
|
||||
|
||||
## v1.0
|
||||
|
||||
- [ ] Support obscure protocal tweaks in `dig`
|
||||
|
|
27
cmd/cli.go
27
cmd/cli.go
|
@ -1,11 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/knadh/koanf"
|
||||
"github.com/knadh/koanf/providers/posflag"
|
||||
"github.com/sirupsen/logrus"
|
||||
flag "github.com/spf13/pflag"
|
||||
)
|
||||
|
||||
|
@ -27,10 +27,7 @@ func main() {
|
|||
// Configure Flags
|
||||
// Use the POSIX compliant pflag lib instead of Go's flag lib.
|
||||
f := flag.NewFlagSet("config", flag.ContinueOnError)
|
||||
f.Usage = func() {
|
||||
fmt.Println(f.FlagUsages())
|
||||
os.Exit(0)
|
||||
}
|
||||
f.Usage = renderCustomHelp
|
||||
// Path to one or more config files to load into koanf along with some config params.
|
||||
f.StringSliceP("query", "q", []string{}, "Domain name to query")
|
||||
f.StringSliceP("type", "t", []string{}, "Type of DNS record to be queried (A, AAAA, MX etc)")
|
||||
|
@ -50,26 +47,32 @@ func main() {
|
|||
// Output Options
|
||||
f.BoolP("json", "J", false, "Set the output format as JSON")
|
||||
f.Bool("time", false, "Display how long it took for the response to arrive")
|
||||
f.Bool("color", true, "Show colored output")
|
||||
f.Bool("debug", false, "Enable debug mode")
|
||||
|
||||
// Parse and Load Flags
|
||||
f.Parse(os.Args[1:])
|
||||
if err := k.Load(posflag.Provider(f, ".", k), nil); err != nil {
|
||||
hub.Logger.Fatalf("error loading flags: %v", err)
|
||||
fmt.Println(f.FlagUsages())
|
||||
os.Exit(0)
|
||||
hub.Logger.Errorf("error loading flags: %v", err)
|
||||
f.Usage()
|
||||
hub.Logger.Exit(2)
|
||||
}
|
||||
// set log level
|
||||
if k.Bool("debug") {
|
||||
// Set logger level
|
||||
hub.Logger.SetLevel(logrus.DebugLevel)
|
||||
} else {
|
||||
hub.Logger.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
|
||||
// Run the app.
|
||||
hub.Logger.Debug("Starting doggo...")
|
||||
hub.Logger.Debug("Starting doggo 🐶")
|
||||
|
||||
// Parse Query Args
|
||||
hub.loadQueryArgs()
|
||||
|
||||
// Start App
|
||||
if len(hub.QueryFlags.QNames) == 0 {
|
||||
fmt.Println(f.FlagUsages())
|
||||
os.Exit(0)
|
||||
f.Usage()
|
||||
}
|
||||
hub.Lookup()
|
||||
|
||||
|
|
47
cmd/help.go
47
cmd/help.go
|
@ -1,21 +1,42 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"html/template"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Override Help Template
|
||||
var helpTmpl = `NAME:
|
||||
{{.Name}}
|
||||
{{ range $key, $value := . }}
|
||||
<li><strong>{{ $key }}</strong>: {{ $value }}</li>
|
||||
{{ end }}
|
||||
// AppHelpTemplate is the text template to customise the Help output.
|
||||
// Uses text/template to render templates.
|
||||
var AppHelpTemplate = `NAME:
|
||||
{{.Name}} {{.Description}}
|
||||
|
||||
USAGE:
|
||||
{{.Name}} [OPTIONS] [--] <arguments>
|
||||
|
||||
VERSION:
|
||||
{{.Version}} Built at {{.Date}}
|
||||
|
||||
EXAMPLES:
|
||||
doggo mrkaran.dev Query a domain using defaults
|
||||
doggo mrkaran.dev CNAME Looks up for a CNAME record.
|
||||
doggo mrkaran.dev MX @9.9.9.9 Uses a custom DNS resolver.
|
||||
doggo -q mrkaran.dev -t MX -n 1.1.1.1 Using named arguments
|
||||
`
|
||||
|
||||
func renderCustomHelp(w io.Writer, templ string, data interface{}) {
|
||||
var helpTmplVars = map[string]string{}
|
||||
|
||||
helpTmplVars["Name"] = "doggo"
|
||||
fmt.Fprintf(w, helpTmpl, helpTmplVars)
|
||||
func renderCustomHelp() {
|
||||
helpTmplVars := map[string]string{
|
||||
"Name": "doggo",
|
||||
"Description": "DNS Client for Humans",
|
||||
"Version": buildVersion,
|
||||
"Date": buildDate,
|
||||
}
|
||||
tmpl, err := template.New("test").Parse(AppHelpTemplate)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = tmpl.Execute(os.Stdout, helpTmplVars)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ type QueryFlags struct {
|
|||
ShowJSON bool `koanf:"json"`
|
||||
UseSearchList bool `koanf:"search"`
|
||||
Ndots int `koanf:"ndots"`
|
||||
Color bool `koanf:"color"`
|
||||
}
|
||||
|
||||
// NewHub initializes an instance of Hub which holds app wide configuration.
|
||||
|
|
|
@ -64,9 +64,15 @@ func (hub *Hub) outputJSON(out []Output, msgs []resolvers.Response) {
|
|||
}
|
||||
|
||||
func (hub *Hub) outputTerminal(out []Output) {
|
||||
green := color.New(color.FgGreen).SprintFunc()
|
||||
blue := color.New(color.FgBlue).SprintFunc()
|
||||
magenta := color.New(color.FgMagenta).SprintFunc()
|
||||
green := color.New(color.FgGreen, color.Bold).SprintFunc()
|
||||
blue := color.New(color.FgBlue, color.Bold).SprintFunc()
|
||||
yellow := color.New(color.FgYellow, color.Bold).SprintFunc()
|
||||
cyan := color.New(color.FgCyan, color.Bold).SprintFunc()
|
||||
red := color.New(color.FgRed, color.Bold).SprintFunc()
|
||||
|
||||
if !hub.QueryFlags.Color {
|
||||
color.NoColor = true // disables colorized output
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
header := []string{"Name", "Type", "Class", "TTL", "Address", "Nameserver"}
|
||||
|
@ -87,7 +93,24 @@ func (hub *Hub) outputTerminal(out []Output) {
|
|||
table.SetNoWhiteSpace(true)
|
||||
|
||||
for _, o := range out {
|
||||
output := []string{green(o.Name), blue(o.Type), o.Class, o.TTL, magenta(o.Address), o.Nameserver}
|
||||
var typOut string
|
||||
switch typ := o.Type; typ {
|
||||
case "A":
|
||||
typOut = blue(o.Type)
|
||||
case "AAAA":
|
||||
typOut = blue(o.Type)
|
||||
case "MX":
|
||||
typOut = cyan(o.Type)
|
||||
case "NS":
|
||||
typOut = cyan(o.Type)
|
||||
case "CNAME":
|
||||
typOut = yellow(o.Type)
|
||||
case "TXT":
|
||||
typOut = yellow(o.Type)
|
||||
default:
|
||||
typOut = red(o.Type)
|
||||
}
|
||||
output := []string{green(o.Name), typOut, o.Class, o.TTL, o.Address, o.Nameserver}
|
||||
// Print how long it took
|
||||
if hub.QueryFlags.DisplayTimeTaken {
|
||||
output = append(output, o.TimeTaken)
|
||||
|
@ -125,10 +148,28 @@ func collectOutput(responses []resolvers.Response) []Output {
|
|||
addr = t.AAAA.String()
|
||||
case *dns.CNAME:
|
||||
addr = t.Target
|
||||
case *dns.CAA:
|
||||
addr = t.Tag + " " + t.Value
|
||||
case *dns.HINFO:
|
||||
addr = t.Cpu + " " + t.Os
|
||||
// case *dns.LOC:
|
||||
// addr = t.String()
|
||||
case *dns.PTR:
|
||||
addr = t.Ptr
|
||||
case *dns.SRV:
|
||||
addr = strconv.Itoa(int(t.Priority)) + " " +
|
||||
strconv.Itoa(int(t.Weight)) + " " +
|
||||
t.Target + ":" + strconv.Itoa(int(t.Port))
|
||||
case *dns.TXT:
|
||||
addr = t.String()
|
||||
case *dns.NS:
|
||||
addr = t.String()
|
||||
case *dns.MX:
|
||||
addr = strconv.Itoa(int(t.Preference)) + " " + t.Mx
|
||||
case *dns.SOA:
|
||||
addr = t.String()
|
||||
case *dns.NAPTR:
|
||||
addr = t.String()
|
||||
}
|
||||
|
||||
h := a.Header()
|
||||
|
|
|
@ -5,17 +5,9 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/miekg/dns"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func (hub *Hub) loadQueryArgs() error {
|
||||
// set log level
|
||||
if k.Bool("debug") {
|
||||
// Set logger level
|
||||
hub.Logger.SetLevel(logrus.DebugLevel)
|
||||
} else {
|
||||
hub.Logger.SetLevel(logrus.InfoLevel)
|
||||
}
|
||||
|
||||
err := hub.loadNamedArgs()
|
||||
|
||||
|
|
Loading…
Reference in New Issue