2020-04-14 07:05:10 +08:00
|
|
|
package shell
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
|
|
|
"github.com/elves/elvish/pkg/util"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Paths keeps all paths required for the Elvish runtime.
|
|
|
|
type Paths struct {
|
|
|
|
RunDir string
|
|
|
|
Sock string
|
|
|
|
DaemonLogPrefix string
|
|
|
|
|
|
|
|
DataDir string
|
|
|
|
Db string
|
|
|
|
Rc string
|
|
|
|
LibDir string
|
|
|
|
|
|
|
|
Bin string
|
|
|
|
}
|
|
|
|
|
2020-04-16 23:39:44 +08:00
|
|
|
// MakePaths makes a populated Paths, using the given overrides.
|
|
|
|
func MakePaths(stderr io.Writer, overrides Paths) Paths {
|
|
|
|
p := overrides
|
2020-04-14 07:05:10 +08:00
|
|
|
setDir(&p.RunDir, "secure run directory", getSecureRunDir, stderr)
|
|
|
|
if p.RunDir != "" {
|
|
|
|
setChild(&p.Sock, p.RunDir, "sock")
|
|
|
|
setChild(&p.DaemonLogPrefix, p.RunDir, "daemon.log-")
|
|
|
|
}
|
|
|
|
|
|
|
|
setDir(&p.DataDir, "data directory", ensureDataDir, stderr)
|
|
|
|
if p.DataDir != "" {
|
|
|
|
setChild(&p.Db, p.DataDir, "db")
|
|
|
|
setChild(&p.Rc, p.DataDir, "rc.elv")
|
|
|
|
setChild(&p.LibDir, p.DataDir, "lib")
|
|
|
|
}
|
|
|
|
|
|
|
|
if p.Bin == "" {
|
|
|
|
binFile, err := os.Executable()
|
|
|
|
if err == nil {
|
|
|
|
p.Bin = binFile
|
|
|
|
} else {
|
|
|
|
fmt.Fprintln(stderr, "warning: cannot get executable path:", err)
|
|
|
|
}
|
|
|
|
}
|
2020-04-16 23:39:44 +08:00
|
|
|
return p
|
2020-04-14 07:05:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func setDir(p *string, what string, f func() (string, error), stderr io.Writer) {
|
|
|
|
if *p == "" {
|
|
|
|
dir, err := f()
|
|
|
|
if err == nil {
|
|
|
|
*p = dir
|
|
|
|
} else {
|
|
|
|
fmt.Fprintf(stderr, "warning: cannot create %v: %v\n", what, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func setChild(p *string, d, name string) {
|
|
|
|
if *p == "" {
|
|
|
|
*p = filepath.Join(d, name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensures Elvish's data directory exists, creating it if necessary. It returns
|
|
|
|
// the path to the data directory (never with a trailing slash) and possible
|
|
|
|
// error.
|
|
|
|
func ensureDataDir() (string, error) {
|
|
|
|
home, err := util.GetHome("")
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
ddir := home + "/.elvish"
|
|
|
|
return ddir, os.MkdirAll(ddir, 0700)
|
|
|
|
}
|