dodo/config/file.go

84 lines
2.0 KiB
Go

package config
import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"os"
"slices"
"strings"
"time"
"github.com/aykhans/dodo/types"
"gopkg.in/yaml.v3"
)
var supportedFileTypes = []string{"json", "yaml", "yml"}
func (config *Config) ReadFile(filePath types.ConfigFile) error {
var (
data []byte
err error
)
fileExt := filePath.Extension()
if slices.Contains(supportedFileTypes, fileExt) {
if filePath.LocationType() == types.FileLocationTypeRemoteHTTP {
client := &http.Client{
Timeout: 10 * time.Second,
}
resp, err := client.Get(filePath.String())
if err != nil {
return fmt.Errorf("failed to fetch config file from %s", filePath)
}
defer resp.Body.Close()
data, err = io.ReadAll(io.Reader(resp.Body))
if err != nil {
return fmt.Errorf("failed to read config file from %s", filePath)
}
} else {
data, err = os.ReadFile(filePath.String())
if err != nil {
return errors.New("failed to read config file from " + filePath.String())
}
}
if fileExt == "json" {
return parseJSONConfig(data, config)
} else if fileExt == "yml" || fileExt == "yaml" {
return parseYAMLConfig(data, config)
}
}
return fmt.Errorf("unsupported config file type (supported types: %v)", strings.Join(supportedFileTypes, ", "))
}
func parseJSONConfig(data []byte, config *Config) error {
err := json.Unmarshal(data, &config)
if err != nil {
switch parsedErr := err.(type) {
case *json.SyntaxError:
return fmt.Errorf("JSON Config file: invalid syntax at byte offset %d", parsedErr.Offset)
case *json.UnmarshalTypeError:
return fmt.Errorf("JSON Config file: invalid type %v for field %s, expected %v", parsedErr.Value, parsedErr.Field, parsedErr.Type)
default:
return fmt.Errorf("JSON Config file: %s", err.Error())
}
}
return nil
}
func parseYAMLConfig(data []byte, config *Config) error {
err := yaml.Unmarshal(data, &config)
if err != nil {
return fmt.Errorf("YAML Config file: %s", err.Error())
}
return nil
}