1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package file
16
17 import (
18 "os"
19 "path/filepath"
20
21 "cuelang.org/go/cue"
22 "cuelang.org/go/cue/errors"
23 "cuelang.org/go/internal/task"
24 )
25
26 func init() {
27 task.Register("tool/file.Read", newReadCmd)
28 task.Register("tool/file.Append", newAppendCmd)
29 task.Register("tool/file.Create", newCreateCmd)
30 task.Register("tool/file.Glob", newGlobCmd)
31 task.Register("tool/file.Mkdir", newMkdirCmd)
32 task.Register("tool/file.MkdirTemp", newMkdirTempCmd)
33 task.Register("tool/file.RemoveAll", newRemoveAllCmd)
34 }
35
36 func newReadCmd(v cue.Value) (task.Runner, error) { return &cmdRead{}, nil }
37 func newAppendCmd(v cue.Value) (task.Runner, error) { return &cmdAppend{}, nil }
38 func newCreateCmd(v cue.Value) (task.Runner, error) { return &cmdCreate{}, nil }
39 func newGlobCmd(v cue.Value) (task.Runner, error) { return &cmdGlob{}, nil }
40 func newMkdirCmd(v cue.Value) (task.Runner, error) { return &cmdMkdir{}, nil }
41 func newMkdirTempCmd(v cue.Value) (task.Runner, error) { return &cmdMkdirTemp{}, nil }
42 func newRemoveAllCmd(v cue.Value) (task.Runner, error) { return &cmdRemoveAll{}, nil }
43
44 type cmdRead struct{}
45 type cmdAppend struct{}
46 type cmdCreate struct{}
47 type cmdGlob struct{}
48 type cmdMkdir struct{}
49 type cmdMkdirTemp struct{}
50 type cmdRemoveAll struct{}
51
52 func (c *cmdRead) Run(ctx *task.Context) (res interface{}, err error) {
53 filename := ctx.String("filename")
54 if ctx.Err != nil {
55 return nil, ctx.Err
56 }
57
58 b, err := os.ReadFile(filename)
59 if err != nil {
60 return nil, err
61 }
62 update := map[string]interface{}{"contents": b}
63
64 switch v := ctx.Lookup("contents"); v.IncompleteKind() {
65 case cue.BytesKind:
66
67 case cue.StringKind:
68 update["contents"] = string(b)
69 }
70 return update, nil
71 }
72
73 func (c *cmdAppend) Run(ctx *task.Context) (res interface{}, err error) {
74 var (
75 filename = filepath.FromSlash(ctx.String("filename"))
76 mode = ctx.Int64("permissions")
77 b = ctx.Bytes("contents")
78 )
79 if ctx.Err != nil {
80 return nil, ctx.Err
81 }
82
83 f, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.FileMode(mode))
84 if err != nil {
85 return nil, err
86 }
87 defer f.Close()
88
89 if _, err := f.Write(b); err != nil {
90 return nil, err
91 }
92 return nil, nil
93 }
94
95 func (c *cmdCreate) Run(ctx *task.Context) (res interface{}, err error) {
96 var (
97 filename = filepath.FromSlash(ctx.String("filename"))
98 mode = ctx.Int64("permissions")
99 b = ctx.Bytes("contents")
100 )
101 if ctx.Err != nil {
102 return nil, ctx.Err
103 }
104
105 return nil, os.WriteFile(filename, b, os.FileMode(mode))
106 }
107
108 func (c *cmdGlob) Run(ctx *task.Context) (res interface{}, err error) {
109 glob := ctx.String("glob")
110 if ctx.Err != nil {
111 return nil, ctx.Err
112 }
113 m, err := filepath.Glob(glob)
114 for i, s := range m {
115 m[i] = filepath.ToSlash(s)
116 }
117 files := map[string]interface{}{"files": m}
118 return files, err
119 }
120
121 func (c *cmdMkdir) Run(ctx *task.Context) (res interface{}, err error) {
122 path := ctx.String("path")
123 mode := ctx.Int64("permissions")
124 createParents, _ := ctx.Lookup("createParents").Bool()
125
126 if ctx.Err != nil {
127 return nil, ctx.Err
128 }
129
130 if createParents {
131 if err := os.MkdirAll(path, os.FileMode(mode)); err != nil {
132 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to create directory")
133 }
134 } else {
135 dir, err := os.Stat(path)
136 if err == nil && dir.IsDir() {
137 return nil, nil
138 }
139 if err := os.Mkdir(path, os.FileMode(mode)); err != nil {
140 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to create directory")
141 }
142 }
143
144 return nil, nil
145 }
146
147 func (c *cmdMkdirTemp) Run(ctx *task.Context) (res interface{}, err error) {
148 dir := ctx.String("dir")
149 pattern := ctx.String("pattern")
150
151 if ctx.Err != nil {
152 return nil, ctx.Err
153 }
154
155 path, err := os.MkdirTemp(dir, pattern)
156 if err != nil {
157 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to create temporary directory")
158 }
159
160 return map[string]interface{}{"path": path}, nil
161 }
162
163 func (c *cmdRemoveAll) Run(ctx *task.Context) (res interface{}, err error) {
164 path := ctx.String("path")
165
166 if ctx.Err != nil {
167 return nil, ctx.Err
168 }
169
170 if _, err := os.Stat(path); err != nil {
171 return map[string]interface{}{"success": false}, nil
172 }
173
174 if err := os.RemoveAll(path); err != nil {
175 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to remove path")
176 }
177
178 return map[string]interface{}{"success": true}, nil
179 }
180
View as plain text