-
Notifications
You must be signed in to change notification settings - Fork 0
/
system.go
153 lines (125 loc) · 3.23 KB
/
system.go
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
package builtin
import (
"fmt"
"io"
"math/rand"
"os"
"path"
"time"
"github.com/dece2183/hexowl/user"
)
type Environment struct {
Description string
UserVars map[string]interface{}
UserFuncs map[string]user.Func
}
type System struct {
// Writer for additional output.
Stdout io.Writer
// Callback that should clears screen.
ClearScreen func()
// Random seed that sets on SystemInit.
RandomSeed int64
// Callback that should return list of available environment file names.
ListEnvironments func() ([]string, error)
// Callback that should open environment file with provided name for write and return it as io.WriteCloser.
WriteEnvironment func(name string) (io.WriteCloser, error)
// Callback that should open environment file with provided name for read and return it as io.ReadCloser.
ReadEnvironment func(name string) (io.ReadCloser, error)
}
type descriptor struct {
functions *FuncMap
system System
}
var defaultSystem = System{
Stdout: os.Stdout,
ClearScreen: sysClearScreen,
RandomSeed: time.Now().UnixNano(),
ListEnvironments: sysListEnv,
WriteEnvironment: sysWriteEnv,
ReadEnvironment: sysReadEnv,
}
var bDesc descriptor
func init() {
bDesc.functions = &functions
SystemInit(defaultSystem)
}
func sysClearScreen() {
fmt.Fprintf(bDesc.system.Stdout, "\x1bc")
}
func sysGetEnvPath(envName string) (string, error) {
userDir, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("unable to get home directory")
}
saveDir := path.Join(userDir, ".hexowl/environment")
err = os.MkdirAll(saveDir, 0666)
if err != nil {
return "", fmt.Errorf("unable to make directory")
}
return path.Join(saveDir, envName) + ".json", nil
}
func sysListEnv() ([]string, error) {
userDir, err := os.UserHomeDir()
if err != nil {
return nil, fmt.Errorf("unable to get home directory")
}
envDir := path.Join(userDir, ".hexowl/environment")
err = os.MkdirAll(envDir, 0666)
if err != nil {
return nil, fmt.Errorf("unable to make directory")
}
dir, err := os.Open(envDir)
if err != nil {
return nil, fmt.Errorf("unable to open directory")
}
defer dir.Close()
files, err := dir.Readdir(0)
if err != nil {
return nil, fmt.Errorf("unable to read directory")
}
envs := make([]string, 0, len(files))
for _, f := range files {
if f.IsDir() {
continue
}
name := f.Name()
ext := path.Ext(name)
if ext != ".json" {
continue
}
envs = append(envs, name[:len(name)-len(ext)])
}
return envs, nil
}
func sysWriteEnv(name string) (io.WriteCloser, error) {
envPath, err := sysGetEnvPath(name)
if err != nil {
return nil, err
}
f, err := os.OpenFile(envPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0755)
if err != nil {
return nil, fmt.Errorf("unable to create file")
}
return f, nil
}
func sysReadEnv(name string) (io.ReadCloser, error) {
envPath, err := sysGetEnvPath(name)
if err != nil {
return nil, err
}
f, err := os.OpenFile(envPath, os.O_RDONLY, 0755)
if err != nil {
return nil, fmt.Errorf("unable to open file")
}
return f, nil
}
// Provide your own system description.
//
// Use this function to implement native integration into your application.
func SystemInit(sys System) {
bDesc.system = sys
if sys.RandomSeed != 0 {
rand.Seed(sys.RandomSeed)
}
}