Files
ResolveSpec/pkg/server/staticweb/providers/local.go

81 lines
1.9 KiB
Go

package providers
import (
"fmt"
"io/fs"
"os"
"path/filepath"
)
// LocalFSProvider serves files from a local directory.
type LocalFSProvider struct {
path string
fs fs.FS
}
// NewLocalFSProvider creates a new LocalFSProvider for the given directory path.
// The path must be an absolute path to an existing directory.
func NewLocalFSProvider(path string) (*LocalFSProvider, error) {
// Validate that the path exists and is a directory
info, err := os.Stat(path)
if err != nil {
return nil, fmt.Errorf("failed to stat directory: %w", err)
}
if !info.IsDir() {
return nil, fmt.Errorf("path is not a directory: %s", path)
}
// Convert to absolute path
absPath, err := filepath.Abs(path)
if err != nil {
return nil, fmt.Errorf("failed to get absolute path: %w", err)
}
return &LocalFSProvider{
path: absPath,
fs: os.DirFS(absPath),
}, nil
}
// Open opens the named file from the local directory.
func (p *LocalFSProvider) Open(name string) (fs.File, error) {
return p.fs.Open(name)
}
// Close releases any resources held by the provider.
// For local filesystem, this is a no-op since os.DirFS doesn't hold resources.
func (p *LocalFSProvider) Close() error {
return nil
}
// Type returns "local".
func (p *LocalFSProvider) Type() string {
return "local"
}
// Path returns the absolute path to the directory being served.
func (p *LocalFSProvider) Path() string {
return p.path
}
// Reload refreshes the filesystem view.
// For local directories, os.DirFS automatically picks up changes,
// so this recreates the DirFS to ensure a fresh view.
func (p *LocalFSProvider) Reload() error {
// Verify the directory still exists
info, err := os.Stat(p.path)
if err != nil {
return fmt.Errorf("failed to stat directory: %w", err)
}
if !info.IsDir() {
return fmt.Errorf("path is no longer a directory: %s", p.path)
}
// Recreate the DirFS
p.fs = os.DirFS(p.path)
return nil
}