github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/pkg/shell/paths.go (about)

     1  package shell
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	"src.elv.sh/pkg/fsutil"
    10  )
    11  
    12  // Paths keeps all paths required for the Elvish runtime.
    13  type Paths struct {
    14  	RunDir string
    15  	Sock   string
    16  
    17  	DataDir string
    18  	Db      string
    19  	Rc      string
    20  	LibDir  string
    21  
    22  	Bin string
    23  }
    24  
    25  // MakePaths makes a populated Paths, using the given overrides.
    26  func MakePaths(stderr io.Writer, overrides Paths) Paths {
    27  	p := overrides
    28  	setDir(&p.RunDir, "secure run directory", getSecureRunDir, stderr)
    29  	if p.RunDir != "" {
    30  		setChild(&p.Sock, p.RunDir, "sock")
    31  	}
    32  
    33  	setDir(&p.DataDir, "data directory", ensureDataDir, stderr)
    34  	if p.DataDir != "" {
    35  		setChild(&p.Db, p.DataDir, "db")
    36  		setChild(&p.Rc, p.DataDir, "rc.elv")
    37  		setChild(&p.LibDir, p.DataDir, "lib")
    38  	}
    39  
    40  	if p.Bin == "" {
    41  		binFile, err := os.Executable()
    42  		if err == nil {
    43  			p.Bin = binFile
    44  		} else {
    45  			fmt.Fprintln(stderr, "warning: cannot get executable path:", err)
    46  		}
    47  	}
    48  	return p
    49  }
    50  
    51  func setDir(p *string, what string, f func() (string, error), stderr io.Writer) {
    52  	if *p == "" {
    53  		dir, err := f()
    54  		if err == nil {
    55  			*p = dir
    56  		} else {
    57  			fmt.Fprintf(stderr, "warning: cannot create %v: %v\n", what, err)
    58  		}
    59  	}
    60  }
    61  
    62  func setChild(p *string, d, name string) {
    63  	if *p == "" {
    64  		*p = filepath.Join(d, name)
    65  	}
    66  }
    67  
    68  // Ensures Elvish's data directory exists, creating it if necessary. It returns
    69  // the path to the data directory (never with a trailing slash) and possible
    70  // error.
    71  func ensureDataDir() (string, error) {
    72  	home, err := fsutil.GetHome("")
    73  	if err != nil {
    74  		return "", err
    75  	}
    76  	ddir := home + "/.elvish"
    77  	return ddir, os.MkdirAll(ddir, 0700)
    78  }