Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TASKFILE_DIR always resolves to ROOT_DIR #860

Closed
postlund opened this issue Sep 6, 2022 · 10 comments
Closed

TASKFILE_DIR always resolves to ROOT_DIR #860

postlund opened this issue Sep 6, 2022 · 10 comments
Labels
area: variables Changes related to variables.

Comments

@postlund
Copy link

postlund commented Sep 6, 2022

  • Task version: Task version: v3.15.0 (h1:k1s4CXeADCJyRt8tR67XC+gusYR0BL6d/r3AIOeE98c=)
  • Operating System:Linux 5.10.102.1-microsoft-standard-WSL2

Example Taskfile showing the issue

I'm trying to use TASKFILE_DIR in an included Taskfile.yml file but it always seems to resolve to the absolute path of the root Taskfile.yml file.

/home/postlund/foo/Taskfile.yml

version: "3"

includes:
  subdir: ./subdir

tasks:
  default:
    deps: [subdir:foobar]

/home/postlund/foo/subdir/Taskfile.yml

version: "3"

tasks:
  foobar:
    cmds:
      - echo {{.TASKFILE_DIR}}

Running task:

$ cd /home/postlund/foo
$ task
task: [subdir:foobar] echo /home/postlund/foo
/home/postlund/foo

I might have misunderstood something, but I would have expected TASKFILE_DIR being resolved to /home/postlund/foo/subdir in this case.

@andreynering
Copy link
Member

Hi @postlund,

It will return the right directory if you change the execution directory to be the subdir as well:

includes:
  subdir:
    taskfile: ./subdir
    dir: ./subdir

To me the current behavior is the expected, and we could improve the documentation to make it clearer.

But if anyone disagree, let me know.

@postlund
Copy link
Author

postlund commented Sep 6, 2022

@andreynering Ok, then I understand (I think). Is there any reason why it wouldn't always point to the directory of the Taskfile.yml it is "used" in instead? At least to me that seems way more obvious.

@ameergituser
Copy link

@andreynering Hi, I feel that the default behavior should be that the tasks are run from the location of the specific included taskfile.

This is the behavior if you run that specific taskfile on its own.

It's also the behavior if you only use one taskfile.

For me it is a secondary function to run tasks included in other taskfiles in the root of the parent taskfile.

I use task as a build tool and write many separated libraries/projects. Each of them have thier own taskfiles. So when I include these libraries in a main project where the one lib would include the other and so forth, it's natural to expect that the taskfile is run from where it was intended to run, and was probably tested that way too.

@andreynering
Copy link
Member

@ameergituser We could consider changing the default behavior in the future, but on v3 it would be a backwards incompatible change, so we need at least to wait for v4 (which I think will take a long time to happen).

Also, note that the expected behavior change from user to user. I've seem many people having a directory like .taskfiles/ and including them on root expecting those tasks to run on root.

Other (like me) more often setup them to run on the Taskfile directory.

So this decision is not a matter of right and wrong, but what most people would do most of the time.

@postlund
Copy link
Author

postlund commented Sep 6, 2022

@andreynering Maybe the behavior could be altered via a global setting? Just like you can change run for instance.

@ameergituser
Copy link

@andreynering I agree with you on the breaking backwards compatibility issues, and the use case aspect.

@davingreen
Copy link

Chiming in... I found this same issue thinking I had found a bug. I expect TASKFILE_DIR to be the dir of the Taskfile for the command I've sent, not the root/including taskfile (which I'd assume was ROOT_DIR)

If taskfile1 includes taskfile2 and my command is task taskfile1:taskfile2:command, then I'd want TASKFILE_DIR to be the dir of taskfile2...

@morozovcookie
Copy link

Hello, everyone! I am also found "expected" behavior a little bit unexpected. But for me that is totally ok - just add one more string. And I found another case when I specified dir parameter and it still work.

In my case I have set of 3 Taskfile.yml:

.
├── Taskfile.yml
└── api
    ├── Taskfile.yml
    └── v1
        ├── Taskfile.yml
        └── openapi.yml

I prefer to have a lot of Taskfile.yml over have one single big includes: section. Also I came from C++ background and I did work with cmake so this is ok for me. Anyway, if I will write next stuff:

# /Taskfile.yml

version: '3'

includes:
  api:
    taskfile: ./api
    dir: ./api

# /api/Taskfile.yml

version: '3'

includes:
  v1:
    taskfile: ./v1
    dir: ./v1

# /api/v1/Taskfile.yml

version: '3'

tasks:
  test:
    cmds:
      - echo {{.TASKFILE_DIR}}

And I will run command task api:v1:test then I will get /api as output. But if I jump into /api directory and run v1:test then I will get the correct output.

Let's summarize it. I expect that I can build a tree of any deep and variable should defines correct. But it is looks like I can work only with second level of deep.

@jracollins
Copy link

jracollins commented Mar 16, 2023

Hi all 👋 - this has confused me too with the expected behaviour.

The docs state the following under https://taskfile.dev/api/#special-variables :

ROOT_DIR | The absolute path of the root Taskfile.
TASKFILE_DIR | The absolute path of the included Taskfile.
USER_WORKING_DIR | The absolute path of the directory task was called from.

The wording does imply what people in this thread expected, and make the current implemented effect sound like a bug 😅.

The USER_WORKING_DIR and the ROOT_DIR should actually already be able cover the mentioned current use cases as they have the same outputted value as TASKFILE_DIR without the dir arg provided.

If I have a nested taskfile containing the following:

tasks:
  test:
    cmds: 
      - echo {{ .TASKFILE_DIR }}
      - echo {{ .ROOT_DIR }}
      - echo {{ .USER_WORKING_DIR }}

These all output the same directory when invoked, regardless of whether I execute it in the root or from the directory it is defined.

I can make it work like others in this thread by specifying the dir argument at the include level, which then changes the TASKFILE_DIR . It feels like a potentially better solution would be to have a new {{ .TASKFILE_WORKING_DIR }} that inherits that value instead and change TASKFILE_DIR to what implies? That way the same Taskfile could actually be reused with different directories too.

My use case is nested tasks wanting to send output to the same directory relative to where the file is defined, regardless of where it is run, i.e: all goes to output:

tasks:
  test:
    cmds: 
      - echo "test" > {{ .TASKFILE_DIR }}/../../task1_output
Taskfile.yaml
output/
└── task1_output
my_tasks/
├── task1/
│   └── Taskfile.yaml
└── task2/
    └── Taskfile.yaml

It also seems that manually specifying the dir only works for 1 level deep, and any 3rd level or deep nested tasks return the 2nd level TASKFILE_DIR when echo'ed - looks like this has been raised before here @: #894

@andreynering andreynering added the area: variables Changes related to variables. label Aug 10, 2023
@pd93
Copy link
Member

pd93 commented May 10, 2024

This works as expected in the latest version.

@pd93 pd93 closed this as completed May 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: variables Changes related to variables.
Projects
None yet
Development

No branches or pull requests

7 participants