From bb9d58225502953eb32b58525c975f078d3d9c8e Mon Sep 17 00:00:00 2001 From: Pete Davison Date: Thu, 25 Jan 2024 12:22:10 +0000 Subject: [PATCH] feat: stdin node --- setup.go | 17 +++++++---------- taskfile/node.go | 25 +++++++++++++++++++++++++ taskfile/node_stdin.go | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 10 deletions(-) create mode 100644 taskfile/node_stdin.go diff --git a/setup.go b/setup.go index 073ba0bd..9f27b3a9 100644 --- a/setup.go +++ b/setup.go @@ -67,22 +67,19 @@ func (e *Executor) setCurrentDir() error { return err } e.Dir = wd + } else { + var err error + e.Dir, err = filepath.Abs(e.Dir) + if err != nil { + return err + } } - // Search for a taskfile - root, err := taskfile.ExistsWalk(e.Dir) - if err != nil { - return err - } - e.Dir = filepath.Dir(root) - e.Entrypoint = filepath.Base(root) - return nil } func (e *Executor) readTaskfile() error { - uri := filepath.Join(e.Dir, e.Entrypoint) - node, err := taskfile.NewNode(uri, e.Insecure) + node, err := taskfile.NewRootNode(e.Dir, e.Entrypoint, e.Insecure) if err != nil { return err } diff --git a/taskfile/node.go b/taskfile/node.go index b8c0debe..7957ca37 100644 --- a/taskfile/node.go +++ b/taskfile/node.go @@ -2,6 +2,8 @@ package taskfile import ( "context" + "os" + "path/filepath" "strings" "github.com/go-task/task/v3/errors" @@ -16,6 +18,29 @@ type Node interface { Remote() bool } +func NewRootNode( + dir string, + entrypoint string, + insecure bool, +) (Node, error) { + // Check if there is something to read on STDIN + stat, _ := os.Stdin.Stat() + if (stat.Mode()&os.ModeCharDevice) == 0 && stat.Size() > 0 { + return NewStdinNode() + } + // If no entrypoint is specified, search for a taskfile + if entrypoint == "" { + root, err := ExistsWalk(dir) + if err != nil { + return nil, err + } + return NewNode(root, insecure) + } + // Use the specified entrypoint + uri := filepath.Join(dir, entrypoint) + return NewNode(uri, insecure) +} + func NewNode( uri string, insecure bool, diff --git a/taskfile/node_stdin.go b/taskfile/node_stdin.go new file mode 100644 index 00000000..b942ce87 --- /dev/null +++ b/taskfile/node_stdin.go @@ -0,0 +1,40 @@ +package taskfile + +import ( + "bufio" + "context" + "fmt" + "os" +) + +// A StdinNode is a node that reads a taskfile from the standard input stream. +type StdinNode struct { + *BaseNode +} + +func NewStdinNode() (*StdinNode, error) { + base := NewBaseNode() + return &StdinNode{ + BaseNode: base, + }, nil +} + +func (node *StdinNode) Location() string { + return "__stdin__" +} + +func (node *StdinNode) Remote() bool { + return false +} + +func (node *StdinNode) Read(ctx context.Context) ([]byte, error) { + var stdin []byte + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + stdin = fmt.Appendln(stdin, scanner.Text()) + } + if err := scanner.Err(); err != nil { + return nil, err + } + return stdin, nil +}