mirror of
https://github.com/go-task/task.git
synced 2026-06-11 09:51:50 +00:00
Compare commits
8 Commits
v3.51.1
...
fix/specia
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc0cf49f54 | ||
|
|
58340492cb | ||
|
|
d96d6fe703 | ||
|
|
b27a6653f6 | ||
|
|
76269b03c4 | ||
|
|
ed492ac862 | ||
|
|
1d385ad5b4 | ||
|
|
2eff3545d9 |
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@1e7e51e771db61008b38414a730f564565cf7c20 # v9.2.0
|
||||
with:
|
||||
version: v2.11.4
|
||||
version: v2.12.2
|
||||
|
||||
lint-jsonschema:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
uses: go-task/setup-task@3be4020d41929789a01026e0e427a4321ce0ad44 # v2
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@739bfe42ca9233c5e6aca07c1a25a9d34aca49b0 # v6
|
||||
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6
|
||||
with:
|
||||
package_json_file: "website/package.json"
|
||||
run_install: "true"
|
||||
@@ -48,6 +48,7 @@ jobs:
|
||||
args: release --clean --draft
|
||||
env:
|
||||
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
|
||||
GH_GORELEASER_TOKEN: ${{secrets.GH_GORELEASER_TOKEN}}
|
||||
GORELEASER_KEY: ${{secrets.GORELEASER_KEY}}
|
||||
CLOUDSMITH_TOKEN: ${{secrets.CLOUDSMITH_TOKEN}}
|
||||
|
||||
|
||||
33
compiler.go
33
compiler.go
@@ -15,6 +15,7 @@ import (
|
||||
"github.com/go-task/task/v3/internal/logger"
|
||||
"github.com/go-task/task/v3/internal/templater"
|
||||
"github.com/go-task/task/v3/internal/version"
|
||||
"github.com/go-task/task/v3/taskfile"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
@@ -201,10 +202,19 @@ func (c *Compiler) getSpecialVars(t *ast.Task, call *Call) (map[string]string, e
|
||||
// Use filepath.ToSlash for all paths to ensure consistent forward slashes
|
||||
// across platforms. This prevents issues with backslashes being interpreted
|
||||
// as escape sequences when paths are used in shell commands on Windows.
|
||||
var rootTaskfile, rootDir string
|
||||
if taskfile.IsRemoteEntrypoint(c.Entrypoint) {
|
||||
rootTaskfile = c.Entrypoint
|
||||
rootDir = ""
|
||||
} else {
|
||||
rootTaskfile = filepath.ToSlash(filepathext.SmartJoin(c.Dir, c.Entrypoint))
|
||||
rootDir = filepath.ToSlash(c.Dir)
|
||||
}
|
||||
|
||||
allVars := map[string]string{
|
||||
"TASK_EXE": filepath.ToSlash(os.Args[0]),
|
||||
"ROOT_TASKFILE": filepath.ToSlash(filepathext.SmartJoin(c.Dir, c.Entrypoint)),
|
||||
"ROOT_DIR": filepath.ToSlash(c.Dir),
|
||||
"ROOT_TASKFILE": rootTaskfile,
|
||||
"ROOT_DIR": rootDir,
|
||||
"USER_WORKING_DIR": filepath.ToSlash(c.UserWorkingDir),
|
||||
"TASK_VERSION": version.GetVersion(),
|
||||
"PATH_LIST_SEPARATOR": string(os.PathListSeparator),
|
||||
@@ -212,9 +222,22 @@ func (c *Compiler) getSpecialVars(t *ast.Task, call *Call) (map[string]string, e
|
||||
}
|
||||
if t != nil {
|
||||
allVars["TASK"] = t.Task
|
||||
allVars["TASK_DIR"] = filepath.ToSlash(filepathext.SmartJoin(c.Dir, t.Dir))
|
||||
allVars["TASKFILE"] = filepath.ToSlash(t.Location.Taskfile)
|
||||
allVars["TASKFILE_DIR"] = filepath.ToSlash(filepath.Dir(t.Location.Taskfile))
|
||||
if taskfile.IsRemoteEntrypoint(t.Location.Taskfile) {
|
||||
allVars["TASKFILE"] = t.Location.Taskfile
|
||||
allVars["TASKFILE_DIR"] = ""
|
||||
switch {
|
||||
case t.Dir == "":
|
||||
allVars["TASK_DIR"] = filepath.ToSlash(c.UserWorkingDir)
|
||||
case filepath.IsAbs(t.Dir):
|
||||
allVars["TASK_DIR"] = filepath.ToSlash(t.Dir)
|
||||
default:
|
||||
allVars["TASK_DIR"] = filepath.ToSlash(filepathext.SmartJoin(c.UserWorkingDir, t.Dir))
|
||||
}
|
||||
} else {
|
||||
allVars["TASK_DIR"] = filepath.ToSlash(filepathext.SmartJoin(c.Dir, t.Dir))
|
||||
allVars["TASKFILE"] = filepath.ToSlash(t.Location.Taskfile)
|
||||
allVars["TASKFILE_DIR"] = filepath.ToSlash(filepath.Dir(t.Location.Taskfile))
|
||||
}
|
||||
} else {
|
||||
allVars["TASK"] = ""
|
||||
allVars["TASK_DIR"] = ""
|
||||
|
||||
135
compiler_internal_test.go
Normal file
135
compiler_internal_test.go
Normal file
@@ -0,0 +1,135 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
func TestGetSpecialVarsRemote(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
uwd := t.TempDir()
|
||||
uwdSlash := filepath.ToSlash(uwd)
|
||||
localProj := filepath.Join(uwd, "proj")
|
||||
localProjSlash := filepath.ToSlash(localProj)
|
||||
localTaskfile := filepath.Join(localProj, "Taskfile.yml")
|
||||
localTaskfileSlash := filepath.ToSlash(localTaskfile)
|
||||
absTaskDir := filepath.Join(uwd, "opt", "work")
|
||||
absTaskDirSlash := filepath.ToSlash(absTaskDir)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
entrypoint string
|
||||
compilerDir string
|
||||
taskDir string
|
||||
taskfileLocation string
|
||||
wantRootTaskfile string
|
||||
wantRootDir string
|
||||
wantTaskfile string
|
||||
wantTaskfileDir string
|
||||
wantTaskDir string
|
||||
}{
|
||||
{
|
||||
name: "local entrypoint, local task",
|
||||
entrypoint: localTaskfile,
|
||||
compilerDir: localProj,
|
||||
taskDir: "",
|
||||
taskfileLocation: localTaskfile,
|
||||
wantRootTaskfile: localTaskfileSlash,
|
||||
wantRootDir: localProjSlash,
|
||||
wantTaskfile: localTaskfileSlash,
|
||||
wantTaskfileDir: localProjSlash,
|
||||
wantTaskDir: localProjSlash,
|
||||
},
|
||||
{
|
||||
name: "https entrypoint, empty task.dir",
|
||||
entrypoint: "https://taskfile.dev/Taskfile.yml",
|
||||
compilerDir: "",
|
||||
taskDir: "",
|
||||
taskfileLocation: "https://taskfile.dev/Taskfile.yml",
|
||||
wantRootTaskfile: "https://taskfile.dev/Taskfile.yml",
|
||||
wantRootDir: "",
|
||||
wantTaskfile: "https://taskfile.dev/Taskfile.yml",
|
||||
wantTaskfileDir: "",
|
||||
wantTaskDir: uwdSlash,
|
||||
},
|
||||
{
|
||||
name: "https entrypoint, relative task.dir",
|
||||
entrypoint: "https://taskfile.dev/Taskfile.yml",
|
||||
compilerDir: "",
|
||||
taskDir: "subdir",
|
||||
taskfileLocation: "https://taskfile.dev/Taskfile.yml",
|
||||
wantRootTaskfile: "https://taskfile.dev/Taskfile.yml",
|
||||
wantRootDir: "",
|
||||
wantTaskfile: "https://taskfile.dev/Taskfile.yml",
|
||||
wantTaskfileDir: "",
|
||||
wantTaskDir: filepath.ToSlash(filepathext.SmartJoin(uwd, "subdir")),
|
||||
},
|
||||
{
|
||||
name: "https entrypoint, absolute task.dir",
|
||||
entrypoint: "https://taskfile.dev/Taskfile.yml",
|
||||
compilerDir: "",
|
||||
taskDir: absTaskDir,
|
||||
taskfileLocation: "https://taskfile.dev/Taskfile.yml",
|
||||
wantRootTaskfile: "https://taskfile.dev/Taskfile.yml",
|
||||
wantRootDir: "",
|
||||
wantTaskfile: "https://taskfile.dev/Taskfile.yml",
|
||||
wantTaskfileDir: "",
|
||||
wantTaskDir: absTaskDirSlash,
|
||||
},
|
||||
{
|
||||
name: "git entrypoint",
|
||||
entrypoint: "https://github.com/foo/bar.git//Taskfile.yml?ref=main",
|
||||
compilerDir: "",
|
||||
taskDir: "",
|
||||
taskfileLocation: "https://github.com/foo/bar.git//Taskfile.yml?ref=main",
|
||||
wantRootTaskfile: "https://github.com/foo/bar.git//Taskfile.yml?ref=main",
|
||||
wantRootDir: "",
|
||||
wantTaskfile: "https://github.com/foo/bar.git//Taskfile.yml?ref=main",
|
||||
wantTaskfileDir: "",
|
||||
wantTaskDir: uwdSlash,
|
||||
},
|
||||
{
|
||||
name: "local root, remote included task",
|
||||
entrypoint: localTaskfile,
|
||||
compilerDir: localProj,
|
||||
taskDir: "",
|
||||
taskfileLocation: "https://taskfile.dev/included.yml",
|
||||
wantRootTaskfile: localTaskfileSlash,
|
||||
wantRootDir: localProjSlash,
|
||||
wantTaskfile: "https://taskfile.dev/included.yml",
|
||||
wantTaskfileDir: "",
|
||||
wantTaskDir: uwdSlash,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
c := &Compiler{
|
||||
Dir: tt.compilerDir,
|
||||
Entrypoint: tt.entrypoint,
|
||||
UserWorkingDir: uwd,
|
||||
}
|
||||
task := &ast.Task{
|
||||
Task: "mytask",
|
||||
Dir: tt.taskDir,
|
||||
Location: &ast.Location{Taskfile: tt.taskfileLocation},
|
||||
}
|
||||
|
||||
vars, err := c.getSpecialVars(task, nil)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tt.wantRootTaskfile, vars["ROOT_TASKFILE"], "ROOT_TASKFILE")
|
||||
assert.Equal(t, tt.wantRootDir, vars["ROOT_DIR"], "ROOT_DIR")
|
||||
assert.Equal(t, tt.wantTaskfile, vars["TASKFILE"], "TASKFILE")
|
||||
assert.Equal(t, tt.wantTaskfileDir, vars["TASKFILE_DIR"], "TASKFILE_DIR")
|
||||
assert.Equal(t, tt.wantTaskDir, vars["TASK_DIR"], "TASK_DIR")
|
||||
})
|
||||
}
|
||||
}
|
||||
8
go.mod
8
go.mod
@@ -7,14 +7,14 @@ require (
|
||||
charm.land/bubbletea/v2 v2.0.6
|
||||
charm.land/lipgloss/v2 v2.0.3
|
||||
github.com/Ladicle/tabwriter v1.0.0
|
||||
github.com/Masterminds/semver/v3 v3.4.0
|
||||
github.com/alecthomas/chroma/v2 v2.23.1
|
||||
github.com/Masterminds/semver/v3 v3.5.0
|
||||
github.com/alecthomas/chroma/v2 v2.24.1
|
||||
github.com/chainguard-dev/git-urls v1.0.2
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
|
||||
github.com/dominikbraun/graph v0.23.0
|
||||
github.com/elliotchance/orderedmap/v3 v3.1.0
|
||||
github.com/fatih/color v1.19.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/fsnotify/fsnotify v1.10.1
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0
|
||||
github.com/go-task/template v0.2.0
|
||||
github.com/google/uuid v1.6.0
|
||||
@@ -77,7 +77,7 @@ require (
|
||||
github.com/clipperhouse/displaywidth v0.11.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20251210132809-ee656c7534f5 // indirect
|
||||
github.com/dlclark/regexp2 v1.11.5 // indirect
|
||||
github.com/dlclark/regexp2 v1.12.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect
|
||||
|
||||
8
go.sum
8
go.sum
@@ -38,10 +38,14 @@ github.com/Ladicle/tabwriter v1.0.0 h1:DZQqPvMumBDwVNElso13afjYLNp0Z7pHqHnu0r4t9
|
||||
github.com/Ladicle/tabwriter v1.0.0/go.mod h1:c4MdCjxQyTbGuQO/gvqJ+IA/89UEwrsD6hUCW98dyp4=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
|
||||
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY=
|
||||
github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o=
|
||||
github.com/alecthomas/chroma/v2 v2.24.1 h1:m5ffpfZbIb++k8AqFEKy9uVgY12xIQtBsQlc6DfZJQM=
|
||||
github.com/alecthomas/chroma/v2 v2.24.1/go.mod h1:l+ohZ9xRXIbGe7cIW+YZgOGbvuVLjMps/FYN/CwuabI=
|
||||
github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs=
|
||||
github.com/alecthomas/repr v0.5.2/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
|
||||
@@ -120,6 +124,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
|
||||
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dominikbraun/graph v0.23.0 h1:TdZB4pPqCLFxYhdyMFb1TBdFxp8XLcJfTTBQucVPgCo=
|
||||
github.com/dominikbraun/graph v0.23.0/go.mod h1:yOjYyogZLY1LSG9E33JWZJiq5k83Qy2C6POAuiViluc=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
@@ -140,6 +146,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
|
||||
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
|
||||
@@ -81,7 +81,7 @@ func TraverseStringsFunc[T any](v T, fn func(v string) (string, error)) (T, erro
|
||||
traverseFunc = func(copy, v reflect.Value) error {
|
||||
switch v.Kind() {
|
||||
|
||||
case reflect.Ptr:
|
||||
case reflect.Pointer:
|
||||
// Unwrap the pointer
|
||||
originalValue := v.Elem()
|
||||
// If the pointer is nil, do nothing
|
||||
|
||||
@@ -73,7 +73,7 @@ func NewNode(
|
||||
return node, err
|
||||
}
|
||||
|
||||
func isRemoteEntrypoint(entrypoint string) bool {
|
||||
func IsRemoteEntrypoint(entrypoint string) bool {
|
||||
scheme, _ := getScheme(entrypoint)
|
||||
switch scheme {
|
||||
case "git", "http", "https":
|
||||
|
||||
@@ -60,7 +60,7 @@ func (node *FileNode) Read() ([]byte, error) {
|
||||
|
||||
func (node *FileNode) ResolveEntrypoint(entrypoint string) (string, error) {
|
||||
// If the file is remote, we don't need to resolve the path
|
||||
if isRemoteEntrypoint(entrypoint) {
|
||||
if IsRemoteEntrypoint(entrypoint) {
|
||||
return entrypoint, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -188,7 +188,7 @@ func (node *GitNode) ReadContext(ctx context.Context) ([]byte, error) {
|
||||
|
||||
func (node *GitNode) ResolveEntrypoint(entrypoint string) (string, error) {
|
||||
// If the file is remote, we don't need to resolve the path
|
||||
if isRemoteEntrypoint(entrypoint) {
|
||||
if IsRemoteEntrypoint(entrypoint) {
|
||||
return entrypoint, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ func (node *StdinNode) Read() ([]byte, error) {
|
||||
|
||||
func (node *StdinNode) ResolveEntrypoint(entrypoint string) (string, error) {
|
||||
// If the file is remote, we don't need to resolve the path
|
||||
if isRemoteEntrypoint(entrypoint) {
|
||||
if IsRemoteEntrypoint(entrypoint) {
|
||||
return entrypoint, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -23,5 +23,5 @@
|
||||
"vitepress-plugin-llms": "^1.9.1",
|
||||
"vue": "^3.5.18"
|
||||
},
|
||||
"packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
|
||||
"packageManager": "pnpm@11.1.2+sha512.415a1cc25974731e75455c1468371be74c5aa5fb7621b50d4056d222451609f11412f23fd602e6169f1e060466641f798597e1be961a10688836a67b16569499"
|
||||
}
|
||||
|
||||
1762
website/pnpm-lock.yaml
generated
1762
website/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
6
website/pnpm-workspace.yaml
Normal file
6
website/pnpm-workspace.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
allowBuilds:
|
||||
'@parcel/watcher': true
|
||||
esbuild: true
|
||||
netlify-cli: true
|
||||
sharp: true
|
||||
unix-dgram: true
|
||||
@@ -190,6 +190,21 @@ includes:
|
||||
my-remote-namespace: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
|
||||
## Special Variables
|
||||
|
||||
The file-path [special variables](../reference/templating.md#file-paths) behave
|
||||
differently when a Taskfile is loaded from a remote source, because there is no
|
||||
local file or directory that corresponds 1:1 to the Taskfile:
|
||||
|
||||
| Variable | Value when loaded remotely |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `TASKFILE` / `ROOT_TASKFILE` | The original URL, unchanged |
|
||||
| `TASKFILE_DIR` / `ROOT_DIR` | Empty string — a directory variable cannot point to a URL |
|
||||
| `TASK_DIR` | Resolved against `USER_WORKING_DIR` (relative `dir:` → joined with `USER_WORKING_DIR`, empty `dir:` → `USER_WORKING_DIR`, absolute `dir:` → kept as-is) |
|
||||
|
||||
If a remote Taskfile includes a local Taskfile (or vice-versa), each variable
|
||||
reflects the source of the Taskfile it refers to.
|
||||
|
||||
## Security
|
||||
|
||||
### Automatic checksums
|
||||
|
||||
Reference in New Issue
Block a user