mirror of https://github.com/mickael-menu/zk
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
1.9 KiB
Go
93 lines
1.9 KiB
Go
package zk
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/mickael-menu/zk/util/errors"
|
|
)
|
|
|
|
const defaultConfig = `
|
|
# Test
|
|
test = thing
|
|
`
|
|
|
|
// Open locates a slip box at the given path and parses its configuration.
|
|
func Open(path string) error {
|
|
wrap := errors.Wrapper("open failed")
|
|
|
|
path, err := filepath.Abs(path)
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
_, err = locateRoot(path)
|
|
return wrap(err)
|
|
}
|
|
|
|
// Create initializes a new slip box at the given path.
|
|
func Create(path string) error {
|
|
wrap := errors.Wrapper("init failed")
|
|
|
|
path, err := filepath.Abs(path)
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
|
|
if existingPath, err := locateRoot(path); err == nil {
|
|
return wrap(fmt.Errorf("a slip box already exists in %v", existingPath))
|
|
}
|
|
|
|
// Create .zk and .zk/templates directories.
|
|
err = os.MkdirAll(filepath.Join(path, ".zk/templates"), os.ModePerm)
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
|
|
// Write default config.toml.
|
|
f, err := os.Create(filepath.Join(path, ".zk/config.toml"))
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
_, err = f.WriteString(defaultConfig)
|
|
if err != nil {
|
|
return wrap(err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// locate finds the root of the slip box containing the given path.
|
|
func locateRoot(path string) (string, error) {
|
|
if !filepath.IsAbs(path) {
|
|
panic("absolute path expected")
|
|
}
|
|
|
|
var locate func(string) (string, error)
|
|
locate = func(currentPath string) (string, error) {
|
|
if currentPath == "/" || currentPath == "." {
|
|
return "", fmt.Errorf("no slip box found in %v or a parent directory", path)
|
|
}
|
|
if dotPath := filepath.Join(currentPath, ".zk"); dirExists(dotPath) {
|
|
return currentPath, nil
|
|
}
|
|
|
|
return locate(filepath.Dir(currentPath))
|
|
}
|
|
|
|
return locate(path)
|
|
}
|
|
|
|
func dirExists(path string) bool {
|
|
fi, err := os.Stat(path)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
switch mode := fi.Mode(); {
|
|
case mode.IsDir():
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|