1
0
mirror of https://github.com/go-task/task.git synced 2025-05-13 22:16:31 +02:00
task/taskfile/node_file.go
Pete Davison c5afffb551
feat: recursive config search (#2166)
* refactor: experiments flags

* refactor: args.Parse

* feat: recursive search for taskrc files

* feat: consolidate some code into new fsext package

* feat: add tests for search and default dir

* fix: linting issues
2025-04-19 12:20:33 +01:00

85 lines
2.0 KiB
Go

package taskfile
import (
"io"
"os"
"path/filepath"
"strings"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/fsext"
)
// A FileNode is a node that reads a taskfile from the local filesystem.
type FileNode struct {
*BaseNode
Entrypoint string
}
func NewFileNode(entrypoint, dir string, opts ...NodeOption) (*FileNode, error) {
var err error
base := NewBaseNode(dir, opts...)
entrypoint, base.dir, err = fsext.Search(entrypoint, base.dir, defaultTaskfiles)
if err != nil {
return nil, err
}
return &FileNode{
BaseNode: base,
Entrypoint: entrypoint,
}, nil
}
func (node *FileNode) Location() string {
return node.Entrypoint
}
func (node *FileNode) Read() ([]byte, error) {
f, err := os.Open(node.Location())
if err != nil {
return nil, err
}
defer f.Close()
return io.ReadAll(f)
}
func (node *FileNode) ResolveEntrypoint(entrypoint string) (string, error) {
// If the file is remote, we don't need to resolve the path
if strings.Contains(entrypoint, "://") {
return entrypoint, nil
}
if strings.HasPrefix(entrypoint, "git") {
return entrypoint, nil
}
path, err := execext.ExpandLiteral(entrypoint)
if err != nil {
return "", err
}
if filepathext.IsAbs(path) {
return path, nil
}
// NOTE: Uses the directory of the entrypoint (Taskfile), not the current working directory
// This means that files are included relative to one another
entrypointDir := filepath.Dir(node.Entrypoint)
return filepathext.SmartJoin(entrypointDir, path), nil
}
func (node *FileNode) ResolveDir(dir string) (string, error) {
path, err := execext.ExpandLiteral(dir)
if err != nil {
return "", err
}
if filepathext.IsAbs(path) {
return path, nil
}
// NOTE: Uses the directory of the entrypoint (Taskfile), not the current working directory
// This means that files are included relative to one another
entrypointDir := filepath.Dir(node.Entrypoint)
return filepathext.SmartJoin(entrypointDir, path), nil
}