...

Source file src/cuelang.org/go/pkg/tool/file/file.go

Documentation: cuelang.org/go/pkg/tool/file

     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  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  		// already set above
    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