Files
ExploreDNS/internal/output/formatter.go
T
5d4fa94286
CI / test (pull_request) Failing after 1m32s
CI / docker (pull_request) Has been skipped
fix: rename Go module path to gitea.hansenits.com.au/hits/ExploreDNS
- Update go.mod module declaration
- Update all internal import paths in .go files
- Update go install lines in README.md

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-06-08 23:17:00 +10:00

107 lines
2.6 KiB
Go

// Package output renders ExploreDNS traversal results for human consumption or
// machine processing.
//
// Two formats are supported:
//
// - FormatText — a coloured hierarchical tree (default)
// - FormatJSON — a JSON array of traversal results
//
// Create a Formatter via NewFormatter and call RunTraversal to drive the
// traversal engine and stream output incrementally.
package output
import (
"fmt"
"io"
"os"
"gitea.hansenits.com.au/hits/ExploreDNS/internal/traverse"
)
type Format int
const (
FormatText Format = iota
FormatJSON
)
type Config struct {
Format Format
Domain string
QueryType string
ShowProgress bool
ShowResolves bool
ShowServers bool
ShowVersions bool
ShowAllStats bool
ShowResults bool
ShowSummaryResults bool
Verbose bool
Quiet bool
Color bool
Debug int
// Fingerprints maps server IP strings to their version.bind version strings.
// Populated by RunTraversal when ShowVersions and ShowServers are both true.
Fingerprints map[string]string
}
func DefaultConfig() *Config {
return &Config{
Format: FormatText,
ShowProgress: true,
ShowResolves: true,
ShowServers: true,
ShowVersions: true,
ShowAllStats: true,
ShowResults: true,
ShowSummaryResults: true,
Color: os.Getenv("NO_COLOR") == "",
}
}
type Formatter interface {
WriteProgress(event traverse.TraversalEvent) error
WriteResolve(event traverse.TraversalEvent) error
WriteResult(result traverse.TraversalResult) error
WriteSummary(results []traverse.TraversalResult) error
Flush() error
}
func NewFormatter(cfg *Config, w io.Writer) Formatter {
if cfg == nil {
cfg = DefaultConfig()
}
if w == nil {
w = os.Stdout
}
if cfg.Format == FormatJSON {
return newJSONFormatter(cfg, w)
}
return newTextFormatter(cfg, w)
}
func AttachHooks(cfg *Config, formatter Formatter) *traverse.TraverserHooks {
if cfg == nil || formatter == nil {
return nil
}
logErr := func(context string, err error) {
if err != nil && cfg.Debug > 0 {
fmt.Fprintf(os.Stderr, "Debug: formatter %s: %v\n", context, err)
}
}
return &traverse.TraverserHooks{
OnEvent: func(event traverse.TraversalEvent) {
switch {
case event.IsResolve && cfg.ShowResolves:
logErr("WriteResolve", formatter.WriteResolve(event))
case !event.IsResolve && cfg.ShowProgress:
logErr("WriteProgress", formatter.WriteProgress(event))
}
if event.Stage == traverse.EventComplete && cfg.ShowAllStats {
logErr("WriteResult", formatter.WriteResult(event.Result))
}
},
}
}