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

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions