task icon indicating copy to clipboard operation
task copied to clipboard

Nested tasks should inherit the calling task's dir

Open amancevice opened this issue 2 years ago • 6 comments

  • Task version: 3.9.0
  • Operating System: macOS 11.6 (Big Sur)

Example Taskfile showing the issue

When a task invokes another task as part of its cmds block, the called task should inherit the dir of the calling task.

Consider the following taskfile at /tmp/task/Taskfile.yml:

---
version: "3"
tasks:
  inner:
    cmds:
      - pwd
  outer:
    dir: inner
    cmds:
      - pwd
      - task: inner

I would expect the command task outer to produce:

/tmp/task/inner
/tmp/task/inner

but instead it produces:

/tmp/task/inner
/tmp/task

I think this is unexpected behavior, but I'm happy to hear another point of view

amancevice avatar Oct 15 '21 15:10 amancevice

I should add, the solution I've found is to do something like this:

---
version: "3"
tasks:
  inner:
    dir: "{{.DIR}}"
    cmds:
      - pwd
  outer:
    dir: inner
    cmds:
      - pwd
      - task: inner
        vars:
          DIR: inner

amancevice avatar Oct 15 '21 15:10 amancevice

Hi, I had the same issue once and created a draft PR as PoC: #620 But I'm not sure if this is a breaking change in some use cases.

sylv-io avatar Dec 01 '21 22:12 sylv-io

I'm afraid this is a breaking change. It's also a bit unambiguous to handle properly. Consider the example:

version: '3'

tasks:
  inner:
    dir: other
    cmds:
      - pwd
  
  test:
    dir: first
    cmds:
      - pwd
      - task: inner

Would the test task dir still override inner set dir? What if tasks are defined in separate files?

It's pretty hard to implement in a way that it would not surprise the user. The workaround @amancevice suggested is more clear for the user.

kerma avatar Dec 04 '21 16:12 kerma

I'm of two minds — I do agree that this could be considered a breaking change, but I also think making the change would make more intuitive sense to a user because it would behave more like how variables work in Task. What I mean by that is if I define a task that uses, but doesn't define a variable then it resolves up the stack up to the user's ENV.

In your example I think a typical user would understand that inner task runs from the ./other/ directory and won't be overridden by a calling task. On the other hand, if inner omitted the dir: entry then I think it would make sense for the calling task to impose its working directory on the callee.

Expanding on your example:

# /tmp/task/Taskfile.yml

version: '3'

tasks:
  inner-overrides:
    dir: other
    cmds:
      - pwd

  inner-inherits:
    cmds:
      - pwd

  test:
    dir: first
    cmds:
      - pwd
      - task: inner-overrides
      - task: inner-inherits

I would expect the output of task test to be:

task: [test] pwd
/tmp/task/first
task: [inner-overrides] pwd
/tmp/task/other
task: [inner-inherits] pwd
/tmp/task/first

But instead it's:

task: [test] pwd
/tmp/task/first
task: [inner-overrides] pwd
/tmp/task/other
task: [inner-inherits] pwd
/tmp/task

(note the last line)

amancevice avatar Dec 04 '21 22:12 amancevice

This would certainly a breaking change, and would certainly surprise many users that expect the current behavior IMO.

The current way of overriding the directory is doing like @amancevice suggested here.

If someone has any idea on how we could make that clearer, let me know. But I think it should be a setting somehow and not the default behavior.

andreynering avatar Dec 06 '21 13:12 andreynering

I see 2 problems, the first being, that calling other tasks inside cmds is the only way to make the be called in series (as they are called in parallel when using deps). So I don't really consider these "inner" tasks. But I can see how you may want to inherit some settings, such as the working directory.

ghostsquad avatar Apr 29 '22 05:04 ghostsquad