// Copyright 2024 Matthew Rich . All rights reserved. package source import ( _ "context" _ "encoding/json" _ "fmt" _ "gopkg.in/yaml.v3" "net/url" "path/filepath" "decl/internal/resource" "os" "io" ) type Dir struct { Path string `yaml:"path" json:"path"` subDirsStack []string `yaml:"-" json:"-"` } func NewDir() *Dir { return &Dir{ subDirsStack: make([]string, 0, 100), } } func init() { SourceTypes.Register([]string{"file"}, func(u *url.URL) DocSource { t := NewDir() t.Path,_ = filepath.Abs(filepath.Join(u.Hostname(), u.RequestURI())) return t }) } func (d *Dir) Type() string { return "dir" } func (d *Dir) ExtractDirectory(path string) (*resource.Document, error) { document := resource.NewDocument() files, err := os.ReadDir(path) if err != nil { return nil, err } for _,file := range files { f := resource.NewFile() f.Path = filepath.Join(path, file.Name()) info, infoErr := file.Info() if infoErr != nil { return document, infoErr } if fiErr := f.UpdateAttributesFromFileInfo(info); fiErr != nil { return document, fiErr } f.FileType.SetMode(file.Type()) if file.IsDir() { d.subDirsStack = append(d.subDirsStack, f.Path) } else { fileReader, fileReaderErr := os.Open(f.Path) if fileReaderErr != nil { return document, fileReaderErr } readFileData, readErr := io.ReadAll(fileReader) if readErr != nil { return document, readErr } f.Content = string(readFileData) f.UpdateContentAttributes() } document.AddResourceDeclaration("file", f) } return document, nil } func (d *Dir) ExtractResources(filter ResourceSelector) ([]*resource.Document, error) { documents := make([]*resource.Document, 0, 100) d.subDirsStack = append(d.subDirsStack, d.Path) for { if len(d.subDirsStack) == 0 { break } var dirPath string dirPath, d.subDirsStack = d.subDirsStack[len(d.subDirsStack) - 1], d.subDirsStack[:len(d.subDirsStack) - 1] document, dirErr := d.ExtractDirectory(dirPath) if dirErr != nil { return documents, dirErr } documents = append(documents, document) } return documents, nil }