mirror of
https://github.com/go-task/task.git
synced 2025-11-25 22:32:55 +02:00
feat: remote taskfile improvements (cache/expiry) (#2176)
* feat: cache as node, RemoteNode and cache-first approach * feat: cache expiry * feat: pass ctx into reader methods instead of timeout * docs: updated remote taskfiles experiment doc * feat: use cache if download fails
This commit is contained in:
@@ -2,11 +2,12 @@ package taskfile
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"time"
|
||||
"strings"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/execext"
|
||||
@@ -18,14 +19,12 @@ type HTTPNode struct {
|
||||
*BaseNode
|
||||
URL *url.URL // stores url pointing actual remote file. (e.g. with Taskfile.yml)
|
||||
entrypoint string // stores entrypoint url. used for building graph vertices.
|
||||
timeout time.Duration
|
||||
}
|
||||
|
||||
func NewHTTPNode(
|
||||
entrypoint string,
|
||||
dir string,
|
||||
insecure bool,
|
||||
timeout time.Duration,
|
||||
opts ...NodeOption,
|
||||
) (*HTTPNode, error) {
|
||||
base := NewBaseNode(dir, opts...)
|
||||
@@ -41,7 +40,6 @@ func NewHTTPNode(
|
||||
BaseNode: base,
|
||||
URL: url,
|
||||
entrypoint: entrypoint,
|
||||
timeout: timeout,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -49,12 +47,12 @@ func (node *HTTPNode) Location() string {
|
||||
return node.entrypoint
|
||||
}
|
||||
|
||||
func (node *HTTPNode) Remote() bool {
|
||||
return true
|
||||
func (node *HTTPNode) Read() ([]byte, error) {
|
||||
return node.ReadContext(context.Background())
|
||||
}
|
||||
|
||||
func (node *HTTPNode) Read(ctx context.Context) ([]byte, error) {
|
||||
url, err := RemoteExists(ctx, node.URL, node.timeout)
|
||||
func (node *HTTPNode) ReadContext(ctx context.Context) ([]byte, error) {
|
||||
url, err := RemoteExists(ctx, node.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -66,8 +64,8 @@ func (node *HTTPNode) Read(ctx context.Context) ([]byte, error) {
|
||||
|
||||
resp, err := http.DefaultClient.Do(req.WithContext(ctx))
|
||||
if err != nil {
|
||||
if errors.Is(err, context.DeadlineExceeded) {
|
||||
return nil, &errors.TaskfileNetworkTimeoutError{URI: node.URL.String(), Timeout: node.timeout}
|
||||
if ctx.Err() != nil {
|
||||
return nil, err
|
||||
}
|
||||
return nil, errors.TaskfileFetchFailedError{URI: node.URL.String()}
|
||||
}
|
||||
@@ -116,7 +114,14 @@ func (node *HTTPNode) ResolveDir(dir string) (string, error) {
|
||||
return filepathext.SmartJoin(parent, path), nil
|
||||
}
|
||||
|
||||
func (node *HTTPNode) FilenameAndLastDir() (string, string) {
|
||||
func (node *HTTPNode) CacheKey() string {
|
||||
checksum := strings.TrimRight(checksum([]byte(node.Location())), "=")
|
||||
dir, filename := filepath.Split(node.entrypoint)
|
||||
return filepath.Base(dir), filename
|
||||
lastDir := filepath.Base(dir)
|
||||
prefix := filename
|
||||
// Means it's not "", nor "." nor "/", so it's a valid directory
|
||||
if len(lastDir) > 1 {
|
||||
prefix = fmt.Sprintf("%s-%s", lastDir, filename)
|
||||
}
|
||||
return fmt.Sprintf("%s.%s", prefix, checksum)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user