jorge/config/config.go
Facundo Olano 7bc5baa253
Minify exclusions (#31)
* add minify exclusions support

* load exclusions

* fix bug

* load minify

* fix yaml type coersion

* skip dot files when building
2024-03-15 19:55:50 -03:00

137 lines
3.8 KiB
Go

package config
import (
"errors"
"fmt"
"maps"
"os"
"path/filepath"
"gopkg.in/yaml.v3"
)
// The properties that are depended upon in the source code are declared explicitly in the config struct.
// The constructors will set default values for most.
// Depending on the command, different defaults will be used (serve is assumed to be a "dev" environment
// while build is assumed to be prod)
// Some defaults could be overridden by cli flags (eg disable live reload on serve).
// The user can override some of those via config yaml.
// The non declared values found in config yaml will just be passed as site.config values
type Config struct {
RootDir string
SrcDir string
TargetDir string
LayoutsDir string
IncludesDir string
DataDir string
SiteUrl string
PostFormat string
Lang string
HighlightTheme string
Minify bool
MinifyExclusions []string
LiveReload bool
LinkStatic bool
IncludeDrafts bool
ServerHost string
ServerPort int
pageDefaults map[string]interface{}
// the user provided overrides, as found in config.yml
// these will passed as found as template context
overrides map[string]interface{}
}
func Load(rootDir string) (*Config, error) {
// TODO allow to disable minify
config := &Config{
RootDir: rootDir,
SrcDir: filepath.Join(rootDir, "src"),
TargetDir: filepath.Join(rootDir, "target"),
LayoutsDir: filepath.Join(rootDir, "layouts"),
IncludesDir: filepath.Join(rootDir, "includes"),
DataDir: filepath.Join(rootDir, "data"),
PostFormat: "blog/:title.org",
Lang: "en",
HighlightTheme: "github",
Minify: true,
MinifyExclusions: make([]string, 0),
LiveReload: false,
LinkStatic: false,
IncludeDrafts: false,
pageDefaults: map[string]interface{}{},
}
// load overrides from config.yml
configPath := filepath.Join(rootDir, "config.yml")
yamlContent, err := os.ReadFile(configPath)
if errors.Is(err, os.ErrNotExist) {
// config file is not mandatory
return config, nil
} else if err != nil {
return nil, err
}
err = yaml.Unmarshal(yamlContent, &config.overrides)
if err != nil {
return nil, err
}
// set user-provided overrides of declared config keys
// FIXME less copypasty way of declaring config overrides
if url, found := config.overrides["url"]; found {
config.SiteUrl = url.(string)
}
if format, found := config.overrides["post_format"]; found {
config.PostFormat = format.(string)
}
if lang, found := config.overrides["lang"]; found {
config.Lang = lang.(string)
}
if theme, found := config.overrides["highlight_theme"]; found {
config.HighlightTheme = theme.(string)
}
if exclusions, found := config.overrides["minify_exclusions"]; found {
for _, exclusion := range exclusions.([]interface{}) {
config.MinifyExclusions = append(config.MinifyExclusions, exclusion.(string))
}
}
return config, nil
}
func LoadDev(rootDir string, host string, port int, reload bool) (*Config, error) {
// TODO revisit is this Load vs LoadDevServer is the best way to handle both modes
// TODO some of the options need to be overridable: host, port, live reload at least
config, err := Load(rootDir)
if err != nil {
return nil, err
}
// setup serve command specific overrides (these could be eventually tweaked with flags)
config.ServerHost = host
config.ServerPort = port
config.LiveReload = reload
config.Minify = false
config.LinkStatic = true
config.IncludeDrafts = true
config.SiteUrl = fmt.Sprintf("http://%s:%d", config.ServerHost, config.ServerPort)
return config, nil
}
func (config Config) AsContext() map[string]interface{} {
context := map[string]interface{}{
"url": config.SiteUrl,
}
maps.Copy(context, config.overrides)
return context
}