---
version: '3'

tasks:
  act:
    summary: |
      ## Simulate GitHub Actions Locally

      [Act]((https://github.com/nektos/act) gives you the capability to test
      GitHub Actions locally. The program allows you to programmatically run
      steps defined in your `.github/workflows/` folder. Just like GitHub,
      it runs the actions in Docker containers. You can then simulate
      your GitHub Actions with a CLI:

      **Example triggering pull_request flow:**
      `act pull_request`

      **Example running a specific job:**
      `act -j test`
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: act
    status:
      - type act > /dev/null

  allure:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: allure
    status:
      - type allure > /dev/null

  ansifilter:
    run: once
    tags:
      - update
    cmds:
      - task: install:software
        vars:
          PACKAGE: ansifilter
    status:
      - type ansifilter > /dev/null

  axel:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: axel
    status:
      - type axel > /dev/null

  bfg:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: bfg
    status:
      - type bfg > /dev/null

  brew:
    run: once
    log:
      error: Failed to install or load Homebrew
      start: Ensuring Homebrew is installed and available
      success: Successfully ensured Homebrew is installed
    cmds:
      - task: common
      - task: brew:{{OS}}
    status:
      - type brew > /dev/null || [ -n "$NO_INSTALL_HOMEBREW" ]

  brew:cask:
    run: when_changed
    log:
      error: Failed to install `{{.CASK}}`
      start: Ensuring the `{{.CASK}}` Homebrew cask is installed
      success: Successfully installed `{{.CASK}}`
    cmds:
      - task: brew
      - |
        if [ -n "$CI" ]; then echo "*************** brew cask --> {{.CASK}}"; fi
      - brew install --cask {{.CASK}}
    status:
      - type {{.CASK}} &> /dev/null

  brew:darwin:
    cmds:
      - |
        if ! type brew &> /dev/null; then
          if type sudo &> /dev/null && sudo -n true; then
            echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
          else
            .config/log info 'Attempting to install Homebrew - you may be prompted for your `sudo` password'
            /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
          fi
          task install:software:exit:notice:reload
        fi
      - task: brew:utils
    status:
      - type brew &> /dev/null

  brew:formulae:
    cmds:
      - task: install:software
        vars:
          BIN_NAME: '{{.BIN_NAME}}'
          PACKAGE: '{{.PACKAGE}}'

  brew:linux:
    run: once
    cmds:
      - |
        function ensureSource() {
          if ! (grep "/bin/brew shellenv" < "$1" &> /dev/null); then
            echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> "$1"
          fi
        }
        if ! type brew &> /dev/null; then
          if type sudo &> /dev/null && sudo -n bash; then
            echo | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
          else
            /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
          fi
          eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"
          ensureSource "$HOME/.profile"
          task install:software:exit:notice:reload
        fi
    status:
      - type brew &> /dev/null

  brew:utils:
    run: once
    log:
      error: Failed to setup GNU-compatibility tools
      start: Installing GNU-compatibility tools for macOS via Homebrew
      success: Successfully installed GNU-compatibility tools
    cmds:
      - task: compatibility:coreutils
      - task: compatibility:findutils
      - task: compatibility:gnu-sed
      - task: compatibility:grep
      - task: compatibility:gnu-tar
      - task: compatibility:gawk
    status:
      - '[ "{{OS}}" != "darwin" ]'

  brew:windows:
    cmds:
      - task: common:windows

  bundle:
    deps:
      - brew
    cmds:
      - brew tap Homebrew/bundle

  codeclimate:
    cmds:
      - task: install:software
        vars:
          INSTALL_TASK: '{{.TASK}}'
          PACKAGE: codeclimate/formulae/codeclimate
    status:
      - type codeclimate > /dev/null

  common:
    run: once
    log:
      error: There was an error ensuring common system tools are present
      start: Ensuring common system tools are present
      success: Ensured common system tools are present
    cmds:
      - task: common:{{OS}}

  common:darwin:
    cmds:
      - task: common:darwin:xcode

  common:darwin:xcode:
    vars:
      CLT_STATUS:
        sh: brew config | grep CLT
    log:
      error: Failed to run `sudo xcode-select --install`
      start: Running `sudo xcode-select --install` to install macOS developer tools
      success: Successfully ran `sudo xcode-select --install`
    cmds:
      - sudo xcode-select --install
    status:
      - '[ "{{.CLT_STATUS}}" != "CLT: N/A" ]'

  common:linux:
    vars:
      LINUX_FAMILY:
        sh: |
          if [ -f "/etc/debian_version" ]; then
            echo 'debian'
          elif [ -f "/etc/redhat-release" ]; then
            echo 'redhat'
          elif [ -f "/etc/arch-release" ]; then
            echo 'archlinux'
          elif [ -f "/etc/alpine-release" ]; then
            echo 'alpine'
          elif type apk &> /dev/null; then
            echo 'alpine'
          elif type apt-get &> /dev/null; then
            echo 'debian'
          elif type dnf &> /dev/null || type yum &> /dev/null; then
            echo 'redhat'
          elif type pacman &> /dev/null; then
            echo 'archlinux'
          elif type yum &> /dev/null; then
            echo 'redhat'
          else
            echo 'unknown'
          fi
    log:
      error: Failed to ensure basic system dependencies are installed
      start: Ensuring basic system dependencies are installed
      success: Basic system dependencies are installed!
    cmds:
      - task: common:linux:{{.LINUX_FAMILY}}

  common:linux:alpine:
    vars:
      APK_INFO:
        sh: apk info
      PACKAGES: bash coreutils curl file g++ grep git libc6-compat make ruby ruby-bigdecimal ruby-etc ruby-irb ruby-json ruby-test-unit sudo
    log:
      error: Failed to run `apk --no-cache add {{.PACKAGES}}`
      start: Installing common dependencies by running `apk --no-cache add {{.PACKAGES}}`
      success: Successfully installed common dependencies
    cmds:
      - |
        if type sudo &> /dev/null; then
          sudo apk --no-cache add {{.PACKAGES}}
        else
          apk --no-cache add {{.PACKAGES}}
        fi
    status:
      - type bash &> /dev/null
      - type curl &> /dev/null
      - type git &> /dev/null
      - type grep &> /dev/null
      - type gzip &> /dev/null
      - type make &> /dev/null
      - type ruby &> /dev/null
      - type sudo &> /dev/null
      - '{{.APK_INFO}} | grep coreutils'
      - '{{.APK_INFO}} | grep g++'
      - '{{.APK_INFO}} | grep libc6-compat'
      - '{{.APK_INFO}} | grep ruby-bigdecimal'
      - '{{.APK_INFO}} | grep ruby-etc'
      - '{{.APK_INFO}} | grep ruby-irb'
      - '{{.APK_INFO}} | grep ruby-json'
      - '{{.APK_INFO}} | grep ruby-test-unit'

  common:linux:archlinux:
    interactive: true
    vars:
      PACKAGES: base-devel bash curl file gcc git grep gzip make procps-ng ruby sudo
    log:
      error: Failed to run `pacman -S {{.PACKAGES}}`
      start: Installing common software by running `pacman -S {{.PACKAGES}}`
      success: Successfully installed common software dependencies
    cmds:
      - .config/log warn "Archlinux support for Homebrew is not very well documented.. if this does not work and you can get it working, please open a PR :)"
      - |
        if type sudo &> /dev/null; then
          sudo pacman update
          sudo pacman -S {{.PACKAGES}}
        else
          pacman update
          pacman -S base-devel {{.PACKAGES}}
        fi
    status:
      - type bash &> /dev/null
      - type curl &> /dev/null
      - type git &> /dev/null
      - type grep &> /dev/null
      - type gzip &> /dev/null
      - type make &> /dev/null
      - type ruby &> /dev/null
      - type sudo &> /dev/null
      - ldconfig -p | grep base-devel
      - ldconfig -p | grep file
      - ldconfig -p | grep procps-ng

  common:linux:debian:
    interactive: true
    vars:
      PACKAGES: bash build-essential curl file gcc git grep gzip make procps ruby sudo
    log:
      error: Failed to install common software with `apt-get install -y {{.PACKAGES}}`
      start: Installing common software by running `apt-get install -y {{.PACKAGES}}`
      success: Successfully installed common software dependencies
    cmds:
      - |
        if type sudo &> /dev/null; then
          sudo apt-get update
          sudo apt-get install -y {{.PACKAGES}}
        else
          apt-get update
          apt-get install -y {{.PACKAGES}}
        fi
    status:
      - type bash &> /dev/null
      - type curl &> /dev/null
      - type git &> /dev/null
      - type grep &> /dev/null
      - type gzip &> /dev/null
      - type make &> /dev/null
      - type ruby &> /dev/null
      - type sudo &> /dev/null
      - dpkg-query -l build-essential &> /dev/null
      - dpkg-query -l file &> /dev/null
      - dpkg-query -l procps &> /dev/null

  common:linux:redhat:
    interactive: true
    cmds:
      - task: common:linux:redhat:packages
      - task: common:linux:redhat:devtools
      - task: common:linux:redhat:fedora

  common:linux:redhat:devtools:
    vars:
      PACKAGE_MANAGER:
        sh: if type dnf &> /dev/null; then echo 'dnf'; else echo 'yum'; fi
    log:
      error: Failed to install the "Development Tools" group with {{.PACKAGE_MANAGER}}
      start: Installing the "Development Tools" group
      success: Successfully installed the "Development Tools" group
    cmds:
      - mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/bodega"
      - |
        if [ ! -f "${XDG_CONFIG_HOME:-$HOME/.config}HOME:-$HOME/.config}/bodega/yum-devtools-check-ran" ]; then
          if type dnf &> /dev/null; then
            dnf groupinfo 'Development Tools' &> "${XDG_CONFIG_HOME:-$HOME/.config}/bodega/dnf-devtools-check-ran"
          else
            yum grouplist 'Development Tools' &> "${XDG_CONFIG_HOME:-$HOME/.config}/bodega/yum-devtools-check-ran"
          fi
          DEV_TOOLS_NOT_INSTALLED="$(grep 'No groups match' < "${XDG_CONFIG_HOME:-$HOME/.config}/bodega/yum-devtools-check-ran" > /dev/null)"
          if [[ "$DEV_TOOLS_NOT_INSTALLED" == '0' ]]; then
            if type sudo &> /dev/null; then
              if type dnf &> /dev/null; then
                sudo dnf groupinfo 'Development Tools'
              else
                sudo yum groupinstall -y 'Development Tools'
              fi
            else
              if type dnf  &> /dev/null; then
                dnf group install -y 'Development Tools'
              else
                yum groupinstall -y 'Development Tools'
              fi
            fi
          fi
          touch "${XDG_CONFIG_HOME:-$HOME/.config}/bodega/yum-devtools-check-ran"
        fi

  common:linux:redhat:fedora:
    vars:
      PACKAGES: libxcrypt-compat
      PACKAGE_MANAGER:
        sh: if type dnf &> /dev/null; then echo 'dnf'; else echo 'yum'; fi
    log:
      error: Failed to install Fedora-specific common software with `{{.PACKAGE_MANAGER}} install -y {{.PACKAGES}}`
      start: Installing Fedora-specific common software by running `{{.PACKAGE_MANAGER}} install -y {{.PACKAGES}}`
      success: Successfully installed Fedora-specific common software dependencies
    cmds:
      - |
        if ! rpm --quiet --query {{.PACKAGES}}; then
          if type sudo &> /dev/null; then
            sudo {{.PACKAGE_MANAGER}} -y install {{.PACKAGES}}
          else
            {{.PACKAGE_MANAGER}} install -y {{.PACKAGES}}
          fi
        fi
    status:
      - '[ -f /etc/os-release ] && source /etc/os-release && [[ "$ID" == "fedora" ]] && [ "$VERSION_ID" -gt "29" ]'

  common:linux:redhat:packages:
    vars:
      PACKAGES: bash curl file git grep gzip make procps-ng ruby sudo
      PACKAGE_MANAGER:
        sh: if type dnf &> /dev/null; then echo 'dnf'; else echo 'yum'; fi
    log:
      error: Failed to install common software with `{{.PACKAGE_MANAGER}} install -y {{.PACKAGES}}`
      start: Installing common software by running `{{.PACKAGE_MANAGER}} install -y {{.PACKAGES}}`
      success: Successfully installed common software dependencies
    cmds:
      - |
        if type sudo &> /dev/null; then
          sudo {{.PACKAGE_MANAGER}} install -y {{.PACKAGES}}
        else
          yum install -y {{.PACKAGES}}
        fi
    status:
      - type bash &> /dev/null
      - type curl &> /dev/null
      - type git &> /dev/null
      - type grep &> /dev/null
      - type gzip &> /dev/null
      - type make &> /dev/null
      - type ruby &> /dev/null
      - type sudo &> /dev/null
      - rpm -q | grep file
      - rpm -q | grep procps-ng

  common:linux:unknown:
    log:
      start: You are using an operating system that we do not directly support. Please make sure
        the equivalent of `build-essential`, `curl`, `file`, `git`, and `procps` are installed.
    cmds:
      - .config/log warn "*** Unknown OS -> $OSTYPE ***"

  common:windows:
    log:
      error: Windows is not supported. Try using a Windows WSL environment.
    cmds:
      - exit 1

  compatibility:findutils:
    cmds:
      - task: install:software
        vars:
          PACKAGE: findutils
    status:
      - type gfind > /dev/null

  compatibility:gawk:
    cmds:
      - task: install:software
        vars:
          PACKAGE: gawk
    status:
      - type gawk > /dev/null

  compatibility:gnu-sed:
    cmds:
      - task: install:software
        vars:
          PACKAGE: gnu-sed
    status:
      - type gsed > /dev/null

  compatibility:gnu-tar:
    cmds:
      - task: install:software
        vars:
          PACKAGE: gnu-tar
    status:
      - type gtar > /dev/null

  compatibility:grep:
    cmds:
      - task: install:software
        vars:
          PACKAGE: grep
    status:
      - type ggrep > /dev/null

  container-structure-test:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: container-structure-test
    status:
      - type container-structure-test > /dev/null

  coreutils:
    cmds:
      - task: install:software
        vars:
          PACKAGE: coreutils
    status:
      - type gcp > /dev/null || [ "{{OS}}" != "darwin" ]

  dasel:
    tags:
      - update
    cmds:
      - task: install:software
        vars:
          PACKAGE: dasel
    status:
      - type dasel > /dev/null

  deno:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: deno
    status:
      - type deno > /dev/null

  docker:
    run: once
    cmds:
      - task: docker:{{OS}}
      - task: :docker:ensure:running
    status:
      - type docker > /dev/null

  docker-slim:
    run: once
    tags:
      - docker-build
    cmds:
      - task: install:software
        vars:
          PACKAGE: docker-slim
    status:
      - type docker-slim > /dev/null

  docker:darwin:
    run: once
    cmds:
      - task: brew:cask
        vars:
          CASK: docker
      - task: exit:notice:restart
    status:
      - type docker > /dev/null

  docker:linux:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: docker
      - task: exit:notice:restart
    status:
      - type docker > /dev/null

  docker:windows:
    cmds:
      - task: common:windows

  dockle:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: dockle
          PACKAGE: goodwithtech/r/dockle
    status:
      - type dockle > /dev/null

  exiftool:
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: exiftool
      - task: install:software
        vars:
          PACKAGE: exiftool
    status:
      - type exiftool > /dev/null

  exit:notice:reload:
    cmds:
      - .config/log warn 'Software was installed that requires a terminal session reload'
      - .config/log warn 'Please close and re-open the terminal. Then, re-run the same command to continue if you face any issues.'
    status:
      - '[ -f /.dockerenv ]'

  exit:notice:restart:
    cmds:
      - .config/log warn 'Software was installed that requires a system reboot'
      - .config/log info 'Please reboot the system and re-run the same command after rebooting'
      - exit 1
    status:
      - '[ -f /.dockerenv ]'

  expect:
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: expect
      - task: install:software
        vars:
          PACKAGE: expect
    status:
      - type expect > /dev/null

  fury:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: fury
          PACKAGE: gemfury/tap/gemfury
    status:
      - type fury > /dev/null

  gcc:
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: gcc
    status:
      - type gcc > /dev/null

  gcloud:
    run: once
    cmds:
      - task: gcloud:{{OS}}
    status:
      - type gcloud > /dev/null

  gcloud:darwin:
    cmds:
      - task: brew:cask
        vars:
          CASK: google-cloud-sdk
    status:
      - type gcloud > /dev/null

  gcloud:linux:
    cmds:
      - curl -sSL https://sdk.cloud.google.com | bash

  gcloud:windows:
    cmds:
      - task: common:windows

  gh:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: gh
    status:
      - type gh &> /dev/null

  git:
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: git
      - task: common
    status:
      - type git > /dev/null

  git-bug:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: git-bug
    status:
      - type git-bug > /dev/null

  git-issue:admin:
    run: once
    cmds:
      - git clone https://github.com/dspinellis/git-issue.git .git-issue
      - |
        cd .git-issue
        sudo make install
      - rm -rf .git-issue

  gitlab-runner:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: gitlab-runner
    status:
      - type gitlab-runner > /dev/null

  gitleaks:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: gitleaks
    status:
      - type gitleaks > /dev/null

  glab:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: glab
    status:
      - type glab > /dev/null

  glow:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: glow
    status:
      - type glow > /dev/null

  go:
    run: once
    cmds:
      - task: go:gopath
      - task: go:goroot
      - task: :install:profile:add
        vars:
          PROFILE_STRING: export PATH="$PATH:${GOPATH}/bin:${GOROOT}/bin"
      - task: go:install

  go:gopath:
    run: once
    cmds:
      - task: :install:profile:add
        vars:
          PROFILE_STRING: export GOPATH="${HOME}/.local/go"
    status:
      - '[ -n "$GOPATH" ]'

  go:goroot:
    run: once
    cmds:
      - task: :install:profile:add
        vars:
          PROFILE_STRING: export GOROOT="$(brew --prefix golang)/libexec"
    status:
      - '[ -n "$GOROOT" ]'

  go:install:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: go

  golangci-lint:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: golangci-lint

  grype:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: anchore/grype/grype

  gum:
    run: once
    cmds:
      - task: :install:go:gum

  gzip:
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: gzip
      - task: install:software
        vars:
          PACKAGE: gzip
    status:
      - type gzip > /dev/null

  heroku:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: heroku/brew/heroku

  hey:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: hey

  install:software:
    vars:
      BIN: '{{if .BIN_NAME}}{{.BIN_NAME}}{{else}}{{last (splitList "/" .PACKAGE)}}{{end}}'
    run: when_changed
    log:
      error: Failed to install `{{.PACKAGE}}`
      start: Ensuring the `{{.PACKAGE}}` Homebrew formulae is installed
      success: Successfully installed `{{.PACKAGE}}`
    cmds:
      - task: brew
      - |
        if [ -n "$CI" ]; then echo "*************** brew formulae --> {{.PACKAGE}}"; fi
      - brew install {{.PACKAGE}}
    status:
      - type {{.BIN}} &> /dev/null || [ -n "$NO_INSTALL_HOMEBREW" ]

  jq:
    tags:
      - update
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: jq
      - task: install:software
        vars:
          PACKAGE: jq
    status:
      - type jq > /dev/null

  kvm:
    run: once
    cmds:
      - task: :install:install-doctor
        vars:
          SOFTWARE: kvm
      - task: exit:notice:restart
    status:
      - type qemu-system-x86_64 > /dev/null

  node:
    deps:
      - common
      - volta
    run: once
    cmds:
      - task: node:install
    status:
      - type node &> /dev/null

  node:install:
    cmds:
      - |
        . "$HOME/.profile" &> /dev/null || true
        volta install node

  openssl:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: openssl

  p7zip:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: 7z
          PACKAGE: p7zip

  packer:
    run: once
    tags:
      - semantic-packer
    cmds:
      - task: install:software
        vars:
          PACKAGE: packer

  parallels:
    run: once
    cmds:
      - task: brew:cask
        vars:
          CASK: parallels
    status:
      - '[ "{{OS}}" != "darwin" ] || ! mdfind -name "Parallels Desktop.app" &> /dev/null'

  pinentry:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: pinentry-mac
    status:
      - '[ "{{OS}}" != "darwin" ] || [ -f /usr/local/bin/pinentry-mac ]'

  pipx:
    tags:
      - update
    run: once
    log:
      error: Failed to ensure `pipx` is installed
      start: Ensuring `pipx` is installed
      success: Successfully ensured `pipx` is installed
    cmds:
      - task: python
      - task: pipx:{{OS}}
    status:
      - type pipx > /dev/null

  pipx:darwin:
    cmds:
      - task: brew
      - brew install pipx
      - pipx ensurepath

  pipx:linux:
    deps:
      - pipx:linux:brew
      - pipx:linux:system

  pipx:linux:brew:
    cmds:
      - brew install pipx
      - pipx ensurepath
    status:
      - '! type brew > /dev/null'

  pipx:linux:system:
    deps:
      - python
    cmds:
      - task: system
        vars:
          PACKAGE: python3-pip
      - task: system
        vars:
          PACKAGE: python3-venv
      - |
        if ! type pip3; then
          python3 -m ensurepip > /dev/null
        fi
      - python3 -m pip install --user pipx
      - python3 -m pipx ensurepath
    status:
      - type brew > /dev/null

  pipx:windows:
    log:
      error: These scripts are not currently compatible with Windows. Try using WSL.
    cmds:
      - exit 1

  poetry:
    tags:
      - update
    run: once
    cmds:
      - task: poetry:{{OS}}
      - task: exit:notice:reload
    status:
      - type poetry > /dev/null || [ -n "$NO_INSTALL_POETRY" ]

  poetry:darwin:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: poetry

  poetry:linux:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: poetry

  poetry:windows:
    log:
      error: These scripts are not currently compatible with Windows. Try using WSL.
    cmds:
      - exit 1

  python:
    deps:
      - common
    run: once
    cmds:
      - task: brew
      - task: python:{{OS}}
    status:
      - type python3 > /dev/null

  python:darwin:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: python@3.10
    status:
      - type python3 > /dev/null

  python:linux:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: python@3.10
    status:
      - type python3 > /dev/null

  python:pip:
    run: once
    cmds:
      - |
        PIP_LOCATION="$(which pip)"
        PIP3_LOCATION="$(which pip3)"
        if [ "$USER" == "root" ]; then
          if type pip &> /dev/null && type pip3 &> /dev/null; then
            rm "$PIP_LOCATION"
            ln -s "$PIP3_LOCATION" "$PIP_LOCATION"
          elif type pip3 &> /dev/null; then
            ln -s "$PIP3_LOCATION" /usr/bin/pip
          elif type pip &> /dev/null; then
            ln -s "$PIP_LOCATION" /usr/bin/pip3
          else
            .config/log warn 'Both `pip` and `pip3` appear to be missing'
          fi
        elif type sudo &> /dev/null && sudo -n true; then
          if type pip &> /dev/null && type pip3 &> /dev/null; then
            sudo rm "$PIP_LOCATION"
            sudo ln -s "$PIP3_LOCATION" "$PIP_LOCATION"
          elif type pip3 &> /dev/null; then
            sudo ln -s "$PIP3_LOCATION" /usr/bin/pip
          elif type pip &> /dev/null; then
            sudo ln -s "$PIP_LOCATION" /usr/bin/pip3
          else
            .config/log warn 'Both `pip` and `pip3` appear to be missing'
          fi
        elif type sudo &> /dev/null; then
          if type pip &> /dev/null && type pip3 &> /dev/null; then
            .config/log info 'Running `sudo rm $(which pip)`'
            sudo rm "$PIP_LOCATION"
            sudo ln -s "$PIP3_LOCATION" "$PIP_LOCATION"
          elif type pip3 &> /dev/null; then
            .config/log info 'Running `sudo ln -s $(which pip3) /usr/bin/pip`'
            sudo ln -s "$PIP3_LOCATION" /usr/bin/pip
          elif type pip &> /dev/null; then
            .config/log info 'Running `sudo ln -s $(which pip) /usr/bin/pip3`'
            sudo ln -s "$PIP_LOCATION" /usr/bin/pip3
          else
            .config/log warn 'Both `pip` and `pip3` appear to be missing'
          fi
        else
           .config/log warn '`sudo` unavailable and user has no permissions'
        fi
    status:
      - which pip > /dev/null
      - which pip3 > /dev/null
      - '[ "$(which pip)" == "$(which pip3)" ]'

  python:windows:
    log:
      error: These scripts are not currently compatible with Windows. Try using WSL.
    cmds:
      - exit 1

  rsync:
    tags:
      - update
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: rsync
      - task: install:software
        vars:
          PACKAGE: rsync
    status:
      - type rsync > /dev/null

  rust:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: cargo
          PACKAGE: rust

  s5cmd:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: s5cmd
          PACKAGE: peak/tap/s5cmd

  sentry:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: sentry-cli
          PACKAGE: getsentry/tools/sentry-cli

  snapcraft:
    run: once
    tags:
      - semantic
    cmds:
      - task: snapcraft:snap
      - task: install:software
        vars:
          PACKAGE: snapcraft
    status:
      - type snapcraft > /dev/null

  snapcraft:snap:
    log:
      error: Failed to run `sudo snap install snapcraft --classic`
      start: Running `sudo snap install snapcraft --classic`
      success: Successfully installed `snapcraft`
    cmds:
      - sudo snap install snapcraft --classic
    status:
      - '! type snap > /dev/null'

  sshfs:
    run: once
    cmds:
      - task: system
        vars:
          PACKAGE: sshfs

  sshpass:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: hudochenkov/sshpass/sshpass

  subrepo:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: git-subrepo
    status:
      - git subrepo --version > /dev/null || [[ "${container:=}" == "docker" ]]

  system:
    vars:
      PACKAGE: '{{if .PACKAGE}}{{.PACKAGE}}{{else}}{{.CLI_ARGS}}{{end}}'
    cmds:
      - .config/log start 'Attempting to install `{{.PACKAGE}}` using the system package manager'
      - |
        if [ -f "/etc/redhat-release" ]; then
          if type dnf &> /dev/null; then
            task install:software:system:dnf -- '{{.PACKAGE}}'
          else
            task install:software:system:yum -- '{{.PACKAGE}}'
          fi
        elif [ -f "/etc/debian_version" ]; then
          task install:software:system:apt-get -- '{{.PACKAGE}}'
        elif [ -f "/etc/arch-release" ]; then
          task install:software:system:pacman -- '{{.PACKAGE}}'
        elif [ -f "/etc/alpine-release" ]; then
          task install:software:system:apk -- '{{.PACKAGE}}'
        elif type dnf &> /dev/null; then
          task install:software:system:dnf -- '{{.PACKAGE}}'
        elif type yum &> /dev/null; then
          task install:software:system:yum -- '{{.PACKAGE}}'
        elif type apt-get &> /dev/null; then
          task install:software:system:apt-get -- '{{.PACKAGE}}'
        elif type pacman &> /dev/null; then
          task install:software:system:pacman -- '{{.PACKAGE}}'
        elif type apk &> /dev/null; then
          task install:software:system:apk -- '{{.PACKAGE}}'
        else
          if [ '{{OS}}' == 'darwin' ]; then
            task install:software:system:macos -- '{{.PACKAGE}}'
          else
            .config/log error 'No matching system. Cannot continue with installation.' && exit 1
          fi
        fi
    status:
      - type {{.PACKAGE}} > /dev/null || [ '{{.PACKAGE}}' == 'null' ]

  system:apk:
    vars:
      PACKAGE: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}{{.PACKAGE}}{{end}}'
    cmds:
      - |
        if [ "$USER" == "root" ]; then
          apk --no-cache add {{.PACKAGE}}
        elif type sudo &> /dev/null && sudo -n true; then
          sudo apk --no-cache add {{.PACKAGE}}
        elif type sudo &> /dev/null; then
          .config/log info 'Running `sudo apk --no-cache add {{.PACKAGE}}`'
          sudo apk --no-cache add {{.PACKAGE}}
        else
          .config/log warn '`sudo` unavailable and user has no permissions'
        fi
    status:
      - '[ -z "$(which apk)" ]'

  system:apt-get:
    vars:
      PACKAGE: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}{{.PACKAGE}}{{end}}'
    cmds:
      - |
        if [ "$USER" == "root" ]; then
          apt-get update
          apt-get install -y {{.PACKAGE}}
        elif type sudo &> /dev/null && sudo -n true; then
          sudo apt-get update
          sudo apt-get install -y {{.PACKAGE}}
        elif type sudo &> /dev/null; then
          .config/log info 'Running `sudo apt-get update`'
          sudo apt-get update
          .config/log info 'Running `sudo apt-get install -y {{.PACKAGE}}`'
          sudo apt-get install -y {{.PACKAGE}}
        else
           .config/log warn '`sudo` unavailable and user has no permissions'
        fi
    status:
      - '[ -z "$(which apt-get)" ]'

  system:dnf:
    vars:
      PACKAGE: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}{{.PACKAGE}}{{end}}'
    cmds:
      - |
        if [ "$USER" == "root" ]; then
          dnf install {{.PACKAGE}}
        elif type sudo &> /dev/null && sudo -n true; then
          sudo dnf install {{.PACKAGE}}
        elif type sudo &> /dev/null; then
          .config/log info 'Running `sudo dnf install {{.PACKAGE}}`'
          sudo dnf install {{.PACKAGE}}
        else
           .config/log warn '`sudo` unavailable and user has no permissions'
        fi
    status:
      - '[ -z "$(which dnf)" ]'

  system:macos:
    vars:
      PACKAGE: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}{{.PACKAGE}}{{end}}'
    cmds:
      - brew install {{.PACKAGE}}
    status:
      - '[ "{{OS}}" != "darwin" ]'

  system:pacman:
    vars:
      PACKAGE: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}{{.PACKAGE}}{{end}}'
    cmds:
      - |
        if [ "$USER" == "root" ]; then
          pacman -S {{.PACKAGE}}
        elif type sudo &> /dev/null && sudo -n true; then
          sudo pacman -S {{.PACKAGE}}
        elif type sudo &> /dev/null; then
          .config/log info 'Running `sudo pacman -S {{.PACKAGE}}`'
          sudo pacman -S {{.PACKAGE}}
        else
           .config/log warn '`sudo` unavailable and user has no permissions'
        fi
    status:
      - '[ -z "$(which pacman)" ]'

  system:yum:
    vars:
      PACKAGE: '{{if .CLI_ARGS}}{{.CLI_ARGS}}{{else}}{{.PACKAGE}}{{end}}'
    cmds:
      - |
        if [ "$USER" == "root" ]; then
          yum install -y {{.PACKAGE}}
        elif type sudo &> /dev/null && sudo -n true; then
          sudo yum install -y {{.PACKAGE}}
        elif type sudo &> /dev/null; then
          .config/log info 'Running `sudo yum install -y {{.PACKAGE}}`'
          sudo yum install -y {{.PACKAGE}}
        else
           .config/log warn '`sudo` unavailable and user has no permissions'
        fi
    status:
      - '[ -z "$(which yum)" ]'

  task:
    run: once
    cmds:
      - |
        if [[ "$(which task)" == *'.local/bin/task' ]] && command -v brew > /dev/null && ! brew list go-task/tap/go-task; then
          brew install go-task/tap/go-task
        fi

  tokei:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: tokei

  trivy:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: aquasecurity/trivy/trivy

  unbuffer:
    run: once
    cmds:
      - task: install:software
        vars:
          BIN_NAME: unbuffer
          PACKAGE: expect

  vagrant:
    cmds:
      - task: vagrant:{{OS}}
    status:
      - type vagrant > /dev/null

  vagrant:darwin:
    run: once
    cmds:
      - task: brew:cask
        vars:
          CASK: vagrant

  vagrant:linux:
    run: once
    cmds:
      - task: :install:install-doctor
        vars:
          SOFTWARE: vagrant

  virtualbox:
    cmds:
      - task: virtualbox:{{OS}}
      - task: exit:notice:restart
    status:
      - type vboxmanage > /dev/null

  virtualbox:darwin:
    run: once
    cmds:
      - task: brew:cask
        vars:
          CASK: virtualbox

  virtualbox:linux:
    run: once
    cmds:
      - task: :install:install-doctor
        vars:
          SOFTWARE: virtualbox

  vmware:
    cmds:
      - task: vmware:{{OS}}
      - task: exit:notice:restart
    status:
      - type vmrun > /dev/null

  vmware:darwin:
    run: once
    cmds:
      - task: brew:cask
        vars:
          CASK: vmware-fusion

  vmware:linux:
    run: once
    cmds:
      - task: :install:install-doctor
        vars:
          SOFTWARE: vmware

  volta:
    run: once
    cmds:
      - .config/log info 'Installing Volta'
      - curl https://get.volta.sh | bash
      - |
        . "$HOME/.profile" &> /dev/null || true
        volta setup
      - .config/log success 'Successfully setup Volta'
    status:
      - type volta > /dev/null

  yarn:
    tags:
      - update
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: yarn

  yq:
    tags:
      - update
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: yq

  yubikey-agent:
    run: once
    cmds:
      - task: install:software
        vars:
          PACKAGE: yubikey-agent
