version: 2

defaults: &defaults
  working_directory: /go/src/github.com/cosmos/cosmos-sdk
  docker:
    - image: circleci/golang:1.10.3
  environment:
    GOBIN: /tmp/workspace/bin

jobs:
  setup_dependencies:
    <<: *defaults
    steps:
      - run: mkdir -p /tmp/workspace/bin
      - run: mkdir -p /tmp/workspace/profiles
      - checkout
      - restore_cache:
          keys:
            - v1-pkg-cache
      - run:
          name: tools
          command: |
            export PATH="$GOBIN:$PATH"
            make get_tools
      - run:
          name: dependencies
          command: |
            export PATH="$GOBIN:$PATH"
            make get_vendor_deps
      - run:
          name: binaries
          command: |
            export PATH="$GOBIN:$PATH"
            make install
            make install_examples
      - persist_to_workspace:
          root: /tmp/workspace
          paths:
            - bin
            - profiles
      - save_cache:
          key: v1-pkg-cache
          paths:
            - /go/pkg
      - save_cache:
          key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
          paths:
            - /go/src/github.com/cosmos/cosmos-sdk

  lint:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - restore_cache:
          key: v1-pkg-cache
      - restore_cache:
          key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
      - run:
          name: Get metalinter
          command: |
            export PATH="$GOBIN:$PATH"
            make get_tools
      - run:
          name: Lint source
          command: |
            export PATH="$GOBIN:$PATH"
            make test_lint
  test_unit:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - restore_cache:
          key: v1-pkg-cache
      - restore_cache:
          key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
      - run:
          name: Test unit
          command: |
            export PATH="$GOBIN:$PATH"
            make test_unit

  test_cli:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - restore_cache:
          key: v1-pkg-cache
      - restore_cache:
          key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
      - run:
          name: Test cli
          command: |
            export PATH="$GOBIN:$PATH"
            make test_cli_retry

  test_cover:
    <<: *defaults
    parallelism: 1
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - restore_cache:
          key: v1-pkg-cache
      - restore_cache:
          key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
      - run:
          name: Run tests
          command: |
            export PATH="$GOBIN:$PATH"
            make install
            for pkg in $(go list github.com/cosmos/cosmos-sdk/... | grep -v /vendor/ | grep -v github.com/cosmos/cosmos-sdk/cmd/gaia/cli_test | circleci tests split --split-by=timings); do
              id=$(basename "$pkg")

              go test -timeout 8m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg"
            done
      - persist_to_workspace:
          root: /tmp/workspace
          paths:
            - "profiles/*"

  upload_coverage:
    <<: *defaults
    steps:
      - attach_workspace:
          at: /tmp/workspace
      - restore_cache:
          key: v1-tree-{{ .Environment.CIRCLE_SHA1 }}
      - run:
          name: gather
          command: |
            set -ex

            echo "mode: atomic" > coverage.txt
            for prof in $(ls /tmp/workspace/profiles/); do
              tail -n +2 /tmp/workspace/profiles/"$prof" >> coverage.txt
            done
      - run:
          name: upload
          command: bash <(curl -s https://codecov.io/bash) -f coverage.txt

workflows:
  version: 2
  test-suite:
    jobs:
      - setup_dependencies
      - lint:
          requires:
            - setup_dependencies
      - test_cli:
          requires:
            - setup_dependencies
      - test_unit:
          requires:
            - setup_dependencies
      - test_cover:
          requires:
            - setup_dependencies
      - upload_coverage:
          requires:
            - test_cover
