...
1 package xos
2
3 import (
4 "fmt"
5 "os"
6 "path/filepath"
7 "strings"
8 "sync"
9 )
10
11 type Env struct {
12 environMu sync.RWMutex
13 environ []string
14 }
15
16 func NewEnv(environ []string) *Env {
17 return &Env{
18 environ: environ,
19 }
20 }
21
22 func (e *Env) Environ() []string {
23 e.environMu.RLock()
24 defer e.environMu.RUnlock()
25
26 environ2 := make([]string, 0, len(e.environ))
27 return append(environ2, e.environ...)
28 }
29
30 func (e *Env) Setenv(name, value string) {
31 e.environMu.Lock()
32 defer e.environMu.Unlock()
33
34 l := fmt.Sprintf("%s=%s", name, value)
35
36 for i, l2 := range e.environ {
37 j := strings.Index(l2, "=")
38 if j == -1 {
39 continue
40 }
41 name2 := l2[:j]
42 if name != name2 {
43 continue
44 }
45 e.environ[i] = l
46 return
47 }
48 e.environ = append(e.environ, l)
49 }
50
51 func (e *Env) Getenv(name string) string {
52 e.environMu.RLock()
53 defer e.environMu.RUnlock()
54
55 for _, l := range e.environ {
56 i := strings.Index(l, "=")
57 if i == -1 {
58 continue
59 }
60 name2 := l[:i]
61 if name == name2 {
62 return l[i+1:]
63 }
64 }
65 return ""
66 }
67
68 func (e *Env) Bool(name string) (*bool, error) {
69 ev := e.Getenv(name)
70 if ev == "" {
71 return nil, nil
72 }
73 eb := new(bool)
74 if ev == "0" || ev == "false" {
75 return eb, nil
76 }
77 if ev == "1" || ev == "true" {
78 *eb = true
79 return eb, nil
80 }
81 return nil, fmt.Errorf("$%s must be 0, 1, false or true but got %q", name, ev)
82 }
83
84 func (e *Env) HumanPath(fp string) string {
85 if strings.HasPrefix(fp, e.Getenv("HOME")) {
86 return filepath.Join("~", strings.TrimPrefix(fp, e.Getenv("HOME")))
87 }
88 return fp
89 }
90
91 func (e *Env) Debug() bool {
92 debug, err := e.Bool("DEBUG")
93 if err != nil {
94 os.Stderr.WriteString(fmt.Sprintf("env: %v", err))
95 return false
96 }
97 if debug == nil || !*debug {
98 return false
99 }
100 return true
101 }
102
103 func (e *Env) CI() bool {
104 ci, err := e.Bool("CI")
105 if err != nil {
106 os.Stderr.WriteString(fmt.Sprintf("env: %v", err))
107 return false
108 }
109 if ci == nil || !*ci {
110 return false
111 }
112 return true
113 }
114
View as plain text