Skip to content

Reference via ref: or via {{}} Templating of included vars (global, not task) in(to) a Taskfile vars section (global, not task) doesn't work. #2405

@tobiashochguertel

Description

@tobiashochguertel

Description

I try to get a value of a (global, not task) var from an included taskfile to define in the including Taskfile a new var with the value.

I expect that I get the value in the (global, not task) vars of the including Taskfile.

Instead, the variable has an empty value.

Here is an example:

File: .taskfiles/modules/common.yml
common.yml

File: .taskfiles/modules/cmds.yml

version: '3'

shopt: [globstar, expand_aliases]

includes:
  common: ./common.yml

vars:
  # =========================================================================
  # CMDS MODULE VARIABLES
  # =========================================================================
  # This file follows the hybrid variable scoping approach:
  # 1. Module-specific variables use CMDS_ prefix
  # 2. Global variables from main Taskfile are referenced with GLOBAL_ prefix
  # 3. Each global variable has a default value as fallback
  # =========================================================================

  # Module namespace - uniquely identifies this taskfile
  CMDS_NAMESPACE: '{{.CMDS_NAMESPACE | default "cmds"}}'

  # Special system variables from Go-Task
  T: '{{.TASK_EXE}}' # Task executable path
  WORKING_DIR: '{{.USER_WORKING_DIR}}' # Current working directory

  # Color definitions - referencing global variables with fallback
  COLORS:
    map:
      GREEN: '{{.GLOBAL_COLORS.GREEN | default "\\033[0;32m"}}'
      YELLOW: '{{.GLOBAL_COLORS.YELLOW | default "\\033[0;33m"}}'
      RED: '{{.GLOBAL_COLORS.RED | default "\\033[0;31m"}}'
      BLUE: '{{.GLOBAL_COLORS.BLUE | default "\\033[0;34m"}}'
      CYAN: '{{.GLOBAL_COLORS.CYAN | default "\\033[0;36m"}}'
      NC: '{{.GLOBAL_COLORS.NC | default "\\033[0m"}}'

  # Debug flag with fallback
  CMDS_DEBUG: '{{or .GLOBAL_DEBUG .CMDS_DEBUG | default "false"}}'

  # Stores the paths to the often used commands
  CMDS_DOCKER_COMPOSE:
    sh: |
      {{.FUNCS.debug}}
      {{.FUNCS.info}}
      {{.FUNCS.check_command}}

      debug "CMDS_DOCKER_COMPOSE"

      if command -v jq &> /dev/null && command -v docker &> /dev/null; then
        # Get Docker version in JSON format and extract version with jq
        VERSION_INFO=$(docker version --format json 2>/dev/null | jq -r '.Client.Version' 2>/dev/null)
        if [[ -n "$VERSION_INFO" ]] && [[ "$(echo $VERSION_INFO | awk -F. '{print $1}')" -ge 20 ]] || [[ "$(echo $VERSION_INFO | awk -F. '{print $1}')" -eq 19 && "$(echo $VERSION_INFO | awk -F. '{print $2}')" -ge 3 ]]; then
          # Docker 19.03+ has built-in compose plugin
          echo "docker compose"
        elif command -v docker-compose &> /dev/null; then
          echo "docker-compose"
        else
          error_exit "ERROR: Docker Compose is not available" >&2
        fi
      elif command -v docker-compose &> /dev/null; then
        echo "docker-compose"
      else
        error_exit "ERROR: Required dependencies (docker, jq, or docker-compose) not available" >&2
      fi

  CMDS:
    map:
      DOCKER_COMPOSE: |
        {{.FUNCS.debug}}
        {{.FUNCS.info}}
        {{.FUNCS.check_command}}

        function get() {
          if command -v jq &> /dev/null && command -v docker &> /dev/null; then
            # Get Docker version in JSON format and extract version with jq
            VERSION_INFO=$(docker version --format json 2>/dev/null | jq -r '.Client.Version' 2>/dev/null)
            if [[ -n "$VERSION_INFO" ]] && [[ "$(echo $VERSION_INFO | awk -F. '{print $1}')" -ge 20 ]] || [[ "$(echo $VERSION_INFO | awk -F. '{print $1}')" -eq 19 && "$(echo $VERSION_INFO | awk -F. '{print $2}')" -ge 3 ]]; then
              # Docker 19.03+ has built-in compose plugin
              echo "docker compose"
            elif command -v docker-compose &> /dev/null; then
              echo "docker-compose"
            else
              error_exit "ERROR: Docker Compose is not available" >&2
            fi
          elif command -v docker-compose &> /dev/null; then
            echo "docker-compose"
          else
            error_exit "ERROR: Required dependencies (docker, jq, or docker-compose) not available" >&2
          fi
        }

        get

tasks:
  info:
    desc: Show info about the cmds module
    cmds:
      - |-
        # Source error handling functions
        {{.FUNCS.info}}

        info "CMDS Module Info"
        echo "CMDS_DOCKER_COMPOSE: {{.CMDS_DOCKER_COMPOSE}}"

File: Taskfile.yml

version: '3'

shopt: [globstar, expand_aliases]

dotenv: ['.env', '{{.ENV}}/.env', '{{.HOME}}/.env']

# Include task files by functionality area
includes:
  common: ./.taskfiles/modules/common.yml
  cmds: ./.taskfiles/modules/cmds.yml

vars:
  GLOBAL_CMDS_DOCKER_COMPOSE:
    ref: .CMDS_DOCKER_COMPOSE

tasks:
  test:
    desc: Test task
    dir: '{{.WORKING_DIR}}'
    vars:
      TASK_VAR_CMDS_DOCKER_COMPOSE:
        ref: .CMDS_DOCKER_COMPOSE
    cmds:
      - |
        # Source common functions
        {{.FUNCS.info}}
        {{.FUNCS.success}}
        {{.FUNCS.error}}
        {{.FUNCS.debug}}
        {{.FUNCS.debug_header}}

        debug_header "{{.TASK}}"
        debug "CMDS_DOCKER_COMPOSE" "{{.CMDS_DOCKER_COMPOSE}}"
        debug "CMDS.DOCKER_COMPOSE" "$({{.CMDS.DOCKER_COMPOSE}})"
        debug "GLOBAL_CMDS_DOCKER_COMPOSE" "{{.GLOBAL_CMDS_DOCKER_COMPOSE}}"
        debug "TASK_VAR_CMDS_DOCKER_COMPOSE" "{{.TASK_VAR_CMDS_DOCKER_COMPOSE}}"

When I run task -s test I get the following output:

> task -s test

🔍 DEBUG: CMDS_DOCKER_COMPOSE
╔════════════════════════════════════════════════════════════════════════════════╗
║ test                                                                           ║
╚════════════════════════════════════════════════════════════════════════════════╝
🔍 DEBUG: CMDS_DOCKER_COMPOSE: docker compose
🔍 DEBUG: CMDS.DOCKER_COMPOSE: docker compose
🔍 DEBUG: GLOBAL_CMDS_DOCKER_COMPOSE
🔍 DEBUG: TASK_VAR_CMDS_DOCKER_COMPOSE: docker compose

The value of GLOBAL_CMDS_DOCKER_COMPOSE is always empty; that is sad.

  • Do I do something wrong?
  • Or is this really a bug?

Version

3.44.1

Operating system

macos

Experiments Enabled

No response

Example Taskfile

Metadata

Metadata

Assignees

No one assigned

    Labels

    state: needs triageWaiting to be triaged by a maintainer.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions