Skip to content

Commit 083da4e

Browse files
committed
feat: adding dawgrun
1 parent f87dddb commit 083da4e

28 files changed

Lines changed: 3446 additions & 0 deletions

go.mod

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,7 @@ require (
3636
google.golang.org/protobuf v1.36.6 // indirect
3737
gopkg.in/yaml.v3 v3.0.1 // indirect
3838
)
39+
40+
replace github.com/specterops/dawgs/tools/dawgrun/cmd/dawgrun => ./tools/dawgrun/cmd/dawgrun
41+
42+
tool github.com/specterops/dawgs/tools/dawgrun/cmd/dawgrun

go.work

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
go 1.25.4
2+
3+
use (
4+
.
5+
./tools/dawgrun
6+
)

go.work.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
2+
github.com/charmbracelet/x/exp/golden v0.0.0-20240806155701-69247e0abc2a/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
3+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
4+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
5+
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
6+
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
7+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
8+
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
9+
github.com/yuin/goldmark v1.7.13/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
10+
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
11+
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=

tools/dawgrun/cmd/dawgrun/art.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.--~~,__
2+
:-....,-------`~~'._.'
3+
`-,,, ,_ ;'~U'
4+
_,-' ,'`-__; '--.
5+
(_/'~~ ''''(;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
,---. ,-.-. _,---.
2+
_,..---._ .--.' \ ,-..-.-./ \==\ _.='.'-, \
3+
/==/, - \ \==\-/\ \ |, \=/\=|- |==|/==.'- /
4+
|==| _ _\/==/-|_\ ||- |/ |/ , /==/==/ - .-'
5+
|==| .=. |\==\, - \\, , _|==|==|_ /_,-.
6+
|==|,| | -|/==/ - ,|| - - , |==|==| , \_.' )
7+
|==| '=' /==/- /\ - \\ , - /==/\==\- , (
8+
|==|-, _`/\==\ _.\=\.-'|- /\ /==/ /==/ _ , /
9+
`-.`.____.' `--` `--` `--` `--`------'
10+
.-._
11+
.-.,.---. .--.-. .-.-./==/ \ .-._
12+
/==/ ` \/==/ -|/=/ ||==|, \/ /, /
13+
|==|-, .=., |==| ,||=| -||==|- \| |
14+
|==| '=' /==|- | =/ ||==| , | -|
15+
|==|- , .'|==|, \/ - ||==| - _ |
16+
|==|_ . ,'.|==|- , /|==| /\ , |
17+
/==/ /\ , )==/ , _ .' /==/, | |- |
18+
`--`-`--`--'`--`..---' `--`./ `--`

tools/dawgrun/cmd/dawgrun/main.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
package main
2+
3+
import (
4+
"context"
5+
_ "embed"
6+
"fmt"
7+
"log/slog"
8+
"os"
9+
"path"
10+
"runtime/trace"
11+
"strings"
12+
13+
"github.com/charmbracelet/lipgloss"
14+
"github.com/google/shlex"
15+
repl "github.com/openengineer/go-repl"
16+
17+
"github.com/specterops/dawgs/tools/dawgrun/pkg/commands"
18+
)
19+
20+
var (
21+
//go:embed art.txt
22+
art string
23+
24+
//go:embed banner.txt
25+
banner string
26+
27+
bannerStyle = lipgloss.NewStyle().
28+
Foreground(lipgloss.Color("#87dc70")).
29+
Background(lipgloss.Color("#533d25"))
30+
)
31+
32+
func main() {
33+
fmt.Printf("\n%s\n%s",
34+
art,
35+
bannerStyle.Render(banner),
36+
)
37+
fmt.Printf("\n\n\n")
38+
fmt.Printf(" ::: DAWGRUN REPL ::: Type 'help' for more info\n")
39+
40+
userConfigDir, err := os.UserConfigDir()
41+
if err != nil {
42+
panic(fmt.Errorf("could not get user config dir: %w", err))
43+
}
44+
45+
// TODO: Someday, also load a config file from here for highlighting color scheme, colors enablement, etc
46+
appConfigBaseDir := path.Join(userConfigDir, "dawgrun")
47+
if err := os.MkdirAll(appConfigBaseDir, 0o750); err != nil {
48+
panic(fmt.Errorf("could not create dawgrun config dir: %w", err))
49+
}
50+
51+
handler := new(handler)
52+
handler.cmdScope = commands.NewScope()
53+
handler.r = repl.NewRepl(handler, &repl.Options{
54+
HistoryFilePath: path.Join(appConfigBaseDir, "history.txt"),
55+
HistoryMaxLines: 10000,
56+
StatusWidgets: &repl.StatusWidgetFns{
57+
Right: makeConnectionsStatusWidget(handler.cmdScope),
58+
},
59+
})
60+
61+
if err := handler.r.Loop(); err != nil {
62+
slog.Error("repl encountered error: %w", slog.String("error", err.Error()))
63+
}
64+
}
65+
66+
var _ repl.Handler = (*handler)(nil)
67+
68+
type handler struct {
69+
r *repl.Repl
70+
cmdScope *commands.Scope
71+
}
72+
73+
func (h *handler) Prompt() string {
74+
return "dawgrun > "
75+
}
76+
77+
func (h *handler) Tab(buffer string) string {
78+
return ""
79+
}
80+
81+
func (h *handler) Eval(line string) string {
82+
ctx, cancel := context.WithCancel(context.Background())
83+
defer cancel()
84+
85+
fields, err := shlex.Split(line)
86+
if err != nil {
87+
return fmt.Sprintf("Unparseable command: '%s': %s", line, err)
88+
}
89+
90+
if len(fields) == 0 {
91+
return "Woof!"
92+
}
93+
94+
command := strings.ToLower(fields[0])
95+
rest := fields[1:]
96+
if cmd, ok := commands.Registry()[command]; ok {
97+
cmdCtx := commands.NewCommandContext(ctx, h.r, h.cmdScope)
98+
defer trace.StartRegion(cmdCtx, fmt.Sprintf("command-%s", command)).End()
99+
err := cmd.Fn(cmdCtx, rest)
100+
if err != nil {
101+
return fmt.Sprintf("%s failed: %v", command, err)
102+
}
103+
104+
out := cmdCtx.OutputString()
105+
if !strings.HasSuffix(out, "\n") {
106+
return out + "\n"
107+
} else {
108+
return out
109+
}
110+
}
111+
112+
return fmt.Sprintf("Unknown command %s; try `help`?", command)
113+
}
114+
115+
func makeConnectionsStatusWidget(cmdScope *commands.Scope) repl.StatusWidgetFn {
116+
return func(r *repl.Repl) string {
117+
if numConns := cmdScope.NumConns(); numConns == 0 {
118+
return "No connections"
119+
} else {
120+
return fmt.Sprintf("%d connection(s)", numConns)
121+
}
122+
}
123+
}

tools/dawgrun/go.mod

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
module github.com/specterops/dawgs/tools/dawgrun
2+
3+
go 1.25.4
4+
5+
require (
6+
github.com/alecthomas/chroma/v2 v2.13.0
7+
github.com/charmbracelet/lipgloss v1.1.0
8+
github.com/davecgh/go-spew v1.1.1
9+
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
10+
github.com/kanmu/go-sqlfmt v0.0.2-0.20200215095417-d1e63e2ee5eb
11+
github.com/mitchellh/go-wordwrap v1.0.1
12+
github.com/openengineer/go-repl v0.0.0-00010101000000-000000000000
13+
github.com/specterops/dawgs v0.3.2
14+
)
15+
16+
require (
17+
github.com/RoaringBitmap/roaring/v2 v2.14.4 // indirect
18+
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
19+
github.com/axiomhq/hyperloglog v0.2.6 // indirect
20+
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
21+
github.com/bits-and-blooms/bitset v1.24.4 // indirect
22+
github.com/cespare/xxhash/v2 v2.3.0 // indirect
23+
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
24+
github.com/charmbracelet/x/ansi v0.8.0 // indirect
25+
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
26+
github.com/charmbracelet/x/term v0.2.1 // indirect
27+
github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect
28+
github.com/dlclark/regexp2 v1.11.0 // indirect
29+
github.com/gammazero/deque v1.2.0 // indirect
30+
github.com/jackc/pgio v1.0.0 // indirect
31+
github.com/jackc/pgpassfile v1.0.0 // indirect
32+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
33+
github.com/jackc/pgtype v1.14.4 // indirect
34+
github.com/jackc/pgx/v5 v5.8.0 // indirect
35+
github.com/jackc/puddle/v2 v2.2.2 // indirect
36+
github.com/kamstrup/intmap v0.5.2 // indirect
37+
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
38+
github.com/mattn/go-isatty v0.0.20 // indirect
39+
github.com/mattn/go-runewidth v0.0.16 // indirect
40+
github.com/mschoch/smat v0.2.0 // indirect
41+
github.com/muesli/termenv v0.16.0 // indirect
42+
github.com/neo4j/neo4j-go-driver/v5 v5.28.4 // indirect
43+
github.com/pkg/errors v0.8.1 // indirect
44+
github.com/rivo/uniseg v0.4.7 // indirect
45+
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
46+
golang.org/x/exp v0.0.0-20260112195511-716be5621a96 // indirect
47+
golang.org/x/sync v0.19.0 // indirect
48+
golang.org/x/sys v0.40.0 // indirect
49+
golang.org/x/term v0.39.0 // indirect
50+
golang.org/x/text v0.33.0 // indirect
51+
)
52+
53+
replace github.com/openengineer/go-repl => ./pkg/go-repl

0 commit comments

Comments
 (0)