forked from coder/coder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfile.go
More file actions
133 lines (111 loc) · 2.82 KB
/
file.go
File metadata and controls
133 lines (111 loc) · 2.82 KB
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package config
import (
"io"
"os"
"path/filepath"
"github.com/kirsle/configdir"
"golang.org/x/xerrors"
)
const (
FlagName = "global-config"
)
// Root represents the configuration directory.
type Root string
// mustNotBeEmpty prevents us from accidentally writing configuration to the
// current directory. This is primarily valuable in development, where we may
// accidentally use an empty root.
func (r Root) mustNotEmpty() {
if r == "" {
panic("config root must not be empty")
}
}
func (r Root) Session() File {
r.mustNotEmpty()
return File(filepath.Join(string(r), "session"))
}
// ReplicaID is a unique identifier for the Coder server.
func (r Root) ReplicaID() File {
r.mustNotEmpty()
return File(filepath.Join(string(r), "replica_id"))
}
func (r Root) URL() File {
r.mustNotEmpty()
return File(filepath.Join(string(r), "url"))
}
func (r Root) Organization() File {
r.mustNotEmpty()
return File(filepath.Join(string(r), "organization"))
}
func (r Root) DotfilesURL() File {
r.mustNotEmpty()
return File(filepath.Join(string(r), "dotfilesurl"))
}
func (r Root) PostgresPath() string {
r.mustNotEmpty()
return filepath.Join(string(r), "postgres")
}
func (r Root) PostgresPassword() File {
r.mustNotEmpty()
return File(filepath.Join(r.PostgresPath(), "password"))
}
func (r Root) PostgresPort() File {
r.mustNotEmpty()
return File(filepath.Join(r.PostgresPath(), "port"))
}
// File provides convenience methods for interacting with *os.File.
type File string
// Delete deletes the file.
func (f File) Delete() error {
if f == "" {
return xerrors.Errorf("empty file path")
}
return os.Remove(string(f))
}
// Write writes the string to the file.
func (f File) Write(s string) error {
if f == "" {
return xerrors.Errorf("empty file path")
}
return write(string(f), 0o600, []byte(s))
}
// Read reads the file to a string.
func (f File) Read() (string, error) {
if f == "" {
return "", xerrors.Errorf("empty file path")
}
byt, err := read(string(f))
return string(byt), err
}
// open opens a file in the configuration directory,
// creating all intermediate directories.
func open(path string, flag int, mode os.FileMode) (*os.File, error) {
err := os.MkdirAll(filepath.Dir(path), 0o750)
if err != nil {
return nil, err
}
return os.OpenFile(path, flag, mode)
}
func write(path string, mode os.FileMode, dat []byte) error {
fi, err := open(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, mode)
if err != nil {
return err
}
defer fi.Close()
_, err = fi.Write(dat)
return err
}
func read(path string) ([]byte, error) {
fi, err := open(path, os.O_RDONLY, 0)
if err != nil {
return nil, err
}
defer fi.Close()
return io.ReadAll(fi)
}
func DefaultDir() string {
configDir := configdir.LocalConfig("coderv2")
if dir := os.Getenv("CLIDOCGEN_CONFIG_DIRECTORY"); dir != "" {
configDir = dir
}
return configDir
}