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

Allowing assigning the STDOUT result of a task to a variable #178

Open
dischello opened this issue Feb 22, 2019 · 10 comments
Open

Allowing assigning the STDOUT result of a task to a variable #178

dischello opened this issue Feb 22, 2019 · 10 comments
Labels
area: variables Changes related to variables. type: feature A new feature or functionality.

Comments

@dischello
Copy link

dischello commented Feb 22, 2019

Set value of the task to the var:

task-B:
    vars:
        ARG1:
        ARG2:
task-A:
    vars:
      VAR-A: 
        - task-B: 
          vars: {ARG1: "first", ARG2: "second"}

it would be nice to have such thing to reuse existing tasks more efficiently or is there way to pass variable/values/data between task?

@andreynering andreynering added the type: question Further information is requested. label Feb 24, 2019
@andreynering
Copy link
Member

Hi @dischello,

Sorry, I'm not sure I understood the request. Do you want to assign the result of a task (STDOUT) to a variable?

@dischello
Copy link
Author

dischello commented Feb 25, 2019

Hi @andreynering,

Sorry for confusion.
I found solution. Basically when i am calling task like this

task-B:
    vars:
        ARG1:
        ARG2:
task-A:
    vars:
      VAR-A: 
        - task task-B "ARG1=agr1" "ARG2=arg2"

worked perfectly fine for me.

@andreynering andreynering changed the title Is it possible to set value of the task to the var? Allowing assigning the STDOUT result of a task to a variable Mar 3, 2019
@andreynering andreynering added type: feature A new feature or functionality. and removed type: question Further information is requested. labels Mar 3, 2019
@andreynering
Copy link
Member

@dischello Yeah, that's not ideal, but recursively calling task works.

I'll keep this open in order to maybe allow this in the future:

vars:
  FOO: {task: foobar}

This can be tricky though, since it can in theory allow a recursive dependency (i.e. a var depending on a task and this task depending on the same variable).

For now you can just use sh:.

@dolfelt
Copy link

dolfelt commented Jul 7, 2021

@andreynering I think this feature could be great but my use case would be a bit different.

I think if the output of any generic command (or task) could be assigned to a variable within the scope (or perhaps global) it would greatly improve the flexibility and allow variables to be generated only after preconditions, something I cannot figure out how to do now.

Here's an example of something I'm trying to transition from our own internal Go task runner.

tasks:
  install:
    desc: Create a user with accounts
    vars:
      GIT_USER_EMAIL:
        sh: git config user.email
      EMAIL: "{{.EMAIL | default (.GIT_USER_EMAIL)}}"
    cmds:
      - kubectl rollout status deployment/app
      - echo "Creating Accounts for {{.EMAIL}}"
      - cmd: kubectl get po -lapp=app -o jsonpath='{.items[*].metadata.name}' | cut -d" " -f1
        assign: POD
      - kubectl exec -it {{.POD}} -c app -- bin/console dev:install {{.EMAIL}}
      - task: prepare
        vars: { POD_NAME: "{{.POD}}" }
      - echo -e "\nSuccess! You can now login."

The reason I find this important is that the POD information can't be collected until after the rollout completes. For many things is possible to just do a variable in the same command block, but this provides greater flexibility. And right now I know of no way to pass a command output to another task.

As far as the original poster, I imagine creating a task to assign could also be helpful.

tasks:
  get-data:
    cmds:
      - echo "my data"
  run:
    cmds:
      - task: get-data
        assign: DATA
      - 'echo "{{.DATA}}" | jq | etc'

In this scenario there are considerations on what kind of output is expected with multiple commands and how to merge those together if necessary.

Let me know what you think. If this is something you think we can add I'll be more than happy to make a PR.

Thanks!

@russellseymour
Copy link

@dolfelt where you able to get the assign working?

I have been trying to get it working for something I am doing, and have bumped into an issue reading from Stdout.

If you have would you be able to share your code please?

@orsinium
Copy link

I also have a case where assigning stdout of another command would help. This is the shell command:

sudo docker run -d --publish 8043 --volume ${CREDS}:/srv/http \
    --name secrets-server pierrezemb/gostatic
secrets_ip=$(sudo docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' secrets-server)
sudo docker build ... --add-host=secrets-server:${secrets_ip} ...

Here, secrets_ip can be set only after the first command is executed and before executing the next one. In the current task version, if I translate it as is, the created environment variable is not available in the next command.

@timharris777
Copy link

Something like this would be great! I'm currently looking for a way to have one cmd or task save output to env or var that can be referenced in the next cmd or task. Any news on this?

@amancevice
Copy link
Contributor

Throwing this out there: would it make more sense to attack this problem from the opposite end? eg:

tasks:
  get-data:
    cmds:
      - echo "my data"

  use-data:
    vars:
      DATA:
        task: get-data
    cmds:
      - 'echo "{{.DATA}}" | jq | etc'

this strategy would conflict with the any-variables experiment, but I think it's cleaner this way.

@amancevice
Copy link
Contributor

another workaround I've been playing with using a scripts section and YAML anchors to re-use bits of code:

scripts:
  AUTO_SCALING_GROUP: &AUTO_SCALING_GROUP
    sh: >-
      aws autoscaling describe-auto-scaling-groups
      | jq -r '.AutoScalingGroups[].AutoScalingGroupName'
      | fzf --prompt '{{.PROMPT | default "Pick Auto Scaling Group > "}}'

tasks:
  list-instances:
    desc: List instance IDs in auto scaling group
    vars:
      PROMPT: "This overrides the prompt below > "
      AUTO_SCALING_GROUP: *AUTO_SCALING_GROUP
    cmds:
      - >-
        aws autoscaling describe-auto-scaling-groups
        --auto-scaling-group-names {{.AUTO_SCALING_GROUP}}
        | jq -r '.AutoScalingGroups[].Instances[].InstanceId

@JonZeolla
Copy link
Contributor

I was coming here hoping to find something like this. Specifically I was hoping to find a way to get this to work:

➜ ls
Taskfile.included.yml Taskfile.yml
➜ cat *
---
# https://taskfile.dev

version: '3'

tasks:
  get-vars:
    vars:
      EXAMPLE: 'hit'
---
# https://taskfile.dev

version: '3'

includes:
  example:
    taskfile: Taskfile.included.yml

tasks:
  default:
    cmds:
      - task: example:get-vars
      - echo '{{.EXAMPLE}}'
➜ task -v
task: [/Users/jonzeolla/src/testing] Not found - Using alternative (Taskfile.yml)
task: "default" started
task: "example:get-vars" started
task: "example:get-vars" finished
task: [default] echo ''

task: "default" finished

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. type: feature A new feature or functionality.
Projects
None yet
Development

No branches or pull requests

8 participants