go-task / task

A task runner / simpler Make alternative written in Go
https://taskfile.dev
MIT License
11.02k stars 585 forks source link

Feature: matrix support #1766

Closed nikaro closed 1 week ago

nikaro commented 3 weeks ago

Hello,

It would be nice to be able to do something like this:

env:
  APP: myapp
  CGO_ENABLED: 0
  GOARCH:
    sh: go env GOARCH
  GOOS:
    sh: go env GOOS

tasks:
  build:
    desc: Build application
    cmd: go build -o build/${APP}-${GOOS}-${GOARCH} .

  build:all:
    desc: Build for all targets
    matrix:
      ARCH: [amd64, arm64]
      OS: [linux, darwin, windows]
    env:
      GOARCH: "{{.matrix.ARCH}}"
      GOOS: "{{.matrix.OS}}"
    cmds:
      - task: build

Previous issue on the subject: https://github.com/go-task/task/issues/675

Current workaround:

  build:all:
    desc: Build for all targets
    cmds:
      - for: [linux/amd64, linux/arm64, darwin/amd64, darwin/arm64, windows/amd64, windows/arm64]
        cmd: >-
          export GOOS=$(echo {{.ITEM}} | cut -d/ -f1);
          export GOARCH=$(echo {{.ITEM}} | cut -d/ -f2);
          go build -o build/${APP}-${GOOS}-${GOARCH} .
andreynering commented 3 weeks ago

Hey @nikaro,

We already have for: so you can loop though variables. That would sove your use case.

https://taskfile.dev/usage/#looping-over-values

nikaro commented 3 weeks ago

Hello @andreynering,

You mean something like this?

  build:all:
    desc: Build for all targets
    vars:
      matrix:
        - os: linux
          arch: arm64
        - os: linux
          arch: amd64
        - os: darwin
          arch: arm64
        - os: darwin
          arch: darwin
        - os: windows
          arch: arm64
        - os: windows
          arch: amd64
    cmds:
      - for:
          var: matrix
        cmd: go build -o build/${APP}-{{.ITEM.os}}-{{.ITEM.arch}} .

This is a bit cleaner (as it avoids the | cut -d hack), but still a proper matrix support would be better in terms of readability :-)

pd93 commented 3 weeks ago

@andreynering I'm inclined to agree that there is a valid use-case here even if it is only to reduce a bit of repetition. Can I propose the following syntax:

  build:all:
    desc: Build for all targets
    cmds:
      - for:
          matrix:
            ARCH: [amd64, arm64]
            OS: [linux, darwin, windows]
        cmd: go build -o build/${APP}-{{.ITEM.OS}}-{{.ITEM.ARCH}} .

This way it is any extension to the existing for functionality rather than another looping keyword. This should be relatively simple to plug into the existing code.

Edit: Also related: https://github.com/go-task/task/issues/675

andreynering commented 3 weeks ago

Yeah, thinking in it as an extension to for: makes more sense 👍

vmaerten commented 3 weeks ago

I totally agree. I would add this is implemented like that in Github action and it works well