Skip to content

Commit

Permalink
Add context awarenes to fs functions
Browse files Browse the repository at this point in the history
  • Loading branch information
vladimirvivien committed Nov 23, 2024
1 parent ad13b6d commit 53bbca2
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 58 deletions.
29 changes: 19 additions & 10 deletions exec/builder.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package exec

import (
"context"
"fmt"
"io"
"sync"
Expand Down Expand Up @@ -112,24 +113,32 @@ type CommandBuilder struct {
stderr io.Writer
}

// Commands creates a *CommandBuilder used to collect
// command strings to be executed.
func Commands(cmds ...string) *CommandBuilder {
// CommandsWithContextVars creates a *CommandBuilder with the specified context and session variables.
// The resulting *CommandBuilder is used to execute command strings.
func CommandsWithContextVars(ctx context.Context, variables *vars.Variables, cmds ...string) *CommandBuilder {
cb := new(CommandBuilder)
cb.vars = &vars.Variables{}
cb.vars = variables
for _, cmd := range cmds {
cb.procs = append(cb.procs, NewProc(cmd))
cb.procs = append(cb.procs, NewProcWithContextVars(ctx, cmd, variables))
}
return cb
}

// CommandsWithContext creates a *CommandBuilder, with specified context, used to collect
// command strings to be executed.
func CommandsWithContext(ctx context.Context, cmds ...string) *CommandBuilder {
return CommandsWithContextVars(ctx, &vars.Variables{}, cmds...)
}

// Commands creates a *CommandBuilder used to collect
// command strings to be executed.
func Commands(cmds ...string) *CommandBuilder {
return CommandsWithContext(context.Background(), cmds...)
}

// CommandsWithVars creates a new CommandBuilder and sets session varialbes for it
func CommandsWithVars(variables *vars.Variables, cmds ...string) *CommandBuilder {
cb := &CommandBuilder{vars: variables}
for _, cmd := range cmds {
cb.procs = append(cb.procs, NewProc(variables.Eval(cmd)))
}
return cb
return CommandsWithContextVars(context.Background(), variables, cmds...)
}

// WithPolicy sets one or more command policy mask values, i.e. (CmdOnErrContinue | CmdExecConcurrent)
Expand Down
33 changes: 22 additions & 11 deletions filesys.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gexe

import (
"context"
"os"

"github.com/vladimirvivien/gexe/fs"
Expand Down Expand Up @@ -31,23 +32,33 @@ func (e *Echo) PathInfo(path string) *fs.FSInfo {
return fs.PathWithVars(path, e.vars).Info()
}

// FileReadWithContext uses specified context to provide methods to read file
// content at path.
func (e *Echo) FileReadWithContext(ctx context.Context, path string) *fs.FileReader {
return fs.ReadWithContextVars(ctx, path, e.vars)
}

// FileRead provides methods to read file content
//
// FileRead(path).Lines()
func (e *Echo) FileRead(path string) *fs.FileReader {
return fs.PathWithVars(path, e.vars).Read()
return fs.ReadWithContextVars(context.Background(), path, e.vars)
}

// FileWriteWithContext uses context ctx to create a fs.FileWriter to write content to provided path
func (e *Echo) FileWriteWithContext(ctx context.Context, path string) *fs.FileWriter {
return fs.WriteWithContextVars(ctx, path, e.vars)
}

// FileWrite provides methods to write content to provided path
//
// FileWrite(path).String("hello world")
// FileWrite creates a fs.FileWriter to write content to provided path
func (e *Echo) FileWrite(path string) *fs.FileWriter {
return fs.PathWithVars(path, e.vars).Write()
return fs.WriteWithContextVars(context.Background(), path, e.vars)
}

// FileAppend creates a new fs.FileWriter to append content to provided path
func (e *Echo) FileAppendWithContext(ctx context.Context, path string) *fs.FileWriter {
return fs.AppendWithContextVars(ctx, path, e.vars)
}

// FileAppend provides methods to append content to provided path
//
// FileAppend(path).String("hello world")
// FileAppend creates a new fs.FileWriter to append content to provided path
func (e *Echo) FileAppend(path string) *fs.FileWriter {
return fs.PathWithVars(path, e.vars).Append()
return fs.AppendWithContextVars(context.Background(), path, e.vars)
}
65 changes: 53 additions & 12 deletions fs/file_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package fs
import (
"bufio"
"bytes"
"context"
"io"
"os"

Expand All @@ -16,34 +17,49 @@ type FileReader struct {
mode os.FileMode
vars *vars.Variables
content *bytes.Buffer
ctx context.Context
}

// Read reads the file at path and creates new FileReader.
// Access file content using FileReader methods.
func Read(path string) *FileReader {
info, err := os.Stat(path)
// ReadWithContextVars uses specified context and session variables to read the file at path
// and returns a *FileReader to access its content
func ReadWithContextVars(ctx context.Context, path string, variables *vars.Variables) *FileReader {
if variables == nil {
variables = &vars.Variables{}
}
filePath := variables.Eval(path)

if err := ctx.Err(); err != nil {
return &FileReader{err: err, path: filePath}
}

info, err := os.Stat(filePath)
if err != nil {
return &FileReader{err: err, path: path}
return &FileReader{err: err, path: filePath}
}

fileData, err := os.ReadFile(path)
fileData, err := os.ReadFile(filePath)
if err != nil {
return &FileReader{err: err, path: path}
return &FileReader{err: err, path: filePath}
}

return &FileReader{
path: path,
path: filePath,
info: info,
mode: info.Mode(),
content: bytes.NewBuffer(fileData),
vars: variables,
ctx: ctx,
}
}

// ReadWithVars creates a new FileReader and sets the reader's session variables
// ReadWithVars uses session variables to create a new FileReader
func ReadWithVars(path string, variables *vars.Variables) *FileReader {
reader := Read(variables.Eval(path))
reader.vars = variables
return reader
return ReadWithContextVars(context.Background(), path, variables)
}

// Read reads the file at path and returns FileReader to access its content
func Read(path string) *FileReader {
return ReadWithContextVars(context.Background(), path, &vars.Variables{})
}

// SetVars sets the FileReader's session variables
Expand All @@ -52,6 +68,12 @@ func (fr *FileReader) SetVars(variables *vars.Variables) *FileReader {
return fr
}

// SetContext sets the context for the FileReader operations
func (fr *FileReader) SetContext(ctx context.Context) *FileReader {
fr.ctx = ctx
return fr
}

// Err returns an operation error during file read.
func (fr *FileReader) Err() error {
return fr.err
Expand All @@ -73,10 +95,19 @@ func (fr *FileReader) Lines() []string {
return []string{}
}

if err := fr.ctx.Err(); err != nil {
fr.err = err
return []string{}
}

var lines []string
scnr := bufio.NewScanner(fr.content)

for scnr.Scan() {
if err := fr.ctx.Err(); err != nil {
fr.err = err
break
}
lines = append(lines, scnr.Text())
}

Expand All @@ -95,6 +126,11 @@ func (fr *FileReader) Bytes() []byte {
return []byte{}
}

if err := fr.ctx.Err(); err != nil {
fr.err = err
return []byte{}
}

return fr.content.Bytes()
}

Expand All @@ -105,6 +141,11 @@ func (fr *FileReader) Into(w io.Writer) *FileReader {
return fr
}

if err := fr.ctx.Err(); err != nil {
fr.err = err
return fr
}

if _, err := io.Copy(w, fr.content); err != nil {
fr.err = err
}
Expand Down
Loading

0 comments on commit 53bbca2

Please sign in to comment.