Skip to content

Consistent way to get the SHELL env, PATH env, and add folders to a PATH #2164

@joeblew999

Description

@joeblew999

Description

I am working up a Best Practice project that uses task for my team..

I cant get the SHELL printing in Linux or Windows.
I cant add new paths to the OS Path.

Darwin works locally and in CI.

Linux and Windows does not work locally or in CI.

--

Full reproduction:

The example TASK file below is here: https://github.com/joeblew999/pb-stack/blob/main/base.taskfile.yml, so you can reproduce the issue.

The Actions run that same file is here: https://github.com/joeblew999/pb-stack/actions

task base 


- shell
BASE_SHELL: /bin/zsh
BASE_SHELL_OS_NAME: darwin
BASE_SHELL_OS_ARCH: arm64
BASE_GOOS_NAME: darwin
BASE_GOOS_ARCH: arm64

- user
BASE_HOME: /Users/apple
BASE_USER: apple

BASE_SRC_NAME: base_name

BASE_SRC: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack

BASE_BIN_NAME: .bin
BASE_BIN: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.bin

BASE_DEP_NAME: .dep
BASE_DEP: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep

BASE_PACK_NAME: .pack
BASE_PACK: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.pack


PATH: /Users/apple/Library/pnpm:/opt/homebrew/opt/git/libexec/git-core:/opt/homebrew/opt/make/libexec/gnubin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Users/apple/.cargo/bin:/Users/apple/.orbstack/bin:/Users/apple/workspace:/Users/apple/workspace/go/bin:/opt/homebrew/opt/go/libexec/bin::

BASE_PATH: /Users/apple/Library/pnpm:/opt/homebrew/opt/git/libexec/git-core:/opt/homebrew/opt/make/libexec/gnubin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/Users/apple/.cargo/bin:/Users/apple/.orbstack/bin:/Users/apple/workspace:/Users/apple/workspace/go/bin:/opt/homebrew/opt/go/libexec/bin:::/Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep:/Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.bin

BASE_TASK_CMD: task --yes


- task

- task bin

- task env
TASK_TEMP_DIR:
TASK_REMOTE_DIR:
TASK_OFFLINE:
FORCE_COLOR:

- task vars
CLI_ARGS:
CLI_FORCE: false
CLI_SILENT: false
CLI_VERBOSE: false
CLI_OFFLINE: false

The name of the current task:
TASK: base:default
The alias used for the current task, otherwise matches TASK:
ALIAS: base
TASK_EXE: task
ROOT_TASKFILE: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack
ROOT_DIR: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack
TASKFILE: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/base.taskfile.yml
TASKFILE_DIR: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack
TASK_DIR: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack
USER_WORKING_DIR: /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack
CHECKSUM:
TIMESTAMP:
TASK_VERSION: v3.42.1
ITEM:
EXIT_CODE:
task base:test
task: [base:test] echo ''

task: [base:test] echo 'testing base  ...'
testing base  ...
task: [base:test] task --yes base:clean
task: [base:clean] echo ''

task: [base:clean] echo 'cleaning base  ...'
cleaning base  ...
task: [base:clean] rm -rf /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.bin
task: [base:clean] rm -rf /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep
task: [base:clean] rm -rf /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.pack
task: [base:test] task --yes base:bin
task: [base:bin] echo ''

task: [base:bin] echo 'installing base shell tools ...'
installing base shell tools ...
task: [base:bin] echo ''

task: [base:bin] echo '1. Creating base folders ...'
1. Creating base folders ...
task: [base:bin] mkdir -p /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.bin
task: [base:bin] mkdir -p /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep
task: [base:bin] mkdir -p /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.pack
task: [base:bin] echo ''

task: [base:bin] echo '2. Installing base tools ...'
2. Installing base tools ...
task: [base:bin] echo ''

task: [base:bin] echo '- which tool ...'
- which tool ...
task: [base:bin] env GOBIN=/Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep go install github.com/hairyhenderson/go-which/cmd/which@latest
task: [base:bin] mv /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep/which /Users/apple/workspace/go/src/github.com/joeblew999/pb-stack/.dep/amp-which
task: [base:bin] echo ''

task: [base:bin] echo 'TODO - add the other tools after we sort out the SHELL and BIN Naming to be cross platform  ...'
TODO - add the other tools after we sort out the SHELL and BIN Naming to be cross platform  ...
task: [base:test] task --yes base:run-which-test
task: [base:run-which-test] amp-which task

Version

v3.42.1

Operating system

all

Experiments Enabled

Env Precedence, Map Variables (2), Remote Taskfiles, Gentle Force

Example Taskfile

# https://taskfile.dev

version: '3'

vars:
  # OS
  # '/bin/zsh'  
  BASE_SHELL: '{{.SHELL}}'
  BASE_SHELL_OS_NAME:
    sh: uname -s | tr A-Z a-z
  BASE_SHELL_OS_ARCH:
    sh: uname -m | tr A-Z a-z
  BASE_GOOS_NAME:
    sh: go env GOOS
  BASE_GOOS_ARCH:
    sh: go env GOARCH

  # OS User
  BASE_HOME: '{{.HOME}}'
  # 'apple'
  BASE_USER: '{{.USER}}'

  # Project (always named like project root '_' cmd path), as in go projects cmd is the entry point. 
  BASE_SRC_NAME: base_name

  # Our dot folders.
  # We want this to be where the Task file is.
  BASE_SRC: '{{.USER_WORKING_DIR}}'
  # We want BIN near the SRC
  BASE_BIN_NAME: '.bin'
  BASE_BIN: '{{.BASE_SRC}}/{{.BASE_BIN_NAME}}'
  
  # We want DEP in root
  BASE_DEP_NAME: '.dep'
  BASE_DEP: '{{.TASKFILE_DIR}}/{{.BASE_DEP_NAME}}'

  # We want PACKS near the SRC and BIN
  BASE_PACK_NAME: '.pack'
  BASE_PACK: '{{.BASE_SRC}}/{{.BASE_PACK_NAME}}'

  # Our base helpers ( many to help with cross OS differences, cause u-root is not good enough )
  BASE_AMP_WHICH_BIN_NAME: amp-which
  BASE_AMP_WHICH_BIN_VERSION: latest

  # Lastly, calculate the OS Paths, so we do not pollute the OS.
  BASE_PATH: '{{.PATH}}:{{.BASE_DEP}}:{{.BASE_BIN}}'

  # Simple wrapper to apply defaults.
  BASE_TASK_CMD: '{{.TASK_EXE}} --yes'

env:
  # export Path to include our .bin and .dep
  #export PATH:=$(PATH):$(BASE_BIN):$(BASE_DEP)
  #export PATH:=$(PATH):$(BASE_PWD_BIN)
  # https://github.com/go-task/task/issues/202

  #PATH: '{{.BASE_BIN}}:{{.BASE_DEP}}:{{.PATH}}'
  # try to make windows happy.
  PATH: '{{.PATH}}:{{.BASE_DEP}}:{{.BASE_BIN}}'
  
tasks:
  default:
    desc: base print
    cmds:
      - echo ''
      
      - echo ''
      - echo '- shell'
      - echo 'BASE_SHELL:'            {{.BASE_SHELL}}
      - echo 'BASE_SHELL_OS_NAME:'    {{.BASE_SHELL_OS_NAME}}
      - echo 'BASE_SHELL_OS_ARCH:'    {{.BASE_SHELL_OS_ARCH}}
      - echo 'BASE_GOOS_NAME:'        {{.BASE_GOOS_NAME}}
      - echo 'BASE_GOOS_ARCH:'        {{.BASE_GOOS_ARCH}}
      - echo ''
      - echo '- user'
      - echo 'BASE_HOME:'             {{.BASE_HOME}}
      - echo 'BASE_USER:'             {{.BASE_USER}}
      
      - echo ''
      - echo 'BASE_SRC_NAME:'         {{.BASE_SRC_NAME}}
      - echo ''
      - echo 'BASE_SRC:'              {{.BASE_SRC}}
      - echo ''
      - echo 'BASE_BIN_NAME:'         {{.BASE_BIN_NAME}}
      - echo 'BASE_BIN:'              {{.BASE_BIN}}
      - echo ''
      - echo 'BASE_DEP_NAME:'         {{.BASE_DEP_NAME}}
      - echo 'BASE_DEP:'              {{.BASE_DEP}}
      - echo ''
      - echo 'BASE_PACK_NAME:'        {{.BASE_PACK_NAME}}
      - echo 'BASE_PACK:'             {{.BASE_PACK}}
      - echo ''
      - echo ''
      - echo 'PATH:'                  {{.PATH}}
      - echo ''
      - echo 'BASE_PATH:'             {{.BASE_PATH}}
      - echo ''
      - echo 'BASE_TASK_CMD:'         {{.BASE_TASK_CMD}}
      
      - echo ''
      - echo ''
      - echo '- task'
      - echo ''
      - echo '- task bin'
      - echo ''
      # https://taskfile.dev/reference/environment/
      - echo '- task env'
      - echo 'TASK_TEMP_DIR:'         {{.TASK_TEMP_DIR}}
      - echo 'TASK_REMOTE_DIR:'       {{.TASK_REMOTE_DIR}}
      - echo 'TASK_OFFLINE:'          {{.TASK_OFFLINE}}
      - echo 'FORCE_COLOR:'           {{.FORCE_COLOR}}
      
      
      - echo ''
      # https://taskfile.dev/reference/templating/#special-variables
      - echo '- task vars'
      # Contain all extra arguments passed after -- when calling Task through the CLI.
      - echo 'CLI_ARGS:'              {{.CLI_ARGS}}
      # A boolean containing whether the --force or --force-all flags were set.
      - echo 'CLI_FORCE:'             {{.CLI_FORCE}}
      # A boolean containing whether the --silent flag was set.
      - echo 'CLI_SILENT:'            {{.CLI_SILENT}}
      # A boolean containing whether the --verbose flag was set.
      - echo 'CLI_VERBOSE:'           {{.CLI_VERBOSE}}
      # A boolean containing whether the --offline flag was set.
      - echo 'CLI_OFFLINE:'           {{.CLI_OFFLINE}}
      - echo ''
      # The name of the current task.
      - echo 'The name of the current task:'  
      - echo 'TASK:'                  {{.TASK}}
      # The alias used for the current task, otherwise matches TASK.
      - echo 'The alias used for the current task, otherwise matches TASK:'  
      - echo 'ALIAS:'                 {{.ALIAS}}
      # The Task executable name or path.
      - echo 'TASK_EXE:'              {{.TASK_EXE}}
      # The absolute path of the root Taskfile
      - echo 'ROOT_TASKFILE:'         {{.ROOT_TASKFILE}}
      # The absolute path of the root Taskfile directory
      - echo 'ROOT_DIR:'              {{.ROOT_DIR}}
      # The absolute path of the included Taskfile.
      - echo 'TASKFILE:'              {{.TASKFILE}}
      # The absolute path of the included Taskfile directory.
      - echo 'TASKFILE_DIR:'          {{.TASKFILE_DIR}}
      # The absolute path of the directory where the task is executed.
      - echo 'TASK_DIR:'              {{.TASK_DIR}}
      # The absolute path of the directory task was called from.
      - echo 'USER_WORKING_DIR:'      {{.USER_WORKING_DIR}}
      # The checksum of the files listed in sources. Only available within the status prop and if method is set to checksum.
      - echo 'CHECKSUM:'              {{.CHECKSUM}}
      # The date object of the greatest timestamp of the files listed in sources. Only available within the status prop and if method is set to timestamp.
      - echo 'TIMESTAMP:'             {{.TIMESTAMP}}
      # The current version of task.
      - echo 'TASK_VERSION:'          {{.TASK_VERSION}}
      # The value of the current iteration when using the for property. Can be changed to a different variable name using as:.
      - echo 'ITEM:'                  {{.ITEM}}
      # Available exclusively inside the defer: command. Contains the failed command exit code. Only set when non-zero.
      - echo 'EXIT_CODE:'             {{.EXIT_CODE}}
    silent: true

  test:
    desc: base test, checks that base is working.
    cmds:
      - echo ''
      - echo 'testing base  ...'
      - '{{.BASE_TASK_CMD}} base:clean'
      - '{{.BASE_TASK_CMD}} base:bin'
      - '{{.BASE_TASK_CMD}} base:run-which-test'
    silent: false

  clean:
    desc: base clean, cleans the base folders.
    cmds:
      - echo ''
      - echo 'cleaning base  ...'
      - rm -rf {{.BASE_BIN}}
      - rm -rf {{.BASE_DEP}}
      - rm -rf {{.BASE_PACK}}
    silent: false

  bin:
    desc: base bin, installs shell level components.
    cmds:
      - echo ''
      - echo 'installing base shell tools ...'
      - echo ''
      - echo '1. Creating base folders ...'
      - mkdir -p {{.BASE_BIN}}
      - mkdir -p {{.BASE_DEP}}
      - mkdir -p {{.BASE_PACK}}
      - echo ''
      - echo '2. Installing base tools ...'
      - echo ''
      - echo '- which tool ...'
      # https://github.com/hairyhenderson/go-which/tree/main/cmd
      - env GOBIN={{.BASE_DEP}} {{.GO_BIN_NAME}} install github.com/hairyhenderson/go-which/cmd/which@{{.BASE_AMP_WHICH_BIN_VERSION}}
      - mv {{.BASE_DEP}}/which {{.BASE_DEP}}/{{.BASE_AMP_WHICH_BIN_NAME}}
      - echo ''
      - echo 'TODO - add the other tools after we sort out the SHELL and BIN Naming to be cross platform  ...'

  run-which-h:
    desc: which is a cross platform **which** command.
    cmds:
      - '{{.BASE_AMP_WHICH_BIN_NAME}} -h'
  run-which:
    desc: find binary.
    cmds:
      - '{{.BASE_AMP_WHICH_BIN_NAME}} {{.CLI_ARGS}}'
  run-which-test:
    desc: find binary.
    cmds:
      - '{{.BASE_AMP_WHICH_BIN_NAME}} {{.TASK_EXE}}'

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions