gf/os/gfile/gfile_home.go

83 lines
1.9 KiB
Go

// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gfile
import (
"bytes"
"os"
"os/exec"
"os/user"
"runtime"
"strings"
"github.com/gogf/gf/v2/errors/gerror"
)
// Home returns absolute path of current user's home directory.
// The optional parameter `names` specifies the sub-folders/sub-files,
// which will be joined with current system separator and returned with the path.
func Home(names ...string) (string, error) {
path, err := getHomePath()
if err != nil {
return "", err
}
for _, name := range names {
path += Separator + name
}
return path, nil
}
// getHomePath returns absolute path of current user's home directory.
func getHomePath() (string, error) {
u, err := user.Current()
if nil == err {
return u.HomeDir, nil
}
if runtime.GOOS == "windows" {
return homeWindows()
}
return homeUnix()
}
// homeUnix retrieves and returns the home on unix system.
func homeUnix() (string, error) {
if home := os.Getenv("HOME"); home != "" {
return home, nil
}
var stdout bytes.Buffer
cmd := exec.Command("sh", "-c", "eval echo ~$USER")
cmd.Stdout = &stdout
if err := cmd.Run(); err != nil {
err = gerror.Wrapf(err, `retrieve home directory failed`)
return "", err
}
result := strings.TrimSpace(stdout.String())
if result == "" {
return "", gerror.New("blank output when reading home directory")
}
return result, nil
}
// homeWindows retrieves and returns the home on windows system.
func homeWindows() (string, error) {
var (
drive = os.Getenv("HOMEDRIVE")
path = os.Getenv("HOMEPATH")
home = drive + path
)
if drive == "" || path == "" {
home = os.Getenv("USERPROFILE")
}
if home == "" {
return "", gerror.New("environment keys HOMEDRIVE, HOMEPATH and USERPROFILE are empty")
}
return home, nil
}