From 4347af833a3cf1fc4cc1c4bc10bf924c89336759 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 21 Mar 2026 00:18:52 +0100 Subject: [PATCH 1/6] chore: Use more descriptive names for helper scripts Signed-off-by: Michael Vetter --- .github/workflows/main.yml | 6 +++--- CONTRIBUTING.md | 8 ++++---- Makefile.am | 2 +- meson.build | 2 +- ci/ci-build.sh => scripts/build-configuration-matrix.sh | 2 ++ scripts/{quality-check.sh => lint-and-test.sh} | 6 +++--- 6 files changed, 14 insertions(+), 12 deletions(-) rename ci/ci-build.sh => scripts/build-configuration-matrix.sh (98%) rename scripts/{quality-check.sh => lint-and-test.sh} (96%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d7442f5f..d046e09b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,17 +21,17 @@ jobs: buildsystem: autotools tests: unit omemo: signal - script: ./ci/ci-build.sh + script: ./scripts/build-configuration-matrix.sh - flavor: fedora buildsystem: autotools tests: unit omemo: signal - script: ./ci/ci-build.sh + script: ./scripts/build-configuration-matrix.sh - flavor: ubuntu buildsystem: autotools tests: unit omemo: signal - script: ./ci/ci-build.sh + script: ./scripts/build-configuration-matrix.sh - flavor: debian buildsystem: meson tests: unit diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d402d35c..22671b1a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -192,7 +192,7 @@ snippet to `.git/hooks/pre-push`: ```shell #!/bin/sh set -e -./ci/ci-build.sh +./scripts/build-configuration-matrix.sh ``` This will run the same tests that the CI runs and refuse the push if it fails. @@ -214,7 +214,7 @@ In cases where you want to disable automatic formatting for a specific block of ## Verification & Testing ### Running unit tests -Run `make check` to run the unit tests with your current configuration or `./ci/ci-build.sh` to check with different switches passed to configure. +Run `make check` to run the unit tests with your current configuration or `./scripts/build-configuration-matrix.sh` to check with different switches passed to configure. ### Writing unit tests We use the [cmocka](https://cmocka.org/) testing framework for unit tests. @@ -331,7 +331,7 @@ meson compile doublecheck Alternatively, you can run the script directly: ``` -./scripts/quality-check.sh --fix-formatting --meson # or --autotools +./scripts/lint-and-test.sh --fix-formatting --meson # or --autotools ``` ### Pre-commit hook @@ -339,7 +339,7 @@ It is highly recommended to install the quality check script as a git pre-commit To install the hook: ``` -./scripts/quality-check.sh --install +./scripts/lint-and-test.sh --install ``` If you need to bypass the formatting check (e.g. due to a `clang-format` version mismatch), you can set the `SKIP_FORMAT` environment variable: diff --git a/Makefile.am b/Makefile.am index 3423fea4..1ce59239 100644 --- a/Makefile.am +++ b/Makefile.am @@ -376,4 +376,4 @@ spell: codespell doublecheck: - @./scripts/quality-check.sh --fix-formatting --autotools + @./scripts/lint-and-test.sh --fix-formatting --autotools diff --git a/meson.build b/meson.build index d43cd3cb..921aa8a9 100644 --- a/meson.build +++ b/meson.build @@ -727,7 +727,7 @@ if get_option('tests') endif run_target('doublecheck', - command: ['scripts/quality-check.sh', '--fix-formatting', '--meson'] + command: ['scripts/lint-and-test.sh', '--fix-formatting', '--meson'] ) summary({ diff --git a/ci/ci-build.sh b/scripts/build-configuration-matrix.sh similarity index 98% rename from ci/ci-build.sh rename to scripts/build-configuration-matrix.sh index 606732bf..bbb2334e 100755 --- a/ci/ci-build.sh +++ b/scripts/build-configuration-matrix.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +# Exhaustive build configuration matrix testing for Profanity + log_content() { echo diff --git a/scripts/quality-check.sh b/scripts/lint-and-test.sh similarity index 96% rename from scripts/quality-check.sh rename to scripts/lint-and-test.sh index dfda561a..88ed28e0 100755 --- a/scripts/quality-check.sh +++ b/scripts/lint-and-test.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -# Central quality check script for Profanity +# Central linting and testing script for Profanity set -e @@ -118,7 +118,7 @@ while [[ "$#" -gt 0 ]]; do echo "Installing pre-commit hook..." mkdir -p .git/hooks echo "#!/usr/bin/env bash" > .git/hooks/pre-commit - echo "./scripts/quality-check.sh --hook" >> .git/hooks/pre-commit + echo "./scripts/lint-and-test.sh --hook" >> .git/hooks/pre-commit chmod +x .git/hooks/pre-commit echo "Hook installed." exit 0 @@ -140,4 +140,4 @@ if [ "$BUILD_SYSTEM" != "none" ]; then run_tests "$BUILD_SYSTEM" fi -echo -e "${GREEN}Quality check successful!${NC}" +echo -e "${GREEN}Validation successful!${NC}" From a786ba35643fcd613684c123e5c7245407350f46 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 21 Mar 2026 00:23:46 +0100 Subject: [PATCH 2/6] chore: Add changelog-helper script Since we now use Conventional Commits we can create our Changelog semi-automatically. Signed-off-by: Michael Vetter --- scripts/changelog-helper.py | 165 ++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100755 scripts/changelog-helper.py diff --git a/scripts/changelog-helper.py b/scripts/changelog-helper.py new file mode 100755 index 00000000..9a97c3ef --- /dev/null +++ b/scripts/changelog-helper.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python3 + +# Since we use Conventional Commits +# we can now create our Changelog semi-automatically + +import subprocess +import sys +import re +import argparse +from collections import defaultdict + +# Configuration for sections and their order +SECTION_CONFIG = [ + ("fix", "Bug Fixes"), + ("feat", "Features"), + ("build", "Build System"), + ("ci", "CI"), + ("docs", "Documentation"), + ("perf", "Performance Improvements"), + ("refactor", "Refactorings"), + ("cleanup", "Cleanup"), + ("style", "Style"), + ("tests", "Tests"), + ("chore", "Chores"), +] +SECTIONS = dict(SECTION_CONFIG) +TYPE_ORDER = [t for t, _ in SECTION_CONFIG] + +CORRECTIONS = { + "ests": "tests", + "wleanup": "cleanup", +} + +def git_run(args): + """Run a git command and return stripped output lines.""" + try: + result = subprocess.run(["git"] + args, capture_output=True, text=True, check=True) + return [line for line in result.stdout.strip().split('\n') if line] + except subprocess.CalledProcessError: + return [] + +def get_last_tag(): + output = git_run(["describe", "--tags", "--abbrev=0"]) + return output[0] if output else None + +def get_commits(revision_range): + """Get list of (hash, subject) tuples.""" + lines = git_run(["log", revision_range, "--format=%H %s"]) + commits = [] + for line in lines: + parts = line.split(' ', 1) + if len(parts) == 2: + commits.append(parts) + return commits + +def get_pr_mappings(revision_range): + """Map commit hashes to PR numbers found in merge commits.""" + merge_commits = git_run(["log", revision_range, "--merges", "--format=%H %s"]) + pr_map = {} + pr_re = re.compile(r'Merge pull request #(\d+)') + + for line in merge_commits: + parts = line.split(' ', 1) + if len(parts) < 2: + continue + m_hash, m_subject = parts + match = pr_re.search(m_subject) + if match: + pr_num = match.group(1) + # Find all commits that are part of this merge branch + branch_commits = git_run(["rev-list", f"{m_hash}^1..{m_hash}^2"]) + for b_hash in branch_commits: + pr_map[b_hash] = pr_num + return pr_map + +def get_contributors(revision_range): + """Get sorted list of all unique contributors.""" + cmd = ["log", revision_range, "--format=%an%n%(trailers:key=Co-authored-by,valueonly=true)"] + output = git_run(cmd) + + contributors = set() + for line in output: + # Remove email part if present: "Name " -> "Name" + name = line.split('<')[0].strip() + if name: + contributors.add(name) + + return sorted(list(contributors)) + +def format_description(description): + """Capitalize first letter of description.""" + description = description.strip() + if description and description[0].islower(): + return description[0].upper() + description[1:] + return description + +def main(): + parser = argparse.ArgumentParser(description="Generate a sorted changelog from git commits.") + parser.add_argument("--pr", action="store_true", help="Append PR number to each commit.") + args = parser.parse_args() + + last_tag = get_last_tag() + if not last_tag: + print("No tags found in the repository.", file=sys.stderr) + + revision_range = f"{last_tag}..HEAD" if last_tag else "HEAD" + + commits = get_commits(revision_range) + if not commits: + print(f"No commits found since {last_tag if last_tag else 'the beginning'}.") + return + + pr_map = get_pr_mappings(revision_range) if args.pr else {} + + # Conventional Commit regex: type(scope): description + commit_re = re.compile(r'^(\w+)(?:\(([^)]+)\))?:\s*(.*)$') + + grouped = defaultdict(list) + others = [] + + for c_hash, c_subject in commits: + # Skip merge commits in the output + if c_subject.startswith(("Merge pull request", "Merge branch")): + continue + + pr_suffix = f" (#{pr_map[c_hash]})" if c_hash in pr_map else "" + match = commit_re.match(c_subject) + + if match: + ctype = match.group(1).lower() + ctype = CORRECTIONS.get(ctype, ctype) + description = format_description(match.group(3)) + grouped[ctype].append(f"{description}{pr_suffix}") + else: + others.append(f"{c_subject}{pr_suffix}") + + # Output sections in ordered priority + all_types = TYPE_ORDER + sorted([t for t in grouped if t not in TYPE_ORDER]) + first = True + for ctype in all_types: + if ctype in grouped: + if not first: + print() + section_name = SECTIONS.get(ctype, ctype.capitalize()) + print(f"{section_name}:") + for msg in sorted(grouped[ctype]): + print(f"- {msg}") + first = False + + if others: + if not first: + print() + print("Others:") + for msg in sorted(others): + print(f"- {msg}") + + # Contributors section + contributors = get_contributors(revision_range) + if contributors: + print("\nContributors:") + for i, name in enumerate(contributors, 1): + print(f"{i}. {name}") + +if __name__ == "__main__": + main() From d808b88b5516349cd6ff86fbb5be75d2da3b9773 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 21 Mar 2026 00:30:40 +0100 Subject: [PATCH 3/6] chore: Add README explaining the purpose and usage of helper scripts Signed-off-by: Michael Vetter --- scripts/README.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 scripts/README.md diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 00000000..2c3c4b0d --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,34 @@ +# Scripts + +This directory contains various scripts used for development, CI, and maintenance. + +## `lint-and-test.sh` +Central validation script mainly for local development. + +- **Purpose:** Runs spelling checks, code formatting, and unit testing. +- **Usage:** `./scripts/lint-and-test.sh [options]` +- **Options:** + - `--fix-formatting`: Automatically apply `clang-format` fixes. + - `--autotools` / `--meson`: Run unit tests using the specified build system. + - `--hook`: Run in "hook mode" (checks only staged files). + - `--install`: Install the script as a git `pre-commit` hook. + +## `build-configuration-matrix.sh` +Exhaustive build configuration matrix testing. It ensures that Profanity compiles and passes unit tests across a variety of feature configurations. + +- **Purpose:** Verifies architectural compatibility by testing many combinations of build flags. +- **Usage:** `./scripts/build-configuration-matrix.sh` +- **Environment:** Primarily used in CI (GitHub Actions), but can be run locally to verify all configurations. + +## `changelog-helper.py` +Generates a sorted changelog from git commits since the last tag. + +- **Purpose:** Automates the creation of release notes by parsing Conventional Commit messages. +- **Usage:** `python3 scripts/changelog-helper.py [--pr]` +- **Options:** Use `--pr` to append Pull Request numbers to each entry. + +## `check-new-xeps.py` +Checks for updates to XMPP Extension Protocols (XEPs). + +- **Purpose:** Compares the versions of XEPs implemented in Profanity (tracked in `profanity.doap`) against the latest versions available at `xmpp.org`. +- **Usage:** `python3 scripts/check-new-xeps.py` From 9407eb958d8cf4af40dac6b535f07b59dc4067d2 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 21 Mar 2026 00:41:16 +0100 Subject: [PATCH 4/6] ci: Add linter to make sure we use Conventional Commits This will make it easier for us to write Changelogs for example. See https://www.conventionalcommits.org/en/v1.0.0. Also mentioned in the CONTRIBUTING.md Signed-off-by: Michael Vetter --- .commitlintrc.json | 23 +++++++++++++++++++++++ .github/workflows/commit-lint.yml | 17 +++++++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 .commitlintrc.json create mode 100644 .github/workflows/commit-lint.yml diff --git a/.commitlintrc.json b/.commitlintrc.json new file mode 100644 index 00000000..8c6c4297 --- /dev/null +++ b/.commitlintrc.json @@ -0,0 +1,23 @@ +{ + "extends": ["@commitlint/config-conventional"], + "rules": { + "type-enum": [ + 2, + "always", + [ + "feat", + "fix", + "docs", + "style", + "refactor", + "perf", + "tests", + "build", + "ci", + "chore", + "cleanup" + ] + ], + "subject-case": [0] + } +} diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml new file mode 100644 index 00000000..c32dc3e8 --- /dev/null +++ b/.github/workflows/commit-lint.yml @@ -0,0 +1,17 @@ +name: "Commits" + +on: + pull_request: + branches: [master] + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + # Applies to all commits + fetch-depth: 0 + + - name: "Conventional Commits" + uses: wagoid/commitlint-github-action@v6 From beef714a30ee661fc6c9187bf32078cbd23895c2 Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 21 Mar 2026 00:45:57 +0100 Subject: [PATCH 5/6] ci: Add linter to make sure all commits are DCO signed Mentioned in the CONTRIBUTING.md as well. Let's enforce it. Signed-off-by: Michael Vetter --- .github/workflows/commit-lint.yml | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index c32dc3e8..48aa6d91 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -1,17 +1,34 @@ -name: "Commits" +name: "Lint" on: pull_request: branches: [master] + types: [opened, synchronize, reopened] jobs: - lint: + commitlint: + name: "Conventional Commits" runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: - # Applies to all commits + # Fetch all history so commitlint can see the commits in the PR fetch-depth: 0 - name: "Conventional Commits" uses: wagoid/commitlint-github-action@v6 + + dco: + name: "DCO" + runs-on: ubuntu-latest + steps: + - name: "Get PR Commits" + id: "get-pr-commits" + uses: tim-actions/get-pr-commits@v1.3.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: "Check DCO" + uses: tim-actions/dco@v1.1.0 + with: + commits: ${{ steps.get-pr-commits.outputs.commits }} From a8c7850a97f93af0ea5fcfc55fcd5ed49444778f Mon Sep 17 00:00:00 2001 From: Michael Vetter Date: Sat, 21 Mar 2026 00:53:54 +0100 Subject: [PATCH 6/6] chore: Unify build configuration script into one Earlier ci/meson-build.sh and ci/ci-build.sh. The latter we then renamed to the more descriptive build-configuration-matrix.sh. Both scripts are doing the same thing but for different build systems. So lets merge them together. Signed-off-by: Michael Vetter --- .github/workflows/main.yml | 4 +- CONTRIBUTING.md | 2 +- ci/ci-meson-build.sh | 72 ------- scripts/README.md | 5 +- scripts/build-configuration-matrix.sh | 283 +++++++++++++++----------- 5 files changed, 171 insertions(+), 195 deletions(-) delete mode 100755 ci/ci-meson-build.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d046e09b..20c0536e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,13 +36,13 @@ jobs: buildsystem: meson tests: unit omemo: signal - script: ./ci/ci-meson-build.sh + script: ./scripts/build-configuration-matrix.sh meson omemo_env: libsignal - flavor: debian buildsystem: meson tests: unit omemo: libomemo - script: ./ci/ci-meson-build.sh + script: ./scripts/build-configuration-matrix.sh meson omemo_env: libomemo-c name: ${{ matrix.flavor }} | ${{ matrix.buildsystem }} | ${{ matrix.tests }} | ${{ matrix.omemo }} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 22671b1a..8bb73db9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -214,7 +214,7 @@ In cases where you want to disable automatic formatting for a specific block of ## Verification & Testing ### Running unit tests -Run `make check` to run the unit tests with your current configuration or `./scripts/build-configuration-matrix.sh` to check with different switches passed to configure. +Run `make check` to run the unit tests with your current configuration or `./scripts/build-configuration-matrix.sh [autotools|meson]` to check with different switches passed to configure. ### Writing unit tests We use the [cmocka](https://cmocka.org/) testing framework for unit tests. diff --git a/ci/ci-meson-build.sh b/ci/ci-meson-build.sh deleted file mode 100755 index 873b8c44..00000000 --- a/ci/ci-meson-build.sh +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env bash - -# Exit on error -set -e - -error_handler() -{ - ERR_CODE=$? - echo - echo "Error ${ERR_CODE} with command '${BASH_COMMAND}' on line ${BASH_LINENO[0]}. Exiting." - # Meson logs are stored in the build directory - for log in build_run/meson-logs/testlog.txt build_valgrind/meson-logs/testlog.txt; do - if [ -f "$log" ]; then - echo "--- Meson Test Log ($log) ---" - cat "$log" - fi - done - exit ${ERR_CODE} -} - -trap error_handler ERR - -tests=( - "-Dnotifications=enabled -Dicons-and-clipboard=enabled -Dotr=enabled -Dpgp=enabled -Domemo=enabled -Dc-plugins=enabled -Dpython-plugins=enabled -Dxscreensaver=enabled -Domemo-qrcode=enabled -Dgdk-pixbuf=enabled" - "" - "-Dnotifications=disabled" - "-Dicons-and-clipboard=disabled" - "-Dotr=disabled" - "-Dpgp=disabled" - "-Domemo=disabled -Domemo-qrcode=disabled" - "-Dpgp=disabled -Dotr=disabled" - "-Dpgp=disabled -Dotr=disabled -Domemo=disabled" - "-Dpython-plugins=disabled" - "-Dc-plugins=disabled" - "-Dc-plugins=disabled -Dpython-plugins=disabled" - "-Dxscreensaver=disabled" - "-Dgdk-pixbuf=disabled" -) - -BACKEND_OPT="" -if [ -n "${OMEMO_BACKEND}" ]; then - BACKEND_OPT="-Domemo-backend=${OMEMO_BACKEND}" -fi - -# Run Valgrind check (Only on Linux, on first/full feature set) -if [[ "$(uname | tr '[:upper:]' '[:lower:]')" == linux* ]]; then - echo "--> Running Valgrind check with full features ${BACKEND_OPT}" - - meson setup build_valgrind ${tests[0]} ${BACKEND_OPT} -Dtests=true -Db_sanitize=address,undefined - meson compile -C build_valgrind - - meson test -C build_valgrind "unit tests" --print-errorlogs --wrap=valgrind || echo "Valgrind issues detected" - - rm -rf build_valgrind -fi - -# Iterate through all feature combinations -for features in "${tests[@]}" -do - echo "----------------------------------------------------" - echo "--> Building with: ${features} ${BACKEND_OPT}" - echo "----------------------------------------------------" - - rm -rf build_run - - meson setup build_run ${features} ${BACKEND_OPT} -Dtests=true - meson compile -C build_run - - meson test -C build_run "unit tests" --print-errorlogs - - ./build_run/profanity -v -done diff --git a/scripts/README.md b/scripts/README.md index 2c3c4b0d..58a0cc56 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -14,10 +14,11 @@ Central validation script mainly for local development. - `--install`: Install the script as a git `pre-commit` hook. ## `build-configuration-matrix.sh` -Exhaustive build configuration matrix testing. It ensures that Profanity compiles and passes unit tests across a variety of feature configurations. +Exhaustive build configuration matrix testing. It ensures that Profanity compiles and passes unit tests across a variety of feature configurations for both Autotools and Meson. - **Purpose:** Verifies architectural compatibility by testing many combinations of build flags. -- **Usage:** `./scripts/build-configuration-matrix.sh` +- **Usage:** `./scripts/build-configuration-matrix.sh [autotools|meson] [extra-args]` +- **Extra Arguments:** Any arguments passed after the build system are forwarded directly to the configuration command (`./configure` or `meson setup`). - **Environment:** Primarily used in CI (GitHub Actions), but can be run locally to verify all configurations. ## `changelog-helper.py` diff --git a/scripts/build-configuration-matrix.sh b/scripts/build-configuration-matrix.sh index bbb2334e..8a943302 100755 --- a/scripts/build-configuration-matrix.sh +++ b/scripts/build-configuration-matrix.sh @@ -1,9 +1,16 @@ #!/usr/bin/env bash # Exhaustive build configuration matrix testing for Profanity +# Supports both Autotools and Meson -log_content() -{ +set -e + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +log_content() { echo if [ -f "$1" ]; then echo "Content of $1:" @@ -13,144 +20,184 @@ log_content() fi } -error_handler() -{ +error_handler() { ERR_CODE=$? + echo -e "${RED}Error ${ERR_CODE} with command '${BASH_COMMAND}' on line ${BASH_LINENO[0]}. Exiting.${NC}" - log_content ./config.log - log_content ./test-suite.log - log_content ./test-suite-memcheck.log - - echo - echo "Error ${ERR_CODE} with command '${BASH_COMMAND}' on line ${BASH_LINENO[0]}. Exiting." - echo + if [ "$BUILD_SYSTEM" == "autotools" ]; then + log_content ./config.log + log_content ./test-suite.log + log_content ./test-suite-memcheck.log + else + for log in build_run/meson-logs/testlog.txt build_valgrind/meson-logs/testlog.txt; do + if [ -f "$log" ]; then + echo "--- Meson Test Log ($log) ---" + cat "$log" + fi + done + fi exit ${ERR_CODE} } trap error_handler ERR -num_cores() -{ - # Check for cores, for systems with: - # Line 1. Linux w/ coreutils, or... - # Line 2. OpenBSD, FreeBSD, NetBSD or macOS, or... - # Line 3. Fallback for Linux w/o coreutils (glibc). +num_cores() { nproc \ || sysctl -n hw.ncpu \ - || getconf _NPROCESSORS_ONLN 2>/dev/null + || getconf _NPROCESSORS_ONLN 2>/dev/null \ + || echo 2 } -./bootstrap.sh +usage() { + echo "Usage: $0 [autotools|meson] [extra-args]" + echo "" + echo "Run exhaustive build matrix tests for the specified build system." + echo "Default build system is 'autotools'." + echo "" + echo "Extra arguments are passed directly to the configuration command:" + echo " - Autotools: ./configure [extra-args]" + echo " - Meson: meson setup [extra-args]" + exit 0 +} -tests=() -MAKE="make --quiet -j$(num_cores)" -CC="gcc" +# Determine build system +BUILD_SYSTEM="autotools" +if [[ "$1" == "autotools" || "$1" == "meson" ]]; then + BUILD_SYSTEM="$1" + shift +fi + +if [[ "$1" == "--help" || "$1" == "-h" ]]; then + usage +fi ARCH="$(uname | tr '[:upper:]' '[:lower:]')" +EXTRA_ARGS="$*" -case "$ARCH" in - linux*) - tests=( - "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp - --enable-omemo --enable-plugins --enable-c-plugins - --enable-python-plugins --with-xscreensaver --enable-omemo-qrcode --enable-gdk-pixbuf" - "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp - --disable-omemo --disable-plugins --disable-c-plugins - --disable-python-plugins --without-xscreensaver" - "--disable-notifications" - "--disable-icons-and-clipboard" - "--disable-otr" - "--disable-pgp" - "--disable-omemo --disable-omemo-qrcode" - "--disable-pgp --disable-otr" - "--disable-pgp --disable-otr --disable-omemo" - "--disable-plugins" - "--disable-python-plugins" - "--disable-c-plugins" - "--disable-c-plugins --disable-python-plugins" - "--without-xscreensaver" - "--disable-gdk-pixbuf" - "") - source /etc/profile.d/debuginfod.sh 2>/dev/null || true - ;; - darwin*) - tests=( - "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp - --enable-omemo --enable-plugins --enable-c-plugins - --enable-python-plugins" - "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp - --disable-omemo --disable-plugins --disable-c-plugins - --disable-python-plugins" - "--disable-notifications" - "--disable-icons-and-clipboard" - "--disable-otr" - "--disable-pgp" - "--disable-omemo" - "--disable-pgp --disable-otr" - "--disable-pgp --disable-otr --disable-omemo" - "--disable-plugins" - "--disable-python-plugins" - "--disable-c-plugins" - "--disable-c-plugins --disable-python-plugins" - "") - ;; - openbsd*) - MAKE="gmake" - # TODO(#1231): - # `-std=gnu99 -fexec-charset=UTF-8` to silence: - # src/event/server_events.c:1453:19: error: universal character names are only valid in C++ and C99 - # src/event/server_events.c:1454:19: error: universal character names are only valid in C++ and C99 - CC="egcc -std=gnu99 -fexec-charset=UTF-8" +if [ "$BUILD_SYSTEM" == "autotools" ]; then + echo -e "${YELLOW}---> Starting Autotools build matrix...${NC}" + ./bootstrap.sh - tests=( - "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp - --enable-omemo --enable-plugins --enable-c-plugins - --enable-python-plugins" - "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp - --disable-omemo --disable-plugins --disable-c-plugins - --disable-python-plugins" - "--disable-notifications" - "--disable-icons-and-clipboard" - "--disable-otr" - "--disable-pgp" - "--disable-omemo" - "--disable-pgp --disable-otr" - "--disable-pgp --disable-otr --disable-omemo" - "--disable-plugins" - "--disable-python-plugins" - "--disable-c-plugins" - "--disable-c-plugins --disable-python-plugins" - "") - ;; -esac + MAKE="make --quiet -j$(num_cores)" + CC="gcc" -case "$ARCH" in - linux*) - echo - echo "--> Building with ./configure ${tests[0]} --enable-valgrind --disable-functional-tests $*" - echo - - # shellcheck disable=SC2086 - ./configure ${tests[0]} --enable-valgrind --disable-functional-tests $* + case "$ARCH" in + linux*) + tests=( + "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp + --enable-omemo --enable-plugins --enable-c-plugins + --enable-python-plugins --with-xscreensaver --enable-omemo-qrcode --enable-gdk-pixbuf" + "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp + --disable-omemo --disable-plugins --disable-c-plugins + --disable-python-plugins --without-xscreensaver" + "--disable-notifications" + "--disable-icons-and-clipboard" + "--disable-otr" + "--disable-pgp" + "--disable-omemo --disable-omemo-qrcode" + "--disable-pgp --disable-otr" + "--disable-pgp --disable-otr --disable-omemo" + "--disable-plugins" + "--disable-python-plugins" + "--disable-c-plugins" + "--disable-c-plugins --disable-python-plugins" + "--without-xscreensaver" + "--disable-gdk-pixbuf" + "") + source /etc/profile.d/debuginfod.sh 2>/dev/null || true + ;; + *) + # Darwin, OpenBSD, etc. + if [ "$ARCH" == "openbsd*" ]; then + MAKE="gmake" + CC="egcc -std=gnu99 -fexec-charset=UTF-8" + fi + tests=( + "--enable-notifications --enable-icons-and-clipboard --enable-otr --enable-pgp + --enable-omemo --enable-plugins --enable-c-plugins + --enable-python-plugins" + "--disable-notifications --disable-icons-and-clipboard --disable-otr --disable-pgp + --disable-omemo --disable-plugins --disable-c-plugins + --disable-python-plugins" + "--disable-notifications" + "--disable-icons-and-clipboard" + "--disable-otr" + "--disable-pgp" + "--disable-omemo" + "--disable-pgp --disable-otr" + "--disable-pgp --disable-otr --disable-omemo" + "--disable-plugins" + "--disable-python-plugins" + "--disable-c-plugins" + "--disable-c-plugins --disable-python-plugins" + "") + ;; + esac + # Valgrind check (Linux only) + if [[ "$ARCH" == linux* ]]; then + echo -e "${YELLOW}--> Building with ./configure ${tests[0]} --enable-valgrind --disable-functional-tests ${EXTRA_ARGS}${NC}" + ./configure ${tests[0]} --enable-valgrind --disable-functional-tests ${EXTRA_ARGS} $MAKE CC="${CC}" $MAKE check-valgrind $MAKE distclean - ;; -esac + fi -for features in "${tests[@]}" -do - echo - echo "--> Building with ./configure ${features} --disable-functional-tests $*" - echo + for features in "${tests[@]}" + do + echo -e "${YELLOW}--> Building with ./configure ${features} --disable-functional-tests ${EXTRA_ARGS}${NC}" + ./configure $features --disable-functional-tests ${EXTRA_ARGS} + $MAKE CC="${CC}" + $MAKE check-unit + ./profanity -v + $MAKE clean + done - # shellcheck disable=SC2086 - ./configure $features --disable-functional-tests $* +else + # Meson Build Matrix + echo -e "${YELLOW}---> Starting Meson build matrix...${NC}" - $MAKE CC="${CC}" - $MAKE check-unit + tests=( + "-Dnotifications=enabled -Dicons-and-clipboard=enabled -Dotr=enabled -Dpgp=enabled -Domemo=enabled -Dc-plugins=enabled -Dpython-plugins=enabled -Dxscreensaver=enabled -Domemo-qrcode=enabled -Dgdk-pixbuf=enabled" + "" + "-Dnotifications=disabled" + "-Dicons-and-clipboard=disabled" + "-Dotr=disabled" + "-Dpgp=disabled" + "-Domemo=disabled -Domemo-qrcode=disabled" + "-Dpgp=disabled -Dotr=disabled" + "-Dpgp=disabled -Dotr=disabled -Domemo=disabled" + "-Dpython-plugins=disabled" + "-Dc-plugins=disabled" + "-Dc-plugins=disabled -Dpython-plugins=disabled" + "-Dxscreensaver=disabled" + "-Dgdk-pixbuf=disabled" + ) - ./profanity -v - $MAKE clean -done + BACKEND_OPT="" + if [ -n "${OMEMO_BACKEND}" ]; then + BACKEND_OPT="-Domemo-backend=${OMEMO_BACKEND}" + fi + + # Valgrind check (Linux only) + if [[ "$ARCH" == linux* ]]; then + echo -e "${YELLOW}--> Running Valgrind check with full features ${BACKEND_OPT} ${EXTRA_ARGS}${NC}" + rm -rf build_valgrind + meson setup build_valgrind ${tests[0]} ${BACKEND_OPT} -Dtests=true -Db_sanitize=address,undefined ${EXTRA_ARGS} + meson compile -C build_valgrind + meson test -C build_valgrind "unit tests" --print-errorlogs --wrap=valgrind || echo "Valgrind issues detected" + rm -rf build_valgrind + fi + + for features in "${tests[@]}" + do + echo -e "${YELLOW}--> Building with: ${features} ${BACKEND_OPT} ${EXTRA_ARGS}${NC}" + rm -rf build_run + meson setup build_run ${features} ${BACKEND_OPT} -Dtests=true ${EXTRA_ARGS} + meson compile -C build_run + meson test -C build_run "unit tests" --print-errorlogs + ./build_run/profanity -v + done +fi + +echo -e "${GREEN}Build configuration matrix testing successful!${NC}"