chore: mercury changes

This commit is contained in:
xuu
2024-04-05 12:40:51 -06:00
parent 44aa1358ad
commit 912157fbf0
20 changed files with 903 additions and 298 deletions

View File

@@ -62,10 +62,16 @@ func (lis Config) ToSpaceMap() SpaceMap {
// String format config as string
func (lis Config) String() string {
attLen := 0
tagLen := 0
for _, o := range lis {
var buf strings.Builder
for i, o := range lis {
attLen := 0
tagLen := 0
if i > 0 {
buf.WriteRune('\n')
}
for _, v := range o.List {
l := len(v.Name)
if attLen <= l {
@@ -77,10 +83,7 @@ func (lis Config) String() string {
tagLen = t
}
}
}
var buf strings.Builder
for _, o := range lis {
if len(o.Notes) > 0 {
buf.WriteString("# ")
buf.WriteString(strings.Join(o.Notes, "\n# "))
@@ -133,7 +136,10 @@ func (lis Config) String() string {
}
}
buf.WriteRune('\n')
for _, line := range o.Trailer {
buf.WriteString(line)
buf.WriteRune('\n')
}
}
return buf.String()
@@ -188,11 +194,21 @@ func (lis Config) EnvString() string {
func (lis Config) INIString() string {
var buf strings.Builder
for _, o := range lis {
for _, note := range o.Notes {
buf.WriteString("; ")
buf.WriteString(note)
buf.WriteRune('\n')
}
buf.WriteRune('[')
buf.WriteString(o.Space)
buf.WriteRune(']')
buf.WriteRune('\n')
for _, v := range o.List {
for _, note := range v.Notes {
buf.WriteString("; ")
buf.WriteString(note)
buf.WriteRune('\n')
}
buf.WriteString(v.Name)
switch len(v.Values) {
case 0:
@@ -221,6 +237,13 @@ func (lis Config) INIString() string {
}
}
}
for _, line := range o.Trailer {
buf.WriteString("; ")
buf.WriteString(line)
buf.WriteRune('\n')
}
buf.WriteRune('\n')
}
return buf.String()
@@ -228,10 +251,16 @@ func (lis Config) INIString() string {
// String format config as string
func (lis Config) HTMLString() string {
attLen := 0
tagLen := 0
for _, o := range lis {
var buf strings.Builder
for i, o := range lis {
attLen := 0
tagLen := 0
if i > 0 {
buf.WriteRune('\n')
}
for _, v := range o.List {
l := len(v.Name)
if attLen <= l {
@@ -243,10 +272,7 @@ func (lis Config) HTMLString() string {
tagLen = t
}
}
}
var buf strings.Builder
for _, o := range lis {
if len(o.Notes) > 0 {
buf.WriteString("<i>")
buf.WriteString("# ")
@@ -311,7 +337,12 @@ func (lis Config) HTMLString() string {
}
}
buf.WriteRune('\n')
for _, line := range o.Trailer {
buf.WriteString("<small>")
buf.WriteString(line)
buf.WriteString("</small>")
buf.WriteRune('\n')
}
}
return buf.String()
@@ -319,10 +350,11 @@ func (lis Config) HTMLString() string {
// Space stores a registry of spaces
type Space struct {
Space string `json:"space"`
Tags []string `json:"tags,omitempty"`
Notes []string `json:"notes,omitempty"`
List []Value `json:"list,omitempty"`
Space string `json:"space"`
Tags []string `json:"tags,omitempty"`
Notes []string `json:"notes,omitempty"`
List []Value `json:"list,omitempty"`
Trailer []string `json:"trailer,omitempty"`
}
func NewSpace(space string) *Space {
@@ -437,7 +469,7 @@ type SpaceMap map[string]*Space
func (m SpaceMap) Space(name string) (*Space, bool) {
s, ok := m[name]
return s, ok
}
}
// Rule is a type of rule
type Rule struct {

View File

@@ -20,17 +20,11 @@ type NamespaceSearch []NamespaceSpec
func ParseNamespace(ns string) (lis NamespaceSearch) {
for _, part := range strings.Split(ns, ";") {
if strings.HasPrefix(part, "trace:") {
for _, s := range strings.Split(part[6:], ",") {
lis = append(lis, NamespaceTrace(s))
}
lis = append(lis, NamespaceTrace(part[6:]))
} else if strings.Contains(part, "*") {
lis = append(lis, NamespaceStar(part))
} else {
for _, s := range strings.Split(part, ",") {
if strings.Contains(s, "*") {
lis = append(lis, NamespaceStar(s))
} else {
lis = append(lis, NamespaceNode(s))
}
}
lis = append(lis, NamespaceNode(part))
}
}
@@ -44,7 +38,7 @@ func (n NamespaceSearch) String() string {
for _, v := range n {
lis = append(lis, v.String())
}
return strings.Join(lis, ",")
return strings.Join(lis, ";")
}
// Match returns true if any match.

59
mercury/namespace_test.go Normal file
View File

@@ -0,0 +1,59 @@
package mercury_test
import (
"fmt"
"testing"
"github.com/matryer/is"
"go.sour.is/pkg/mercury"
sq "github.com/Masterminds/squirrel"
)
func TestNamespaceParse(t *testing.T) {
var tests = []struct {
in string
out string
args []any
}{
{
in: "d42.bgp.kapha.*;trace:d42.bgp.kapha",
out: "(column LIKE ? OR ? LIKE column || '%')",
args: []any{"d42.bgp.kapha.%", "d42.bgp.kapha"},
},
{
in: "d42.bgp.kapha.*,d42.bgp.kapha",
out: "(column LIKE ? OR column = ?)",
args: []any{"d42.bgp.kapha.%", "d42.bgp.kapha"},
},
}
for i, tt := range tests {
t.Run(fmt.Sprintf("test %d", i), func(t *testing.T) {
is := is.New(t)
out := mercury.ParseNamespace(tt.in)
sql, args, err := getWhere(out).ToSql()
is.NoErr(err)
is.Equal(sql, tt.out)
is.Equal(args, tt.args)
})
}
}
func getWhere(search mercury.NamespaceSearch) sq.Sqlizer {
var where sq.Or
space := "column"
for _, m := range search {
switch m.(type) {
case mercury.NamespaceNode:
where = append(where, sq.Eq{space: m.Value()})
case mercury.NamespaceStar:
where = append(where, sq.Like{space: m.Value()})
case mercury.NamespaceTrace:
e := sq.Expr(`? LIKE `+space+` || '%'`, m.Value())
where = append(where, e)
}
}
return where
}

View File

@@ -3,6 +3,7 @@ package mercury
import (
"bufio"
"io"
"log"
"strings"
)
@@ -49,6 +50,26 @@ func ParseText(body io.Reader) (config SpaceMap, err error) {
continue
}
if strings.HasPrefix(line, "----") && strings.HasSuffix(line, "----") {
var trailer []string
trailer = append(trailer, line)
for scanner.Scan() {
line = scanner.Text()
trailer = append(trailer, line)
if strings.HasPrefix(line, "----") && strings.HasSuffix(line, "----") {
break
}
}
c, ok := config[space]
if !ok {
c = &Space{Space: space}
}
log.Println(trailer)
c.Trailer = append(c.Trailer, trailer...)
config[space] = c
continue
}
if space == "" {
continue
}
@@ -59,10 +80,8 @@ func ParseText(body io.Reader) (config SpaceMap, err error) {
}
if strings.TrimSpace(sp[0]) == "" {
var c *Space
var ok bool
if c, ok = config[space]; !ok {
c, ok := config[space]
if !ok {
c = &Space{Space: space}
}
@@ -78,10 +97,8 @@ func ParseText(body io.Reader) (config SpaceMap, err error) {
tags = fields[1:]
}
var c *Space
var ok bool
if c, ok = config[space]; !ok {
c, ok := config[space]
if !ok {
c = &Space{Space: space}
}

28
mercury/parse_test.go Normal file
View File

@@ -0,0 +1,28 @@
package mercury_test
import (
"strings"
"testing"
"github.com/matryer/is"
"go.sour.is/pkg/mercury"
)
func TestParseText(t *testing.T) {
is := is.New(t)
sm, err := mercury.ParseText(strings.NewReader(`
@test.sign
key :value1
-----BEGIN SSH SIGNATURE-----
U1NIU0lHAAAAAQAAADMAAAALc3NoLWVkMjU1MTkAAAAgZ+OuJYdd3UiUbyBuO1RlsQR20a
Qm5mKneuMxRjGo3zkAAAAEZmlsZQAAAAAAAAAGc2hhNTEyAAAAUwAAAAtzc2gtZWQyNTUx
OQAAAED8T4C6WILXYZ1KxqDIlVhlrAEjr1Vc+tn8ypcVM3bN7iOexVvuUuvm90nr8eEwKU
acrdDxmq2S+oysQbK+pMUE
-----END SSH SIGNATURE-----
`))
is.NoErr(err)
for _, c := range sm {
is.Equal(len(c.Trailer), 6)
}
}

View File

@@ -32,7 +32,7 @@
<br />
<textarea name="content" rows="45" wrap="off"
onkeyup="if (this.scrollHeight > this.clientHeight) this.style.height = this.scrollHeight + ' px';"
style="overflow:auto; overflow-y:hidden; transition: height 0.2s ease-out;"></textarea>
style="overflow:auto; transition: height 0.2s ease-out;"></textarea>
</form>
<pre id="space-saved"></pre>
</div>

View File

@@ -6,6 +6,7 @@
body {
margin: 0;
min-height: 100vh;
background: rgb(210, 221, 240);
}
header {
@@ -57,6 +58,11 @@ code i {
}
code em {
color: orangered;
}
code small {
font-size-adjust: 50%;
color: orange;
}
@@ -94,7 +100,7 @@ footer>span {
.container>div {
overflow: auto;
padding: 10px;
background: rgb(238, 174, 202);
background-color: white;
border: 0px ;
}
@@ -158,7 +164,7 @@ footer>span {
}
@media (prefers-color-scheme: dark) {
html {
html, body {
color: white;
background: #111
}

View File

@@ -8,8 +8,8 @@ import (
"strconv"
"strings"
"go.sour.is/pkg/lg"
"go.sour.is/pkg/ident"
"go.sour.is/pkg/lg"
"go.sour.is/pkg/rsql"
"go.sour.is/pkg/set"
"golang.org/x/sync/errgroup"
@@ -122,16 +122,32 @@ func (r *registry) Register(name string, h func(*Space) any) {
func (r *registry) Configure(m SpaceMap) error {
r.resetMatchers()
for space, c := range m {
space = strings.TrimPrefix(space, "mercury.source.")
handler, name, _ := strings.Cut(space, ".")
matches := c.FirstValue("match")
for _, match := range matches.Values {
ps := strings.Fields(match)
priority, err := strconv.Atoi(ps[0])
if err != nil {
return err
if strings.HasPrefix(space, "mercury.source.") {
space = strings.TrimPrefix(space, "mercury.source.")
handler, name, _ := strings.Cut(space, ".")
matches := c.FirstValue("match")
for _, match := range matches.Values {
ps := strings.Fields(match)
priority, err := strconv.Atoi(ps[0])
if err != nil {
return err
}
r.add(name, handler, ps[1], priority, c)
}
}
if strings.HasPrefix(space, "mercury.output.") {
space = strings.TrimPrefix(space, "mercury.output.")
handler, name, _ := strings.Cut(space, ".")
matches := c.FirstValue("match")
for _, match := range matches.Values {
ps := strings.Fields(match)
priority, err := strconv.Atoi(ps[0])
if err != nil {
return err
}
r.add(name, handler, ps[1], priority, c)
}
r.add(name, handler, ps[1], priority, c)
}
}

View File

@@ -1,8 +1,10 @@
package mercury
import (
"embed"
"encoding/json"
"fmt"
"io/fs"
"log"
"net/http"
"sort"
@@ -11,8 +13,8 @@ import (
"github.com/BurntSushi/toml"
"github.com/golang/gddo/httputil"
"go.sour.is/pkg/lg"
"go.sour.is/pkg/ident"
"go.sour.is/pkg/lg"
)
type root struct{}
@@ -21,8 +23,13 @@ func NewHTTP() *root {
return &root{}
}
//go:embed public
var public embed.FS
func (s *root) RegisterHTTP(mux *http.ServeMux) {
mux.Handle("/", http.FileServer(http.Dir("./mercury/public")))
// mux.Handle("/", http.FileServer(http.Dir("./mercury/public")))
public, _ := fs.Sub(public, "public")
mux.Handle("/", http.FileServerFS(public))
}
func (s *root) RegisterAPIv1(mux *http.ServeMux) {
mux.HandleFunc("GET /mercury", s.indexV1)
@@ -30,6 +37,9 @@ func (s *root) RegisterAPIv1(mux *http.ServeMux) {
mux.HandleFunc("GET /mercury/config", s.configV1)
mux.HandleFunc("POST /mercury/config", s.storeV1)
}
func (s *root) RegisterWellKnown(mux *http.ServeMux) {
s.RegisterAPIv1(mux)
}
func (s *root) configV1(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
@@ -62,7 +72,7 @@ func (s *root) configV1(w http.ResponseWriter, r *http.Request) {
log.Print("SPC: ", space)
ns := ParseNamespace(space)
log.Print("PRE: ", ns)
ns = rules.ReduceSearch(ns)
//ns = rules.ReduceSearch(ns)
log.Print("POST: ", ns)
lis, err := Registry.GetConfig(ctx, ns.String(), "", "")

View File

@@ -6,6 +6,7 @@ CREATE TABLE IF NOT EXISTS mercury_spaces
id integer NOT NULL DEFAULT nextval('mercury_spaces_id_seq'::regclass),
notes character varying[] NOT NULL DEFAULT '{}'::character varying[],
tags character varying[] NOT NULL DEFAULT '{}'::character varying[],
trailer character varying[] NOT NULL DEFAULT '{}'::character varying[],
CONSTRAINT mercury_namespace_pk PRIMARY KEY (id)
);
CREATE UNIQUE INDEX IF NOT EXISTS mercury_namespace_space_uindex
@@ -35,7 +36,8 @@ CREATE OR REPLACE VIEW mercury_registry_vw
v.name,
v."values",
v.notes,
v.tags
v.tags,
s.trailer
FROM mercury_spaces s
JOIN mercury_values v ON s.id = v.id;

View File

@@ -3,7 +3,8 @@ CREATE TABLE IF NOT EXISTS mercury_spaces
space character varying NOT NULL unique,
id integer NOT NULL CONSTRAINT mercury_namespace_pk PRIMARY KEY autoincrement,
notes json NOT NULL DEFAULT '[]',
tags json NOT NULL DEFAULT '[]'
tags json NOT NULL DEFAULT '[]',
trailer json NOT NULL DEFAULT '[]'
);
CREATE TABLE IF NOT EXISTS mercury_values
@@ -27,7 +28,8 @@ CREATE VIEW if not exists mercury_registry_vw
v.name,
v."values",
v.notes,
v.tags
v.tags,
s.trailer
FROM mercury_spaces s
JOIN mercury_values v ON s.id = v.id;

View File

@@ -166,7 +166,7 @@ func (p *sqlHandler) listSpace(ctx context.Context, tx sq.BaseRunner, where sq.S
tx = p.db
}
query := sq.Select(`"id"`, `"space"`, `"tags"`, `"notes"`).
query := sq.Select(`"id"`, `"space"`, `"notes"`, `"tags"`, `"trailer"`).
From("mercury_spaces").
Where(where).
OrderBy("space asc").
@@ -189,6 +189,7 @@ func (p *sqlHandler) listSpace(ctx context.Context, tx sq.BaseRunner, where sq.S
&s.Space.Space,
listScan(&s.Space.Notes, p.listFormat),
listScan(&s.Space.Tags, p.listFormat),
listScan(&s.Trailer, p.listFormat),
)
if err != nil {
return nil, err
@@ -287,6 +288,7 @@ func (p *sqlHandler) WriteConfig(ctx context.Context, config mercury.Config) (er
Where(sq.Eq{"id": updateIDs[i]}).
Set("tags", listValue(u.Tags, p.listFormat)).
Set("notes", listValue(u.Notes, p.listFormat)).
Set("trailer", listValue(u.Trailer, p.listFormat)).
PlaceholderFormat(sq.Dollar)
span.AddEvent(lg.LogQuery(query.ToSql()))
_, err := query.RunWith(tx).ExecContext(ctx)
@@ -305,8 +307,13 @@ func (p *sqlHandler) WriteConfig(ctx context.Context, config mercury.Config) (er
var id uint64
query := sq.Insert("mercury_spaces").
PlaceholderFormat(sq.Dollar).
Columns("space", "tags", "notes").
Values(s.Space, listValue(s.Tags, p.listFormat), listValue(s.Notes, p.listFormat)).
Columns("space", "tags", "notes", "trailer").
Values(
s.Space,
listValue(s.Tags, p.listFormat),
listValue(s.Notes, p.listFormat),
listValue(s.Trailer, p.listFormat),
).
Suffix("RETURNING \"id\"")
span.AddEvent(lg.LogQuery(query.ToSql()))