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

How to get the result of a command as a variable for other tasks? #21

Closed
kikohs opened this issue Apr 6, 2021 · 7 comments
Closed

How to get the result of a command as a variable for other tasks? #21

kikohs opened this issue Apr 6, 2021 · 7 comments
Labels
enhancement New feature or request

Comments

@kikohs
Copy link

kikohs commented Apr 6, 2021

I'm trying to get the result of a poe or (shell) command as a environment variable for another POE task. It is dynamic and cannot be set beforehand.

Is it possible?

Thank you

@nat-n
Copy link
Owner

nat-n commented Apr 6, 2021

That's an interesting idea. Could you tell me more about your use case?

Maybe you can do what you want to with POSIX shell command substitution? silly example:

foo_task.shell = "echo $(echo foo)"

or command substitution plus a shell variable?

thing.shell = """
foo=$(echo bar1)
echo $foo
echo $foo
"""

@kikohs
Copy link
Author

kikohs commented Apr 6, 2021

This is what I got so far:

docker-build = { "shell" = "VERSION=$(poetry version | cut -d ' ' -f2) && docker build -f Dockerfile -t kikohs/movements:$VERSION . "}

It would be cool to save $VERSION and pass it to other POE tasks.

@nat-n
Copy link
Owner

nat-n commented Apr 6, 2021

Right, so you'd like to be able to avoid repeating that poetry version sub command, in each of the tasks that needs it, and instead do something like:

[tool.poe.env]
VERSION = { cmd = "poetry version | cut -d ' ' -f2" }

[tool.poe.tasks]
docker-build = "docker build -f Dockerfile -t kikohs/movements:$VERSION . "
version = "echo $VERSION"

This seems like a nice solution when I look at it now, but it's hard to know when to evaluate the variable. I wouldn't want it to be done eagerly, because the poetry CLI is slow and would add more than a second to every task! But reliably guessing whether is a task depends on a variable doesn't seem likely to work well. We could make the task have to declare that it depends on that variable as an option, but then I wonder if that's getting a bit complicated for the potential benefit.

@kikohs What do you think?

@kikohs
Copy link
Author

kikohs commented Apr 6, 2021

The solution you wrote is elegant but could add too much time as you said.
In my case I have 4 tasks that need the VERSION variable. Maybe we could imagine a task-group with shared variables?

[tool.poe.tasks]
  [tool.poe.tasks.mygroup]
    [tool.poe.tasks.mygroup.env]
      version = { cmd = "poetry version | cut -d ' ' -f2" }
      somevar = 42
    docker-build = "docker build -f Dockerfile -t kikohs/movements:$VERSION . "
   # or something like this
   docker-build = "docker build -f Dockerfile -t kikohs/movements:${env.version} . "

Or other syntax:

[tool.poe.tasks.group.env]
mygroup.version = { 
    cmd = "poetry version | cut -d ' ' -f2"
    cached = true 
}
mygroup.timestamp = {
   cmd = "date '+%s'"
   cached = false
}

[tool.poe.tasks]
docker-build.group = "mygroup"
docker-build = "docker build -f Dockerfile -t kikohs/movements:{{mygroup.version}} . "

docker-build = {
  "group" = mygroup
  "task" = "docker build -f Dockerfile -t kikohs/movements:{{mygroup.version}}-{{mygroup.timestamp}} . "
}

The group properties and env variables are only evaluated if you belong to this group. The results of the commands could be cached as well so that it is only run once. This could be optional if one really needs to re-evaluate the env variables at each command (maybe with dates, files, etc.).
I tried to be creative with the syntax.

What do you think?

@nat-n
Copy link
Owner

nat-n commented Apr 8, 2021

This idea of task groups might make sense, but it does introduce a bit of complexity that I would want to find more reasons to justify as an architectural feature, and I'm not quite seeing it yet. I might still become convinced.

I'm also cautious of introducing any kind of persistent caching, because cache invalidation is hard. Unless you meant caching within a single run so that multiple tasks in a sequence can benefit, in which case that could work, but it's quite limited.

Thinking further along those lines, I wonder if that could be elegantly expressed in terms of task dependencies. Maybe something like:

[tool.poe.tasks]
version = "poetry version | cut -d ' ' -f2"

  [tool.poe.tasks.docker-build]
    cmd = "docker build -f Dockerfile -t kikohs/movements:$VERSION ."
    deps = { VERSION = "version" }

Essentially a DAG of tasks, which makes it start to resemble more of a build tool... which I like. Ideally the structure should dovetail well with #12

@kikohs Thoughts?

@nat-n nat-n added the enhancement New feature or request label Apr 8, 2021
@kikohs
Copy link
Author

kikohs commented Apr 8, 2021

I understand you points.
Task dependencies are great, it would get the tool closer to what one can do with a Makefile!

@nat-n
Copy link
Owner

nat-n commented Apr 28, 2021

Closing in favour of #26

@nat-n nat-n closed this as completed Apr 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants