101 lines
3.7 KiB
Go
101 lines
3.7 KiB
Go
package promptkit
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"gitea.maximumdirect.net/eric/ConfigKit"
|
|
"gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
|
"gitea.maximumdirect.net/eric/promptkit/internal/filecatalog"
|
|
)
|
|
|
|
// CollectionInput mounts source at the selected collection's configuration
|
|
// destination, collections/<namespace>, and enables ConfigKit imports for that
|
|
// input. An invalid namespace returns an error matching ErrInvalidConfig. The
|
|
// source is not read or validated until ConfigKit loads it. Callers may adjust
|
|
// the returned input, including its filesystem context or imports setting.
|
|
func CollectionInput(namespace string, source configkit.Source) (configkit.Input, error) {
|
|
if !domain.IsValidResourceNamespace(namespace) {
|
|
return configkit.Input{}, fmt.Errorf("%w: invalid collection namespace %q", ErrInvalidConfig, namespace)
|
|
}
|
|
return configkit.Input{
|
|
Source: source,
|
|
Destination: configkit.Keys("collections", namespace),
|
|
Imports: true,
|
|
}, nil
|
|
}
|
|
|
|
// DirectoryInputs selects the YAML files beneath an explicitly chosen host
|
|
// directory as one strict-composition group. The returned order is deterministic;
|
|
// it does not assign precedence among those files. Discovery is recursive over
|
|
// .yaml and .yml files. An unavailable root fails; an empty directory yields
|
|
// no inputs. Imports are disabled unless callers enable them on the inputs.
|
|
func DirectoryInputs(directory string) ([]configkit.Input, error) {
|
|
root, err := filepath.Abs(directory)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("resolve configuration directory: %w", err)
|
|
}
|
|
info, err := os.Stat(root)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("inspect configuration directory: %w", err)
|
|
}
|
|
if !info.IsDir() {
|
|
return nil, fmt.Errorf("configuration root is not a directory: %s", root)
|
|
}
|
|
root, err = filepath.EvalSymlinks(root)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("resolve configuration directory: %w", err)
|
|
}
|
|
files, err := filecatalog.FindYAMLFiles(context.Background(), root)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("discover configuration files: %w", err)
|
|
}
|
|
inputs := make([]configkit.Input, 0, len(files))
|
|
for _, file := range files {
|
|
inputs = append(inputs, configkit.Input{
|
|
Source: configkit.File(file),
|
|
Filesystem: &configkit.FilesystemContext{Root: root},
|
|
})
|
|
}
|
|
return inputs, nil
|
|
}
|
|
|
|
// FilesystemInputs selects the YAML files beneath root in a caller-owned
|
|
// filesystem as one strict-composition group. Discovery is recursive over
|
|
// .yaml and .yml files, with deterministic ordering and no precedence among
|
|
// files. The caller retains ownership of the filesystem; an unavailable root
|
|
// fails and an empty directory yields no inputs. Imports remain disabled unless
|
|
// callers enable them on inputs.
|
|
func FilesystemInputs(label string, filesystem fs.FS, root string) ([]configkit.Input, error) {
|
|
if filesystem == nil {
|
|
return nil, fmt.Errorf("configuration filesystem is nil")
|
|
}
|
|
root = filecatalog.CleanFSRoot(root)
|
|
if !fs.ValidPath(root) {
|
|
return nil, fmt.Errorf("configuration root is not a valid filesystem path: %s", root)
|
|
}
|
|
info, err := fs.Stat(filesystem, root)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("inspect configuration root: %w", err)
|
|
}
|
|
if !info.IsDir() {
|
|
return nil, fmt.Errorf("configuration root is not a directory: %s", root)
|
|
}
|
|
files, err := filecatalog.FindFSYAMLFiles(context.Background(), filesystem, root)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("discover configuration files: %w", err)
|
|
}
|
|
namespace := configkit.NewFilesystem(label, filesystem)
|
|
inputs := make([]configkit.Input, 0, len(files))
|
|
for _, file := range files {
|
|
inputs = append(inputs, configkit.Input{
|
|
Source: namespace.File(file),
|
|
Filesystem: &configkit.FilesystemContext{FS: &namespace, Root: root},
|
|
})
|
|
}
|
|
return inputs, nil
|
|
}
|