Initial commit
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Config holds persistent user preferences stored in .greq/config.yaml.
|
||||
type Config struct {
|
||||
Editor string `yaml:"editor,omitempty"` // e.g. "nvim", "nano", "code --wait"
|
||||
}
|
||||
|
||||
var configPath = filepath.Join(RootDir, "config.yaml")
|
||||
|
||||
// LoadConfig reads .greq/config.yaml. Missing file returns an empty Config.
|
||||
func LoadConfig() (Config, error) {
|
||||
var cfg Config
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return cfg, nil
|
||||
}
|
||||
return cfg, err
|
||||
}
|
||||
return cfg, yaml.Unmarshal(data, &cfg)
|
||||
}
|
||||
|
||||
// SaveConfig writes cfg to .greq/config.yaml.
|
||||
func SaveConfig(cfg Config) error {
|
||||
_ = os.MkdirAll(RootDir, 0o755)
|
||||
data, err := yaml.Marshal(&cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return os.WriteFile(configPath, data, 0o644)
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package storage
|
||||
|
||||
// RequestFile is the YAML schema for a single request file.
|
||||
type RequestFile struct {
|
||||
Name string `yaml:"name"`
|
||||
Method string `yaml:"method"`
|
||||
URL string `yaml:"url"`
|
||||
Headers map[string]string `yaml:"headers,omitempty"`
|
||||
Body string `yaml:"body,omitempty"`
|
||||
PreScript string `yaml:"pre_script,omitempty"` // shell, runs before request
|
||||
TestScript string `yaml:"test_script,omitempty"` // Lua, runs after response
|
||||
}
|
||||
|
||||
// RequestItem pairs a parsed RequestFile with its filesystem metadata.
|
||||
type RequestItem struct {
|
||||
Request RequestFile
|
||||
Path string
|
||||
Folder string
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// SaveRequest writes rf to .greq/requests/<folder>/<slug>.yaml.
|
||||
// folder may be empty (places the file directly in requests/).
|
||||
func SaveRequest(rf RequestFile, folder string) (string, error) {
|
||||
dir := filepath.Join(RootDir, "requests")
|
||||
if folder != "" {
|
||||
dir = filepath.Join(dir, folder)
|
||||
}
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
slug := strings.ToLower(strings.ReplaceAll(rf.Name, " ", "_"))
|
||||
slug = strings.Map(func(r rune) rune {
|
||||
if (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9') || r == '_' || r == '-' {
|
||||
return r
|
||||
}
|
||||
return '_'
|
||||
}, slug)
|
||||
path := filepath.Join(dir, slug+".yaml")
|
||||
|
||||
data, err := yaml.Marshal(&rf)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return path, os.WriteFile(path, data, 0o644)
|
||||
}
|
||||
Reference in New Issue
Block a user