From 6b1ba9a9984963c1751f1e3c76bb6e62bcd0355e Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Tue, 19 May 2026 17:47:13 +0200 Subject: [PATCH] split store constructors into own files: tools.go, root.go --- root.go | 57 +++++++++++++++++++++++++++++++++++ server.go | 90 ------------------------------------------------------- tools.go | 51 +++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 90 deletions(-) create mode 100644 root.go create mode 100644 tools.go diff --git a/root.go b/root.go new file mode 100644 index 0000000..c80997c --- /dev/null +++ b/root.go @@ -0,0 +1,57 @@ +package main + +import ( + "context" + "fmt" + "os" + "strings" + + "ollie/pkg/backend" + "ollie/pkg/paths" + "olliesrv/store" +) + +// NewRootStore returns a read-only Store for synthetic root-level files. +func NewRootStore() *store.DirStore { + helpPath := paths.CfgDir() + "/help.md" + entries := map[string]func() ([]byte, error){ + "backends": func() ([]byte, error) { + return []byte(strings.Join(backend.Backends(), "\n") + "\n"), nil + }, + "help": func() ([]byte, error) { + return os.ReadFile(helpPath) + }, + } + notBlocking := func(context.Context, string) ([]byte, string, error) { + return nil, "", fmt.Errorf("blocking read not supported") + } + readOnly := func([]byte) error { return fmt.Errorf("read-only") } + + return store.NewDirStore(nil, 0444, + store.WithReadOnly(), + store.WithResolver(func(_ []string, name string) (string, error) { + if _, ok := entries[name]; ok { + return name, nil + } + return "", fmt.Errorf("%s: not found", name) + }), + store.WithLister(func(_ []string) ([]os.DirEntry, error) { + return []os.DirEntry{ + syntheticEntry("backends", 0444), + syntheticEntry("help", 0444), + }, nil + }), + store.WithOpener(func(_ []string, name string) (StoreEntry, error) { + readFn, ok := entries[name] + if !ok { + return nil, fmt.Errorf("%s: not found", name) + } + return &store.EntryConfig{ + StatFn: func() (os.FileInfo, error) { return &syntheticFileInfo{Name_: name, Mode_: 0444}, nil }, + ReadFn: readFn, + WriteFn: readOnly, + BlockingReadFn: notBlocking, + }, nil + }), + ) +} diff --git a/server.go b/server.go index 2221bbb..2126969 100644 --- a/server.go +++ b/server.go @@ -42,96 +42,6 @@ func syntheticDirEntry(name string, mode os.FileMode) os.DirEntry { return store.DirEntry(name, mode) } -// toolIndex generates a tool index from a store's file listing. -func toolIndex(s Store) ([]byte, error) { - entries, err := s.List() - if err != nil { - return nil, err - } - var sb strings.Builder - for _, e := range entries { - if e.IsDir() || e.Name() == "idx" { - continue - } - entry, err := s.Open(e.Name()) - if err != nil { - continue - } - data, err := entry.Read() - if err != nil { - continue - } - var desc, args string - for line := range strings.SplitSeq(string(data), "\n") { - if d, ok := strings.CutPrefix(line, "# description:"); ok { - desc = strings.TrimSpace(d) - } else if a, ok := strings.CutPrefix(line, "# Args:"); ok { - args = strings.TrimSpace(a) - } else if a, ok := strings.CutPrefix(line, "# args:"); ok { - args = strings.TrimSpace(a) - } - if !strings.HasPrefix(line, "#") && line != "" { - break - } - } - if desc == "" { - continue - } - fmt.Fprintf(&sb, "## %s\n", e.Name()) - fmt.Fprintf(&sb, "description: %s\n", desc) - if args != "" { - fmt.Fprintf(&sb, "args: %s\n", args) - } - sb.WriteString("\n") - } - return []byte(sb.String()), nil -} - -// NewRootStore returns a read-only Store for synthetic root-level files. -func NewRootStore() *store.DirStore { - helpPath := paths.CfgDir() + "/help.md" - entries := map[string]func() ([]byte, error){ - "backends": func() ([]byte, error) { - return []byte(strings.Join(backend.Backends(), "\n") + "\n"), nil - }, - "help": func() ([]byte, error) { - return os.ReadFile(helpPath) - }, - } - notBlocking := func(context.Context, string) ([]byte, string, error) { - return nil, "", fmt.Errorf("blocking read not supported") - } - readOnly := func([]byte) error { return fmt.Errorf("read-only") } - - return store.NewDirStore(nil, 0444, - store.WithReadOnly(), - store.WithResolver(func(_ []string, name string) (string, error) { - if _, ok := entries[name]; ok { - return name, nil // virtual path, handled by opener - } - return "", fmt.Errorf("%s: not found", name) - }), - store.WithLister(func(_ []string) ([]os.DirEntry, error) { - return []os.DirEntry{ - syntheticEntry("backends", 0444), - syntheticEntry("help", 0444), - }, nil - }), - store.WithOpener(func(_ []string, name string) (StoreEntry, error) { - readFn, ok := entries[name] - if !ok { - return nil, fmt.Errorf("%s: not found", name) - } - return &store.EntryConfig{ - StatFn: func() (os.FileInfo, error) { return &syntheticFileInfo{Name_: name, Mode_: 0444}, nil }, - ReadFn: readFn, - WriteFn: readOnly, - BlockingReadFn: notBlocking, - }, nil - }), - ) -} - const ( QTDir = plan9.QTDIR QTFile = plan9.QTFILE diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..a99f98f --- /dev/null +++ b/tools.go @@ -0,0 +1,51 @@ +package main + +import ( + "fmt" + "strings" +) + +// toolIndex generates a tool index from a store's file listing. +func toolIndex(s Store) ([]byte, error) { + entries, err := s.List() + if err != nil { + return nil, err + } + var sb strings.Builder + for _, e := range entries { + if e.IsDir() || e.Name() == "idx" { + continue + } + entry, err := s.Open(e.Name()) + if err != nil { + continue + } + data, err := entry.Read() + if err != nil { + continue + } + var desc, args string + for line := range strings.SplitSeq(string(data), "\n") { + if d, ok := strings.CutPrefix(line, "# description:"); ok { + desc = strings.TrimSpace(d) + } else if a, ok := strings.CutPrefix(line, "# Args:"); ok { + args = strings.TrimSpace(a) + } else if a, ok := strings.CutPrefix(line, "# args:"); ok { + args = strings.TrimSpace(a) + } + if !strings.HasPrefix(line, "#") && line != "" { + break + } + } + if desc == "" { + continue + } + fmt.Fprintf(&sb, "## %s\n", e.Name()) + fmt.Fprintf(&sb, "description: %s\n", desc) + if args != "" { + fmt.Fprintf(&sb, "args: %s\n", args) + } + sb.WriteString("\n") + } + return []byte(sb.String()), nil +}