---
version: '3'

tasks:
  all:
    deps:
      - ':{{if eq .REPOSITORY_TYPE "packer"}}packer:update:descriptions{{else}}donothing{{end}}'
      - files
      - :install:tslib
      - :python:requirementstxt
    cmds:
      - task: all:continue

  all:continue:
    deps:
      - :git:remotes
      - ':{{if eq .REPOSITORY_SUBTYPE "playbook"}}ansible:playbook:remotes{{else}}donothing{{end}}'
      - all:docs

  all:docs:
    cmds:
      - task: '{{if eq .REPOSITORY_TYPE "common"}}:donothing{{else}}{{if eq .REPOSITORY_TYPE "documentation"}}:donothing{{else}}all:docs:generate{{end}}{{end}}'

  all:docs:generate:
    deps:
      - contributing
      - readme

  ansible:
    deps:
      - :ansible:populate:dependencies
      - :ansible:populate:meta
      - :ansible:update:galaxy-id

  contributing:
    deps:
      - :install:npm:prettier
      - :install:npm:readme
    vars:
      CONTRIB_TEMPLATE: .config/docs/blueprint-contributing.md
    log:
      error: Encountered error while generating `docs/CONTRIBUTING.md`
      start: Generating `docs/CONTRIBUTING.md` using document partials
      success: Successfully generated `docs/CONTRIBUTING.md`
    cmds:
      - mkdir -p docs
      - >
        {{.NPX_HANDLE}}readme generate --silent --headingPrefix '{}' --config .variables.json
        --input "{{.CONTRIB_TEMPLATE}}" --output docs/CONTRIBUTING.md
      - task: markdown:scrub
        vars:
          SCRUB_FILE: docs/CONTRIBUTING.md
      - '{{.NPX_HANDLE}}prettier --write docs/CONTRIBUTING.md > /dev/null'
    sources:
      - docs/CONTRIBUTING.md
      - .config/docs/**/*
      - .variables.json
    preconditions:
      - sh: test -f .config/docs/blueprint-contributing.md
        msg: The CONTRIBUTING.md template file is not present at `.config/docs/blueprint-contributing.md`
      - sh: test -f .variables.json
        msg: The `.variables.json` file is not present.
      - sh: type readme > /dev/null
        msg: '`@appnest/readme` is not installed globally.'

  files:
    vars:
      CONTAINER:
        sh: if [[ "${container:=}" == "docker" ]]; then echo "docker"; fi
      FIRST_LINE:
        sh: if [ -f Dockerfile ]; then head -n 1 Dockerfile; fi
    log:
      error: Encountered error while updating miscellaneous files
      start: Updating miscellaneous files
      success: Updated miscellaneous files
    cmds:
      - |
        {{if eq .REPOSITORY_SUBTYPE "ci-pipeline"}}
          if [[ "{{.FIRST_LINE}}" == *"debian"* ]] || [[ "{{.FIRST_LINE}}" == *"ubuntu"* ]]; then
            cp .config/initctl initctl
            .config/log info 'Added initctl faker file to repository root'
          fi
        {{else}}
          true
        {{end}}
      - |
        if [ -f .dockerignore ]; then
          TMP="$(mktemp)"
          echo '# To keep changes, only add items to end of file' > "$TMP"
          cat .gitignore >> "$TMP"
          if [ ! -f .config/dockerignore ]; then
            curl -sSL https://gitlab.com/megabyte-labs/common/shared/-/raw/master/common/.config/dockerignore > .config/dockerignore
          fi
          cat .config/dockerignore >> "$TMP"
          echo '# Saved entries below' >> "$TMP"
          cat .dockerignore >> "$TMP"
          mv "$TMP" .dockerignore
        elif [ '{{.PROJECT_TYPE}}' == 'project' ]; then
          rm .config/dockerignore
        fi
      - task: :common:{{if eq .CONTAINER "docker"}}husky:ci{{else}}husky{{end}}
      - task: :{{if eq .REPOSITORY_SUBTYPE "role"}}ansible:keywords:sync{{else}}donothing{{end}}

  init:
    log:
      error: Encountered error while initializing project
      start: Ensuring project is initialized
    cmds:
      - |
        if ! test -f package.json; then
          echo '{"blueprint": {}}' > package.json
        fi
    status:
      - test -f package.json

  man-page:
    deps:
      - :install:modules:local
      - :install:npm:remark
      - :install:npm:prettier
      - :install:npm:readme
    vars:
      MAN_TEMPLATE: '{{.REPOSITORY_SUBTYPE}}-blueprint-man.md'
    cmds:
      - |
        if test -f ".config/docs/{{.MAN_TEMPLATE}}"; then
          {{.NPX_HANDLE}}readme generate --headingPrefix '{}' --silent --config .variables.json --input ".config/docs/{{.MAN_TEMPLATE}}" --output MAN.md
          {{.NPX_HANDLE}}prettier --write MAN.md > /dev/null
          .config/log info 'Generated MAN.md'
          mkdir -p dist
          {{.NPX_HANDLE}}remark --use man MAN.md --output dist/man
          .config/log success 'Converted MAN.md to man page located in `dist/man`'
          rm MAN.md
        fi
    sources:
      - .config/docs/**/*
      - .variables.json
      - dist/man
    preconditions:
      - sh: test -f .variables.json
        msg: The `.variables.json` file is not present.

  markdown:scrub:
    vars:
      DIVIDER_SRC: <a href="\1" style="width:100%"><img style="width:100%"
        src="https://gitlab.com/megabyte-labs/assets/-/raw/master/png/aqua-divider.png" /></a>
      REGEX: .*https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/.*.png)][(]\(.*\)[)].*$
    cmds:
      - task: markdown:scrub:{{OS}}
        vars:
          DIVIDER_SRC: '{{.DIVIDER_SRC}}'
          REGEX: '{{.REGEX}}'
          SCRUB_FILE: '{{.SCRUB_FILE}}'

  markdown:scrub:darwin: /usr/bin/sed -i .bak 's^{{.REGEX}}^{{.DIVIDER_SRC}}^g' {{.SCRUB_FILE}} && rm {{.SCRUB_FILE}}.bak

  markdown:scrub:linux: sed -i 's^{{.REGEX}}^{{.DIVIDER_SRC}}^g' {{.SCRUB_FILE}}

  modules:
    deps:
      - :install:software:git
    summary: |
      # Ensure all submodules in `.modules/` are updated

      Some of our projects include submodules. These submodules are generally
      stored in the `.modules/` folder in the root of the project. Some projects
      might symlink files to one of the submodules stored in the `.modules/` folder.
      If you are ok with the risk, you can use this task to update all the submodules
      to the latest on the remote's master branch.
    log:
      error: Failed to ensure submodules in the `.modules/` folder are up-to-date
      start: Ensuring submodules in the `.modules/` folder are up-to-date
      success: Successfully ensured submodules in the `.modules/` folder are up-to-date
    cmds:
      - |
        ROOT_DIR="$PWD"
        if ls .modules/*/ > /dev/null 2>&1; then
          for SUBMODULE_PATH in .modules/*/; do
            cd $SUBMODULE_PATH
            DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
            git reset --hard HEAD
            git checkout "$DEFAULT_BRANCH"
            git pull origin "$DEFAULT_BRANCH" --ff-only || true
          done
          cd "$ROOT_DIR"
          .config/log success 'Ensured submodules in the `.modules` folder are pointing to the master branch'
        fi
    status:
      - '! ls .modules/*/ > /dev/null 2>&1'

  project:
    log:
      start: Pulling `master` if `origin` is defined
    cmds:
      - |
        if [ -d .git ] && git branch -r | grep origin > /dev/null; then
          git pull origin master --no-rebase || true
        fi

  readme:
    deps:
      - ':{{if eq .REPOSITORY_TYPE "ansible"}}ansible:collection-dependencies:markdown{{else}}donothing{{end}}'
      - ':{{if eq .REPOSITORY_SUBTYPE "role"}}ansible:mod-ansible-autodoc{{else}}donothing{{end}}'
      - :install:npm:prettier
      - :install:npm:readme
    vars:
      README_TEMPLATE: blueprint-readme-{{.REPOSITORY_SUBTYPE}}.md
    log:
      error: Error encountered while generating `README.md`
      start: Generating `README.md`
      success: Generated README.md successfully
    cmds:
      - >
        {{.NPX_HANDLE}}readme generate --headingPrefix '{}' --silent --config .variables.json
        --input ".config/docs/{{.README_TEMPLATE}}"
      - task: markdown:scrub
        vars:
          SCRUB_FILE: README.md
      - task: ':{{if eq .REPOSITORY_TYPE "packer"}}packer:update:readme{{else}}donothing{{end}}'
      - '{{.NPX_HANDLE}}prettier --write README.md > /dev/null'
    sources:
      - .autodoc/*
      - .config/docs/**/*
      - .variables.json
      - README.md
    preconditions:
      - sh: 'test -f .config/docs/{{.README_TEMPLATE}}'
        msg: 'The README.md template file is not present at `.config/docs/{{.README_TEMPLATE}}`.'
      - sh: test -f .variables.json
        msg: The `.variables.json` file is not present.

  repositories:
    cmds:
      - task: modules
      - task: project

  services:
    cmds:
      - task: :{{if eq .REPOSITORY_TYPE "project"}}donothing{{else}}start{{end}}
      - task: update
      - task: services:repos

  services:repos:
    deps:
      - :git:update

  start:
    deps:
      - :common:requirements
      - variables

  update:
    deps:
      - ':{{if eq .REPOSITORY_SUBTYPE "role"}}common:update:ansible{{else}}donothing{{end}}'
      - ':{{if eq .REPOSITORY_TYPE "packer"}}packer:latestos{{else}}donothing{{end}}'
      - init
      - repositories
    summary: |
      # Refresh project with latest upstream code and ensure project files are up-to-date

      This task will pull the latest upstream code and overwrite any files that are out of date.
      Ideally, you should run this task often to ensure there are no merge conflicts and to
      ensure you are using the latest production settings. This task is also run by CI so
      normally if you pull the latest changes, you should already have the updates that this
      task applies.

      **Example usage:**
      `task update`
    run: once
    cmds:
      - task: start
      - task: all
      - task: ':{{if eq .REPOSITORY_TYPE "docker"}}docker:update:labels{{else}}donothing{{end}}'
      - task: update:git

  update:git:
    cmds:
      - task: :git:update
    status:
      - '[[ "${container:=}" == "docker" ]] || [[ "$SKIP_UPLOADING" == "true" ]]'

  variables:
    deps:
      - :install:software:jq
    cmds:
      - task: :upstream:variables
        vars:
          INPUT_FILE: .config/variables.json
          OUTPUT_FILE: .variables.json
      - task: ':{{if eq .REPOSITORY_TYPE "go"}}{{if eq .REPOSITORY_SUBTYPE "cli"}}go:help{{else}}donothing{{end}}{{else}}donothing{{end}}'
      - task: ':{{if eq .REPOSITORY_TYPE "packer"}}packer:update:variables{{else}}donothing{{end}}'
      - task: ':{{if eq .REPOSITORY_TYPE "ansible"}}ansible:update:variables{{if eq .REPOSITORY_SUBTYPE "playbook"}}:playbook{{end}}{{else}}donothing{{end}}'
