120 lines
2.8 KiB
Go
120 lines
2.8 KiB
Go
package storage
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"sort"
|
||
"strings"
|
||
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// EnvInfo describes a single environment file under .greq/.
|
||
type EnvInfo struct {
|
||
Name string // "default", "local", "staging", "prod", …
|
||
Path string // absolute or relative path to the yaml file
|
||
}
|
||
|
||
// LoadEnvFromFile reads any env yaml file into a flat key/value map.
|
||
func LoadEnvFromFile(path string) (map[string]string, error) {
|
||
envs := make(map[string]string)
|
||
data, err := os.ReadFile(path)
|
||
if err != nil {
|
||
if os.IsNotExist(err) {
|
||
return envs, nil
|
||
}
|
||
return envs, err
|
||
}
|
||
return envs, yaml.Unmarshal(data, &envs)
|
||
}
|
||
|
||
// LoadEnvList scans .greq/ for files matching env*.yaml and returns them
|
||
// sorted with "default" first, then alphabetically.
|
||
func LoadEnvList() ([]EnvInfo, error) {
|
||
matches, err := filepath.Glob(filepath.Join(RootDir, "env*.yaml"))
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
var list []EnvInfo
|
||
for _, p := range matches {
|
||
base := filepath.Base(p)
|
||
var name string
|
||
if base == "env.yaml" {
|
||
name = "default"
|
||
} else {
|
||
// env.NAME.yaml → NAME
|
||
name = strings.TrimSuffix(strings.TrimPrefix(base, "env."), ".yaml")
|
||
}
|
||
list = append(list, EnvInfo{Name: name, Path: p})
|
||
}
|
||
sort.Slice(list, func(i, j int) bool {
|
||
if list[i].Name == "default" {
|
||
return true
|
||
}
|
||
if list[j].Name == "default" {
|
||
return false
|
||
}
|
||
return list[i].Name < list[j].Name
|
||
})
|
||
return list, nil
|
||
}
|
||
|
||
const RootDir = ".greq"
|
||
|
||
// LoadEnv reads .greq/env.yaml into a flat key/value map.
|
||
// Missing file is not an error – an empty map is returned instead.
|
||
func LoadEnv() (map[string]string, error) {
|
||
return LoadEnvFromFile(filepath.Join(RootDir, "env.yaml"))
|
||
}
|
||
|
||
// LoadRequests walks .greq/requests/ and parses every .yaml/.yml file.
|
||
// The first path segment below requests/ is used as the Folder name.
|
||
func LoadRequests() ([]RequestItem, error) {
|
||
var items []RequestItem
|
||
root := filepath.Join(RootDir, "requests")
|
||
_ = os.MkdirAll(root, 0o755)
|
||
|
||
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if info.IsDir() {
|
||
return nil
|
||
}
|
||
ext := strings.ToLower(filepath.Ext(path))
|
||
if ext != ".yaml" && ext != ".yml" {
|
||
return nil
|
||
}
|
||
|
||
data, err := os.ReadFile(path)
|
||
if err != nil {
|
||
return nil // skip unreadable files silently
|
||
}
|
||
|
||
var rf RequestFile
|
||
if err := yaml.Unmarshal(data, &rf); err != nil {
|
||
return nil
|
||
}
|
||
if rf.Name == "" {
|
||
rf.Name = strings.TrimSuffix(filepath.Base(path), filepath.Ext(path))
|
||
}
|
||
if rf.Method == "" {
|
||
rf.Method = "GET"
|
||
}
|
||
|
||
rel, _ := filepath.Rel(root, path)
|
||
folder := ""
|
||
if parts := strings.Split(rel, string(filepath.Separator)); len(parts) > 1 {
|
||
folder = parts[0]
|
||
}
|
||
|
||
items = append(items, RequestItem{
|
||
Request: rf,
|
||
Path: path,
|
||
Folder: folder,
|
||
})
|
||
return nil
|
||
})
|
||
return items, err
|
||
}
|