1// Package home provides utilities for dealing with the user's home directory.
2package home
3
4import (
5 "log/slog"
6 "os"
7 "path/filepath"
8 "strings"
9 "sync"
10)
11
12// Dir returns the users home directory, or if it fails, tries to create a new
13// temporary directory and use that instead.
14var Dir = sync.OnceValue(func() string {
15 home, err := os.UserHomeDir()
16 if err == nil {
17 slog.Debug("user home directory", "home", home)
18 return home
19 }
20 tmp, err := os.MkdirTemp("crush", "")
21 if err != nil {
22 slog.Error("could not find the user home directory")
23 return ""
24 }
25 slog.Warn("could not find the user home directory, using a temporary one", "home", tmp)
26 return tmp
27})
28
29// Short replaces the actual home path from [Dir] with `~`.
30func Short(p string) string {
31 if !strings.HasPrefix(p, Dir()) || Dir() == "" {
32 return p
33 }
34 return filepath.Join("~", strings.TrimPrefix(p, Dir()))
35}
36
37// Long replaces the `~` with actual home path from [Dir].
38func Long(p string) string {
39 if !strings.HasPrefix(p, "~") || Dir() == "" {
40 return p
41 }
42 return strings.Replace(p, "~", Dir(), 1)
43}