From fedb68cde72fca0b6ec823148ec94fc5a0b4d9c3 Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Fri, 8 Jul 2022 14:40:10 -0300 Subject: [PATCH] Allow override the `.task` dir location with the `TASK_TEMP_DIR` env --- CHANGELOG.md | 2 ++ docs/docs/usage.md | 22 ++++++++++++++++++++-- internal/status/checksum.go | 6 +++--- status.go | 2 +- task.go | 19 +++++++++++++++++++ task_test.go | 27 ++++++++++++++++----------- 6 files changed, 61 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ae51c1b5..f6a04d18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## Unreleased +- Add ability to override the `.task` directory location with the + `TASK_TEMP_DIR` environment variable. - Allow to override Task colors using environment variables: `TASK_COLOR_RESET`, `TASK_COLOR_BLUE`, `TASK_COLOR_GREEN`, `TASK_COLOR_CYAN`, `TASK_COLOR_YELLOW`, `TASK_COLOR_MAGENTA` diff --git a/docs/docs/usage.md b/docs/docs/usage.md index d6f6359d..e1ff85aa 100644 --- a/docs/docs/usage.md +++ b/docs/docs/usage.md @@ -406,8 +406,6 @@ tasks: Task will compare the checksum of the source files to determine if it's necessary to run the task. If not, it will just print a message like `Task "js" is up to date`. -You will probably want to ignore the `.task` folder in your `.gitignore` file -(It is there that Task stores the last checksum). If you prefer this check to be made by the modification timestamp of the files, instead of its checksum (content), just set the `method` property to `timestamp`. @@ -428,6 +426,26 @@ tasks: :::info +By default, task stores checksums on a local `.task` directory in the project's +directory. Most of the time, you'll want to have this directory on `.gitignore` +(or equivalent) so it isn't committed. (If you have a task for code generation +that is committed it may make sense to commit the checksum of that task as +well, though). + +If you want these files to be stored in another directory, you can set a +`TASK_TEMP_DIR` environment variable in your machine. It can contain a relative +path like `tmp/task` that will be interpreted as relative to the project +directory, or an absolute or home path like `/tmp/.task` or `~/.task` +(subdirectories will be created for each project). + +```bash +export TASK_TEMP_DIR='~/.task' +``` + +::: + +:::info + Each task has only one checksum stored for its `sources`. If you want to distinguish a task by any of its input variables, you can add those variables as part of the task's label, and it will be considered a different diff --git a/internal/status/checksum.go b/internal/status/checksum.go index ab608a8d..fc59abbe 100644 --- a/internal/status/checksum.go +++ b/internal/status/checksum.go @@ -13,7 +13,7 @@ import ( // Checksum validades if a task is up to date by calculating its source // files checksum type Checksum struct { - BaseDir string + TempDir string TaskDir string Task string Sources []string @@ -43,7 +43,7 @@ func (c *Checksum) IsUpToDate() (bool, error) { } if !c.Dry { - _ = os.MkdirAll(filepath.Join(c.BaseDir, ".task", "checksum"), 0755) + _ = os.MkdirAll(filepath.Join(c.TempDir, "checksum"), 0755) if err = os.WriteFile(checksumFile, []byte(newMd5+"\n"), 0644); err != nil { return false, err } @@ -107,7 +107,7 @@ func (*Checksum) Kind() string { } func (c *Checksum) checksumFilePath() string { - return filepath.Join(c.BaseDir, ".task", "checksum", c.normalizeFilename(c.Task)) + return filepath.Join(c.TempDir, "checksum", c.normalizeFilename(c.Task)) } var checksumFilenameRegexp = regexp.MustCompile("[^A-z0-9]") diff --git a/status.go b/status.go index 0924ac10..4d8a120e 100644 --- a/status.go +++ b/status.go @@ -95,7 +95,7 @@ func (e *Executor) timestampChecker(t *taskfile.Task) status.Checker { func (e *Executor) checksumChecker(t *taskfile.Task) status.Checker { return &status.Checksum{ - BaseDir: e.Dir, + TempDir: e.TempDir, TaskDir: t.Dir, Task: t.Name(), Sources: t.Sources, diff --git a/task.go b/task.go index 60f9cb3d..7b2d424b 100644 --- a/task.go +++ b/task.go @@ -6,6 +6,8 @@ import ( "fmt" "io" "os" + "path/filepath" + "strings" "sync" "sync/atomic" @@ -34,6 +36,7 @@ type Executor struct { Taskfile *taskfile.Taskfile Dir string + TempDir string Entrypoint string Force bool Watch bool @@ -151,6 +154,22 @@ func (e *Executor) Setup() error { Color: e.Color, } + if e.TempDir == "" { + if os.Getenv("TASK_TEMP_DIR") == "" { + e.TempDir = filepath.Join(e.Dir, ".task") + } else if filepath.IsAbs(os.Getenv("TASK_TEMP_DIR")) || strings.HasPrefix(os.Getenv("TASK_TEMP_DIR"), "~") { + tempDir, err := execext.Expand(os.Getenv("TASK_TEMP_DIR")) + if err != nil { + return err + } + projectDir, _ := filepath.Abs(e.Dir) + projectName := filepath.Base(projectDir) + e.TempDir = filepath.Join(tempDir, projectName) + } else { + e.TempDir = filepath.Join(e.Dir, os.Getenv("TASK_TEMP_DIR")) + } + } + if v < 2 { return fmt.Errorf(`task: Taskfile versions prior to v2 are not supported anymore`) } diff --git a/task_test.go b/task_test.go index 1094ea65..a01b0b8a 100644 --- a/task_test.go +++ b/task_test.go @@ -42,6 +42,7 @@ func (fct fileContentTest) Run(t *testing.T) { e := &task.Executor{ Dir: fct.Dir, + TempDir: filepath.Join(fct.Dir, ".task"), Entrypoint: fct.Entrypoint, Stdout: io.Discard, Stderr: io.Discard, @@ -270,10 +271,11 @@ func TestStatus(t *testing.T) { var buff bytes.Buffer e := &task.Executor{ - Dir: dir, - Stdout: &buff, - Stderr: &buff, - Silent: true, + Dir: dir, + TempDir: filepath.Join(dir, ".task"), + Stdout: &buff, + Stderr: &buff, + Silent: true, } assert.NoError(t, e.Setup()) assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "gen-foo"})) @@ -421,9 +423,10 @@ func TestStatusChecksum(t *testing.T) { var buff bytes.Buffer e := task.Executor{ - Dir: dir, - Stdout: &buff, - Stderr: &buff, + Dir: dir, + TempDir: filepath.Join(dir, ".task"), + Stdout: &buff, + Stderr: &buff, } assert.NoError(t, e.Setup()) @@ -579,6 +582,7 @@ func TestStatusVariables(t *testing.T) { var buff bytes.Buffer e := task.Executor{ Dir: dir, + TempDir: filepath.Join(dir, ".task"), Stdout: &buff, Stderr: &buff, Silent: false, @@ -718,10 +722,11 @@ func TestDryChecksum(t *testing.T) { _ = os.Remove(checksumFile) e := task.Executor{ - Dir: dir, - Stdout: io.Discard, - Stderr: io.Discard, - Dry: true, + Dir: dir, + TempDir: filepath.Join(dir, ".task"), + Stdout: io.Discard, + Stderr: io.Discard, + Dry: true, } assert.NoError(t, e.Setup()) assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "default"}))