language: cpp
sudo: false

matrix:
  include:

    # bionic 18
    # 2
    - os: linux
      dist: Bionic
      env: BADGE=linux BUILD_TYPE=debug
      addons:
        apt:
          update: true
          packages:
            - ninja-build

    # Clang 4.0 address sanitizer
    # 3
    - os: linux
      dist: Bionic
      env: BADGE=linux BUILD_TYPE=asan C_COMPILER=clang-4.0 CXX_COMPILER=clang++-4.0
      addons:
        apt:
          sources:
            - ubuntu-toolchain-r-test
            - llvm-toolchain-precise-4.0
          packages:
            - clang-4.0

    # GCC 6
    # 4
    - os: linux
      dist: Bionic
      env: BADGE=linux C_COMPILER=gcc-6 CXX_COMPILER=g++-6
      addons:
        apt:
          update: true
          sources:
            - ubuntu-toolchain-r-test
          packages:
            - gcc-6
            - g++-6
            - ninja-build

    # OSX
    # 5
    - os: osx
      env: BADGE=osx BUILD_TYPE=debug

    # 6
    - os: osx
      env: BADGE=osx BUILD_TYPE=release

    # focal 20
    # 7
    - os: linux
      dist: focal
      env: BADGE=linux BUILD_TYPE=debug
      addons:
        apt:
          update: true
          packages:
            - ninja-build

    # 8
    - os: linux
      dist: focal
      env: BADGE=linux BUILD_TYPE=release
      addons:
        apt:
          update: true
          packages:
            - ninja-build

    # 9
    - os: linux
      dist: focal
      env: BADGE=linux BUILD_TYPE=release NO_MACRO_VARARG=1

    ### Clang address sanitizer
    ### 10
    ##- os: linux
    ##  dist: focal
    ##  env: BADGE=linux BUILD_TYPE=asan C_COMPILER=clang-12.0 CXX_COMPILER=clang++-12.0
    ##  addons:
    ##    apt:
    ##      sources:
    ##        - ubuntu-toolchain-r-test
    ##        - llvm-toolchain-precise-12.0
    ##      packages:
    ##        - clang-12.0

    # mingw-w64 Win64 cross-compile
    # 11
    - os: linux
      dist: focal
      env: BADGE=linux BUILD_TYPE=cross C_COMPILER=x86_64-w64-mingw32-gcc CXX_COMPILER=x86_64-w64-mingw32-g++
      addons:
        apt:
          packages:
            - mingw-w64
            - binutils-mingw-w64
            - binutils-mingw-w64-i686
            - binutils-mingw-w64-x86-64
            - gcc-mingw-w64
            - gcc-mingw-w64-i686
            - gcc-mingw-w64-x86-64
            - g++-mingw-w64
            - g++-mingw-w64-i686
            - g++-mingw-w64-x86-64

    # 12
    - os: linux
      dist: focal
      env: BUILD_TYPE=coverage COVERALLS_TOKEN="Dy94SOU3ajc1VbIy1wnWaNaeIUzfgdtEg"
      compiler: gcc

branches:
  only:
  - master

before_install:
  - |
    if [ "x${BUILD_TYPE}" == "xcoverage" ]; then
      sudo apt-get update
      sudo apt-get install -qy python3-pip lcov
      pip3 install --user --upgrade setuptools
      pip3 install --user --upgrade pip
      pip3 install --user PyYAML
      pip3 install --user --upgrade cpp-coveralls
    fi
  - if [ -n "${C_COMPILER}" ]; then export CC="${C_COMPILER}"; fi
  - if [ -n "${CXX_COMPILER}" ]; then export CXX="${CXX_COMPILER}"; fi
  - ${CXX} --version
  - cmake --version
  - mkdir build
  - cd build
  - type -p ninja && export GENERATOR=-GNinja || true

before_script:
  # to stop the script after an error/warning
  - set -e
  # workarounds for OSX traivs build failure issues:
  # 1. rvm overrides cd with a function so that it can hook into it to run some scripts from the new
  # working directory. The workaround is to revert it to the builtin shell one.
  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then unset -f cd; fi
  # 2. Redefine shell_session_update as a dummy function to avoid travis error:
  # /Users/travis/.rvm/scripts/functions/support: line 57: shell_session_update: command not found.
  - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then shell_session_update() { :; }; fi
  # prepare make files with cmake
  - |-
    case "${BUILD_TYPE}" in
      "coverage")
        cmake ${GENERATOR} -DCMAKE_BUILD_TYPE=Debug -DENABLE_CODECOVERAGE=ON ..
        ;;
      "asan")
        cmake ${GENERATOR} -DCMAKE_BUILD_TYPE=Debug -DENABLE_SANITIZER=address ..
        ;;
      "ubsan")
        cmake ${GENERATOR} -DCMAKE_BUILD_TYPE=Debug -DENABLE_SANITIZER=undefined ..
        ;;
      "cross")
        cmake ${GENERATOR} -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=OFF -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake -DCMAKE_EXE_LINKER_FLAGS="-static -s" ..
        ;;
      "release")
        cmake ${GENERATOR} -DCMAKE_BUILD_TYPE=Release ..
        ;;
      *)
        cmake ${GENERATOR} ..
        ;;
    esac


script:
  # build
  - if [ -f build.ninja ]; then ninja -v; else make VERBOSE=1; fi
  # run all tests
  - if [ "x${BUILD_TYPE}" != "xcross" ]; then ../scripts/run_ctest.py; fi
  # collect coverage (needs to be after running tests)
  - if [ "x${BUILD_TYPE}" == "xcoverage" ]; then make coverage; fi

  # DO NOT REMOVE (debugging purposes)
  #- /home/travis/build/uncrustify/uncrustify/build/uncrustify -l cs -c /home/travis/build/uncrustify/uncrustify/tests/config/U10-Cpp.cfg -f /home/travis/build/uncrustify/uncrustify/tests/input/cs/newlines.mm -L A

after_success:
  # publish coverage data to coveralls
  - if [ "x${BUILD_TYPE}" == "xcoverage" ]; then cd ../ && coveralls -l build/cmake_coverage.output -t $COVERALLS_TOKEN; fi