aboutsummaryrefslogtreecommitdiffhomepage
path: root/internal/env/env.go
blob: 45fd5fcb38ab16dcb381984bd0bcee9955c3693a (plain)
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
// Package env provides the [Paths] struct for efficiently building paths from the environment.
package env

import (
	"log"
	"os"
	"strconv"

	"hakurei.app/check"
	"hakurei.app/hst"
)

// Paths holds paths copied from the environment and is used to create [hst.Paths].
type Paths struct {
	// TempDir is returned by [os.TempDir].
	TempDir *check.Absolute
	// RuntimePath is copied from $XDG_RUNTIME_DIR.
	RuntimePath *check.Absolute
}

// Copy expands [Paths] into [hst.Paths].
func (env *Paths) Copy(v *hst.Paths, userid int) {
	if env == nil || env.TempDir == nil || v == nil {
		panic("attempting to use an invalid Paths")
	}

	v.TempDir = env.TempDir
	v.SharePath = env.TempDir.Append("hakurei." + strconv.Itoa(userid))

	if env.RuntimePath == nil {
		// fall back to path in share since hakurei has no hard XDG dependency
		v.RuntimePath = v.SharePath.Append("compat")
	} else {
		v.RuntimePath = env.RuntimePath
	}
	v.RunDirPath = v.RuntimePath.Append("hakurei")
}

// CopyPaths returns a populated [Paths].
func CopyPaths() *Paths { return CopyPathsFunc(log.Fatalf, os.TempDir, os.Getenv) }

// CopyPathsFunc returns a populated [Paths],
// using the provided [log.Fatalf], [os.TempDir], [os.Getenv] functions.
func CopyPathsFunc(
	fatalf func(format string, v ...any),
	tempdir func() string,
	getenv func(key string) string,
) *Paths {
	const xdgRuntimeDir = "XDG_RUNTIME_DIR"

	var env Paths

	if tempDir, err := check.NewAbs(tempdir()); err != nil {
		fatalf("invalid TMPDIR: %v", err)
		panic("unreachable")
	} else {
		env.TempDir = tempDir
	}

	if a, err := check.NewAbs(getenv(xdgRuntimeDir)); err == nil {
		env.RuntimePath = a
	}

	return &env
}