go-task / task

A task runner / simpler Make alternative written in Go
https://taskfile.dev
MIT License
11.01k stars 584 forks source link

Paths are not correctly resolved when using "dir" #828

Open Nantero1 opened 2 years ago

Nantero1 commented 2 years ago

Since minor version v3.14.1 we have problems to chdir into the correct directory using the following setup. Version 3.14.0 had no issues.

Example Taskfile showing the issue

Directory structure:

/home/user/git/repo/projectname/Taskfile.yaml
/home/user/git/repo/.Taskfiles/Generic.yaml

Taskfile.yaml:

# https://taskfile.dev

version: "3"

vars:
  project: "projectname"

includes:
  generics:
    taskfile: "../.Taskfiles/Generic.yaml"

tasks:
  default:
    cmds:
      - task -l
    silent: true

Generic.yaml:

version: "3"

vars:
  gitBase:
    sh: git rev-parse --show-toplevel

tasks:

  plan:
    desc: Example on strange "dir" variable templating
    dir: "{{.gitBase}}/{{.project}}"
    cmds:
      - pwd
      - echo "{.gitBase}{.project} {{.gitBase}}/{{.project}}"
      - echo "{.gitBase} {{.gitBase}}"

Expected behaviour

When using task version v3.14.0, the current dir is correct:

cd /home/user/git/repo/
git init
cd /home/user/git/repo/projectname/
task generics:plan

output:

task: [generics:plan] pwd
/home/user/git/repo/projectname
task: [generics:plan] echo "{.gitBase}{.project} /home/user/git/repo/projectname"
{.gitBase}{.project} /home/user/git/repo/projectname
task: [generics:plan] echo "{.gitBase} /home/user/git/repo"
{.gitBase} /home/user/git/repo

Actual behaviour

When using task version v3.14.1, the current dir is wrong:

cd /home/user/git/repo/projectname/
task generics:plan

output:

task: [generics:plan] pwd
/home/user/git/repo/projectname/home/user/git/repo/projectname
task: [generics:plan] echo "{.gitBase}{.project} /home/user/git/repo/projectname"
{.gitBase}{.project} /home/user/git/repo/projectname
task: [generics:plan] echo "{.gitBase} /home/user/git/repo"
{.gitBase} /home/user/git/repo

Please note the weird double path /home/user/git/repo/projectname/home/user/git/repo/projectname resulting the pwd command, see the first line. Other commands are only for debug purposes and show that the templating works for these other commands.

Due to this error no files in the current folder can be found.

lucasfcnunes commented 2 years ago

I was planning to report the same thing. Thanks!

andreynering commented 2 years ago

Hi @Nantero1 and @lucasfcnunes,

I just took quite some time debugging this issue, and it's a bit tricky to fix. I'll write it here to help myself when I back to this.

The source of the problem is that you're using a value in dir: that starts with a template like {{.DIRECTORY}}.

There's a place in the code where the Taskfile dir in joined with the task dir like this:

/path/to/project + sub/dir = /path/to/project/sub/dir

There's an exception: if the task dir is already absolute (starts with / in linux/mac or C:/ in Windows) the joining is skipped.

The problem is that interpolation only happens in a later stage, so it's failing to detect that {{.DIRECTORY}} holds an absolute path, so it'll be joined like:

/path/to/project/{{.DIRECTORY}} which will be later expanded as /path/to/project/path/to/project.

While this is not fixed, you can change dir to have a relative path like ../../

davinkevin commented 5 months ago

To fix that "issue", I did this:

tasks
  foo:
    dir: /$TMPDIR/{{.COMPONENT_NAME}}

The trick is to start with / even if $TMPDIR contains the slash… it's a way to say "force absolute". It's tricky and a bit ugly, but it works for now.

A better solution (like "if it starts with $ or {{, then it's absolute…) is still welcome 😇

brettinternet commented 3 months ago

I was able to get this to work in the subtask file by simply added a slash to indicate the absolute path:

tasks:
  foo:
    dir: "/{{.DIRECTORY}}/subpath/in/my/repo"
    cmd: pwd