1
0
mirror of https://github.com/go-task/task.git synced 2024-12-04 10:24:45 +02:00

Refactor: Add SmartJoin to handle IsAbs automatically

This commit is contained in:
Andrey Nering 2022-08-06 18:19:07 -03:00
parent c20842e7cd
commit c4e10ef0aa
12 changed files with 76 additions and 71 deletions

View File

@ -4,7 +4,8 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"github.com/go-task/task/v3/internal/filepathext"
)
const defaultTaskfile = `# https://taskfile.dev
@ -23,7 +24,7 @@ tasks:
// InitTaskfile Taskfile creates a new Taskfile
func InitTaskfile(w io.Writer, dir string) error {
f := filepath.Join(dir, "Taskfile.yaml")
f := filepathext.SmartJoin(dir, "Taskfile.yaml")
if _, err := os.Stat(f); err == nil {
return ErrTaskfileAlreadyExists

View File

@ -4,12 +4,12 @@ import (
"bytes"
"context"
"fmt"
"path/filepath"
"strings"
"sync"
"github.com/go-task/task/v3/internal/compiler"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/logger"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/taskfile"
@ -83,9 +83,7 @@ func (c *CompilerV3) getVariables(t *taskfile.Task, call *taskfile.Call, evaluat
if err := tr.Err(); err != nil {
return nil, err
}
if !filepath.IsAbs(dir) {
dir = filepath.Join(c.Dir, dir)
}
dir = filepathext.SmartJoin(c.Dir, dir)
taskRangeFunc = getRangeFunc(dir)
}

View File

@ -0,0 +1,14 @@
package filepathext
import (
"path/filepath"
)
// SmartJoin joins two paths, but only if the second is not already an
// absolute path.
func SmartJoin(a, b string) string {
if filepath.IsAbs(b) {
return b
}
return filepath.Join(a, b)
}

View File

@ -8,6 +8,8 @@ import (
"path/filepath"
"regexp"
"strings"
"github.com/go-task/task/v3/internal/filepathext"
)
// Checksum validades if a task is up to date by calculating its source
@ -43,7 +45,7 @@ func (c *Checksum) IsUpToDate() (bool, error) {
}
if !c.Dry {
_ = os.MkdirAll(filepath.Join(c.TempDir, "checksum"), 0755)
_ = os.MkdirAll(filepathext.SmartJoin(c.TempDir, "checksum"), 0755)
if err = os.WriteFile(checksumFile, []byte(newMd5+"\n"), 0644); err != nil {
return false, err
}

View File

@ -2,12 +2,12 @@ package status
import (
"os"
"path/filepath"
"sort"
"github.com/mattn/go-zglob"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
)
func globs(dir string, globs []string) ([]string, error) {
@ -25,17 +25,18 @@ func globs(dir string, globs []string) ([]string, error) {
func Glob(dir string, g string) ([]string, error) {
files := make([]string, 0)
if !filepath.IsAbs(g) {
g = filepath.Join(dir, g)
}
g = filepathext.SmartJoin(dir, g)
g, err := execext.Expand(g)
if err != nil {
return nil, err
}
fs, err := zglob.Glob(g)
if err != nil {
return nil, err
}
for _, f := range fs {
info, err := os.Stat(f)
if err != nil {

View File

@ -12,6 +12,7 @@ import (
compilerv2 "github.com/go-task/task/v3/internal/compiler/v2"
compilerv3 "github.com/go-task/task/v3/internal/compiler/v3"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/logger"
"github.com/go-task/task/v3/internal/output"
"github.com/go-task/task/v3/taskfile"
@ -69,7 +70,7 @@ func (e *Executor) setupTempDir() error {
}
if os.Getenv("TASK_TEMP_DIR") == "" {
e.TempDir = filepath.Join(e.Dir, ".task")
e.TempDir = filepathext.SmartJoin(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 {
@ -77,9 +78,9 @@ func (e *Executor) setupTempDir() error {
}
projectDir, _ := filepath.Abs(e.Dir)
projectName := filepath.Base(projectDir)
e.TempDir = filepath.Join(tempDir, projectName)
e.TempDir = filepathext.SmartJoin(tempDir, projectName)
} else {
e.TempDir = filepath.Join(e.Dir, os.Getenv("TASK_TEMP_DIR"))
e.TempDir = filepathext.SmartJoin(e.Dir, os.Getenv("TASK_TEMP_DIR"))
}
return nil

View File

@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/go-task/task/v3"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/taskfile"
)
@ -37,12 +38,12 @@ func (fct fileContentTest) name(file string) string {
func (fct fileContentTest) Run(t *testing.T) {
for f := range fct.Files {
_ = os.Remove(filepath.Join(fct.Dir, f))
_ = os.Remove(filepathext.SmartJoin(fct.Dir, f))
}
e := &task.Executor{
Dir: fct.Dir,
TempDir: filepath.Join(fct.Dir, ".task"),
TempDir: filepathext.SmartJoin(fct.Dir, ".task"),
Entrypoint: fct.Entrypoint,
Stdout: io.Discard,
Stderr: io.Discard,
@ -52,7 +53,7 @@ func (fct fileContentTest) Run(t *testing.T) {
for name, expectContent := range fct.Files {
t.Run(fct.name(name), func(t *testing.T) {
path := filepath.Join(fct.Dir, name)
path := filepathext.SmartJoin(fct.Dir, name)
b, err := os.ReadFile(path)
assert.NoError(t, err, "Error reading file")
s := string(b)
@ -235,7 +236,7 @@ func TestDeps(t *testing.T) {
}
for _, f := range files {
_ = os.Remove(filepath.Join(dir, f))
_ = os.Remove(filepathext.SmartJoin(dir, f))
}
e := &task.Executor{
@ -247,7 +248,7 @@ func TestDeps(t *testing.T) {
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "default"}))
for _, f := range files {
f = filepath.Join(dir, f)
f = filepathext.SmartJoin(dir, f)
if _, err := os.Stat(f); err != nil {
t.Errorf("File %s should exist", f)
}
@ -263,7 +264,7 @@ func TestStatus(t *testing.T) {
}
for _, f := range files {
path := filepath.Join(dir, f)
path := filepathext.SmartJoin(dir, f)
_ = os.Remove(path)
if _, err := os.Stat(path); err == nil {
t.Errorf("File should not exist: %v", err)
@ -273,7 +274,7 @@ func TestStatus(t *testing.T) {
var buff bytes.Buffer
e := &task.Executor{
Dir: dir,
TempDir: filepath.Join(dir, ".task"),
TempDir: filepathext.SmartJoin(dir, ".task"),
Stdout: &buff,
Stderr: &buff,
Silent: true,
@ -283,7 +284,7 @@ func TestStatus(t *testing.T) {
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "gen-bar"}))
for _, f := range files {
if _, err := os.Stat(filepath.Join(dir, f)); err != nil {
if _, err := os.Stat(filepathext.SmartJoin(dir, f)); err != nil {
t.Errorf("File should exist: %v", err)
}
}
@ -360,10 +361,10 @@ func TestGenerates(t *testing.T) {
fileWithSpaces = "my text file.txt"
)
var srcFile = filepath.Join(dir, srcTask)
var srcFile = filepathext.SmartJoin(dir, srcTask)
for _, task := range []string{srcTask, relTask, absTask, fileWithSpaces} {
path := filepath.Join(dir, task)
path := filepathext.SmartJoin(dir, task)
_ = os.Remove(path)
if _, err := os.Stat(path); err == nil {
t.Errorf("File should not exist: %v", err)
@ -379,7 +380,7 @@ func TestGenerates(t *testing.T) {
assert.NoError(t, e.Setup())
for _, theTask := range []string{relTask, absTask, fileWithSpaces} {
var destFile = filepath.Join(dir, theTask)
var destFile = filepathext.SmartJoin(dir, theTask)
var upToDate = fmt.Sprintf("task: Task \"%s\" is up to date\n", srcTask) +
fmt.Sprintf("task: Task \"%s\" is up to date\n", theTask)
@ -416,16 +417,16 @@ func TestStatusChecksum(t *testing.T) {
}
for _, f := range files {
_ = os.Remove(filepath.Join(dir, f))
_ = os.Remove(filepathext.SmartJoin(dir, f))
_, err := os.Stat(filepath.Join(dir, f))
_, err := os.Stat(filepathext.SmartJoin(dir, f))
assert.Error(t, err)
}
var buff bytes.Buffer
e := task.Executor{
Dir: dir,
TempDir: filepath.Join(dir, ".task"),
TempDir: filepathext.SmartJoin(dir, ".task"),
Stdout: &buff,
Stderr: &buff,
}
@ -433,7 +434,7 @@ func TestStatusChecksum(t *testing.T) {
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "build"}))
for _, f := range files {
_, err := os.Stat(filepath.Join(dir, f))
_, err := os.Stat(filepathext.SmartJoin(dir, f))
assert.NoError(t, err)
}
@ -577,13 +578,13 @@ func TestListCanListDescOnly(t *testing.T) {
func TestStatusVariables(t *testing.T) {
const dir = "testdata/status_vars"
_ = os.RemoveAll(filepath.Join(dir, ".task"))
_ = os.Remove(filepath.Join(dir, "generated.txt"))
_ = os.RemoveAll(filepathext.SmartJoin(dir, ".task"))
_ = os.Remove(filepathext.SmartJoin(dir, "generated.txt"))
var buff bytes.Buffer
e := task.Executor{
Dir: dir,
TempDir: filepath.Join(dir, ".task"),
TempDir: filepathext.SmartJoin(dir, ".task"),
Stdout: &buff,
Stderr: &buff,
Silent: false,
@ -594,7 +595,7 @@ func TestStatusVariables(t *testing.T) {
assert.Contains(t, buff.String(), "d41d8cd98f00b204e9800998ecf8427e")
inf, err := os.Stat(filepath.Join(dir, "source.txt"))
inf, err := os.Stat(filepathext.SmartJoin(dir, "source.txt"))
assert.NoError(t, err)
ts := fmt.Sprintf("%d", inf.ModTime().Unix())
tf := inf.ModTime().String()
@ -605,7 +606,7 @@ func TestStatusVariables(t *testing.T) {
func TestInit(t *testing.T) {
const dir = "testdata/init"
var file = filepath.Join(dir, "Taskfile.yaml")
var file = filepathext.SmartJoin(dir, "Taskfile.yaml")
_ = os.Remove(file)
if _, err := os.Stat(file); err == nil {
@ -694,7 +695,7 @@ func TestExpand(t *testing.T) {
func TestDry(t *testing.T) {
const dir = "testdata/dry"
file := filepath.Join(dir, "file.txt")
file := filepathext.SmartJoin(dir, "file.txt")
_ = os.Remove(file)
var buff bytes.Buffer
@ -719,12 +720,12 @@ func TestDry(t *testing.T) {
func TestDryChecksum(t *testing.T) {
const dir = "testdata/dry_checksum"
checksumFile := filepath.Join(dir, ".task/checksum/default")
checksumFile := filepathext.SmartJoin(dir, ".task/checksum/default")
_ = os.Remove(checksumFile)
e := task.Executor{
Dir: dir,
TempDir: filepath.Join(dir, ".task"),
TempDir: filepathext.SmartJoin(dir, ".task"),
Stdout: io.Discard,
Stderr: io.Discard,
Dry: true,
@ -964,7 +965,7 @@ func TestSummary(t *testing.T) {
assert.NoError(t, e.Setup())
assert.NoError(t, e.Run(context.Background(), taskfile.Call{Task: "task-with-summary"}, taskfile.Call{Task: "other-task-with-summary"}))
data, err := os.ReadFile(filepath.Join(dir, "task-with-summary.txt"))
data, err := os.ReadFile(filepathext.SmartJoin(dir, "task-with-summary.txt"))
assert.NoError(t, err)
expectedOutput := string(data)

View File

@ -6,6 +6,7 @@ import (
"path/filepath"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"gopkg.in/yaml.v3"
)
@ -133,7 +134,7 @@ func (it *IncludedTaskfile) resolvePath(path string) (string, error) {
return path, nil
}
result, err := filepath.Abs(filepath.Join(it.BaseDir, path))
result, err := filepath.Abs(filepathext.SmartJoin(it.BaseDir, path))
if err != nil {
return "", fmt.Errorf("task: error resolving path %s relative to %s: %w", path, it.BaseDir, err)
}

View File

@ -2,11 +2,11 @@ package read
import (
"os"
"path/filepath"
"github.com/joho/godotenv"
"github.com/go-task/task/v3/internal/compiler"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/taskfile"
)
@ -27,10 +27,8 @@ func Dotenv(c compiler.Compiler, tf *taskfile.Taskfile, dir string) (*taskfile.V
for _, dotEnvPath := range tf.Dotenv {
dotEnvPath = tr.Replace(dotEnvPath)
dotEnvPath = filepathext.SmartJoin(dir, dotEnvPath)
if !filepath.IsAbs(dotEnvPath) {
dotEnvPath = filepath.Join(dir, dotEnvPath)
}
if _, err := os.Stat(dotEnvPath); os.IsNotExist(err) {
continue
}

View File

@ -9,6 +9,7 @@ import (
"gopkg.in/yaml.v3"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/taskfile"
)
@ -44,7 +45,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, error) {
readerNode.Dir = d
}
path, err := exists(filepath.Join(readerNode.Dir, readerNode.Entrypoint))
path, err := exists(filepathext.SmartJoin(readerNode.Dir, readerNode.Entrypoint))
if err != nil {
return nil, err
}
@ -140,10 +141,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, error) {
}
for _, task := range includedTaskfile.Tasks {
if !filepath.IsAbs(task.Dir) {
task.Dir = filepath.Join(dir, task.Dir)
}
task.Dir = filepathext.SmartJoin(dir, task.Dir)
task.IncludeVars = includedTask.Vars
task.IncludedTaskfileVars = includedTaskfile.Vars
}
@ -159,7 +157,7 @@ func Taskfile(readerNode *ReaderNode) (*taskfile.Taskfile, error) {
}
if v < 3.0 {
path = filepath.Join(readerNode.Dir, fmt.Sprintf("Taskfile_%s.yml", runtime.GOOS))
path = filepathext.SmartJoin(readerNode.Dir, fmt.Sprintf("Taskfile_%s.yml", runtime.GOOS))
if _, err = os.Stat(path); err == nil {
osTaskfile, err := readTaskfile(path)
if err != nil {
@ -191,29 +189,19 @@ func readTaskfile(file string) (*taskfile.Taskfile, error) {
return &t, yaml.NewDecoder(f).Decode(&t)
}
// exists finds a Taskfile at the stated location, returning a fully qualified path to the file
func exists(path string) (string, error) {
fi, err := os.Stat(path)
if err != nil {
return "", err
}
if fi.Mode().IsRegular() {
// File exists, return a fully qualified path
result, err := filepath.Abs(path)
if err != nil {
return "", err
}
return result, nil
return path, nil
}
for _, n := range defaultTaskfiles {
fpath := filepath.Join(path, n)
fpath := filepathext.SmartJoin(path, n)
if _, err := os.Stat(fpath); err == nil {
result, err := filepath.Abs(fpath)
if err != nil {
return "", err
}
return result, nil
return fpath, nil
}
}
@ -228,14 +216,14 @@ func checkCircularIncludes(node *ReaderNode) error {
return errors.New("task: failed to check for include cycle: node.Parent was nil")
}
var curNode = node
var basePath = filepath.Join(node.Dir, node.Entrypoint)
var basePath = filepathext.SmartJoin(node.Dir, node.Entrypoint)
for curNode.Parent != nil {
curNode = curNode.Parent
curPath := filepath.Join(curNode.Dir, curNode.Entrypoint)
curPath := filepathext.SmartJoin(curNode.Dir, curNode.Entrypoint)
if curPath == basePath {
return fmt.Errorf("task: include cycle detected between %s <--> %s",
curPath,
filepath.Join(node.Parent.Dir, node.Parent.Entrypoint),
filepathext.SmartJoin(node.Parent.Dir, node.Parent.Entrypoint),
)
}
}

View File

@ -3,11 +3,11 @@ package read
import (
"fmt"
"os"
"path/filepath"
"runtime"
"gopkg.in/yaml.v3"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/taskfile"
)
@ -15,7 +15,7 @@ import (
func Taskvars(dir string) (*taskfile.Vars, error) {
vars := &taskfile.Vars{}
path := filepath.Join(dir, "Taskvars.yml")
path := filepathext.SmartJoin(dir, "Taskvars.yml")
if _, err := os.Stat(path); err == nil {
vars, err = readTaskvars(path)
if err != nil {
@ -23,7 +23,7 @@ func Taskvars(dir string) (*taskfile.Vars, error) {
}
}
path = filepath.Join(dir, fmt.Sprintf("Taskvars_%s.yml", runtime.GOOS))
path = filepathext.SmartJoin(dir, fmt.Sprintf("Taskvars_%s.yml", runtime.GOOS))
if _, err := os.Stat(path); err == nil {
osVars, err := readTaskvars(path)
if err != nil {

View File

@ -1,10 +1,10 @@
package task
import (
"path/filepath"
"strings"
"github.com/go-task/task/v3/internal/execext"
"github.com/go-task/task/v3/internal/filepathext"
"github.com/go-task/task/v3/internal/status"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/taskfile"
@ -68,8 +68,8 @@ func (e *Executor) compiledTask(call taskfile.Call, evaluateShVars bool) (*taskf
if err != nil {
return nil, err
}
if e.Dir != "" && !filepath.IsAbs(new.Dir) {
new.Dir = filepath.Join(e.Dir, new.Dir)
if e.Dir != "" {
new.Dir = filepathext.SmartJoin(e.Dir, new.Dir)
}
if new.Prefix == "" {
new.Prefix = new.Task