return values

As we know you will actually implicitly creaet a whole private call stack and spawn a private local vars in this scope, in such a case the work you have done, including register some values to global(relatively to this private stack), will not be reflected in your caller’s var scope. So how do you keep your result in case that you really need to do so.

We can use return cmd to achieve that. When you use return cmd, all the listed var names’ values will be registered to its caller’s var scope

Demo

source

Main task yaml file
    vars:
      tom: this is tom in global
      jerry: this is jerry in global
    tasks:
    - name: task
      desc: main entry
      task:
      - func: call
        desc: call subtask and exam the return value in following steps
        do: subtask
      - func: cmd
        desc: check value of tom
        do:
        - name: print
          cmd: 'in main task print3: {{.tom}}'
        - name: assert
          desc: since .tom is returned from callee, it should be accessible here
          cmd:
          - '{{eq .tom "tom created in sub_loop"}}'
    - name: subtask
      desc: subtask to test reg and return
      task:
      - func: cmd
        desc: check value of tom after it is registered in current task stack
        vars:
          john: john in sub_loop func1
        do:
        - name: reg
          desc: by default hitom is registered in to global context
          cmd:
            name: tom
            value: 'tom created in sub_loop'
        - name: print
          cmd: 'in sub_loop print1: {{.tom}}'
        - name: assert
          cmd:
          - '{{eq .tom "tom created in sub_loop"}}'
      - func: cmd
        desc: check value of tom and it should be available in current stack
        vars:
          john: john in sub_loop func2
        do:
        - name: print
          cmd: 'in sub_loop print2: {{.tom}}'
        - name: assert
          desc: since .tom is in callee's global, it should be accessible here
          cmd:
          - '{{eq .tom "tom created in sub_loop"}}'
        - name: return
          desc: |
            it should return and merge tom to parent's vars scope
            it should report warning as jason does not exist
          cmd:
          - tom
          - jason
    
Main log file
    loading [Config]:  ./tests/functests/upconfig.yml
    Main config:
                 Version -> 1.0.0
                  RefDir -> ./tests/functests
                 WorkDir -> cwd
              AbsWorkDir -> /up_project/up
                TaskFile -> c0113
                 Verbose -> vvv
              ModuleName -> self
               ShellType -> /bin/sh
           MaxCallLayers -> 8
                 Timeout -> 3600000
     MaxModuelCallLayers -> 256
               EntryTask -> task
      ModRepoUsernameRef -> 
      ModRepoPasswordRef -> 
    work dir: /up_project/up
    -exec task: task
    loading [Task]:  ./tests/functests/c0113
    module: [self], instance id: [dev], exec profile: []
    profile -  envVars:
    
    (*core.Cache)({
    })
    
    Task1: [task ==> task: main entry ]
    -Step1: [: call subtask and exam the return value in following steps ]
    self: final context exec vars:
    
    (*core.Cache)({
      "jerry": "this is jerry in global",
      "tom": "this is tom in global",
      "up_runtime_task_layer_number": 0
    })
    
    =Task2: [task ==> subtask: subtask to test reg and return ]
    --Step1: [: check value of tom after it is registered in current task stack ]
    self: final context exec vars:
    
    (*core.Cache)({
      "jerry": "this is jerry in global",
      "tom": "this is tom in global",
      "up_runtime_task_layer_number": 1,
      "john": "john in sub_loop func1"
    })
    
    ~~SubStep1: [reg: by default hitom is registered in to global context ]
    ~~SubStep2: [print:  ]
    in sub_loop print1: tom created in sub_loop
    ~~SubStep3: [assert:  ]
     1 ASSERT OK:     [{{eq .tom "tom created in sub_loop"}}]
    --Step2: [: check value of tom and it should be available in current stack ]
    self: final context exec vars:
    
    (*core.Cache)({
      "john": "john in sub_loop func2",
      "tom": "tom created in sub_loop",
      "up_runtime_task_layer_number": 1,
      "jerry": "this is jerry in global"
    })
    
    ~~SubStep1: [print:  ]
    in sub_loop print2: tom created in sub_loop
    ~~SubStep2: [assert: since .tom is in callee's global, it should be accessible here ]
     1 ASSERT OK:     [{{eq .tom "tom created in sub_loop"}}]
    ~~SubStep3: [return: it should return and merge tom to parent's vars scope
    it should report warning as jason does not exist
     ]
     WARN: [return validation] - [The referencing var name: (jason) not exist]
    -Step2: [: check value of tom ]
    self: final context exec vars:
    
    (*core.Cache)({
      "tom": "tom created in sub_loop",
      "up_runtime_task_layer_number": 1,
      "jerry": "this is jerry in global"
    })
    
    ~SubStep1: [print:  ]
    in main task print3: tom created in sub_loop
    ~SubStep2: [assert: since .tom is returned from callee, it should be accessible here ]
     1 ASSERT OK:     [{{eq .tom "tom created in sub_loop"}}]
    
Logs with different verbose level
Raw logs with different verbose level