github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/pkg/tool/file/file.go (about) 1 // Copyright 2019 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package file 16 17 //go:generate go run gen.go 18 //go:generate gofmt -s -w . 19 20 import ( 21 "io/ioutil" 22 "os" 23 "path/filepath" 24 25 "github.com/joomcode/cue/cue" 26 "github.com/joomcode/cue/cue/errors" 27 "github.com/joomcode/cue/internal/task" 28 ) 29 30 func init() { 31 task.Register("tool/file.Read", newReadCmd) 32 task.Register("tool/file.Append", newAppendCmd) 33 task.Register("tool/file.Create", newCreateCmd) 34 task.Register("tool/file.Glob", newGlobCmd) 35 task.Register("tool/file.Mkdir", newMkdirCmd) 36 task.Register("tool/file.MkdirTemp", newMkdirTempCmd) 37 task.Register("tool/file.RemoveAll", newRemoveAllCmd) 38 } 39 40 func newReadCmd(v cue.Value) (task.Runner, error) { return &cmdRead{}, nil } 41 func newAppendCmd(v cue.Value) (task.Runner, error) { return &cmdAppend{}, nil } 42 func newCreateCmd(v cue.Value) (task.Runner, error) { return &cmdCreate{}, nil } 43 func newGlobCmd(v cue.Value) (task.Runner, error) { return &cmdGlob{}, nil } 44 func newMkdirCmd(v cue.Value) (task.Runner, error) { return &cmdMkdir{}, nil } 45 func newMkdirTempCmd(v cue.Value) (task.Runner, error) { return &cmdMkdirTemp{}, nil } 46 func newRemoveAllCmd(v cue.Value) (task.Runner, error) { return &cmdRemoveAll{}, nil } 47 48 type cmdRead struct{} 49 type cmdAppend struct{} 50 type cmdCreate struct{} 51 type cmdGlob struct{} 52 type cmdMkdir struct{} 53 type cmdMkdirTemp struct{} 54 type cmdRemoveAll struct{} 55 56 func (c *cmdRead) Run(ctx *task.Context) (res interface{}, err error) { 57 filename := ctx.String("filename") 58 if ctx.Err != nil { 59 return nil, ctx.Err 60 } 61 62 b, err := ioutil.ReadFile(filename) 63 if err != nil { 64 return nil, err 65 } 66 update := map[string]interface{}{"contents": b} 67 68 switch v := ctx.Lookup("contents"); v.IncompleteKind() { 69 case cue.BytesKind: 70 // already set above 71 case cue.StringKind: 72 update["contents"] = string(b) 73 } 74 return update, nil 75 } 76 77 func (c *cmdAppend) Run(ctx *task.Context) (res interface{}, err error) { 78 var ( 79 filename = filepath.FromSlash(ctx.String("filename")) 80 mode = ctx.Int64("permissions") 81 b = ctx.Bytes("contents") 82 ) 83 if ctx.Err != nil { 84 return nil, ctx.Err 85 } 86 87 f, err := os.OpenFile(filename, os.O_CREATE|os.O_APPEND|os.O_WRONLY, os.FileMode(mode)) 88 if err != nil { 89 return nil, err 90 } 91 defer f.Close() 92 93 if _, err := f.Write(b); err != nil { 94 return nil, err 95 } 96 return nil, nil 97 } 98 99 func (c *cmdCreate) Run(ctx *task.Context) (res interface{}, err error) { 100 var ( 101 filename = filepath.FromSlash(ctx.String("filename")) 102 mode = ctx.Int64("permissions") 103 b = ctx.Bytes("contents") 104 ) 105 if ctx.Err != nil { 106 return nil, ctx.Err 107 } 108 109 return nil, ioutil.WriteFile(filename, b, os.FileMode(mode)) 110 } 111 112 func (c *cmdGlob) Run(ctx *task.Context) (res interface{}, err error) { 113 glob := ctx.String("glob") 114 if ctx.Err != nil { 115 return nil, ctx.Err 116 } 117 m, err := filepath.Glob(glob) 118 for i, s := range m { 119 m[i] = filepath.ToSlash(s) 120 } 121 files := map[string]interface{}{"files": m} 122 return files, err 123 } 124 125 func (c *cmdMkdir) Run(ctx *task.Context) (res interface{}, err error) { 126 path := ctx.String("path") 127 mode := ctx.Int64("permissions") 128 createParents, _ := ctx.Lookup("createParents").Bool() 129 130 if ctx.Err != nil { 131 return nil, ctx.Err 132 } 133 134 if createParents { 135 if err := os.MkdirAll(path, os.FileMode(mode)); err != nil { 136 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to create directory") 137 } 138 } else { 139 dir, err := os.Stat(path) 140 if err == nil && dir.IsDir() { 141 return nil, nil 142 } 143 if err := os.Mkdir(path, os.FileMode(mode)); err != nil { 144 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to create directory") 145 } 146 } 147 148 return nil, nil 149 } 150 151 func (c *cmdMkdirTemp) Run(ctx *task.Context) (res interface{}, err error) { 152 dir := ctx.String("dir") 153 pattern := ctx.String("pattern") 154 155 if ctx.Err != nil { 156 return nil, ctx.Err 157 } 158 159 path, err := os.MkdirTemp(dir, pattern) 160 if err != nil { 161 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to create temporary directory") 162 } 163 164 return map[string]interface{}{"path": path}, nil 165 } 166 167 func (c *cmdRemoveAll) Run(ctx *task.Context) (res interface{}, err error) { 168 path := ctx.String("path") 169 170 if ctx.Err != nil { 171 return nil, ctx.Err 172 } 173 174 if _, err := os.Stat(path); err != nil { 175 return map[string]interface{}{"success": false}, nil 176 } 177 178 if err := os.RemoveAll(path); err != nil { 179 return nil, errors.Wrapf(err, ctx.Obj.Pos(), "failed to remove path") 180 } 181 182 return map[string]interface{}{"success": true}, nil 183 }