patterns:
    COMPILER:
        default-values:
            - gcc
            - clang
        short-option: c
        long-option: compiler
    MODE:
        default-values:
            - debug
            - release
        short-option: m
        long-option: mode
    TRIPLET:
        default-values:
            - ""
        long-option: triplet
    ARCHITECTURE:
        default-values:
            - x86_64
        long-option: arch
    TARGET:
        default-values:
            - ""
        short-option: t
        long-option: target
    RUNTARGET:
        default-values:
            - unittest
            - integration
        short-option: r
        long-option: run-target
    MODULE:
        default-values:
            - log
            - config
            - core
            - plugins
            - commander
        short-option: e
        long-option: module
    ANALYZE:
        default-values:
            - cppcheck
            - clang-static-analyzer
            - valgrind
            - pmd
            - lcov
            - clang-tidy
            - coverity
            - format
            - asan
        short-option: a
        long-option: analyze
    DOCSTYPE:
        default-values:
            - html
            - man
            - api-html
            - api-xml
        short-option: o
        long-option: docs-type
    COVERITY_ARCHIVE_NAME:
        default-values:
            - exec-helper_$(git describe).xz
        long-option: coverity-archive-name
    SYSROOT:
        default-values:
            - "/"
        short-option: y
        long-option: sysroot
    SOURCE_TYPE:
        default-values:
            - src
            - test
        long-option: source-type

    FILTER:
        default-values:
            - ""
        short-option: f
        long-option: filter

commands:
    setup: Setup the repository for building
    init: Initialize the build infrastructure
    init-build: Initialize the build infrastructure and switches off everything that has nothing to do with building the exec-helper binaries themselves
    init-no-system: Initialize system and disable the use of all system packages
    init-limited-optimization: Initialize system and build using a sensible trade-off between speed and useful backtraces
    init-windows: Initialize windows build
    build: Build-only + install
    build-only: Build only
    install: Install only
    create-installer: Create Windows installer
    clean: Clean build
    distclean: Distclean build
    rebuild: Clean + build
    analyze: Run the specified analysis tool(s)
    run-test: unittest + integration
    unittest: Run the specified unittests using the specified FILTER
    integration: Run the specified integration tests
    coverage: Run the coverage analysis tools using a specific setup (for convenience)
    memory-check: Run the memory check analysis tool for a specific setup (for convenience)
    undefined-behaviour: Check for undefined behaviour using UBSan
    asan: Check for memory usage errors using AddressSanitizer
    docs: Build + install the documentation
    changelog: Build the changelog
    create-toolchain-file: Create the associated toolchain file
    format: Format and check the format of the sources
    language-server: Start and connect to the c++ language server

setup:
    - command-line-command

init:
    - create-toolchain-file
    - meson

init-build:
    - create-toolchain-file
    - meson

init-no-system:
    - create-toolchain-file
    - meson

init-limited-optimization:
    - create-toolchain-file
    - meson

init-coverage:
    - create-toolchain-file
    - meson

init-asan:
    - create-toolchain-file
    - meson

init-windows:
    - cmake

build:
    - build-only
    - install

build-only:
    - meson

install:
    - meson

create-installer:
    - command-line-command

clean:
    - cmake

distclean:
    - command-line-command

rebuild:
    - clean
    - build

analyze:
    - selector

run-test:
    - selector

unittest:
    - command-line-command

integration:
    - command-line-command

coverage:
    - command-line-command

memory-check:
    - command-line-command

format:
    - cpp-format
    - py-format
    - check-changes

cpp-format:
    - command-line-command

py-format:
    - command-line-command

check-changes:
    - command-line-command

docs:
    - build-docs
    - install-docs

build-docs:
    - cmake

install-docs:
    - cmake

selector:
    analyze:
        patterns:
            - ANALYZE
        targets: ["{ANALYZE}"]
    run-test:
        patterns:
            - RUNTARGET
        targets: [ "{RUNTARGET}" ]

undefined-behaviour:
    - command-line-command

asan:
    - command-line-command

changelog:
    - build

create-toolchain-file:
    - command-line-command

language-server:
    - command-line-command

coverity:
    - command-line-command

meson:
    patterns:
        - COMPILER
        - TRIPLET
        - MODE
        - SYSROOT
        - EH_ROOT_DIR

    source-dir: .
    build-dir: "build/{TRIPLET}{COMPILER}/{MODE}/build"
    build-type: "{MODE}"
    prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install"
    cross-file: "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"

    mode: setup

    environment:
        BOOST_ROOT: "{SYSROOT}/usr"

    init:
        options:
            test: true
            usage-documentation: true
            usage-documentation-html: true
            api-documentation: true
            plugins-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"
            license-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper"
            terminate-on-assert: true
            changelog: true
        command-line: [--werror]

    init-build:
        options:
            test: true
            usage-documentation: false
            api-documentation: false
            plugins-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"
            license-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper"
            terminate-on-assert: true
        command-line: [--werror]

    init-limited-optimization:
        build-type: "debug"
        options:
            test: true
            usage-documentation: false
            api-documentation: false
            plugins-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"
            license-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper"
        command-line: [--optimization, 1, --werror]

    init-no-system:
        options:
            test: true
            usage-documentation: false
            api-documentation: false
            plugins-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"
            license-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper"
            use-system-yaml-cpp: disabled
            use-system-lua: disabled
            use-system-catch2: disabled
            use-system-rapidcheck: disabled
            use-static-boost: false
            terminate-on-assert: true
            changelog: false
            b_pie: true

    init-coverage:
        options:
            test: true
            usage-documentation: false
            api-documentation: false
            plugins-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"
            license-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper"
            terminate-on-assert: true
            #cpp_args: "['-g', '--coverage', '-fprofile-arcs', '-ftest-coverage']"
            #cpp_link_args: "['-g', '--coverage', '-fprofile-arcs', '-ftest-coverage']"
            b_coverage: true
        build-type: debug
        command-line: [--werror]

    init-asan:
        options:
            test: true
            usage-documentation: false
            api-documentation: false
            plugins-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"
            license-prefix: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper"
            terminate-on-assert: true
            b_sanitize: address,undefined
            b_lundef: false
        build-type: debugoptimized
        command-line: [--werror]

    build-only:
        mode: compile

    install:
        mode: install
        command-line: [--only-changed, --no-rebuild]

    #unittest:
        #patterns:
            #- COMPILER
            #- TRIPLET
            #- MODE
            #- MODULE
        #mode: test
        #suite: unittest
        #targets: "{MODULE}"
        #environment:
            #PATH: "${PWD}/build/{TRIPLET}{COMPILER}/{MODE}/install/bin:${PWD}/build/{TRIPLET}{COMPILER}/{MODE}/install/test:/usr/local/bin:/usr/bin"
        #command-line: [ --no-rebuild, --print-errorlogs, --test-args, "'\\-\\-reporter=junit'", --test-args, "'\\-\\-out=../{MODULE}_report.xml'"]

cmake:
    patterns:
        - COMPILER
        - TRIPLET
        - MODE

    source-dir: .
    build-dir: "build/{TRIPLET}{COMPILER}/{MODE}/build"
    prefix: "build/{TRIPLET}{COMPILER}/{MODE}/install"
    generator: Ninja

    init-windows:
        mode: generate
        defines:
            CMAKE_BUILD_TYPE: "{MODE}"
            BUILD_USAGE_DOCUMENTATION: OFF
            BUILD_API_DOCUMENTATION: OFF
            ENABLE_TESTING: OFF
            Boost_USE_STATIC_LIBS: ON
            BOOST_ROOT: '%cd%/3rdparty/bin/boost'
            BOOST_INCLUDEDIR: '%cd%/3rdparty/bin/boost/include/boost-1_69'
            Boost_NO_SYSTEM_PATHS: ON
            Boost_USE_STATIC_RUNTIME: OFF
            TERMINATE_ON_ASSERT_FAILURE: ON
            ACTUAL_PLUGINS_INSTALL_PREFIX: "build/{TRIPLET}{COMPILER}/{MODE}/install/share/exec-helper/plugins"

    clean:
        mode: build
        target: clean

    build-docs:
        mode: build
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
            - DOCSTYPE
        target: "docs-{DOCSTYPE}"

    install-docs:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
            - DOCSTYPE
        mode: install
        component: "docs-{DOCSTYPE}"

cppcheck:
    patterns:
        - SOURCE_TYPE
        - MODULE
        - TARGET
    src-dir: "{SOURCE_TYPE}/{MODULE}"
    target-path: "{TARGET}"
    command-line:
        - --std=c++17
        - --error-exitcode=1
        - --includes-file=suppressions/includesfile.cppcheck
        - --inline-suppr
    enable-checks:
        - warning
        - style
        - performance
        - portability
        - information

clang-static-analyzer:
    build-command:
        - init-build
        - build
    clean-command: clean

command-line-command:
    setup:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
        command-line: [ ln, -fs, "build/{TRIPLET}{COMPILER}/{MODE}/build/compile_commands.json"]

    create-toolchain-file:
        patterns:
            - COMPILER
            - TRIPLET
            - ARCHITECTURE
            - SYSROOT
            - MODE
        command-line:
            - create-build-dir: [ mkdir, -p, "build/{TRIPLET}{COMPILER}/{MODE}"]
            - remove-toolchain-tmp: [ rm, -f, "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"]
            - create-toolchain-tmp: [ cp, "crossfiles/{COMPILER}.ini.in", "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"]
            - replace-triplet: [ sed, -i, 's%@TRIPLET@%{TRIPLET}%g', "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"]
            - replace-compiler-family: [ sed, -i, 's%@COMPILER_FAMILY@%{COMPILER}%g', "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"]
            - replace-sysroot: [ sed, -i, 's%@SYSROOT@%{SYSROOT}%g', "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"]
            - replace-arch: [ sed, -i, 's%@ARCHITECTURE@%{ARCHITECTURE}%g', "build/{TRIPLET}{COMPILER}/{MODE}/cross-file.ini"]

    distclean:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
        command-line: [ rm, -rf, "build/{TRIPLET}{COMPILER}/{MODE}"]

    create-installer:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
#        command-line: [ C:\Program Files (x86)\NSIS\Bin\makensis.exe, "build\{TRIPLET}{COMPILER}\{MODE}\install\bin"]

    unittest:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
            - MODULE
            - FILTER
            - EH_ROOT_DIR
        environment:
            PATH: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/bin:{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/test:/usr/local/bin:/usr/bin"
        command-line: [ "build/{TRIPLET}{COMPILER}/{MODE}/install/test/exec-helper-{MODULE}-unittest", "{FILTER}"]

    integration:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
            - FILTER
            - EH_ROOT_DIR
        environment:
            PATH: "{EH_ROOT_DIR}/build/{TRIPLET}{COMPILER}/{MODE}/install/bin:/usr/local/bin:/usr/bin"
        working-dir: test/integration
        command-line: [ pytest, --numprocesses=auto, -m, "'{FILTER}'", "--junitxml=../../build/{TRIPLET}{COMPILER}/{MODE}/system_test_report.xml", "--html=../../build/{TRIPLET}{COMPILER}/{MODE}/system_test_report.html", --self-contained-html, .]

    coverage:
        command-line: [ exec-helper, init-coverage, build, analyze, --analyze, lcov, --compiler, gcc, --mode, coverage, --run-target, unittest]

    undefined-behaviour:
        patterns:
            - EH_ROOT_DIR
        environment:
            CXXFLAGS: -g -fno-omit-frame-pointer -fno-sanitize-recover=undefined
            LDFLAGS: -g -fno-omit-frame-pointer -fno-sanitize-recover=undefined
            UBSAN_OPTIONS: "suppresions={EH_ROOT_DIR}/suppressions/ubsan.blacklist"
        command-line: [ exec-helper, init-limited-optimization, build, run-test, --compiler, clang, --mode, undefined-behaviour, --run-target, unittest, integration]

    memory-check:
        command-line: [ exec-helper, analyze, --analyze, valgrind, --run-target, unittest, --compiler, gcc, --mode, debug]

    asan:
        environment:
            ASAN_OPTIONS: "check_initialization_order=1 print_stacktrace=1"
        command-line: [ exec-helper, init-asan, build, run-test, --compiler, clang, --mode, asan, --run-target, unittest]

    coverity:
        patterns:
            - COMPILER
            - TRIPLET
            - MODE
            - COVERITY_ARCHIVE_NAME
        command-line:
            - init: [ exec-helper, distclean, init-build, --compiler, "{COMPILER}", --mode, "{MODE}"]
            - cov-build: [ cov-build, --dir, cov-int, exec-helper, build-only, --compiler, "{TRIPLET}{COMPILER}", --mode, "{MODE}" ]
            - archive: [tar, --create, --auto-compress, --file, "{COVERITY_ARCHIVE_NAME}", cov-int]
            - upload: [ echo, "{COVERITY_ARCHIVE_NAME} is now ready to get uploaded to coverity scan"]

    cpp-format:
        patterns:
            - SOURCE_TYPE
            - MODULE
        command-line: [ clang-format, -i, '$(find "{SOURCE_TYPE}/{MODULE}" -name "*.cpp" -o -name "*.h")']

    py-format:
        command-line: [ black, --line-length, 100, test/integration/src/*.py]

    check-changes:
        command-line: [ git, diff-index, --quiet, HEAD, --]

    language-server:
        command-line: [ clangd, --background-index]

valgrind:
    environment:
        CFLAGS: '-DLUAJIT_USE_VALGRIND'
    run-command: run-test
    tool: memcheck
    command-line:
        - --leak-check=full
        - --error-exitcode=1
        - --suppressions=suppressions/valgrind
        - --suppressions=suppressions/lua.valgrind

pmd:
    patterns:
        - SOURCE_TYPE
        - MODULE
    exec: pmd
    tool:
        - cpd
    language: cpp
    files: 
        - "{SOURCE_TYPE}/{MODULE}"
    minimum-tokens: 100
    command-line:
        - " "

lcov:
    patterns:
        - COMPILER
        - TRIPLET
        - MODE
    run-command: run-test
    base-directory: "build/{TRIPLET}{COMPILER}/{MODE}/build"
    directory: "build/{TRIPLET}{COMPILER}/{MODE}/build"
    zero-counters: yes
    excludes:
        - /usr*
        - "*/3rdparty/*"
        - "*/test/*"
        - "*/subprojects/*"
        - "boost/*"
        - "c++/*"
        - "rapidcheck/*"
        - "yaml-cpp/*"
    gen-html: yes
    gen-html-output: test_coverage
    gen-html-command-line:
        - --num-spaces
        - 4

clang-tidy:
    patterns:
        - SOURCE_TYPE
        - MODULE
        - TRIPLET
        - COMPILER
        - MODE
    checks:
      - -altera-unroll-loops
      - -altera-id-dependent-backward-branch
      - -altera-struct-pack-align
      - -readability-function-cognitive-complexity
    build-dir: 'build/{TRIPLET}{COMPILER}/{MODE}/build'
    sources:
        - "{SOURCE_TYPE}/{MODULE}/src/*.cpp"
