hugo/hugolib/config.go
Egon Elbre e46148f948 Fix static file change detection on Windows.
Fixed windows uses different filepath separator. The filepath.ToSlash
shouldn't be used, because it can cause errors in filepath suffix and prefix
testing since "c:\a" isn't a prefix of "c:/a/b/c".
2013-12-28 13:45:38 -05:00

198 lines
4.6 KiB
Go

// Copyright © 2013 Steve Francia <spf@spf13.com>.
//
// Licensed under the Simple Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://opensource.org/licenses/Simple-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package hugolib
import (
"encoding/json"
"fmt"
"github.com/BurntSushi/toml"
"io/ioutil"
"launchpad.net/goyaml"
"os"
"path"
"path/filepath"
"strings"
)
// config file items
type Config struct {
ContentDir, PublishDir, BaseUrl, StaticDir string
Path, CacheDir, LayoutDir, DefaultLayout string
ConfigFile string
Title string
Indexes map[string]string // singular, plural
ProcessFilters map[string][]string
Params map[string]interface{}
Permalinks PermalinkOverrides
BuildDrafts, UglyUrls, Verbose bool
}
var c Config
// Read cfgfile or setup defaults.
func SetupConfig(cfgfile *string, path *string) *Config {
c.setPath(*path)
cfg, err := c.findConfigFile(*cfgfile)
c.ConfigFile = cfg
if err != nil {
fmt.Printf("%v", err)
fmt.Println(" using defaults instead")
}
// set defaults
c.ContentDir = "content"
c.LayoutDir = "layouts"
c.PublishDir = "public"
c.StaticDir = "static"
c.DefaultLayout = "post"
c.BuildDrafts = false
c.UglyUrls = false
c.Verbose = false
c.readInConfig()
// set index defaults if none provided
if len(c.Indexes) == 0 {
c.Indexes = make(map[string]string)
c.Indexes["tag"] = "tags"
c.Indexes["category"] = "categories"
}
// ensure map exists, albeit empty
if c.Permalinks == nil {
c.Permalinks = make(PermalinkOverrides, 0)
}
if !strings.HasSuffix(c.BaseUrl, "/") {
c.BaseUrl = c.BaseUrl + "/"
}
return &c
}
func (c *Config) readInConfig() {
file, err := ioutil.ReadFile(c.ConfigFile)
if err == nil {
switch path.Ext(c.ConfigFile) {
case ".yaml":
if err := goyaml.Unmarshal(file, &c); err != nil {
fmt.Printf("Error parsing config: %s", err)
os.Exit(1)
}
case ".json":
if err := json.Unmarshal(file, &c); err != nil {
fmt.Printf("Error parsing config: %s", err)
os.Exit(1)
}
case ".toml":
if _, err := toml.Decode(string(file), &c); err != nil {
fmt.Printf("Error parsing config: %s", err)
os.Exit(1)
}
}
}
}
func (c *Config) setPath(p string) {
if p == "" {
path, err := findPath()
if err != nil {
fmt.Printf("Error finding path: %s", err)
}
c.Path = path
} else {
path, err := filepath.Abs(p)
if err != nil {
fmt.Printf("Error finding path: %s", err)
}
c.Path = path
}
}
func (c *Config) GetPath() string {
if c.Path == "" {
c.setPath("")
}
return c.Path
}
func findPath() (string, error) {
serverFile, err := filepath.Abs(os.Args[0])
if err != nil {
return "", fmt.Errorf("Can't get absolute path for executable: %v", err)
}
path := filepath.Dir(serverFile)
realFile, err := filepath.EvalSymlinks(serverFile)
if err != nil {
if _, err = os.Stat(serverFile + ".exe"); err == nil {
realFile = filepath.Clean(serverFile + ".exe")
}
}
if err == nil && realFile != serverFile {
path = filepath.Dir(realFile)
}
return path, nil
}
// GetAbsPath return the absolute path for a given path with the internal slashes
// properly converted.
func (c *Config) GetAbsPath(name string) string {
if filepath.IsAbs(name) {
return name
}
return filepath.Join(c.GetPath(), name)
}
func (c *Config) findConfigFile(configFileName string) (string, error) {
if configFileName == "" { // config not specified, let's search
if b, _ := exists(c.GetAbsPath("config.json")); b {
return c.GetAbsPath("config.json"), nil
}
if b, _ := exists(c.GetAbsPath("config.toml")); b {
return c.GetAbsPath("config.toml"), nil
}
if b, _ := exists(c.GetAbsPath("config.yaml")); b {
return c.GetAbsPath("config.yaml"), nil
}
return "", fmt.Errorf("config file not found in: %s", c.GetPath())
} else {
// If the full path is given, just use that
if path.IsAbs(configFileName) {
return configFileName, nil
}
// Else check the local directory
t := c.GetAbsPath(configFileName)
if b, _ := exists(t); b {
return t, nil
} else {
return "", fmt.Errorf("config file not found at: %s", t)
}
}
}