version: "3"

includes:
  dist: ./DistTasks.yml

tasks:
  docs:gen:commands:
    desc: Generate command reference files
    dir: ./docsgen
    cmds:
      # docs will generate examples using os.Args[0] so we need to call
      # the generator `arduino-cli`
      - go build -o arduino-cli
      # we invoke `arduino-cli` like this instead of `./arduino-cli` to remove
      # the `./` chars from the examples
      - PATH=. arduino-cli ../docs/commands
      - task: docs:format

  docs:gen:protobuf:
    desc: Generate markdown contents for protobuffers
    cmds:
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,commands.md --proto_path=rpc ./rpc/cc/arduino/cli/commands/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,monitor.md --proto_path=rpc ./rpc/cc/arduino/cli/monitor/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,settings.md --proto_path=rpc ./rpc/cc/arduino/cli/settings/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,debug.md --proto_path=rpc ./rpc/cc/arduino/cli/debug/v1/*.proto'
      - task: docs:format

  docs:gen:
    desc: Generate documentation files
    cmds:
      - task: docs:gen:commands
      - task: docs:gen:protobuf

  docs:build:
    desc: Build documentation website contents
    deps:
      - docs:gen:commands
      - docs:gen:protobuf
    cmds:
      - mkdocs build -s

  docs:publish:
    desc: Use Mike to build and push versioned docs
    deps:
      - docs:gen:commands
      - docs:gen:protobuf
    cmds:
      - mike deploy -u -p -r {{.DOCS_REMOTE}} {{.DOCS_VERSION}} {{.DOCS_ALIAS}}

  docs:serve:
    desc: Run documentation website locally
    deps:
      - docs:build
    cmds:
      - mkdocs serve

  docs:check:
    desc: Run documentation linting
    cmds:
      - npx {{ .PRETTIER }} --check "**/*.md"

  docs:check-links:
    desc: Verifies there are no dead links in documentation
    cmds:
      - |
        npx -p markdown-link-check -c '
        STATUS=0
        for file in $(find docs -name "*.md") README.md test/README.md client_example/README.md; do
          markdown-link-check -c markdown-link-check-config.json -q "$file"
          STATUS=$(( $STATUS + $? ))
        done
        exit $STATUS'

  docs:format:
    desc: Automatically formats documentation
    cmds:
      - npx {{ .PRETTIER }} --write "**/*.md"

  protoc:
    desc: Lint, format and compile protobuf definitions
    deps:
      - protoc:check
      - protoc:format
      - protoc:compile

  protoc:compile:
    desc: Compile protobuf definitions
    cmds:
      - '{{ default "protoc" .PROTOC_BINARY }} --proto_path=rpc --go_out=plugins=grpc,paths=source_relative:rpc ./rpc/cc/arduino/cli/commands/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --proto_path=rpc --go_out=plugins=grpc,paths=source_relative:rpc ./rpc/cc/arduino/cli/monitor/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --proto_path=rpc --go_out=plugins=grpc,paths=source_relative:rpc ./rpc/cc/arduino/cli/settings/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --proto_path=rpc --go_out=plugins=grpc,paths=source_relative:rpc ./rpc/cc/arduino/cli/debug/v1/*.proto'

  protoc:docs:
    desc: Generate docs for protobuf definitions
    cmds:
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,commands.md --proto_path=rpc ./rpc/cc/arduino/cli/commands/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,monitor.md --proto_path=rpc ./rpc/cc/arduino/cli/monitor/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,settings.md --proto_path=rpc ./rpc/cc/arduino/cli/settings/v1/*.proto'
      - '{{ default "protoc" .PROTOC_BINARY }} --doc_out=./docs/rpc --doc_opt=markdown,debug.md --proto_path=rpc ./rpc/cc/arduino/cli/debug/v1/*.proto'

  protoc:check:
    desc: Perform linting of the protobuf definitions
    cmds:
      - buf lint rpc

  protoc:format:
    desc: Perform formatting of the protobuf definitions
    cmds:
      - clang-format -i rpc/cc/arduino/cli/*/*/*.proto

  build:
    desc: Build the project
    cmds:
      - go build -v {{.LDFLAGS}}

  test:
    desc: Run the full testsuite, `legacy` will be skipped
    cmds:
      - task: test-unit
      - task: test-integration

  test-unit:
    desc: Run unit tests only
    cmds:
      - go test -short -run '{{ default ".*" .TEST_REGEX }}' {{ default "-v" .GOFLAGS }} -coverprofile=coverage_unit.txt {{ default .DEFAULT_TARGETS .TARGETS }} {{.TEST_LDFLAGS}}

  test-integration:
    desc: Run integration tests only
    cmds:
      - poetry install --no-root
      - poetry run pytest test

  test-legacy:
    desc: Run tests for the `legacy` package
    cmds:
      - go test {{ default "-v -failfast" .GOFLAGS }} -coverprofile=coverage_legacy.txt ./legacy/...

  test-unit-race:
    desc: Run unit tests only with race condition detection
    cmds:
      - go test -short -race {{ default "-v" .GOFLAGS }} -coverprofile=coverage_race_unit.txt {{ default .DEFAULT_TARGETS .TARGETS }}

  check:
    desc: Check fmt and lint, `legacy` will be skipped
    cmds:
      - test -z $(go fmt {{ default .DEFAULT_TARGETS .TARGETS }})
      - go vet {{ default .DEFAULT_TARGETS .TARGETS }}
      - "'{{.GOLINTBIN}}' {{.GOLINTFLAGS}} {{ default .DEFAULT_TARGETS .TARGETS }}"
      - task: i18n:check
      - task: python:check
      - task: docs:check
      - task: config:check
      - task: protoc:check

  config:check:
    desc: Check linting of configuration and supporting files
    cmds:
      - npx {{ .PRETTIER }} --check "**/*.{yml,yaml}"

  config:format:
    desc: Automatically formats configuration and supporting files
    cmds:
      - npx {{ .PRETTIER }} --write "**/*.{yml,yaml}"

  python:check:
    desc: Linting for Python files
    cmds:
      - poetry install --no-root
      - poetry run flake8

  python:format:
    desc: Automatically formats Python files
    cmds:
      - poetry install --no-root
      - poetry run black .

  check-legacy:
    desc: Check fmt and lint for the `legacy` package
    cmds:
      - test -z $(go fmt ./legacy/...)
      - go vet ./legacy/...

  rpc-client:
    desc: Run the rpc client test routine (server must be already started)
    cmds:
      - go test -run TestWithClientE2E ./commands/daemon

  i18n:update:
    desc: Updates i18n files
    cmds:
      - go run ./i18n/cmd/main.go catalog generate . > ./i18n/data/en.po
      - task: i18n:generate

  i18n:pull:
    desc: Pull i18n files from transifex
    cmds:
      - go run ./i18n/cmd/main.go transifex pull ./i18n/data
      - task: i18n:generate

  i18n:push:
    desc: Push i18n files to transifex
    cmds:
      - go run ./i18n/cmd/main.go transifex push ./i18n/data

  i18n:check:
    desc: Check if the i18n message catalog was updated
    cmds:
      - task: i18n:update
      - git add -N ./i18n/data
      - git diff --exit-code ./i18n/data

  i18n:generate:
    desc: Generate embedded i18n catalog files
    cmds:
      - git add -N ./i18n/data
      - git diff --exit-code ./i18n/data &> /dev/null || (cd ./i18n && rice embed-go)

vars:
  PROJECT_NAME: "arduino-cli"
  DIST_DIR: "dist"
  # all modules of this project except for "legacy/..." module
  DEFAULT_TARGETS:
    sh: echo `go list ./... | grep -v legacy | tr '\n' ' '`
  # build vars
  COMMIT:
    sh: echo "$(git log -n 1 --format=%h)"
  TIMESTAMP:
    sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
  TIMESTAMP_SHORT:
    sh: echo "{{now | date "20060102"}}"
  TAG:
    sh: echo "`git tag --points-at=HEAD 2> /dev/null | head -n1`"
  VERSION: "{{ if .NIGHTLY }}nightly-{{ .TIMESTAMP_SHORT }}{{ else if .TAG }}{{ .TAG }}{{ else }}{{ .PACKAGE_NAME_PREFIX }}git-snapshot{{ end }}"
  LDFLAGS: >
    -ldflags
    '
    -X github.com/arduino/arduino-cli/version.versionString={{.VERSION}}
    -X github.com/arduino/arduino-cli/version.commit={{ .COMMIT }}
    -X github.com/arduino/arduino-cli/version.date={{.TIMESTAMP}}
    '
  # test vars
  GOFLAGS: "-timeout 10m -v -coverpkg=./... -covermode=atomic"
  TEST_VERSION: "0.0.0-test.preview"
  TEST_COMMIT: "deadbeef"
  TEST_LDFLAGS: >
    -ldflags
    '
    -X github.com/arduino/arduino-cli/version.versionString={{.TEST_VERSION}}
    -X github.com/arduino/arduino-cli/version.commit={{.TEST_COMMIT}}
    -X github.com/arduino/arduino-cli/version.date={{.TIMESTAMP}}
    '
  # check-lint vars
  GOLINTBIN:
    sh: go list -f {{"{{"}}".Target{{"}}"}}" golang.org/x/lint/golint
  GOLINTFLAGS: "-min_confidence 0.8 -set_exit_status"
  # docs versioning
  DOCS_VERSION: dev
  DOCS_ALIAS: ""
  DOCS_REMOTE: "origin"
  PRETTIER: prettier@2.0.5
