| 49 | ) |
| 50 | |
| 51 | func LoadFlatFile[T LoadableSimple](path string) (T, error) { |
| 52 | |
| 53 | var loaded T |
| 54 | |
| 55 | path = filepath.FromSlash(path) |
| 56 | |
| 57 | fileInfo, err := os.Stat(path) |
| 58 | if err != nil { |
| 59 | return loaded, errors.Wrap(err, `filepath: `+path) |
| 60 | } |
| 61 | |
| 62 | if fileInfo.IsDir() { |
| 63 | return loaded, errors.New(`filepath: ` + path + ` is a directory`) |
| 64 | } |
| 65 | |
| 66 | fExt := filepath.Ext(path) |
| 67 | if fExt != `.yaml` { |
| 68 | return loaded, errors.New(`invalid file type: ` + path) |
| 69 | } |
| 70 | |
| 71 | bytes, err := os.ReadFile(path) |
| 72 | if err != nil { |
| 73 | return loaded, errors.Wrap(err, `filepath: `+path) |
| 74 | } |
| 75 | |
| 76 | err = yaml.Unmarshal(bytes, &loaded) |
| 77 | if err != nil { |
| 78 | return loaded, errors.Wrap(err, `filepath: `+path) |
| 79 | } |
| 80 | |
| 81 | // Make sure the Filepath it claims is correct in case we need to save it later |
| 82 | if !strings.HasSuffix(path, filepath.FromSlash(loaded.Filepath())) { |
| 83 | return loaded, errors.New(fmt.Sprintf(`filesystem path "%s" did not end in Filepath() "%s" for type %T`, path, loaded.Filepath(), loaded)) |
| 84 | } |
| 85 | |
| 86 | // validate the structure |
| 87 | if err := loaded.Validate(); err != nil { |
| 88 | return loaded, errors.Wrap(err, `filepath: `+path) |
| 89 | } |
| 90 | |
| 91 | return loaded, nil |
| 92 | } |
| 93 | |
| 94 | // LoadAllFlatFilesSimple doesn't require a unique Id() for each item |
| 95 | func LoadAllFlatFilesSimple[T LoadableSimple](basePath string, filePattern ...string) ([]T, error) { |