Skip to content

Commit 05c054e

Browse files
committed
feat(conf): implement Root, safe and mockable
1 parent f42e195 commit 05c054e

3 files changed

Lines changed: 42 additions & 18 deletions

File tree

conf/files.go

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,30 @@ import (
1717
"github.com/LM4eu/goinfer/gie"
1818
)
1919

20+
type Root struct {
21+
Path string
22+
FS fs.FS
23+
}
24+
25+
func NewRoot(path string) Root {
26+
return Root{path, os.DirFS(path)}
27+
}
28+
29+
func (root *Root) Open(name string) (fs.File, error) {
30+
return root.FS.Open(name)
31+
}
32+
33+
func (root *Root) ReadFile(fullPath string) ([]byte, error) {
34+
relativePath, err := filepath.Rel(root.Path, fullPath)
35+
if err != nil {
36+
return nil, err
37+
}
38+
if !filepath.IsLocal(relativePath) {
39+
return nil, gie.New(gie.Invalid, "not local", "full", fullPath, "root", root.Path)
40+
}
41+
return fs.ReadFile(root.FS, filepath.Clean(relativePath))
42+
}
43+
2044
// replaceDIR in flags by the current dir of he file.
2145
// When using models like GPT OSS, we need to provide a grammar file.
2246
// See: github.com/ggml-org/llama.cpp/discussions/15396#discussioncomment-14145537
@@ -201,9 +225,9 @@ func nameWithDir(root, truncated, name string) string {
201225

202226
// extractModelNameAndFlags search for a llama-server command line
203227
// and extract the model path (flag -m or --model) and the flags after -m|--model.
204-
func extractModelNameAndFlags(fsys fs.FS, shellPath string) (modelPath, flags []byte) {
228+
func extractModelNameAndFlags(root Root, shellPath string) (modelPath, flags []byte) {
205229
// shellPath = filepath.Clean(shellPath)
206-
script, err := fs.ReadFile(fsys, shellPath)
230+
script, err := root.ReadFile(shellPath)
207231
if err != nil {
208232
return nil, nil
209233
}

conf/files_test.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ const (
266266
)
267267

268268
func Test_extractModelNameAndFlags(t *testing.T) {
269-
t.Parallel()
269+
// t.Parallel()
270270

271-
testFS := fstest.MapFS{
271+
root := Root{"/home/me/models", fstest.MapFS{
272272
"0.sh": &fstest.MapFile{Data: []byte("")},
273273
"1.sh": &fstest.MapFile{Data: []byte(script1)},
274274
"2.sh": &fstest.MapFile{Data: []byte(script2)},
@@ -277,21 +277,21 @@ func Test_extractModelNameAndFlags(t *testing.T) {
277277
"5.sh": &fstest.MapFile{Data: []byte("llama-server --model ~/model.gguf")},
278278
"6.sh": &fstest.MapFile{Data: []byte("/llama-server --model ~/model.gguf")},
279279
"7.sh": &fstest.MapFile{Data: []byte("/llama-server\t-m\t~/model.gguf\t-c\t0")},
280-
}
280+
}}
281281

282282
tests := []struct{ path, wantModel, wantFlags string }{
283-
{"1.sh", "/path/model.gguf", `--no-mmap --chat-template-kwargs '{"reasoning_effort": "high"}' --reasoning-format auto -c 10240 # --no-context-shift`},
284-
{"2.sh", "/path/model.gguf", `--no-mmap --chat-template-kwargs '{"reasoning_effort": "high"}' --reasoning-format auto -c 10240`},
285-
{"3.sh", "/path/model.gguf", `--no-mmap --chat-template-kwargs '{"reasoning_effort": "high"}' --reasoning-format auto -c 10240`},
286-
{"4.sh", "", ""},
287-
{"5.sh", "", ""},
288-
{"6.sh", "~/model.gguf", ""},
289-
{"7.sh", "~/model.gguf", "-c\t0"},
283+
{"/home/me/models/1.sh", "/path/model.gguf", `--no-mmap --chat-template-kwargs '{"reasoning_effort": "high"}' --reasoning-format auto -c 10240 # --no-context-shift`},
284+
{"/home/me/models/2.sh", "/path/model.gguf", `--no-mmap --chat-template-kwargs '{"reasoning_effort": "high"}' --reasoning-format auto -c 10240`},
285+
{"/home/me/models/3.sh", "/path/model.gguf", `--no-mmap --chat-template-kwargs '{"reasoning_effort": "high"}' --reasoning-format auto -c 10240`},
286+
{"/home/me/models/4.sh", "", ""},
287+
{"/home/me/models/5.sh", "", ""},
288+
{"/home/me/models/6.sh", "~/model.gguf", ""},
289+
{"/home/me/models/7.sh", "~/model.gguf", "-c\t0"},
290290
}
291291
for _, tt := range tests {
292292
t.Run(tt.path, func(t *testing.T) {
293-
t.Parallel()
294-
gotModel, gotFlags := extractModelNameAndFlags(testFS, tt.path)
293+
// t.Parallel()
294+
gotModel, gotFlags := extractModelNameAndFlags(root, tt.path)
295295
if string(gotModel) != tt.wantModel {
296296
t.Errorf("extractModelNameAndFlags(%s) = %s, want %s", tt.path, gotModel, tt.wantModel)
297297
}

conf/info.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -158,8 +158,8 @@ func (cfg *Cfg) updateInfo() {
158158
// search walks the given root directory and appends any valid *.gguf model file to
159159
// cfg.Info. It validates each file using validateFile and warns about errors (logs).
160160
func (cfg *Cfg) search(params map[string]ModelParams, root string) error {
161+
rootFS := NewRoot(root)
161162
return filepath.WalkDir(root, func(path string, dir fs.DirEntry, err error) error {
162-
fsys := os.DirFS(root)
163163
switch {
164164
case err != nil:
165165
if dir == nil {
@@ -176,7 +176,7 @@ func (cfg *Cfg) search(params map[string]ModelParams, root string) error {
176176
case filepath.Ext(path) == ".gguf":
177177
cfg.keepGUFF(root, path)
178178
case filepath.Ext(path) == ".sh":
179-
cfg.keepFlags(fsys, path[len(root):])
179+
cfg.keepFlags(rootFS, path[len(root):])
180180
default:
181181
}
182182
return nil
@@ -235,8 +235,8 @@ func (cfg *Cfg) keepGUFF(root, path string) {
235235
cfg.Info[name] = &mi
236236
}
237237

238-
func (cfg *Cfg) keepFlags(fsys fs.FS, path string) {
239-
modelPath, args := extractModelNameAndFlags(fsys, path)
238+
func (cfg *Cfg) keepFlags(root Root, path string) {
239+
modelPath, args := extractModelNameAndFlags(root, path)
240240
if modelPath == nil {
241241
return
242242
}

0 commit comments

Comments
 (0)