2023-12-29 20:32:03 +00:00
package taskfile
2023-09-02 15:24:01 -05:00
import (
2023-09-12 16:42:54 -05:00
"context"
2024-01-25 12:22:10 +00:00
"os"
"path/filepath"
2023-09-02 15:24:01 -05:00
"strings"
2024-03-25 19:05:21 +00:00
"time"
2023-09-02 15:24:01 -05:00
2024-11-12 12:29:29 +04:00
giturls "github.com/chainguard-dev/git-urls"
2024-09-24 13:44:54 -04:00
2023-09-12 16:42:54 -05:00
"github.com/go-task/task/v3/errors"
"github.com/go-task/task/v3/internal/experiments"
2023-09-02 15:24:01 -05:00
)
type Node interface {
2025-04-19 12:12:08 +01:00
Read ( ) ( [ ] byte , error )
2023-09-02 15:24:01 -05:00
Parent ( ) Node
Location ( ) string
2024-02-13 01:07:00 +00:00
Dir ( ) string
2024-02-13 19:29:28 +00:00
ResolveEntrypoint ( entrypoint string ) ( string , error )
ResolveDir ( dir string ) ( string , error )
2025-04-19 12:12:08 +01:00
}
type RemoteNode interface {
Node
ReadContext ( ctx context . Context ) ( [ ] byte , error )
CacheKey ( ) string
2023-09-02 15:24:01 -05:00
}
2024-01-25 12:22:10 +00:00
func NewRootNode (
entrypoint string ,
2024-02-13 01:07:00 +00:00
dir string ,
2024-01-25 12:22:10 +00:00
insecure bool ,
2024-03-25 19:05:21 +00:00
timeout time . Duration ,
2024-01-25 12:22:10 +00:00
) ( Node , error ) {
2024-03-04 05:34:44 -06:00
dir = getDefaultDir ( entrypoint , dir )
2024-05-08 16:44:05 +01:00
// If the entrypoint is "-", we read from stdin
if entrypoint == "-" {
2024-01-25 12:36:31 +00:00
return NewStdinNode ( dir )
2024-01-25 12:22:10 +00:00
}
2025-04-19 12:12:08 +01:00
return NewNode ( entrypoint , dir , insecure )
2024-01-25 12:22:10 +00:00
}
2023-09-12 16:42:54 -05:00
func NewNode (
2024-02-13 01:07:00 +00:00
entrypoint string ,
dir string ,
2023-09-12 16:42:54 -05:00
insecure bool ,
opts ... NodeOption ,
) ( Node , error ) {
var node Node
var err error
2025-04-19 12:12:08 +01:00
2024-09-24 13:44:54 -04:00
scheme , err := getScheme ( entrypoint )
if err != nil {
return nil , err
}
2025-04-19 12:12:08 +01:00
2024-09-24 13:44:54 -04:00
switch scheme {
case "git" :
node , err = NewGitNode ( entrypoint , dir , insecure , opts ... )
2023-09-12 16:42:54 -05:00
case "http" , "https" :
2025-04-19 12:12:08 +01:00
node , err = NewHTTPNode ( entrypoint , dir , insecure , opts ... )
2023-09-02 15:24:01 -05:00
default :
2025-02-22 16:00:37 +00:00
node , err = NewFileNode ( entrypoint , dir , opts ... )
2023-09-12 16:42:54 -05:00
}
2025-04-19 12:12:08 +01:00
if _ , isRemote := node . ( RemoteNode ) ; isRemote && ! experiments . RemoteTaskfiles . Enabled ( ) {
2023-12-29 20:42:30 +00:00
return nil , errors . New ( "task: Remote taskfiles are not enabled. You can read more about this experiment and how to enable it at https://taskfile.dev/experiments/remote-taskfiles" )
2023-09-02 15:24:01 -05:00
}
2025-04-19 12:12:08 +01:00
2023-09-12 16:42:54 -05:00
return node , err
2023-09-02 15:24:01 -05:00
}
2024-09-24 13:44:54 -04:00
func getScheme ( uri string ) ( string , error ) {
u , err := giturls . Parse ( uri )
if u == nil {
return "" , err
}
2025-04-19 12:12:08 +01:00
2024-09-24 13:44:54 -04:00
if strings . HasSuffix ( strings . Split ( u . Path , "//" ) [ 0 ] , ".git" ) && ( u . Scheme == "git" || u . Scheme == "ssh" || u . Scheme == "https" || u . Scheme == "http" ) {
return "git" , nil
}
2023-09-02 15:24:01 -05:00
if i := strings . Index ( uri , "://" ) ; i != - 1 {
2024-09-24 13:44:54 -04:00
return uri [ : i ] , nil
2023-09-02 15:24:01 -05:00
}
2025-04-19 12:12:08 +01:00
2024-09-24 13:44:54 -04:00
return "" , nil
2023-09-02 15:24:01 -05:00
}
2024-03-04 05:34:44 -06:00
func getDefaultDir ( entrypoint , dir string ) string {
// If the entrypoint and dir are empty, we default the directory to the current working directory
if dir == "" {
if entrypoint == "" {
wd , err := os . Getwd ( )
if err != nil {
return ""
}
dir = wd
}
return dir
}
// If the directory is set, ensure it is an absolute path
var err error
dir , err = filepath . Abs ( dir )
if err != nil {
return ""
}
return dir
}