// 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/gcode" "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 { return "", err } result := strings.TrimSpace(stdout.String()) if result == "" { return "", gerror.NewCode(gcode.CodeInternalError, "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.NewCode(gcode.CodeOperationFailed, "HOMEDRIVE, HOMEPATH, and USERPROFILE are blank") } return home, nil }