File: xdg.go

package info (click to toggle)
golang-github-apparentlymart-go-userdirs 0.0~git20200915.b0c018a-4
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 184 kB
  • sloc: makefile: 2
file content (105 lines) | stat: -rw-r--r-- 3,138 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package xdgbase

import (
	"os"
	"path/filepath"
)

// DataHome returns the value of XDG_DATA_HOME, or the specification-defined
// fallback value of $HOME/.local/share.
func DataHome() string {
	return envSingle("XDG_DATA_HOME", func() string {
		return filepath.Join(home(), ".local", "share")
	})
}

// OtherDataDirs returns the values from XDG_DATA_DIRS, or the specification-defined
// fallback values "/usr/local/share/" and "/usr/share/".
func OtherDataDirs() []string {
	return envMulti("XDG_DATA_DIRS", func() []string {
		return []string{"/usr/local/share/", "/usr/share/"}
	})
}

// DataDirs returns the combination of DataHome and OtherDataDirs, giving the
// full set of data directories to search, in preference order.
func DataDirs() []string {
	ret := make([]string, 0, 3) // default OtherDataDirs has two elements
	ret = append(ret, DataHome())
	ret = append(ret, OtherDataDirs()...)
	return ret[:len(ret):len(ret)]
}

// ConfigHome returns the value of XDG_CONFIG_HOME, or the specification-defined
// fallback value of $HOME/.config.
func ConfigHome() string {
	return envSingle("XDG_CONFIG_HOME", func() string {
		return filepath.Join(home(), ".config")
	})
}

// OtherConfigDirs returns the values from XDG_CONFIG_DIRS, or the
// specification-defined fallback value "/etc/xdg".
func OtherConfigDirs() []string {
	return envMulti("XDG_CONFIG_DIRS", func() []string {
		return []string{"/etc/xdg"}
	})
}

// ConfigDirs returns the combination of ConfigHome and OtherConfigDirs, giving the
// full set of config directories to search, in preference order.
func ConfigDirs() []string {
	ret := make([]string, 0, 2) // default OtherConfigDirs has one element
	ret = append(ret, ConfigHome())
	ret = append(ret, OtherConfigDirs()...)
	return ret[:len(ret):len(ret)]
}

// CacheHome returns the value of XDG_CACHE_HOME, or the specification-defined
// fallback value of $HOME/.cache.
func CacheHome() string {
	return envSingle("XDG_CACHE_HOME", func() string {
		return filepath.Join(home(), ".cache")
	})
}

// MaybeRuntimeDir returns the value of XDG_RUNTIME_DIR, or an empty string if
// it is not set.
//
// Calling applications MUST check that the return value is non-empty before
// using it, because there is no reasonable default behavior when no runtime
// directory is defined.
func MaybeRuntimeDir() string {
	return envSingle("XDG_RUNTIME_DIR", func() string {
		return ""
	})
}

func envSingle(name string, fallback func() string) string {
	if p := os.Getenv(name); p != "" {
		if filepath.IsAbs(p) {
			return p
		}
	}

	return fallback()
}

func envMulti(name string, fallback func() []string) []string {
	if p := os.Getenv(name); p != "" {
		parts := filepath.SplitList(p)
		// Make sure all of the paths are absolute
		for i := len(parts) - 1; i >= 0; i-- {
			if !filepath.IsAbs(parts[i]) {
				// We'll shift everything after this point in the list
				// down so that this element is no longer present.
				copy(parts[i:], parts[i+1:])
				parts = parts[:len(parts)-1]
			}
		}
		parts = parts[:len(parts):len(parts)] // hide any extra capacity from the caller
		return parts
	}

	return fallback()
}