123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- package taskfile
- import (
- "context"
- "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/logger"
- )
- // A FileNode is a node that reads a taskfile from the local filesystem.
- type FileNode struct {
- *BaseNode
- Entrypoint string
- }
- func NewFileNode(l *logger.Logger, entrypoint, dir string, opts ...NodeOption) (*FileNode, error) {
- var err error
- base := NewBaseNode(dir, opts...)
- entrypoint, base.dir, err = resolveFileNodeEntrypointAndDir(l, entrypoint, base.dir)
- if err != nil {
- return nil, err
- }
- return &FileNode{
- BaseNode: base,
- Entrypoint: entrypoint,
- }, nil
- }
- func (node *FileNode) Location() string {
- return node.Entrypoint
- }
- func (node *FileNode) Remote() bool {
- return false
- }
- func (node *FileNode) Read(ctx context.Context) ([]byte, error) {
- f, err := os.Open(node.Location())
- if err != nil {
- return nil, err
- }
- defer f.Close()
- return io.ReadAll(f)
- }
- // resolveFileNodeEntrypointAndDir resolves checks the values of entrypoint and dir and
- // populates them with default values if necessary.
- func resolveFileNodeEntrypointAndDir(l *logger.Logger, entrypoint, dir string) (string, string, error) {
- var err error
- if entrypoint != "" {
- entrypoint, err = Exists(l, entrypoint)
- if err != nil {
- return "", "", err
- }
- if dir == "" {
- dir = filepath.Dir(entrypoint)
- }
- return entrypoint, dir, nil
- }
- if dir == "" {
- dir, err = os.Getwd()
- if err != nil {
- return "", "", err
- }
- }
- entrypoint, err = ExistsWalk(l, dir)
- if err != nil {
- return "", "", err
- }
- dir = filepath.Dir(entrypoint)
- return entrypoint, dir, nil
- }
- 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
- }
- path, err := execext.Expand(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.Expand(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
- }
- func (node *FileNode) FilenameAndLastDir() (string, string) {
- return "", filepath.Base(node.Entrypoint)
- }
|