mirror of
https://github.com/go-task/task.git
synced 2026-06-29 23:55:18 +00:00
feat: Add temp dir option (#2891)
Co-authored-by: Valentin Maerten <maerten.valentin@gmail.com>
This commit is contained in:
6
.vscode/settings-sample.json
vendored
6
.vscode/settings-sample.json
vendored
@@ -5,6 +5,12 @@
|
||||
"Taskfile.yaml",
|
||||
"taskfile.yml",
|
||||
"taskfile.yaml"
|
||||
],
|
||||
"./website/src/public/schema-taskrc.json": [
|
||||
".taskrc.yml",
|
||||
".taskrc.yaml",
|
||||
"taskrc.yml",
|
||||
"taskrc.yaml"
|
||||
]
|
||||
},
|
||||
"gopls": {
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
- Added support for configuring output flags (`--output`, `--output-group-begin`,
|
||||
`--output-group-end`, `--output-group-error-only`) via the `TASK_OUTPUT*`
|
||||
environment variables (#2873 by @liiight).
|
||||
- Added a `--temp-dir` flag (with `TASK_TEMP_DIR` env var and `temp-dir` taskrc
|
||||
config) to customise the directory where Task stores temporary files such as
|
||||
checksums. Relative paths are resolved against the root Taskfile (#2891 by
|
||||
@kjasn).
|
||||
|
||||
## v3.51.1 - 2026-05-16
|
||||
|
||||
|
||||
17
executor.go
17
executor.go
@@ -29,6 +29,7 @@ type (
|
||||
Dir string
|
||||
Entrypoint string
|
||||
TempDir TempDir
|
||||
TempDirPath string
|
||||
Force bool
|
||||
ForceAll bool
|
||||
Insecure bool
|
||||
@@ -165,6 +166,22 @@ func (o *tempDirOption) ApplyToExecutor(e *Executor) {
|
||||
e.TempDir = o.tempDir
|
||||
}
|
||||
|
||||
// WithTempDirPath sets an unresolved path used to build [Executor.TempDir]
|
||||
// during [Executor.Setup]. Relative paths are resolved from the root Taskfile
|
||||
// directory. Use [WithTempDir] when the remote and fingerprint directories have
|
||||
// already been resolved.
|
||||
func WithTempDirPath(path string) ExecutorOption {
|
||||
return &tempDirPathOption{path: path}
|
||||
}
|
||||
|
||||
type tempDirPathOption struct {
|
||||
path string
|
||||
}
|
||||
|
||||
func (o *tempDirPathOption) ApplyToExecutor(e *Executor) {
|
||||
e.TempDirPath = o.path
|
||||
}
|
||||
|
||||
// WithForce ensures that the [Executor] always runs a task, even when
|
||||
// fingerprinting or prompts would normally stop it.
|
||||
func WithForce(force bool) ExecutorOption {
|
||||
|
||||
@@ -87,6 +87,7 @@ var (
|
||||
Cert string
|
||||
CertKey string
|
||||
Interactive bool
|
||||
TempDir string
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -143,6 +144,7 @@ func init() {
|
||||
pflag.BoolVarP(&ExitCode, "exit-code", "x", false, "Pass-through the exit code of the task command.")
|
||||
pflag.StringVarP(&Dir, "dir", "d", "", "Sets the directory in which Task will execute and look for a Taskfile.")
|
||||
pflag.StringVarP(&Entrypoint, "taskfile", "t", "", `Choose which Taskfile to run. Defaults to "Taskfile.yml".`)
|
||||
pflag.StringVar(&TempDir, "temp-dir", getConfig(config, "TEMP_DIR", func() *string { return config.TempDir }, ""), "Sets the directory used to store Task temporary files, such as checksums. Relative paths are relative to the root Taskfile.")
|
||||
pflag.StringVarP(&Output.Name, "output", "o", getConfig(config, "OUTPUT", func() *string { return nil }, ""), "Sets output style: [interleaved|group|prefixed].")
|
||||
pflag.StringVar(&Output.Group.Begin, "output-group-begin", getConfig(config, "OUTPUT_GROUP_BEGIN", func() *string { return nil }, ""), "Message template to print before a task's grouped output.")
|
||||
pflag.StringVar(&Output.Group.End, "output-group-end", getConfig(config, "OUTPUT_GROUP_END", func() *string { return nil }, ""), "Message template to print after a task's grouped output.")
|
||||
@@ -308,6 +310,7 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) {
|
||||
task.WithTaskSorter(sorter),
|
||||
task.WithVersionCheck(true),
|
||||
task.WithFailfast(Failfast),
|
||||
task.WithTempDirPath(TempDir),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
12
setup.go
12
setup.go
@@ -1,6 +1,7 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"cmp"
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
"github.com/sajari/fuzzy"
|
||||
|
||||
"github.com/go-task/task/v3/errors"
|
||||
"github.com/go-task/task/v3/internal/env"
|
||||
"github.com/go-task/task/v3/internal/execext"
|
||||
"github.com/go-task/task/v3/internal/filepathext"
|
||||
"github.com/go-task/task/v3/internal/logger"
|
||||
@@ -133,13 +133,9 @@ func (e *Executor) setupTempDir() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
tempDir := env.GetTaskEnv("TEMP_DIR")
|
||||
if tempDir == "" {
|
||||
e.TempDir = TempDir{
|
||||
Remote: filepathext.SmartJoin(e.Dir, ".task"),
|
||||
Fingerprint: filepathext.SmartJoin(e.Dir, ".task"),
|
||||
}
|
||||
} else if filepath.IsAbs(tempDir) || strings.HasPrefix(tempDir, "~") {
|
||||
// e.TempDirPath carries the resolved CLI precedence (flag > TASK_TEMP_DIR > taskrc).
|
||||
tempDir := cmp.Or(e.TempDirPath, ".task")
|
||||
if filepath.IsAbs(tempDir) || strings.HasPrefix(tempDir, "~") {
|
||||
tempDir, err := execext.ExpandLiteral(tempDir)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -19,6 +19,7 @@ type TaskRC struct {
|
||||
Interactive *bool `yaml:"interactive"`
|
||||
Remote Remote `yaml:"remote"`
|
||||
Failfast bool `yaml:"failfast"`
|
||||
TempDir *string `yaml:"temp-dir"`
|
||||
Experiments map[string]int `yaml:"experiments"`
|
||||
}
|
||||
|
||||
@@ -70,4 +71,5 @@ func (t *TaskRC) Merge(other *TaskRC) {
|
||||
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
|
||||
t.Interactive = cmp.Or(other.Interactive, t.Interactive)
|
||||
t.Failfast = cmp.Or(other.Failfast, t.Failfast)
|
||||
t.TempDir = cmp.Or(other.TempDir, t.TempDir)
|
||||
}
|
||||
|
||||
@@ -112,6 +112,40 @@ func TestGetConfig_OnlyLocal(t *testing.T) { //nolint:paralleltest // cannot run
|
||||
}, cfg)
|
||||
}
|
||||
|
||||
func TestGetConfig_TempDir(t *testing.T) { //nolint:paralleltest // cannot run in parallel
|
||||
_, _, localDir := setupDirs(t)
|
||||
|
||||
writeFile(t, localDir, ".taskrc.yml", `
|
||||
temp-dir: .task-cache
|
||||
`)
|
||||
|
||||
cfg, err := GetConfig(localDir)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cfg)
|
||||
require.NotNil(t, cfg.TempDir)
|
||||
assert.Equal(t, ".task-cache", *cfg.TempDir)
|
||||
}
|
||||
|
||||
func TestGetConfig_TempDirMergePrecedence(t *testing.T) { //nolint:paralleltest // cannot run in parallel
|
||||
xdgConfigDir, homeDir, localDir := setupDirs(t)
|
||||
|
||||
writeFile(t, xdgConfigDir, "taskrc.yml", `
|
||||
temp-dir: xdg-cache
|
||||
`)
|
||||
writeFile(t, homeDir, ".taskrc.yml", `
|
||||
temp-dir: home-cache
|
||||
`)
|
||||
writeFile(t, localDir, ".taskrc.yml", `
|
||||
temp-dir: local-cache
|
||||
`)
|
||||
|
||||
cfg, err := GetConfig(localDir)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, cfg)
|
||||
require.NotNil(t, cfg.TempDir)
|
||||
assert.Equal(t, "local-cache", *cfg.TempDir)
|
||||
}
|
||||
|
||||
func TestGetConfig_All(t *testing.T) { //nolint:paralleltest // cannot run in parallel
|
||||
xdgConfigDir, homeDir, localDir := setupDirs(t)
|
||||
|
||||
|
||||
@@ -220,6 +220,18 @@ Run the global Taskfile from `$HOME/Taskfile.{yml,yaml}`.
|
||||
task backup --global
|
||||
```
|
||||
|
||||
#### `--temp-dir <path>`
|
||||
|
||||
Set the directory used to store Task temporary files, such as checksums.
|
||||
Relative paths are relative to the root Taskfile.
|
||||
|
||||
- **Config equivalent**: [`temp-dir`](./config.md#temp-dir)
|
||||
- **Environment variable**: [`TASK_TEMP_DIR`](./environment.md#task-temp-dir)
|
||||
|
||||
```bash
|
||||
task build --temp-dir .task-cache
|
||||
```
|
||||
|
||||
### Output Control
|
||||
|
||||
#### `-o, --output <mode>`
|
||||
|
||||
@@ -166,6 +166,18 @@ failfast: true
|
||||
interactive: true
|
||||
```
|
||||
|
||||
### `temp-dir`
|
||||
|
||||
- **Type**: `string`
|
||||
- **Default**: `./.task`
|
||||
- **Description**: Directory to store Task temporary files, such as checksums
|
||||
and temporary metadata. Relative paths are relative to the root Taskfile.
|
||||
- **Environment variable**: [`TASK_TEMP_DIR`](./environment.md#task-temp-dir)
|
||||
|
||||
```yaml
|
||||
temp-dir: .task
|
||||
```
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Here's a complete example of a `.taskrc.yml` file with all available options:
|
||||
@@ -177,6 +189,7 @@ silent: false
|
||||
color: true
|
||||
disable-fuzzy: false
|
||||
concurrency: 2
|
||||
temp-dir: .task
|
||||
|
||||
# Enable experimental features
|
||||
experiments:
|
||||
|
||||
@@ -88,6 +88,10 @@
|
||||
"description": "Prompt for missing required variables instead of failing. Requires a TTY.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"temp-dir": {
|
||||
"type": "string",
|
||||
"description": "Directory to store Task temporary files, such as checksums and temporary metadata. Relative paths are relative to the root Taskfile."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
Reference in New Issue
Block a user