{"thread":{"id":"62624","subject":"[PATCH 0/8] ci: wire up support for Meson","startedAt":"2024-12-11T10:53:11Z","lastAt":"2025-07-17T04:43:38Z","messageCount":36,"participants":["Patrick Steinhardt","karthik nayak","Toon Claes","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":8},"messages":[{"id":"508967","messageId":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","threadId":"62624","inReplyTo":null,"subject":"[PATCH 0/8] ci: wire up support for Meson","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:31Z","receivedAt":"2024-12-11T10:53:11Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nthis small patch series wires up Meson into our CI systems. The intent\nis to ensure that it does not regress in functionality as the Git code\nbase evolves.\n\nTo help with keeping it up-to-date, both Meson and our Makefiles learn\nto detect missing or superseded test files in \"t/meson.build\". This\nshould give users an early notification in case they have to add a newly\nadded or removed test to these build instructions. Overall I think that\nthis shouldn't be too much of a burden given that adding a new test is\ntrivial.\n\nOne gap that still exists is newly added code files. Due to many sources\nbeing added to the build conditionally it's hard to have generic checks\nfor these. So I refrain from doing so in this series -- the build would\nalready fail anyway when we're missing code, so at least we will know\nthat something is up.\n\nThe series is built on top of caacdb5dfd (The fifteenth batch,\n2024-12-10) with ps/build at 904339edbd (Introduce support for the Meson\nbuild system, 2024-12-06) and cw/worktree-extension at 2037ca85ad\n(worktree: refactor `repair_worktree_after_gitdir_move()`, 2024-11-29)\nmerged into it.\n\nThanks!\n\nPatrick\n\n---\nPatrick Steinhardt (8):\n      ci/lib: support custom output directories when creating test artifacts\n      Makefile: drop -DSUPPRESS_ANNOTATED_LEAKS\n      t/unit-tests: rename clar-based unit tests to have a common prefix\n      meson: detect missing tests at configure time\n      Makefile: detect missing Meson tests\n      t: fix out-of-tree tests for some git-p4 tests\n      t: introduce compatibility options to clar-based tests\n      ci: wire up Meson builds\n\n .github/workflows/main.yml                  |  7 ++++\n .gitlab-ci.yml                              |  9 ++++++\n Makefile                                    |  5 ++-\n ci/install-dependencies.sh                  |  7 ++++\n ci/lib.sh                                   | 14 ++++----\n ci/print-test-failures.sh                   |  2 +-\n ci/run-build-and-tests.sh                   | 31 ++++++++++++++----\n meson.build                                 |  1 -\n parse-options.h                             | 12 +++++++\n t/Makefile                                  | 18 ++++++++++-\n t/meson.build                               | 40 +++++++++++++++++++++--\n t/t9835-git-p4-metadata-encoding-python2.sh | 48 ++++++++++++++-------------\n t/t9836-git-p4-metadata-encoding-python3.sh | 50 ++++++++++++++---------------\n t/unit-tests/generate-clar-decls.sh         |  5 ++-\n t/unit-tests/{ctype.c => u-ctype.c}         |  0\n t/unit-tests/{strvec.c => u-strvec.c}       |  0\n t/unit-tests/unit-test.c                    | 19 ++++++++++-\n 17 files changed, 196 insertions(+), 72 deletions(-)\n\n\n---\nbase-commit: 2fcbf72f13e8ce3bf1cda9a689f392f8f6e5c65d\nchange-id: 20241129-pks-meson-ci-ba1e40652fbe\n\n"},{"id":"508968","messageId":"20241211-pks-meson-ci-v1-1-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 1/8] ci/lib: support custom output directories when creating test artifacts","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:32Z","receivedAt":"2024-12-11T10:53:12Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Update `create_failed_test_artifacts ()` so that it can handle arbitrary\ntest output directories. This fixes creation of these artifacts for\nmacOS on GitLab CI, which uses a separate output directory already. This\nwill also be used by our out-of-tree builds with Meson.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n ci/lib.sh | 12 ++++++------\n 1 file changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex 930f98d7228166c37c236beb062b14675fb68ef3..2e7a5f0540b66f24bd0f5744311c2c48b472d63d 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -180,9 +180,9 @@ handle_failed_tests () {\n }\n \n create_failed_test_artifacts () {\n-\tmkdir -p t/failed-test-artifacts\n+\tmkdir -p \"${TEST_OUTPUT_DIRECTORY:-t}\"/failed-test-artifacts\n \n-\tfor test_exit in t/test-results/*.exit\n+\tfor test_exit in \"${TEST_OUTPUT_DIRECTORY:-t}\"/test-results/*.exit\n \tdo\n \t\ttest 0 != \"$(cat \"$test_exit\")\" || continue\n \n@@ -191,11 +191,11 @@ create_failed_test_artifacts () {\n \t\tprintf \"\\\\e[33m\\\\e[1m=== Failed test: ${test_name} ===\\\\e[m\\\\n\"\n \t\techo \"The full logs are in the 'print test failures' step below.\"\n \t\techo \"See also the 'failed-tests-*' artifacts attached to this run.\"\n-\t\tcat \"t/test-results/$test_name.markup\"\n+\t\tcat \"${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.markup\"\n \n-\t\ttrash_dir=\"t/trash directory.$test_name\"\n-\t\tcp \"t/test-results/$test_name.out\" t/failed-test-artifacts/\n-\t\ttar czf t/failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n+\t\ttrash_dir=\"${TEST_OUTPUT_DIRECTORY:-t}/trash directory.$test_name\"\n+\t\tcp \"${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.out\" \"${TEST_OUTPUT_DIRECTORY:-t}\"/failed-test-artifacts/\n+\t\ttar czf \"${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts/$test_name.trash.tar.gz\" \"$trash_dir\"\n \tdone\n }\n \n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508969","messageId":"20241211-pks-meson-ci-v1-2-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 2/8] Makefile: drop -DSUPPRESS_ANNOTATED_LEAKS","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:33Z","receivedAt":"2024-12-11T10:53:13Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The -DSUPPRESS_ANNOTATED_LEAKS preprocessor directive was used to enable\nour `UNLEAK()` macro in the past, which marks memory as still-reachable\nso that the leak sanitizer does not complain. Starting with 52c7dbd036\n(git-compat-util: drop now-unused `UNLEAK()` macro, 2024-11-20) this\nmacro has been removed, and thus the preprocessor directive is not\nrequired anymore, either.\n\nDrop it.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n Makefile    | 1 -\n meson.build | 1 -\n 2 files changed, 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 06f01149ecf399ae4bb1932188a007948d767283..2506f3b7e3377ab1a376338c86a727b2ae92a6e9 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1490,7 +1490,6 @@ ifneq ($(filter undefined,$(SANITIZERS)),)\n BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS\n endif\n ifneq ($(filter leak,$(SANITIZERS)),)\n-BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS\n BASIC_CFLAGS += -O0\n SANITIZE_LEAK = YesCompiledWithIt\n endif\ndiff --git a/meson.build b/meson.build\nindex 0dccebcdf16b07650d943e53643f0e09e2975cc9..1af25af5cc1e718a4e50fb14274a36f811506219 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -712,7 +712,6 @@ else\n   build_options_config.set('SANITIZE_ADDRESS', '')\n endif\n if get_option('b_sanitize').contains('leak')\n-  libgit_c_args += '-DSUPPRESS_ANNOTATED_LEAKS'\n   build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt')\n else\n   build_options_config.set('SANITIZE_LEAK', '')\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508970","messageId":"20241211-pks-meson-ci-v1-4-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 4/8] meson: detect missing tests at configure time","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:35Z","receivedAt":"2024-12-11T10:53:14Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"It is quite easy for the list of integration tests to go out-of-sync\nwithout anybody noticing. Introduce a new configure-time check that\nverifies that all tests are wired up properly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/meson.build | 36 ++++++++++++++++++++++++++++++++++++\n 1 file changed, 36 insertions(+)\n\ndiff --git a/t/meson.build b/t/meson.build\nindex 9e676e69363ed6311426500d98fe281e30d26bcb..f1fbc6ae179079f4d5d86f9a60956fad84d0495c 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -1092,6 +1092,42 @@ integration_tests = [\n   't9903-bash-prompt.sh',\n ]\n \n+# Sanity check that we are not missing any tests present in 't/'. This check\n+# only runs once at configure time and is thus best-effort, only. It is\n+# sufficient to catch missing test suites in our CI though.\n+foreach glob, tests : {\n+  't[0-9][0-9][0-9][0-9]-*.sh': integration_tests,\n+  'unit-tests/t-*.c': unit_test_programs,\n+  'unit-tests/u-*.c': clar_test_suites,\n+}\n+  actual_tests = run_command(shell, '-c', 'ls ' + glob,\n+    check: true,\n+    env: script_environment,\n+  ).stdout().strip().split('\\n')\n+\n+  if tests != actual_tests\n+    missing_tests = [ ]\n+    foreach actual_test : actual_tests\n+      if actual_test not in tests\n+        missing_tests += actual_test\n+      endif\n+    endforeach\n+    if missing_tests.length() > 0\n+      error('Missing tests:\\n\\n - ' + '\\n - '.join(missing_tests))\n+    endif\n+\n+    superfluous_tests = [ ]\n+    foreach integration_test : tests\n+      if integration_test not in actual_tests\n+        superfluous_tests += integration_test\n+      endif\n+    endforeach\n+    if superfluous_tests.length() > 0\n+      error('Superfluous tests:\\n\\n - ' + '\\n - '.join(superfluous_tests))\n+    endif\n+  endif\n+endforeach\n+\n # GIT_BUILD_DIR needs to be Unix-style without drive prefixes as it get added\n # to the PATH variable. And given that drive prefixes contain a colon we'd\n # otherwise end up with a broken PATH if we didn't convert it.\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508972","messageId":"20241211-pks-meson-ci-v1-3-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 3/8] t/unit-tests: rename clar-based unit tests to have a common prefix","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:34Z","receivedAt":"2024-12-11T10:53:14Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"All of the code files for unit tests using the self-grown unit testing\nframework have have a \"t-\" prefix to their name. This makes it easy to\nidentify them and use globbing in our Makefile and in other places. On\nthe other hand though, our clar-based unit tests have no prefix at all\nand thus cannot easily be discerned from other files in the unit test\ndirectory.\n\nIntroduce a new \"u-\" prefix for clar-based unit tests. This prefix will\nbe used in a subsequent commit to easily identify such tests.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n Makefile                              | 4 ++--\n t/meson.build                         | 4 ++--\n t/unit-tests/generate-clar-decls.sh   | 5 ++++-\n t/unit-tests/{ctype.c => u-ctype.c}   | 0\n t/unit-tests/{strvec.c => u-strvec.c} | 0\n 5 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 2506f3b7e3377ab1a376338c86a727b2ae92a6e9..6eafaf174aaa380ad8e6a86f75d003eb6c058fb3 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1344,8 +1344,8 @@ THIRD_PARTY_SOURCES += sha1dc/%\n THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/%\n THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%\n \n-CLAR_TEST_SUITES += ctype\n-CLAR_TEST_SUITES += strvec\n+CLAR_TEST_SUITES += u-ctype\n+CLAR_TEST_SUITES += u-strvec\n CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X)\n CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES))\n CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o\ndiff --git a/t/meson.build b/t/meson.build\nindex 13fe854ba0a18f9b83dbc48651f581198042ffd3..9e676e69363ed6311426500d98fe281e30d26bcb 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -1,6 +1,6 @@\n clar_test_suites = [\n-  'unit-tests/ctype.c',\n-  'unit-tests/strvec.c',\n+  'unit-tests/u-ctype.c',\n+  'unit-tests/u-strvec.c',\n ]\n \n clar_sources = [\ndiff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh\nindex 688e0885f4f28182c3afe19c067b6d59dcacccfc..3b315c64b3711bfccc5941852a0782e02cee82f0 100755\n--- a/t/unit-tests/generate-clar-decls.sh\n+++ b/t/unit-tests/generate-clar-decls.sh\n@@ -11,6 +11,9 @@ shift\n \n for suite in \"$@\"\n do\n-\tsed -ne \"s/^\\(void test_$(basename \"${suite%.c}\")__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\\)$/extern \\1;/p\" \"$suite\" ||\n+\tsuite_name=$(basename \"$suite\")\n+\tsuite_name=${suite_name%.c}\n+\tsuite_name=${suite_name#u-}\n+\tsed -ne \"s/^\\(void test_${suite_name}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\\)$/extern \\1;/p\" \"$suite\" ||\n \texit 1\n done >\"$OUTPUT\"\ndiff --git a/t/unit-tests/ctype.c b/t/unit-tests/u-ctype.c\nsimilarity index 100%\nrename from t/unit-tests/ctype.c\nrename to t/unit-tests/u-ctype.c\ndiff --git a/t/unit-tests/strvec.c b/t/unit-tests/u-strvec.c\nsimilarity index 100%\nrename from t/unit-tests/strvec.c\nrename to t/unit-tests/u-strvec.c\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508971","messageId":"20241211-pks-meson-ci-v1-5-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 5/8] Makefile: detect missing Meson tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:36Z","receivedAt":"2024-12-11T10:53:15Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In the preceding commit, we have introduced consistency checks to Meson\nto detect any discrepancies with missing or extraneous tests in its\nbuild instructions. These checks only get executed in Meson though, so\nany users of our Makefiles wouldn't be alerted of the fact that they\nhave to modify the Meson build instructions in case they add or remove\nany tests.\n\nAdd a comparable test target to our Makefile to plug this gap.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/Makefile | 18 +++++++++++++++++-\n 1 file changed, 17 insertions(+), 1 deletion(-)\n\ndiff --git a/t/Makefile b/t/Makefile\nindex 131ffd778fe00864fae1f5750269615556c6cdea..290fb03ff011d39c31c5073c796aa6f4dc966283 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -59,7 +59,7 @@ CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT\n \n all:: $(DEFAULT_TEST_TARGET)\n \n-test: pre-clean check-chainlint $(TEST_LINT)\n+test: pre-clean check-chainlint check-meson $(TEST_LINT)\n \t$(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup\n \n failed:\n@@ -114,6 +114,22 @@ check-chainlint:\n \t{ $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \\\n \tdiff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual\n \n+check-meson:\n+\t@# awk acts up when trying to match single quotes, so we use \\047 instead.\n+\t@printf \"%s\\n\" \\\n+\t\t\"integration_tests t[0-9][0-9][0-9][0-9]-*.sh\" \\\n+\t\t\"unit_test_programs unit-tests/t-*.c\" \\\n+\t\t\"clar_test_suites unit-tests/u-*.c\" | \\\n+\twhile read -r variable pattern; do \\\n+\t\tmeson_tests=$$(awk \"/^$$variable = \\[\\$$/ {flag=1 ; next } /^]$$/ { flag=0 } flag { gsub(/^  \\047/, \\\"\\\"); gsub(/\\047,\\$$/, \\\"\\\"); print }\" meson.build) && \\\n+\t\tactual_tests=$$(ls $$pattern) && \\\n+\t\tif test \"$$meson_tests\" != \"$$actual_tests\"; then \\\n+\t\t\techo \"Meson tests differ from actual tests:\"; \\\n+\t\t\tdiff -u <(echo \"$$meson_tests\") <(echo \"$$actual_tests\"); \\\n+\t\t\texit 1; \\\n+\t\tfi; \\\n+\tdone\n+\n test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \\\n \ttest-lint-filenames\n ifneq ($(GIT_TEST_CHAIN_LINT),0)\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508973","messageId":"20241211-pks-meson-ci-v1-6-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 6/8] t: fix out-of-tree tests for some git-p4 tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:37Z","receivedAt":"2024-12-11T10:53:15Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both t9835 and t9836 exercise git-p4, but one exercises Python 2 whereas\nthe other one uses Python 3. These tests do not exercise \"git p4\", but\ninstead they use \"git p4.py\" so that the unbuilt version of \"git-p4.py\"\nis used that has \"#!/usr/bin/env python\" as shebang instead of the\nreplaced shebang.\n\nBut \"git-p4.py\" is not in our PATH during out-of-tree builds, and thus\nwe cannot locate \"git-p4.py\". The tests thus break with CMake and Meson.\n\nFix this by instead manually setting up script wrappers that invoke the\nrespective Python interpreter directly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/t9835-git-p4-metadata-encoding-python2.sh | 48 ++++++++++++++-------------\n t/t9836-git-p4-metadata-encoding-python3.sh | 50 ++++++++++++++---------------\n 2 files changed, 50 insertions(+), 48 deletions(-)\n\ndiff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh\nindex 036bf79c6674f6f1f0d667c7270674168428ffee..02f9ec09053890a4d41b7dc95644066d6481bbb6 100755\n--- a/t/t9835-git-p4-metadata-encoding-python2.sh\n+++ b/t/t9835-git-p4-metadata-encoding-python2.sh\n@@ -14,23 +14,25 @@ python_target_version='2'\n ## SECTION REPEATED IN t9836 ##\n ###############################\n \n-# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n-# latter references a specific path so we can't easily force it to run under\n-# the python version we need to.\n-\n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-python_target_binary=$(which python$python_target_version)\n-if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n+# These tests are specific to Python 2. Write a custom script that executes\n+# git-p4 directly with the Python 2 interpreter to ensure that we use that\n+# version even if Git was compiled with Python 3.\n+python_target_binary=$(which python2)\n+if test -n \"$python_target_binary\"\n then\n \tmkdir temp_python\n-\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n-\tln -s $python_target_binary temp_python/python\n+\tPATH=\"$(pwd)/temp_python:$PATH\"\n+\texport PATH\n+\n+\twrite_script temp_python/git-p4-python2 <<-EOF\n+\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n+\tEOF\n fi\n \n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-if ! test \"$python_major_version\" = \"$python_target_version\"\n+git p4-python2 >err\n+if ! grep 'valid commands' err\n then\n-\tskip_all=\"skipping python$python_target_version-specific git p4 tests; python$python_target_version not available\"\n+\tskip_all=\"skipping python2 git p4 tests; python2 not available\"\n \ttest_done\n fi\n \n@@ -81,14 +83,14 @@ test_expect_success 'init depot' '\n test_expect_success 'clone non-utf8 repo with strict encoding' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest=\"$git\" //depot@all 2>err &&\n+\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python2 clone --dest=\"$git\" //depot@all 2>err &&\n \tgrep \"Decoding perforce metadata failed!\" err\n '\n \n test_expect_success 'check utf-8 contents with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -100,7 +102,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' '\n test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -114,7 +116,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st\n test_expect_success 'check utf-8 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -126,7 +128,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' '\n test_expect_success 'check latin-1 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -138,7 +140,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' '\n test_expect_success 'check cp-1252 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -150,7 +152,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' '\n test_expect_success 'check cp850 contents parsed with correct fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -162,7 +164,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' '\n test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -174,7 +176,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback'\n test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$cli\" &&\n \t\tP4USER=cp1252_author &&\n@@ -186,7 +188,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n \t(\n \t\tcd \"$git\" &&\n \n-\t\tgit p4.py sync --branch=master &&\n+\t\tgit p4-python2 sync --branch=master &&\n \n \t\tgit log p4/master >actual &&\n \t\tgrep \"sœme more cp-1252 tæxt\" actual &&\n@@ -201,7 +203,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n test_expect_success 'passthrough (latin-1 contents corrupted in git) is the default with python2' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\ndiff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh\nindex 63350dc4b5c6262480cd0be8fd88fba714c55428..5e5217a66b4fdb3c7fcf073a50952c7e9009e9fe 100755\n--- a/t/t9836-git-p4-metadata-encoding-python3.sh\n+++ b/t/t9836-git-p4-metadata-encoding-python3.sh\n@@ -8,29 +8,29 @@ failing, and produces maximally sane output in git.'\n \n . ./lib-git-p4.sh\n \n-python_target_version='3'\n-\n ###############################\n ## SECTION REPEATED IN t9835 ##\n ###############################\n \n-# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n-# latter references a specific path so we can't easily force it to run under\n-# the python version we need to.\n-\n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-python_target_binary=$(which python$python_target_version)\n-if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n+# These tests are specific to Python 3. Write a custom script that executes\n+# git-p4 directly with the Python 3 interpreter to ensure that we use that\n+# version even if Git was compiled with Python 2.\n+python_target_binary=$(which python3)\n+if test -n \"$python_target_binary\"\n then\n \tmkdir temp_python\n-\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n-\tln -s $python_target_binary temp_python/python\n+\tPATH=\"$(pwd)/temp_python:$PATH\"\n+\texport PATH\n+\n+\twrite_script temp_python/git-p4-python3 <<-EOF\n+\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n+\tEOF\n fi\n \n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-if ! test \"$python_major_version\" = \"$python_target_version\"\n+git p4-python3 >err\n+if ! grep 'valid commands' err\n then\n-\tskip_all=\"skipping python$python_target_version-specific git p4 tests; python$python_target_version not available\"\n+\tskip_all=\"skipping python3 git p4 tests; python3 not available\"\n \ttest_done\n fi\n \n@@ -81,14 +81,14 @@ test_expect_success 'init depot' '\n test_expect_success 'clone non-utf8 repo with strict encoding' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest=\"$git\" //depot@all 2>err &&\n+\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python3 clone --dest=\"$git\" //depot@all 2>err &&\n \tgrep \"Decoding perforce metadata failed!\" err\n '\n \n test_expect_success 'check utf-8 contents with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -100,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' '\n test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -114,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st\n test_expect_success 'check utf-8 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -126,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' '\n test_expect_success 'check latin-1 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -138,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' '\n test_expect_success 'check cp-1252 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -150,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' '\n test_expect_success 'check cp850 contents parsed with correct fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -162,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' '\n test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -174,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback'\n test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$cli\" &&\n \t\tP4USER=cp1252_author &&\n@@ -186,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n \t(\n \t\tcd \"$git\" &&\n \n-\t\tgit p4.py sync --branch=master &&\n+\t\tgit p4-python3 sync --branch=master &&\n \n \t\tgit log p4/master >actual &&\n \t\tgrep \"sœme more cp-1252 tæxt\" actual &&\n@@ -202,7 +202,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n test_expect_success 'fallback (both utf-8 and cp-1252 contents handled) is the default with python3' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508974","messageId":"20241211-pks-meson-ci-v1-7-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 7/8] t: introduce compatibility options to clar-based tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:38Z","receivedAt":"2024-12-11T10:53:16Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Our unit tests that don't yet use the clar unit testing framework ignore\nany option that they do not understand. It is thus fine to just pass\ntest options we set up globally to those unit tests as they are simply\nignored. This makes our life easier because we don't have to special\ncase those options with Meson, where test options are set up globally\nvia `meson test --test-args=`.\n\nBut our clar-based unit testing framework is way stricter here and will\nfail in case it is passed an unknown option. Stub out these options with\nno-ops to make our life a bit easier.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n parse-options.h          | 12 ++++++++++++\n t/unit-tests/unit-test.c | 19 ++++++++++++++++++-\n 2 files changed, 30 insertions(+), 1 deletion(-)\n\ndiff --git a/parse-options.h b/parse-options.h\nindex f0801d4532a175b65783689f2a68fb56da2c8e87..d01361ca97fd7227a0005b5c447d954fea472ca0 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -353,6 +353,18 @@ struct option {\n \t.callback = parse_opt_noop_cb, \\\n }\n \n+static char *parse_options_noop_ignored_value MAYBE_UNUSED;\n+#define OPT_NOOP_ARG(s, l) { \\\n+\t.type = OPTION_CALLBACK, \\\n+\t.short_name = (s), \\\n+\t.long_name = (l), \\\n+\t.value = &parse_options_noop_ignored_value, \\\n+\t.argh = \"ignored\", \\\n+\t.help = N_(\"no-op (backward compatibility)\"), \\\n+\t.flags = PARSE_OPT_HIDDEN, \\\n+\t.callback = parse_opt_noop_cb, \\\n+}\n+\n #define OPT_ALIAS(s, l, source_long_name) { \\\n \t.type = OPTION_ALIAS, \\\n \t.short_name = (s), \\\ndiff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c\nindex a474cdcfd351d9d624178a769329252237f951b7..fa8818842a42478c7a8fa6f6ecbee0777bdf472f 100644\n--- a/t/unit-tests/unit-test.c\n+++ b/t/unit-tests/unit-test.c\n@@ -18,8 +18,25 @@ int cmd_main(int argc, const char **argv)\n \t\t\t N_(\"immediately exit upon the first failed test\")),\n \t\tOPT_STRING_LIST('r', \"run\", &run_args, N_(\"suite[::test]\"),\n \t\t\t\tN_(\"run only test suite or individual test <suite[::test]>\")),\n-\t\tOPT_STRING_LIST('x', \"exclude\", &exclude_args, N_(\"suite\"),\n+\t\tOPT_STRING_LIST(0, \"exclude\", &exclude_args, N_(\"suite\"),\n \t\t\t\tN_(\"exclude test suite <suite>\")),\n+\t\t/*\n+\t\t * Compatibility wrappers so that we don't have to filter\n+\t\t * options understood by integration tests.\n+\t\t */\n+\t\tOPT_NOOP_NOARG('d', \"debug\"),\n+\t\tOPT_NOOP_NOARG(0, \"github-workflow-markup\"),\n+\t\tOPT_NOOP_NOARG(0, \"no-bin-wrappers\"),\n+\t\tOPT_NOOP_ARG(0, \"root\"),\n+\t\tOPT_NOOP_ARG(0, \"stress\"),\n+\t\tOPT_NOOP_NOARG(0, \"tee\"),\n+\t\tOPT_NOOP_NOARG(0, \"with-dashes\"),\n+\t\tOPT_NOOP_ARG(0, \"valgrind\"),\n+\t\tOPT_NOOP_ARG(0, \"valgrind-only\"),\n+\t\tOPT_NOOP_NOARG('v', \"verbose\"),\n+\t\tOPT_NOOP_NOARG('V', \"verbose-log\"),\n+\t\tOPT_NOOP_ARG(0, \"verbose-only\"),\n+\t\tOPT_NOOP_NOARG('x', NULL),\n \t\tOPT_END(),\n \t};\n \tstruct strvec args = STRVEC_INIT;\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"508975","messageId":"20241211-pks-meson-ci-v1-8-28d18b494374@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH 8/8] ci: wire up Meson builds","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-11T10:52:39Z","receivedAt":"2024-12-11T10:53:16Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Wire up CI builds for both GitLab and GitHub that use the Meson build\nsystem.\n\nWhile the setup is mostly trivial, one gotcha is the test output\ndirectory used to be in \"t/\", but now it is contained in the build\ndirectory. To unify the logic across Makefile- and Meson-based builds we\nexplicitly set up the `TEST_OUTPUT_DIRECTORY` variable so that it is the\nsame for both build systems.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml |  7 +++++++\n .gitlab-ci.yml             |  9 +++++++++\n ci/install-dependencies.sh |  7 +++++++\n ci/lib.sh                  |  2 +-\n ci/print-test-failures.sh  |  2 +-\n ci/run-build-and-tests.sh  | 31 ++++++++++++++++++++++++-------\n 6 files changed, 49 insertions(+), 9 deletions(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex 808ddc19b8a799abc414c6d6ba078a6e5be6bdfb..c231419abc670fb0bd096c2dce63fd1b66ab14b7 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -286,6 +286,9 @@ jobs:\n           - jobname: osx-gcc\n             cc: gcc-13\n             pool: macos-13\n+          - jobname: osx-meson\n+            cc: clang\n+            pool: macos-13\n           - jobname: linux-gcc-default\n             cc: gcc\n             pool: ubuntu-latest\n@@ -298,11 +301,15 @@ jobs:\n           - jobname: linux-asan-ubsan\n             cc: clang\n             pool: ubuntu-latest\n+          - jobname: linux-meson\n+            cc: gcc\n+            pool: ubuntu-latest\n     env:\n       CC: ${{matrix.vector.cc}}\n       CC_PACKAGE: ${{matrix.vector.cc_package}}\n       jobname: ${{matrix.vector.jobname}}\n       distro: ${{matrix.vector.pool}}\n+      TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t\n     runs-on: ${{matrix.vector.pool}}\n     steps:\n     - uses: actions/checkout@v4\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex a1bc92893f27d6dd404133686b71c8061e55618c..8163aacc8c8715d09f19bd1cc7199532fb5141e2 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -20,6 +20,7 @@ test:linux:\n     - saas-linux-medium-amd64\n   variables:\n     CUSTOM_PATH: \"/custom\"\n+    TEST_OUTPUT_DIRECTORY: \"/tmp/test-output\"\n   before_script:\n     - ./ci/install-dependencies.sh\n   script:\n@@ -31,6 +32,7 @@ test:linux:\n       if test \"$CI_JOB_STATUS\" != 'success'\n       then\n         sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh\n+        mv \"$TEST_OUTPUT_DIRECTORY\"/failed-test-artifacts t/\n       fi\n   parallel:\n     matrix:\n@@ -67,6 +69,10 @@ test:linux:\n         image: fedora:latest\n       - jobname: linux-musl\n         image: alpine:latest\n+      - jobname: linux-meson\n+        image: ubuntu:latest\n+        CC: gcc\n+        CC_PACKAGE: gcc\n   artifacts:\n     paths:\n       - t/failed-test-artifacts\n@@ -104,6 +110,9 @@ test:osx:\n       - jobname: osx-reftable\n         image: macos-13-xcode-14\n         CC: clang\n+      - jobname: osx-meson\n+        image: macos-14-xcode-15\n+        CC: clang\n   artifacts:\n     paths:\n       - t/failed-test-artifacts\ndiff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\nindex d020cb7aa5ef64e8cb9e4c580064a84f4b3d1bfb..d1cb9fa8785388b3674fcea4dd682abc0725c968 100755\n--- a/ci/install-dependencies.sh\n+++ b/ci/install-dependencies.sh\n@@ -58,6 +58,7 @@ ubuntu-*|ubuntu32-*|debian-*)\n \t\tmake libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \\\n \t\ttcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \\\n \t\tlibemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \\\n+\t\tlibpcre2-dev meson ninja-build pkg-config \\\n \t\t${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE\n \n \tcase \"$distro\" in\n@@ -90,6 +91,12 @@ macos-*)\n \tsudo xattr -d com.apple.quarantine \"$CUSTOM_PATH/p4\" \"$CUSTOM_PATH/p4d\" 2>/dev/null || true\n \trm helix-core-server.tgz\n \n+\tcase \"$jobname\" in\n+\tosx-meson)\n+\t\tbrew install meson ninja pcre2\n+\t\t;;\n+\tesac\n+\n \tif test -n \"$CC_PACKAGE\"\n \tthen\n \t\tBREW_PACKAGE=${CC_PACKAGE/-/@}\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex 2e7a5f0540b66f24bd0f5744311c2c48b472d63d..b436f855414226df7f27a1b5ce95702f227d0c53 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -236,7 +236,7 @@ then\n \tCC=\"${CC_PACKAGE:-${CC:-gcc}}\"\n \tDONT_SKIP_TAGS=t\n \thandle_failed_tests () {\n-\t\techo \"FAILED_TEST_ARTIFACTS=t/failed-test-artifacts\" >>$GITHUB_ENV\n+\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts\" >>$GITHUB_ENV\n \t\tcreate_failed_test_artifacts\n \t\treturn 1\n \t}\ndiff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh\nindex b1f80aeac345dd70746b02b6ca1b5282a0c2a4aa..655687dd827e5b3e4d4879803b0d4499e7751380 100755\n--- a/ci/print-test-failures.sh\n+++ b/ci/print-test-failures.sh\n@@ -46,7 +46,7 @@ do\n \t\t\t;;\n \t\tgithub-actions)\n \t\t\tmkdir -p failed-test-artifacts\n-\t\t\techo \"FAILED_TEST_ARTIFACTS=t/failed-test-artifacts\" >>$GITHUB_ENV\n+\t\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts\" >>$GITHUB_ENV\n \t\t\tcp \"${TEST_EXIT%.exit}.out\" failed-test-artifacts/\n \t\t\ttar czf failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n \t\t\tcontinue\ndiff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh\nindex 2e28d02b20f2469afddc4e04fdbd18465babb1ef..c4a41bba0b84df57f6e60aeac2de29dbc0e27dc1 100755\n--- a/ci/run-build-and-tests.sh\n+++ b/ci/run-build-and-tests.sh\n@@ -48,12 +48,29 @@ pedantic)\n \t;;\n esac\n \n-group Build make\n-if test -n \"$run_tests\"\n-then\n-\tgroup \"Run tests\" make test ||\n-\thandle_failed_tests\n-fi\n-check_unignored_build_artifacts\n+case \"$jobname\" in\n+*-meson)\n+\tgroup \"Configure\" meson setup build . \\\n+\t\t--warnlevel 2 --werror \\\n+\t\t--wrap-mode nofallback\n+\tgroup \"Build\" meson compile -C build --\n+\tif test -n \"$run_tests\"\n+\tthen\n+\t\tgroup \"Run tests\" meson test -C build --print-errorlogs --test-args=\"$GIT_TEST_OPTS\" || (\n+\t\t\t./t/aggregate-results.sh \"${TEST_OUTPUT_DIRECTORY:-t}/test-results\"\n+\t\t\thandle_failed_tests\n+\t\t)\n+\tfi\n+\t;;\n+*)\n+\tgroup Build make\n+\tif test -n \"$run_tests\"\n+\tthen\n+\t\tgroup \"Run tests\" make test ||\n+\t\thandle_failed_tests\n+\tfi\n+\t;;\n+esac\n \n+check_unignored_build_artifacts\n save_good_tree\n\n-- \n2.47.1.447.ga7e8429e30.dirty\n\n"},{"id":"509021","messageId":"CAOLa=ZTtkM_unYCjgQf0FZCo=4KOmOiRosC8jPOcs_Np+tCd-g@mail.gmail.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-1-28d18b494374@pks.im","subject":"Re: [PATCH 1/8] ci/lib: support custom output directories when creating test artifacts","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-12-12T10:16:30Z","receivedAt":"2024-12-12T10:16:32Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Update `create_failed_test_artifacts ()` so that it can handle arbitrary\n> test output directories. This fixes creation of these artifacts for\n> macOS on GitLab CI, which uses a separate output directory already. This\n> will also be used by our out-of-tree builds with Meson.\n>\n\nSo currently in the config: `TEST_OUTPUT_DIRECTORY: \"/Volumes/RAMDisk\"`.\nSo this is broken as is?\n\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  ci/lib.sh | 12 ++++++------\n>  1 file changed, 6 insertions(+), 6 deletions(-)\n>\n> diff --git a/ci/lib.sh b/ci/lib.sh\n> index 930f98d7228166c37c236beb062b14675fb68ef3..2e7a5f0540b66f24bd0f5744311c2c48b472d63d 100755\n> --- a/ci/lib.sh\n> +++ b/ci/lib.sh\n> @@ -180,9 +180,9 @@ handle_failed_tests () {\n>  }\n>\n>  create_failed_test_artifacts () {\n> -\tmkdir -p t/failed-test-artifacts\n> +\tmkdir -p \"${TEST_OUTPUT_DIRECTORY:-t}\"/failed-test-artifacts\n>\n> -\tfor test_exit in t/test-results/*.exit\n> +\tfor test_exit in \"${TEST_OUTPUT_DIRECTORY:-t}\"/test-results/*.exit\n>  \tdo\n>  \t\ttest 0 != \"$(cat \"$test_exit\")\" || continue\n>\n> @@ -191,11 +191,11 @@ create_failed_test_artifacts () {\n>  \t\tprintf \"\\\\e[33m\\\\e[1m=== Failed test: ${test_name} ===\\\\e[m\\\\n\"\n>  \t\techo \"The full logs are in the 'print test failures' step below.\"\n>  \t\techo \"See also the 'failed-tests-*' artifacts attached to this run.\"\n> -\t\tcat \"t/test-results/$test_name.markup\"\n> +\t\tcat \"${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.markup\"\n>\n> -\t\ttrash_dir=\"t/trash directory.$test_name\"\n> -\t\tcp \"t/test-results/$test_name.out\" t/failed-test-artifacts/\n> -\t\ttar czf t/failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n> +\t\ttrash_dir=\"${TEST_OUTPUT_DIRECTORY:-t}/trash directory.$test_name\"\n> +\t\tcp \"${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.out\" \"${TEST_OUTPUT_DIRECTORY:-t}\"/failed-test-artifacts/\n> +\t\ttar czf \"${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts/$test_name.trash.tar.gz\" \"$trash_dir\"\n>  \tdone\n>  }\n\nThe changes look good, if the TEST_OUTPUT_DIRECTORY isn't set we default\nto `t` which was the previous directory.\n"},{"id":"509024","messageId":"CAOLa=ZRtQ2ab8_gf348eirDdrJYjSKm28aR6YPeY+7JE=77nOQ@mail.gmail.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-3-28d18b494374@pks.im","subject":"Re: [PATCH 3/8] t/unit-tests: rename clar-based unit tests to have a common prefix","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-12-12T10:42:41Z","receivedAt":"2024-12-12T10:42:43Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> All of the code files for unit tests using the self-grown unit testing\n> framework have have a \"t-\" prefix to their name. This makes it easy to\n\ns/have have/have\n\n> identify them and use globbing in our Makefile and in other places. On\n> the other hand though, our clar-based unit tests have no prefix at all\n> and thus cannot easily be discerned from other files in the unit test\n> directory.\n>\n> Introduce a new \"u-\" prefix for clar-based unit tests. This prefix will\n> be used in a subsequent commit to easily identify such tests.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  Makefile                              | 4 ++--\n>  t/meson.build                         | 4 ++--\n>  t/unit-tests/generate-clar-decls.sh   | 5 ++++-\n>  t/unit-tests/{ctype.c => u-ctype.c}   | 0\n>  t/unit-tests/{strvec.c => u-strvec.c} | 0\n>  5 files changed, 8 insertions(+), 5 deletions(-)\n>\n> diff --git a/Makefile b/Makefile\n> index 2506f3b7e3377ab1a376338c86a727b2ae92a6e9..6eafaf174aaa380ad8e6a86f75d003eb6c058fb3 100644\n> --- a/Makefile\n> +++ b/Makefile\n> @@ -1344,8 +1344,8 @@ THIRD_PARTY_SOURCES += sha1dc/%\n>  THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/%\n>  THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%\n>\n> -CLAR_TEST_SUITES += ctype\n> -CLAR_TEST_SUITES += strvec\n> +CLAR_TEST_SUITES += u-ctype\n> +CLAR_TEST_SUITES += u-strvec\n>  CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X)\n>  CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES))\n>  CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o\n> diff --git a/t/meson.build b/t/meson.build\n> index 13fe854ba0a18f9b83dbc48651f581198042ffd3..9e676e69363ed6311426500d98fe281e30d26bcb 100644\n> --- a/t/meson.build\n> +++ b/t/meson.build\n> @@ -1,6 +1,6 @@\n>  clar_test_suites = [\n> -  'unit-tests/ctype.c',\n> -  'unit-tests/strvec.c',\n> +  'unit-tests/u-ctype.c',\n> +  'unit-tests/u-strvec.c',\n>  ]\n>\n>  clar_sources = [\n> diff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh\n> index 688e0885f4f28182c3afe19c067b6d59dcacccfc..3b315c64b3711bfccc5941852a0782e02cee82f0 100755\n> --- a/t/unit-tests/generate-clar-decls.sh\n> +++ b/t/unit-tests/generate-clar-decls.sh\n> @@ -11,6 +11,9 @@ shift\n>\n>  for suite in \"$@\"\n>  do\n> -\tsed -ne \"s/^\\(void test_$(basename \"${suite%.c}\")__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\\)$/extern \\1;/p\" \"$suite\" ||\n> +\tsuite_name=$(basename \"$suite\")\n\nSo this strips away all dir and keeps the file name.\nSo `t/unit-tests/u-strvec.c` becomes `u-strvec.c`\n\n> +\tsuite_name=${suite_name%.c}\n\nWe strip the .c here, so `u-strvec.c` becomes `u-strvec`\n\n> +\tsuite_name=${suite_name#u-}\n\nSo we finally strip the `u-` prefix here.\n\n> +\tsed -ne \"s/^\\(void test_${suite_name}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\\)$/extern \\1;/p\" \"$suite\" ||\n\nThen we find all test functions in those files. Makes sense.\n\n[snip]\n"},{"id":"509027","messageId":"CAOLa=ZTgQLgWWsgOCufvkaUDD1RwP+cs8eSAK0XuLXXHiZa_4Q@mail.gmail.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-6-28d18b494374@pks.im","subject":"Re: [PATCH 6/8] t: fix out-of-tree tests for some git-p4 tests","fromName":"karthik nayak","fromEmail":"karthik.188@gmail.com","sentAt":"2024-12-12T10:53:47Z","receivedAt":"2024-12-12T10:53:49Z","isPatch":true,"sender":{"key":"karthik.188@gmail.com","avatar":"https://avatars.githubusercontent.com/u/1786334?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Both t9835 and t9836 exercise git-p4, but one exercises Python 2 whereas\n> the other one uses Python 3. These tests do not exercise \"git p4\", but\n> instead they use \"git p4.py\" so that the unbuilt version of \"git-p4.py\"\n> is used that has \"#!/usr/bin/env python\" as shebang instead of the\n> replaced shebang.\n>\n> But \"git-p4.py\" is not in our PATH during out-of-tree builds, and thus\n> we cannot locate \"git-p4.py\". The tests thus break with CMake and Meson.\n>\n> Fix this by instead manually setting up script wrappers that invoke the\n> respective Python interpreter directly.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  t/t9835-git-p4-metadata-encoding-python2.sh | 48 ++++++++++++++-------------\n>  t/t9836-git-p4-metadata-encoding-python3.sh | 50 ++++++++++++++---------------\n>  2 files changed, 50 insertions(+), 48 deletions(-)\n>\n> diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh\n> index 036bf79c6674f6f1f0d667c7270674168428ffee..02f9ec09053890a4d41b7dc95644066d6481bbb6 100755\n> --- a/t/t9835-git-p4-metadata-encoding-python2.sh\n> +++ b/t/t9835-git-p4-metadata-encoding-python2.sh\n> @@ -14,23 +14,25 @@ python_target_version='2'\n>  ## SECTION REPEATED IN t9836 ##\n>  ###############################\n>\n> -# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n> -# latter references a specific path so we can't easily force it to run under\n> -# the python version we need to.\n> -\n> -python_major_version=$(python -V 2>&1 | cut -c  8)\n> -python_target_binary=$(which python$python_target_version)\n> -if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n> +# These tests are specific to Python 2. Write a custom script that executes\n> +# git-p4 directly with the Python 2 interpreter to ensure that we use that\n> +# version even if Git was compiled with Python 3.\n> +python_target_binary=$(which python2)\n> +if test -n \"$python_target_binary\"\n>  then\n>  \tmkdir temp_python\n> -\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n> -\tln -s $python_target_binary temp_python/python\n> +\tPATH=\"$(pwd)/temp_python:$PATH\"\n> +\texport PATH\n> +\n> +\twrite_script temp_python/git-p4-python2 <<-EOF\n> +\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n> +\tEOF\n>  fi\n>\n\nSo if the python version (2 here), is available, we create a temp script\nwhich will use that version. That script is then used in all the\ncommands below. Makes sense.\n\nThis is similarly replicated in `t9836` but with Python 3.\n\n[snip]\n"},{"id":"509046","messageId":"Z1vFKSPMvLNFqBCK@pks.im","threadId":"62624","inReplyTo":"CAOLa=ZTtkM_unYCjgQf0FZCo=4KOmOiRosC8jPOcs_Np+tCd-g@mail.gmail.com","subject":"Re: [PATCH 1/8] ci/lib: support custom output directories when creating test artifacts","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T05:24:57Z","receivedAt":"2024-12-13T05:25:15Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Dec 12, 2024 at 02:16:30AM -0800, karthik nayak wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > Update `create_failed_test_artifacts ()` so that it can handle arbitrary\n> > test output directories. This fixes creation of these artifacts for\n> > macOS on GitLab CI, which uses a separate output directory already. This\n> > will also be used by our out-of-tree builds with Meson.\n> >\n> \n> So currently in the config: `TEST_OUTPUT_DIRECTORY: \"/Volumes/RAMDisk\"`.\n> So this is broken as is?\n\nYeah. I've noticed multiple times that the test output directory is not\nuploaded on failing macOS jobs.\n\nPatrick\n"},{"id":"509047","messageId":"Z1vFLQi9g9J8fCle@pks.im","threadId":"62624","inReplyTo":"CAOLa=ZRtQ2ab8_gf348eirDdrJYjSKm28aR6YPeY+7JE=77nOQ@mail.gmail.com","subject":"Re: [PATCH 3/8] t/unit-tests: rename clar-based unit tests to have a common prefix","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T05:25:01Z","receivedAt":"2024-12-13T05:25:18Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Dec 12, 2024 at 02:42:41AM -0800, karthik nayak wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> > All of the code files for unit tests using the self-grown unit testing\n> > framework have have a \"t-\" prefix to their name. This makes it easy to\n> \n> s/have have/have\n\nIndeed, fixed.\n\nPatrick\n"},{"id":"509048","messageId":"Z1vFNpcaRIFBODZk@pks.im","threadId":"62624","inReplyTo":"CAOLa=ZTgQLgWWsgOCufvkaUDD1RwP+cs8eSAK0XuLXXHiZa_4Q@mail.gmail.com","subject":"Re: [PATCH 6/8] t: fix out-of-tree tests for some git-p4 tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T05:25:10Z","receivedAt":"2024-12-13T05:25:27Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Dec 12, 2024 at 02:53:47AM -0800, karthik nayak wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> > diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh\n> > index 036bf79c6674f6f1f0d667c7270674168428ffee..02f9ec09053890a4d41b7dc95644066d6481bbb6 100755\n> > --- a/t/t9835-git-p4-metadata-encoding-python2.sh\n> > +++ b/t/t9835-git-p4-metadata-encoding-python2.sh\n> > @@ -14,23 +14,25 @@ python_target_version='2'\n> >  ## SECTION REPEATED IN t9836 ##\n> >  ###############################\n> >\n> > -# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n> > -# latter references a specific path so we can't easily force it to run under\n> > -# the python version we need to.\n> > -\n> > -python_major_version=$(python -V 2>&1 | cut -c  8)\n> > -python_target_binary=$(which python$python_target_version)\n> > -if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n> > +# These tests are specific to Python 2. Write a custom script that executes\n> > +# git-p4 directly with the Python 2 interpreter to ensure that we use that\n> > +# version even if Git was compiled with Python 3.\n> > +python_target_binary=$(which python2)\n> > +if test -n \"$python_target_binary\"\n> >  then\n> >  \tmkdir temp_python\n> > -\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n> > -\tln -s $python_target_binary temp_python/python\n> > +\tPATH=\"$(pwd)/temp_python:$PATH\"\n> > +\texport PATH\n> > +\n> > +\twrite_script temp_python/git-p4-python2 <<-EOF\n> > +\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n> > +\tEOF\n> >  fi\n> >\n> \n> So if the python version (2 here), is available, we create a temp script\n> which will use that version. That script is then used in all the\n> commands below. Makes sense.\n> \n> This is similarly replicated in `t9836` but with Python 3.\n\nYeah. This whole setup is just plain awkward from my point of view.\nAnother option would be to accept reality and stop supporting Python 2\naltogether. But doing that as part of this patch series did not feel\nlike a good idea to me.\n\nThanks for your review!\n\nPatrick\n"},{"id":"509062","messageId":"87bjxfj44o.fsf@iotcl.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-4-28d18b494374@pks.im","subject":"Re: [PATCH 4/8] meson: detect missing tests at configure time","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2024-12-13T09:58:47Z","receivedAt":"2024-12-13T09:59:01Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> It is quite easy for the list of integration tests to go out-of-sync\n> without anybody noticing. Introduce a new configure-time check that\n> verifies that all tests are wired up properly.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  t/meson.build | 36 ++++++++++++++++++++++++++++++++++++\n>  1 file changed, 36 insertions(+)\n>\n> diff --git a/t/meson.build b/t/meson.build\n> index 9e676e69363ed6311426500d98fe281e30d26bcb..f1fbc6ae179079f4d5d86f9a60956fad84d0495c 100644\n> --- a/t/meson.build\n> +++ b/t/meson.build\n> @@ -1092,6 +1092,42 @@ integration_tests = [\n>    't9903-bash-prompt.sh',\n>  ]\n>  \n> +# Sanity check that we are not missing any tests present in 't/'. This check\n> +# only runs once at configure time and is thus best-effort, only. It is\n> +# sufficient to catch missing test suites in our CI though.\n> +foreach glob, tests : {\n> +  't[0-9][0-9][0-9][0-9]-*.sh': integration_tests,\n> +  'unit-tests/t-*.c': unit_test_programs,\n> +  'unit-tests/u-*.c': clar_test_suites,\n> +}\n> +  actual_tests = run_command(shell, '-c', 'ls ' + glob,\n> +    check: true,\n> +    env: script_environment,\n> +  ).stdout().strip().split('\\n')\n> +\n> +  if tests != actual_tests\n> +    missing_tests = [ ]\n> +    foreach actual_test : actual_tests\n> +      if actual_test not in tests\n> +        missing_tests += actual_test\n> +      endif\n> +    endforeach\n> +    if missing_tests.length() > 0\n> +      error('Missing tests:\\n\\n - ' + '\\n - '.join(missing_tests))\n\nThis gives nice output:\n\n    $ touch t/unit-tests/u-bar.c t/unit-tests/u-foo.c\n\n    $ meson setup builddir --reconfigure\n\n    The Meson build system\n    Version: 1.4.1\n    [snip]\n    Configuring update.sample using configuration\n    Configuring exclude using configuration\n\n    t/meson.build:1116:6: ERROR: Problem encountered: Missing tests:\n\n     - unit-tests/u-bar.c\n     - unit-tests/u-foo.c\n\n    A full log can be found at git/builddir/meson-logs/meson-log.txt\n\nBut I think the error message is a little bit confusing. It sounds like\nthe test file is missing, but it's the configuration of the test that is\nmissing.\n\nNow I've realized it hard to write a good error message here. But I\nwould suggest something like \"Tests files found, but not configured\".\n\n> +    endif\n> +\n> +    superfluous_tests = [ ]\n> +    foreach integration_test : tests\n> +      if integration_test not in actual_tests\n> +        superfluous_tests += integration_test\n> +      endif\n> +    endforeach\n> +    if superfluous_tests.length() > 0\n> +      error('Superfluous tests:\\n\\n - ' + '\\n - '.join(superfluous_tests))\n\nAlso here I would suggest different error message, maybe something like\n\"Tests configured, but file not found\"\n\n-- \nToon\n"},{"id":"509063","messageId":"87a5czj420.fsf@iotcl.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-6-28d18b494374@pks.im","subject":"Re: [PATCH 6/8] t: fix out-of-tree tests for some git-p4 tests","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2024-12-13T10:00:23Z","receivedAt":"2024-12-13T10:00:43Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Both t9835 and t9836 exercise git-p4, but one exercises Python 2 whereas\n> the other one uses Python 3. These tests do not exercise \"git p4\", but\n> instead they use \"git p4.py\" so that the unbuilt version of \"git-p4.py\"\n> is used that has \"#!/usr/bin/env python\" as shebang instead of the\n> replaced shebang.\n\nIt took me a while to figure out what you mean by \"the replaced\nshebang\"? I think you mean something like:\n\n    These tests do not exercise \"git p4\", but instead they use \"git\n    p4.py\". This calls the unbuilt version of \"git-p4.py\", which has the\n    \"#!/usr/bin/env python\" shebang. This allows the test to modify\n    which `python` comes first in $PATH, making it possible to force a\n    Python version.\n\n> But \"git-p4.py\" is not in our PATH during out-of-tree builds, and thus\n> we cannot locate \"git-p4.py\". The tests thus break with CMake and Meson.\n>\n> Fix this by instead manually setting up script wrappers that invoke the\n> respective Python interpreter directly.\n\nI like this approach, way more explicit now the Python version is in the\ncommand itself.\n\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  t/t9835-git-p4-metadata-encoding-python2.sh | 48 ++++++++++++++-------------\n>  t/t9836-git-p4-metadata-encoding-python3.sh | 50 ++++++++++++++---------------\n>  2 files changed, 50 insertions(+), 48 deletions(-)\n>\n> diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh\n> index 036bf79c6674f6f1f0d667c7270674168428ffee..02f9ec09053890a4d41b7dc95644066d6481bbb6 100755\n> --- a/t/t9835-git-p4-metadata-encoding-python2.sh\n> +++ b/t/t9835-git-p4-metadata-encoding-python2.sh\n> @@ -14,23 +14,25 @@ python_target_version='2'\n>  ## SECTION REPEATED IN t9836 ##\n\nTo be honest, I don't understand why this section wasn't put in a\nfunction in lib-git-p4.sh in the first place, instead of duplicating?\nAnyhow, I think for two test files it's fine to duplicate this code, and\nafter all you're not changing that.\n\nBut I've noticed you are no longer using `python_target_version`. I\nwould suggest to either remove the variable, or use it again so the code\nbetween the two test files is identical again. Doing the latter would\nprobably mean you also need to create a variable like\n`p4_python=p4-python$python_target_version` and use `$p4_python` instead\nof `p4-python2` throughout the script, so I'm not sure that improves\nthings.\n\n>  ###############################\n>  \n> -# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n> -# latter references a specific path so we can't easily force it to run under\n> -# the python version we need to.\n> -\n> -python_major_version=$(python -V 2>&1 | cut -c  8)\n> -python_target_binary=$(which python$python_target_version)\n> -if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n> +# These tests are specific to Python 2. Write a custom script that executes\n> +# git-p4 directly with the Python 2 interpreter to ensure that we use that\n> +# version even if Git was compiled with Python 3.\n> +python_target_binary=$(which python2)\n> +if test -n \"$python_target_binary\"\n>  then\n>  \tmkdir temp_python\n> -\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n> -\tln -s $python_target_binary temp_python/python\n> +\tPATH=\"$(pwd)/temp_python:$PATH\"\n> +\texport PATH\n> +\n> +\twrite_script temp_python/git-p4-python2 <<-EOF\n> +\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n> +\tEOF\n>  fi\n>  \n> -python_major_version=$(python -V 2>&1 | cut -c  8)\n> -if ! test \"$python_major_version\" = \"$python_target_version\"\n> +git p4-python2 >err\n> +if ! grep 'valid commands' err\n\nI like this sanity check, this verifies if the command actually works:\n\nThus the output when the script is properly created:\n\n    usage: /home/toon/devel/git/git-p4 <command> [options]\n\n    valid commands: branches, clone, sync, submit, unshelve, commit, rebase\n\n    Try /home/toon/devel/git/git-p4 <command> --help for command specific help.\n\n\nAnd when the script was not written:\n\n    git: 'p4-python2' is not a git command. See 'git --help'.\n\n\nI noticed though, the stderr output isn's shallowed into /dev/null,\nresulting the output for the test to be the following if Python 2 is not found:\n\n    make[2]: Entering directory '/home/toon/devel/git/t'\n    *** t9835-git-p4-metadata-encoding-python2.sh ***\n    which: no python2 in (/home/toon/devel/git/bin-wrappers:/home/toon/.local/bin:[snip])\n    git: 'p4-python2' is not a git command. See 'git --help'.\n    not ok 1 - start p4d\n\n\nI think that's totally fine though, it's giving the user proper\ninformation about what is wrong.\n\n--\nToon\n"},{"id":"509064","messageId":"878qsjj412.fsf@iotcl.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-7-28d18b494374@pks.im","subject":"Re: [PATCH 7/8] t: introduce compatibility options to clar-based tests","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2024-12-13T10:00:57Z","receivedAt":"2024-12-13T10:01:13Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Our unit tests that don't yet use the clar unit testing framework ignore\n> any option that they do not understand. It is thus fine to just pass\n> test options we set up globally to those unit tests as they are simply\n> ignored. This makes our life easier because we don't have to special\n> case those options with Meson, where test options are set up globally\n> via `meson test --test-args=`.\n>\n> But our clar-based unit testing framework is way stricter here and will\n> fail in case it is passed an unknown option. Stub out these options with\n> no-ops to make our life a bit easier.\n>\n> Signed-off-by: Patrick Steinhardt <ps@pks.im>\n> ---\n>  parse-options.h          | 12 ++++++++++++\n>  t/unit-tests/unit-test.c | 19 ++++++++++++++++++-\n>  2 files changed, 30 insertions(+), 1 deletion(-)\n>\n> diff --git a/parse-options.h b/parse-options.h\n> index f0801d4532a175b65783689f2a68fb56da2c8e87..d01361ca97fd7227a0005b5c447d954fea472ca0 100644\n> --- a/parse-options.h\n> +++ b/parse-options.h\n> @@ -353,6 +353,18 @@ struct option {\n>  \t.callback = parse_opt_noop_cb, \\\n>  }\n>  \n> +static char *parse_options_noop_ignored_value MAYBE_UNUSED;\n> +#define OPT_NOOP_ARG(s, l) { \\\n> +\t.type = OPTION_CALLBACK, \\\n> +\t.short_name = (s), \\\n> +\t.long_name = (l), \\\n> +\t.value = &parse_options_noop_ignored_value, \\\n> +\t.argh = \"ignored\", \\\n> +\t.help = N_(\"no-op (backward compatibility)\"), \\\n> +\t.flags = PARSE_OPT_HIDDEN, \\\n> +\t.callback = parse_opt_noop_cb, \\\n> +}\n> +\n>  #define OPT_ALIAS(s, l, source_long_name) { \\\n>  \t.type = OPTION_ALIAS, \\\n>  \t.short_name = (s), \\\n> diff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c\n> index a474cdcfd351d9d624178a769329252237f951b7..fa8818842a42478c7a8fa6f6ecbee0777bdf472f 100644\n> --- a/t/unit-tests/unit-test.c\n> +++ b/t/unit-tests/unit-test.c\n> @@ -18,8 +18,25 @@ int cmd_main(int argc, const char **argv)\n>  \t\t\t N_(\"immediately exit upon the first failed test\")),\n>  \t\tOPT_STRING_LIST('r', \"run\", &run_args, N_(\"suite[::test]\"),\n>  \t\t\t\tN_(\"run only test suite or individual test <suite[::test]>\")),\n> -\t\tOPT_STRING_LIST('x', \"exclude\", &exclude_args, N_(\"suite\"),\n> +\t\tOPT_STRING_LIST(0, \"exclude\", &exclude_args, N_(\"suite\"),\n\nCould you please explain in the commit message why it's safe to unassign\n`-x` from `--exclude`?\n\n\n-- \nToon\n"},{"id":"509065","messageId":"877c83j40k.fsf@iotcl.com","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-8-28d18b494374@pks.im","subject":"Re: [PATCH 8/8] ci: wire up Meson builds","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2024-12-13T10:01:15Z","receivedAt":"2024-12-13T10:01:26Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n[snip]\n\n> diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\n> index a1bc92893f27d6dd404133686b71c8061e55618c..8163aacc8c8715d09f19bd1cc7199532fb5141e2 100644\n> --- a/.gitlab-ci.yml\n> +++ b/.gitlab-ci.yml\n> @@ -20,6 +20,7 @@ test:linux:\n>      - saas-linux-medium-amd64\n>    variables:\n>      CUSTOM_PATH: \"/custom\"\n> +    TEST_OUTPUT_DIRECTORY: \"/tmp/test-output\"\n>    before_script:\n>      - ./ci/install-dependencies.sh\n>    script:\n> @@ -31,6 +32,7 @@ test:linux:\n>        if test \"$CI_JOB_STATUS\" != 'success'\n>        then\n>          sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh\n> +        mv \"$TEST_OUTPUT_DIRECTORY\"/failed-test-artifacts t/\n>        fi\n>    parallel:\n>      matrix:\n> @@ -67,6 +69,10 @@ test:linux:\n>          image: fedora:latest\n>        - jobname: linux-musl\n>          image: alpine:latest\n> +      - jobname: linux-meson\n> +        image: ubuntu:latest\n> +        CC: gcc\n> +        CC_PACKAGE: gcc\n\nIs it needed to explicitly set the CC_PACKAGE? I see in other places we\nonly set it when it's set to `gcc-8`?\n\n-- \nToon\n"},{"id":"509079","messageId":"Z1wPC1vSlqgWeFis@pks.im","threadId":"62624","inReplyTo":"87bjxfj44o.fsf@iotcl.com","subject":"Re: [PATCH 4/8] meson: detect missing tests at configure time","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:40:11Z","receivedAt":"2024-12-13T10:40:29Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Dec 13, 2024 at 10:58:47AM +0100, Toon Claes wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> > diff --git a/t/meson.build b/t/meson.build\n> > index 9e676e69363ed6311426500d98fe281e30d26bcb..f1fbc6ae179079f4d5d86f9a60956fad84d0495c 100644\n> > --- a/t/meson.build\n> > +++ b/t/meson.build\n> > @@ -1092,6 +1092,42 @@ integration_tests = [\n> >    't9903-bash-prompt.sh',\n> >  ]\n> >  \n> > +# Sanity check that we are not missing any tests present in 't/'. This check\n> > +# only runs once at configure time and is thus best-effort, only. It is\n> > +# sufficient to catch missing test suites in our CI though.\n> > +foreach glob, tests : {\n> > +  't[0-9][0-9][0-9][0-9]-*.sh': integration_tests,\n> > +  'unit-tests/t-*.c': unit_test_programs,\n> > +  'unit-tests/u-*.c': clar_test_suites,\n> > +}\n> > +  actual_tests = run_command(shell, '-c', 'ls ' + glob,\n> > +    check: true,\n> > +    env: script_environment,\n> > +  ).stdout().strip().split('\\n')\n> > +\n> > +  if tests != actual_tests\n> > +    missing_tests = [ ]\n> > +    foreach actual_test : actual_tests\n> > +      if actual_test not in tests\n> > +        missing_tests += actual_test\n> > +      endif\n> > +    endforeach\n> > +    if missing_tests.length() > 0\n> > +      error('Missing tests:\\n\\n - ' + '\\n - '.join(missing_tests))\n> \n> This gives nice output:\n> \n>     $ touch t/unit-tests/u-bar.c t/unit-tests/u-foo.c\n> \n>     $ meson setup builddir --reconfigure\n> \n>     The Meson build system\n>     Version: 1.4.1\n>     [snip]\n>     Configuring update.sample using configuration\n>     Configuring exclude using configuration\n> \n>     t/meson.build:1116:6: ERROR: Problem encountered: Missing tests:\n> \n>      - unit-tests/u-bar.c\n>      - unit-tests/u-foo.c\n> \n>     A full log can be found at git/builddir/meson-logs/meson-log.txt\n> \n> But I think the error message is a little bit confusing. It sounds like\n> the test file is missing, but it's the configuration of the test that is\n> missing.\n> \n> Now I've realized it hard to write a good error message here. But I\n> would suggest something like \"Tests files found, but not configured\".\n> \n> > +    endif\n> > +\n> > +    superfluous_tests = [ ]\n> > +    foreach integration_test : tests\n> > +      if integration_test not in actual_tests\n> > +        superfluous_tests += integration_test\n> > +      endif\n> > +    endforeach\n> > +    if superfluous_tests.length() > 0\n> > +      error('Superfluous tests:\\n\\n - ' + '\\n - '.join(superfluous_tests))\n> \n> Also here I would suggest different error message, maybe something like\n> \"Tests configured, but file not found\"\n\nBoth good suggestions, thanks!\n\nPatrick\n"},{"id":"509080","messageId":"Z1wPD7xSHRs1ID_g@pks.im","threadId":"62624","inReplyTo":"87a5czj420.fsf@iotcl.com","subject":"Re: [PATCH 6/8] t: fix out-of-tree tests for some git-p4 tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:40:15Z","receivedAt":"2024-12-13T10:40:39Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Dec 13, 2024 at 11:00:23AM +0100, Toon Claes wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> > diff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh\n> > index 036bf79c6674f6f1f0d667c7270674168428ffee..02f9ec09053890a4d41b7dc95644066d6481bbb6 100755\n> > --- a/t/t9835-git-p4-metadata-encoding-python2.sh\n> > +++ b/t/t9835-git-p4-metadata-encoding-python2.sh\n> > @@ -14,23 +14,25 @@ python_target_version='2'\n> >  ## SECTION REPEATED IN t9836 ##\n> \n> To be honest, I don't understand why this section wasn't put in a\n> function in lib-git-p4.sh in the first place, instead of duplicating?\n> Anyhow, I think for two test files it's fine to duplicate this code, and\n> after all you're not changing that.\n> \n> But I've noticed you are no longer using `python_target_version`. I\n> would suggest to either remove the variable, or use it again so the code\n> between the two test files is identical again. Doing the latter would\n> probably mean you also need to create a variable like\n> `p4_python=p4-python$python_target_version` and use `$p4_python` instead\n> of `p4-python2` throughout the script, so I'm not sure that improves\n> things.\n\nGood catch. I did it in the Python 3 test, but forgot to do it here, as\nwell.\n\n> >  ###############################\n> >  \n> > -# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n> > -# latter references a specific path so we can't easily force it to run under\n> > -# the python version we need to.\n> > -\n> > -python_major_version=$(python -V 2>&1 | cut -c  8)\n> > -python_target_binary=$(which python$python_target_version)\n> > -if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n> > +# These tests are specific to Python 2. Write a custom script that executes\n> > +# git-p4 directly with the Python 2 interpreter to ensure that we use that\n> > +# version even if Git was compiled with Python 3.\n> > +python_target_binary=$(which python2)\n> > +if test -n \"$python_target_binary\"\n> >  then\n> >  \tmkdir temp_python\n> > -\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n> > -\tln -s $python_target_binary temp_python/python\n> > +\tPATH=\"$(pwd)/temp_python:$PATH\"\n> > +\texport PATH\n> > +\n> > +\twrite_script temp_python/git-p4-python2 <<-EOF\n> > +\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n> > +\tEOF\n> >  fi\n> >  \n> > -python_major_version=$(python -V 2>&1 | cut -c  8)\n> > -if ! test \"$python_major_version\" = \"$python_target_version\"\n> > +git p4-python2 >err\n> > +if ! grep 'valid commands' err\n> \n> I like this sanity check, this verifies if the command actually works:\n> \n> Thus the output when the script is properly created:\n> \n>     usage: /home/toon/devel/git/git-p4 <command> [options]\n> \n>     valid commands: branches, clone, sync, submit, unshelve, commit, rebase\n> \n>     Try /home/toon/devel/git/git-p4 <command> --help for command specific help.\n> \n> \n> And when the script was not written:\n> \n>     git: 'p4-python2' is not a git command. See 'git --help'.\n> \n> \n> I noticed though, the stderr output isn's shallowed into /dev/null,\n> resulting the output for the test to be the following if Python 2 is not found:\n> \n>     make[2]: Entering directory '/home/toon/devel/git/t'\n>     *** t9835-git-p4-metadata-encoding-python2.sh ***\n>     which: no python2 in (/home/toon/devel/git/bin-wrappers:/home/toon/.local/bin:[snip])\n>     git: 'p4-python2' is not a git command. See 'git --help'.\n>     not ok 1 - start p4d\n> \n> \n> I think that's totally fine though, it's giving the user proper\n> information about what is wrong.\n\nYeah, I actually consider it a win to have it. Not that anybody ever\nexecutes these tests outside of CI anyway.\n\nPatrick\n"},{"id":"509081","messageId":"Z1wPEmv8f-omCxUL@pks.im","threadId":"62624","inReplyTo":"877c83j40k.fsf@iotcl.com","subject":"Re: [PATCH 8/8] ci: wire up Meson builds","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:40:18Z","receivedAt":"2024-12-13T10:40:40Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Dec 13, 2024 at 11:01:15AM +0100, Toon Claes wrote:\n> Patrick Steinhardt <ps@pks.im> writes:\n> \n> [snip]\n> \n> > diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\n> > index a1bc92893f27d6dd404133686b71c8061e55618c..8163aacc8c8715d09f19bd1cc7199532fb5141e2 100644\n> > --- a/.gitlab-ci.yml\n> > +++ b/.gitlab-ci.yml\n> > @@ -20,6 +20,7 @@ test:linux:\n> >      - saas-linux-medium-amd64\n> >    variables:\n> >      CUSTOM_PATH: \"/custom\"\n> > +    TEST_OUTPUT_DIRECTORY: \"/tmp/test-output\"\n> >    before_script:\n> >      - ./ci/install-dependencies.sh\n> >    script:\n> > @@ -31,6 +32,7 @@ test:linux:\n> >        if test \"$CI_JOB_STATUS\" != 'success'\n> >        then\n> >          sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh\n> > +        mv \"$TEST_OUTPUT_DIRECTORY\"/failed-test-artifacts t/\n> >        fi\n> >    parallel:\n> >      matrix:\n> > @@ -67,6 +69,10 @@ test:linux:\n> >          image: fedora:latest\n> >        - jobname: linux-musl\n> >          image: alpine:latest\n> > +      - jobname: linux-meson\n> > +        image: ubuntu:latest\n> > +        CC: gcc\n> > +        CC_PACKAGE: gcc\n> \n> Is it needed to explicitly set the CC_PACKAGE? I see in other places we\n> only set it when it's set to `gcc-8`?\n\nGood point, it's not necessary.\n\nThanks for your review!\n\nPatrick\n"},{"id":"509082","messageId":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241211-pks-meson-ci-v1-0-28d18b494374@pks.im","subject":"[PATCH v2 0/8] ci: wire up support for Meson","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:15Z","receivedAt":"2024-12-13T10:41:34Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Hi,\n\nthis small patch series wires up Meson into our CI systems. The intent\nis to ensure that it does not regress in functionality as the Git code\nbase evolves.\n\nTo help with keeping it up-to-date, both Meson and our Makefiles learn\nto detect missing or superseded test files in \"t/meson.build\". This\nshould give users an early notification in case they have to add a newly\nadded or removed test to these build instructions. Overall I think that\nthis shouldn't be too much of a burden given that adding a new test is\ntrivial.\n\nOne gap that still exists is newly added code files. Due to many sources\nbeing added to the build conditionally it's hard to have generic checks\nfor these. So I refrain from doing so in this series -- the build would\nalready fail anyway when we're missing code, so at least we will know\nthat something is up.\n\nChanges in v2:\n\n  - Improve a couple of commit messages.\n  - Explain why we remove `-x` from the unit-test driver.\n  - Remove unneeded `CC_PACKAGE` variable.\n  - Improve error messages when tests weren't found.\n  - Link to v1: https://lore.kernel.org/r/20241211-pks-meson-ci-v1-0-28d18b494374@pks.im\n\nThe series is built on top of caacdb5dfd (The fifteenth batch,\n2024-12-10) with ps/build at 904339edbd (Introduce support for the Meson\nbuild system, 2024-12-06) and cw/worktree-extension at 2037ca85ad\n(worktree: refactor `repair_worktree_after_gitdir_move()`, 2024-11-29)\nmerged into it.\n\nThanks!\n\nPatrick\n\n---\nPatrick Steinhardt (8):\n      ci/lib: support custom output directories when creating test artifacts\n      Makefile: drop -DSUPPRESS_ANNOTATED_LEAKS\n      t/unit-tests: rename clar-based unit tests to have a common prefix\n      meson: detect missing tests at configure time\n      Makefile: detect missing Meson tests\n      t: fix out-of-tree tests for some git-p4 tests\n      t: introduce compatibility options to clar-based tests\n      ci: wire up Meson builds\n\n .github/workflows/main.yml                  |  7 ++++\n .gitlab-ci.yml                              |  8 +++++\n Makefile                                    |  5 ++-\n ci/install-dependencies.sh                  |  7 ++++\n ci/lib.sh                                   | 14 ++++----\n ci/print-test-failures.sh                   |  2 +-\n ci/run-build-and-tests.sh                   | 31 ++++++++++++++----\n meson.build                                 |  1 -\n parse-options.h                             | 12 +++++++\n t/Makefile                                  | 18 ++++++++++-\n t/meson.build                               | 40 +++++++++++++++++++++--\n t/t9835-git-p4-metadata-encoding-python2.sh | 50 ++++++++++++++---------------\n t/t9836-git-p4-metadata-encoding-python3.sh | 50 ++++++++++++++---------------\n t/unit-tests/generate-clar-decls.sh         |  5 ++-\n t/unit-tests/{ctype.c => u-ctype.c}         |  0\n t/unit-tests/{strvec.c => u-strvec.c}       |  0\n t/unit-tests/unit-test.c                    | 19 ++++++++++-\n 17 files changed, 195 insertions(+), 74 deletions(-)\n\nRange-diff versus v1:\n\n1:  329404a926 = 1:  43562781da ci/lib: support custom output directories when creating test artifacts\n2:  71a8cbc131 = 2:  f1655e9338 Makefile: drop -DSUPPRESS_ANNOTATED_LEAKS\n3:  29e75b59e5 ! 3:  f5403a7ce0 t/unit-tests: rename clar-based unit tests to have a common prefix\n    @@ Commit message\n         t/unit-tests: rename clar-based unit tests to have a common prefix\n     \n         All of the code files for unit tests using the self-grown unit testing\n    -    framework have have a \"t-\" prefix to their name. This makes it easy to\n    +    framework have a \"t-\" prefix to their name. This makes it easy to\n         identify them and use globbing in our Makefile and in other places. On\n         the other hand though, our clar-based unit tests have no prefix at all\n         and thus cannot easily be discerned from other files in the unit test\n4:  644903d148 ! 4:  99a4ffdc2a meson: detect missing tests at configure time\n    @@ t/meson.build: integration_tests = [\n     +      endif\n     +    endforeach\n     +    if missing_tests.length() > 0\n    -+      error('Missing tests:\\n\\n - ' + '\\n - '.join(missing_tests))\n    ++      error('Test files found, but not configured:\\n\\n - ' + '\\n - '.join(missing_tests))\n     +    endif\n     +\n     +    superfluous_tests = [ ]\n    @@ t/meson.build: integration_tests = [\n     +      endif\n     +    endforeach\n     +    if superfluous_tests.length() > 0\n    -+      error('Superfluous tests:\\n\\n - ' + '\\n - '.join(superfluous_tests))\n    ++      error('Test files configured, but not found:\\n\\n - ' + '\\n - '.join(superfluous_tests))\n     +    endif\n     +  endif\n     +endforeach\n5:  afad056353 = 5:  ce27e9c1a6 Makefile: detect missing Meson tests\n6:  e398d80f77 ! 6:  8c46997ba4 t: fix out-of-tree tests for some git-p4 tests\n    @@ Commit message\n     \n         Both t9835 and t9836 exercise git-p4, but one exercises Python 2 whereas\n         the other one uses Python 3. These tests do not exercise \"git p4\", but\n    -    instead they use \"git p4.py\" so that the unbuilt version of \"git-p4.py\"\n    -    is used that has \"#!/usr/bin/env python\" as shebang instead of the\n    -    replaced shebang.\n    +    instead they use \"git p4.py\". This calls the unbuilt version of\n    +    \"git-p4.py\" that still has the \"#!/usr/bin/env python\" shebang, which\n    +    allows the test to modify which Python version comes first in $PATH,\n    +    making it possible to force a Python version.\n     \n         But \"git-p4.py\" is not in our PATH during out-of-tree builds, and thus\n         we cannot locate \"git-p4.py\". The tests thus break with CMake and Meson.\n    @@ Commit message\n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n      ## t/t9835-git-p4-metadata-encoding-python2.sh ##\n    -@@ t/t9835-git-p4-metadata-encoding-python2.sh: python_target_version='2'\n    +@@ t/t9835-git-p4-metadata-encoding-python2.sh: failing, and produces maximally sane output in git.'\n    + \n    + . ./lib-git-p4.sh\n    + \n    +-python_target_version='2'\n    +-\n    + ###############################\n      ## SECTION REPEATED IN t9836 ##\n      ###############################\n      \n7:  efa4698fee ! 7:  357f8e7e67 t: introduce compatibility options to clar-based tests\n    @@ Commit message\n         fail in case it is passed an unknown option. Stub out these options with\n         no-ops to make our life a bit easier.\n     \n    +    Note that this also requires us to remove the `-x` short option for\n    +    `--exclude`. This is because `-x` has another meaning in our integration\n    +    tests, as it enables shell tracing. I doubt there are a lot of people\n    +    out there using it as we only got a small hand full of clar tests in the\n    +    first place. So better change it now so that we can in the long run\n    +    improve compatibility between the two different test drivers.\n    +\n         Signed-off-by: Patrick Steinhardt <ps@pks.im>\n     \n      ## parse-options.h ##\n8:  d6f7685eca ! 8:  c1c27341eb ci: wire up Meson builds\n    @@ .gitlab-ci.yml: test:linux:\n     +      - jobname: linux-meson\n     +        image: ubuntu:latest\n     +        CC: gcc\n    -+        CC_PACKAGE: gcc\n        artifacts:\n          paths:\n            - t/failed-test-artifacts\n\n---\nbase-commit: 2fcbf72f13e8ce3bf1cda9a689f392f8f6e5c65d\nchange-id: 20241129-pks-meson-ci-ba1e40652fbe\n\n"},{"id":"509083","messageId":"20241213-pks-meson-ci-v2-1-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 1/8] ci/lib: support custom output directories when creating test artifacts","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:16Z","receivedAt":"2024-12-13T10:41:35Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Update `create_failed_test_artifacts ()` so that it can handle arbitrary\ntest output directories. This fixes creation of these artifacts for\nmacOS on GitLab CI, which uses a separate output directory already. This\nwill also be used by our out-of-tree builds with Meson.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n ci/lib.sh | 12 ++++++------\n 1 file changed, 6 insertions(+), 6 deletions(-)\n\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex 930f98d7228166c37c236beb062b14675fb68ef3..2e7a5f0540b66f24bd0f5744311c2c48b472d63d 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -180,9 +180,9 @@ handle_failed_tests () {\n }\n \n create_failed_test_artifacts () {\n-\tmkdir -p t/failed-test-artifacts\n+\tmkdir -p \"${TEST_OUTPUT_DIRECTORY:-t}\"/failed-test-artifacts\n \n-\tfor test_exit in t/test-results/*.exit\n+\tfor test_exit in \"${TEST_OUTPUT_DIRECTORY:-t}\"/test-results/*.exit\n \tdo\n \t\ttest 0 != \"$(cat \"$test_exit\")\" || continue\n \n@@ -191,11 +191,11 @@ create_failed_test_artifacts () {\n \t\tprintf \"\\\\e[33m\\\\e[1m=== Failed test: ${test_name} ===\\\\e[m\\\\n\"\n \t\techo \"The full logs are in the 'print test failures' step below.\"\n \t\techo \"See also the 'failed-tests-*' artifacts attached to this run.\"\n-\t\tcat \"t/test-results/$test_name.markup\"\n+\t\tcat \"${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.markup\"\n \n-\t\ttrash_dir=\"t/trash directory.$test_name\"\n-\t\tcp \"t/test-results/$test_name.out\" t/failed-test-artifacts/\n-\t\ttar czf t/failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n+\t\ttrash_dir=\"${TEST_OUTPUT_DIRECTORY:-t}/trash directory.$test_name\"\n+\t\tcp \"${TEST_OUTPUT_DIRECTORY:-t}/test-results/$test_name.out\" \"${TEST_OUTPUT_DIRECTORY:-t}\"/failed-test-artifacts/\n+\t\ttar czf \"${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts/$test_name.trash.tar.gz\" \"$trash_dir\"\n \tdone\n }\n \n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509084","messageId":"20241213-pks-meson-ci-v2-2-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 2/8] Makefile: drop -DSUPPRESS_ANNOTATED_LEAKS","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:17Z","receivedAt":"2024-12-13T10:41:37Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"The -DSUPPRESS_ANNOTATED_LEAKS preprocessor directive was used to enable\nour `UNLEAK()` macro in the past, which marks memory as still-reachable\nso that the leak sanitizer does not complain. Starting with 52c7dbd036\n(git-compat-util: drop now-unused `UNLEAK()` macro, 2024-11-20) this\nmacro has been removed, and thus the preprocessor directive is not\nrequired anymore, either.\n\nDrop it.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n Makefile    | 1 -\n meson.build | 1 -\n 2 files changed, 2 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 06f01149ecf399ae4bb1932188a007948d767283..2506f3b7e3377ab1a376338c86a727b2ae92a6e9 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1490,7 +1490,6 @@ ifneq ($(filter undefined,$(SANITIZERS)),)\n BASIC_CFLAGS += -DSHA1DC_FORCE_ALIGNED_ACCESS\n endif\n ifneq ($(filter leak,$(SANITIZERS)),)\n-BASIC_CFLAGS += -DSUPPRESS_ANNOTATED_LEAKS\n BASIC_CFLAGS += -O0\n SANITIZE_LEAK = YesCompiledWithIt\n endif\ndiff --git a/meson.build b/meson.build\nindex 0dccebcdf16b07650d943e53643f0e09e2975cc9..1af25af5cc1e718a4e50fb14274a36f811506219 100644\n--- a/meson.build\n+++ b/meson.build\n@@ -712,7 +712,6 @@ else\n   build_options_config.set('SANITIZE_ADDRESS', '')\n endif\n if get_option('b_sanitize').contains('leak')\n-  libgit_c_args += '-DSUPPRESS_ANNOTATED_LEAKS'\n   build_options_config.set('SANITIZE_LEAK', 'YesCompiledWithIt')\n else\n   build_options_config.set('SANITIZE_LEAK', '')\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509085","messageId":"20241213-pks-meson-ci-v2-3-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 3/8] t/unit-tests: rename clar-based unit tests to have a common prefix","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:18Z","receivedAt":"2024-12-13T10:41:38Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"All of the code files for unit tests using the self-grown unit testing\nframework have a \"t-\" prefix to their name. This makes it easy to\nidentify them and use globbing in our Makefile and in other places. On\nthe other hand though, our clar-based unit tests have no prefix at all\nand thus cannot easily be discerned from other files in the unit test\ndirectory.\n\nIntroduce a new \"u-\" prefix for clar-based unit tests. This prefix will\nbe used in a subsequent commit to easily identify such tests.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n Makefile                              | 4 ++--\n t/meson.build                         | 4 ++--\n t/unit-tests/generate-clar-decls.sh   | 5 ++++-\n t/unit-tests/{ctype.c => u-ctype.c}   | 0\n t/unit-tests/{strvec.c => u-strvec.c} | 0\n 5 files changed, 8 insertions(+), 5 deletions(-)\n\ndiff --git a/Makefile b/Makefile\nindex 2506f3b7e3377ab1a376338c86a727b2ae92a6e9..6eafaf174aaa380ad8e6a86f75d003eb6c058fb3 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -1344,8 +1344,8 @@ THIRD_PARTY_SOURCES += sha1dc/%\n THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/%\n THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/%\n \n-CLAR_TEST_SUITES += ctype\n-CLAR_TEST_SUITES += strvec\n+CLAR_TEST_SUITES += u-ctype\n+CLAR_TEST_SUITES += u-strvec\n CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X)\n CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES))\n CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o\ndiff --git a/t/meson.build b/t/meson.build\nindex 13fe854ba0a18f9b83dbc48651f581198042ffd3..9e676e69363ed6311426500d98fe281e30d26bcb 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -1,6 +1,6 @@\n clar_test_suites = [\n-  'unit-tests/ctype.c',\n-  'unit-tests/strvec.c',\n+  'unit-tests/u-ctype.c',\n+  'unit-tests/u-strvec.c',\n ]\n \n clar_sources = [\ndiff --git a/t/unit-tests/generate-clar-decls.sh b/t/unit-tests/generate-clar-decls.sh\nindex 688e0885f4f28182c3afe19c067b6d59dcacccfc..3b315c64b3711bfccc5941852a0782e02cee82f0 100755\n--- a/t/unit-tests/generate-clar-decls.sh\n+++ b/t/unit-tests/generate-clar-decls.sh\n@@ -11,6 +11,9 @@ shift\n \n for suite in \"$@\"\n do\n-\tsed -ne \"s/^\\(void test_$(basename \"${suite%.c}\")__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\\)$/extern \\1;/p\" \"$suite\" ||\n+\tsuite_name=$(basename \"$suite\")\n+\tsuite_name=${suite_name%.c}\n+\tsuite_name=${suite_name#u-}\n+\tsed -ne \"s/^\\(void test_${suite_name}__[a-zA-Z_0-9][a-zA-Z_0-9]*(void)\\)$/extern \\1;/p\" \"$suite\" ||\n \texit 1\n done >\"$OUTPUT\"\ndiff --git a/t/unit-tests/ctype.c b/t/unit-tests/u-ctype.c\nsimilarity index 100%\nrename from t/unit-tests/ctype.c\nrename to t/unit-tests/u-ctype.c\ndiff --git a/t/unit-tests/strvec.c b/t/unit-tests/u-strvec.c\nsimilarity index 100%\nrename from t/unit-tests/strvec.c\nrename to t/unit-tests/u-strvec.c\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509086","messageId":"20241213-pks-meson-ci-v2-4-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 4/8] meson: detect missing tests at configure time","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:19Z","receivedAt":"2024-12-13T10:41:40Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"It is quite easy for the list of integration tests to go out-of-sync\nwithout anybody noticing. Introduce a new configure-time check that\nverifies that all tests are wired up properly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/meson.build | 36 ++++++++++++++++++++++++++++++++++++\n 1 file changed, 36 insertions(+)\n\ndiff --git a/t/meson.build b/t/meson.build\nindex 9e676e69363ed6311426500d98fe281e30d26bcb..602ebfe6a260211eb2083e5808058852ca86e7a0 100644\n--- a/t/meson.build\n+++ b/t/meson.build\n@@ -1092,6 +1092,42 @@ integration_tests = [\n   't9903-bash-prompt.sh',\n ]\n \n+# Sanity check that we are not missing any tests present in 't/'. This check\n+# only runs once at configure time and is thus best-effort, only. It is\n+# sufficient to catch missing test suites in our CI though.\n+foreach glob, tests : {\n+  't[0-9][0-9][0-9][0-9]-*.sh': integration_tests,\n+  'unit-tests/t-*.c': unit_test_programs,\n+  'unit-tests/u-*.c': clar_test_suites,\n+}\n+  actual_tests = run_command(shell, '-c', 'ls ' + glob,\n+    check: true,\n+    env: script_environment,\n+  ).stdout().strip().split('\\n')\n+\n+  if tests != actual_tests\n+    missing_tests = [ ]\n+    foreach actual_test : actual_tests\n+      if actual_test not in tests\n+        missing_tests += actual_test\n+      endif\n+    endforeach\n+    if missing_tests.length() > 0\n+      error('Test files found, but not configured:\\n\\n - ' + '\\n - '.join(missing_tests))\n+    endif\n+\n+    superfluous_tests = [ ]\n+    foreach integration_test : tests\n+      if integration_test not in actual_tests\n+        superfluous_tests += integration_test\n+      endif\n+    endforeach\n+    if superfluous_tests.length() > 0\n+      error('Test files configured, but not found:\\n\\n - ' + '\\n - '.join(superfluous_tests))\n+    endif\n+  endif\n+endforeach\n+\n # GIT_BUILD_DIR needs to be Unix-style without drive prefixes as it get added\n # to the PATH variable. And given that drive prefixes contain a colon we'd\n # otherwise end up with a broken PATH if we didn't convert it.\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509087","messageId":"20241213-pks-meson-ci-v2-5-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 5/8] Makefile: detect missing Meson tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:20Z","receivedAt":"2024-12-13T10:41:41Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"In the preceding commit, we have introduced consistency checks to Meson\nto detect any discrepancies with missing or extraneous tests in its\nbuild instructions. These checks only get executed in Meson though, so\nany users of our Makefiles wouldn't be alerted of the fact that they\nhave to modify the Meson build instructions in case they add or remove\nany tests.\n\nAdd a comparable test target to our Makefile to plug this gap.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/Makefile | 18 +++++++++++++++++-\n 1 file changed, 17 insertions(+), 1 deletion(-)\n\ndiff --git a/t/Makefile b/t/Makefile\nindex 131ffd778fe00864fae1f5750269615556c6cdea..290fb03ff011d39c31c5073c796aa6f4dc966283 100644\n--- a/t/Makefile\n+++ b/t/Makefile\n@@ -59,7 +59,7 @@ CHAINLINTSUPPRESS = GIT_TEST_EXT_CHAIN_LINT=0 && export GIT_TEST_EXT_CHAIN_LINT\n \n all:: $(DEFAULT_TEST_TARGET)\n \n-test: pre-clean check-chainlint $(TEST_LINT)\n+test: pre-clean check-chainlint check-meson $(TEST_LINT)\n \t$(CHAINLINTSUPPRESS) $(MAKE) aggregate-results-and-cleanup\n \n failed:\n@@ -114,6 +114,22 @@ check-chainlint:\n \t{ $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \\\n \tdiff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual\n \n+check-meson:\n+\t@# awk acts up when trying to match single quotes, so we use \\047 instead.\n+\t@printf \"%s\\n\" \\\n+\t\t\"integration_tests t[0-9][0-9][0-9][0-9]-*.sh\" \\\n+\t\t\"unit_test_programs unit-tests/t-*.c\" \\\n+\t\t\"clar_test_suites unit-tests/u-*.c\" | \\\n+\twhile read -r variable pattern; do \\\n+\t\tmeson_tests=$$(awk \"/^$$variable = \\[\\$$/ {flag=1 ; next } /^]$$/ { flag=0 } flag { gsub(/^  \\047/, \\\"\\\"); gsub(/\\047,\\$$/, \\\"\\\"); print }\" meson.build) && \\\n+\t\tactual_tests=$$(ls $$pattern) && \\\n+\t\tif test \"$$meson_tests\" != \"$$actual_tests\"; then \\\n+\t\t\techo \"Meson tests differ from actual tests:\"; \\\n+\t\t\tdiff -u <(echo \"$$meson_tests\") <(echo \"$$actual_tests\"); \\\n+\t\t\texit 1; \\\n+\t\tfi; \\\n+\tdone\n+\n test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \\\n \ttest-lint-filenames\n ifneq ($(GIT_TEST_CHAIN_LINT),0)\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509088","messageId":"20241213-pks-meson-ci-v2-6-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 6/8] t: fix out-of-tree tests for some git-p4 tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:21Z","receivedAt":"2024-12-13T10:41:42Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Both t9835 and t9836 exercise git-p4, but one exercises Python 2 whereas\nthe other one uses Python 3. These tests do not exercise \"git p4\", but\ninstead they use \"git p4.py\". This calls the unbuilt version of\n\"git-p4.py\" that still has the \"#!/usr/bin/env python\" shebang, which\nallows the test to modify which Python version comes first in $PATH,\nmaking it possible to force a Python version.\n\nBut \"git-p4.py\" is not in our PATH during out-of-tree builds, and thus\nwe cannot locate \"git-p4.py\". The tests thus break with CMake and Meson.\n\nFix this by instead manually setting up script wrappers that invoke the\nrespective Python interpreter directly.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n t/t9835-git-p4-metadata-encoding-python2.sh | 50 ++++++++++++++---------------\n t/t9836-git-p4-metadata-encoding-python3.sh | 50 ++++++++++++++---------------\n 2 files changed, 50 insertions(+), 50 deletions(-)\n\ndiff --git a/t/t9835-git-p4-metadata-encoding-python2.sh b/t/t9835-git-p4-metadata-encoding-python2.sh\nindex 036bf79c6674f6f1f0d667c7270674168428ffee..6116f806f631157aca7de6dbd33dcd94bbefb8aa 100755\n--- a/t/t9835-git-p4-metadata-encoding-python2.sh\n+++ b/t/t9835-git-p4-metadata-encoding-python2.sh\n@@ -8,29 +8,29 @@ failing, and produces maximally sane output in git.'\n \n . ./lib-git-p4.sh\n \n-python_target_version='2'\n-\n ###############################\n ## SECTION REPEATED IN t9836 ##\n ###############################\n \n-# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n-# latter references a specific path so we can't easily force it to run under\n-# the python version we need to.\n-\n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-python_target_binary=$(which python$python_target_version)\n-if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n+# These tests are specific to Python 2. Write a custom script that executes\n+# git-p4 directly with the Python 2 interpreter to ensure that we use that\n+# version even if Git was compiled with Python 3.\n+python_target_binary=$(which python2)\n+if test -n \"$python_target_binary\"\n then\n \tmkdir temp_python\n-\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n-\tln -s $python_target_binary temp_python/python\n+\tPATH=\"$(pwd)/temp_python:$PATH\"\n+\texport PATH\n+\n+\twrite_script temp_python/git-p4-python2 <<-EOF\n+\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n+\tEOF\n fi\n \n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-if ! test \"$python_major_version\" = \"$python_target_version\"\n+git p4-python2 >err\n+if ! grep 'valid commands' err\n then\n-\tskip_all=\"skipping python$python_target_version-specific git p4 tests; python$python_target_version not available\"\n+\tskip_all=\"skipping python2 git p4 tests; python2 not available\"\n \ttest_done\n fi\n \n@@ -81,14 +81,14 @@ test_expect_success 'init depot' '\n test_expect_success 'clone non-utf8 repo with strict encoding' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest=\"$git\" //depot@all 2>err &&\n+\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python2 clone --dest=\"$git\" //depot@all 2>err &&\n \tgrep \"Decoding perforce metadata failed!\" err\n '\n \n test_expect_success 'check utf-8 contents with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -100,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' '\n test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -114,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st\n test_expect_success 'check utf-8 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -126,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' '\n test_expect_success 'check latin-1 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -138,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' '\n test_expect_success 'check cp-1252 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -150,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' '\n test_expect_success 'check cp850 contents parsed with correct fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -162,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' '\n test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -174,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback'\n test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$cli\" &&\n \t\tP4USER=cp1252_author &&\n@@ -186,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n \t(\n \t\tcd \"$git\" &&\n \n-\t\tgit p4.py sync --branch=master &&\n+\t\tgit p4-python2 sync --branch=master &&\n \n \t\tgit log p4/master >actual &&\n \t\tgrep \"sœme more cp-1252 tæxt\" actual &&\n@@ -201,7 +201,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n test_expect_success 'passthrough (latin-1 contents corrupted in git) is the default with python2' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python2 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\ndiff --git a/t/t9836-git-p4-metadata-encoding-python3.sh b/t/t9836-git-p4-metadata-encoding-python3.sh\nindex 63350dc4b5c6262480cd0be8fd88fba714c55428..5e5217a66b4fdb3c7fcf073a50952c7e9009e9fe 100755\n--- a/t/t9836-git-p4-metadata-encoding-python3.sh\n+++ b/t/t9836-git-p4-metadata-encoding-python3.sh\n@@ -8,29 +8,29 @@ failing, and produces maximally sane output in git.'\n \n . ./lib-git-p4.sh\n \n-python_target_version='3'\n-\n ###############################\n ## SECTION REPEATED IN t9835 ##\n ###############################\n \n-# Please note: this test calls \"git-p4.py\" rather than \"git-p4\", because the\n-# latter references a specific path so we can't easily force it to run under\n-# the python version we need to.\n-\n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-python_target_binary=$(which python$python_target_version)\n-if ! test \"$python_major_version\" = \"$python_target_version\" && test \"$python_target_binary\"\n+# These tests are specific to Python 3. Write a custom script that executes\n+# git-p4 directly with the Python 3 interpreter to ensure that we use that\n+# version even if Git was compiled with Python 2.\n+python_target_binary=$(which python3)\n+if test -n \"$python_target_binary\"\n then\n \tmkdir temp_python\n-\tPATH=\"$(pwd)/temp_python:$PATH\" && export PATH\n-\tln -s $python_target_binary temp_python/python\n+\tPATH=\"$(pwd)/temp_python:$PATH\"\n+\texport PATH\n+\n+\twrite_script temp_python/git-p4-python3 <<-EOF\n+\texec \"$python_target_binary\" \"$(git --exec-path)/git-p4\" \"\\$@\"\n+\tEOF\n fi\n \n-python_major_version=$(python -V 2>&1 | cut -c  8)\n-if ! test \"$python_major_version\" = \"$python_target_version\"\n+git p4-python3 >err\n+if ! grep 'valid commands' err\n then\n-\tskip_all=\"skipping python$python_target_version-specific git p4 tests; python$python_target_version not available\"\n+\tskip_all=\"skipping python3 git p4 tests; python3 not available\"\n \ttest_done\n fi\n \n@@ -81,14 +81,14 @@ test_expect_success 'init depot' '\n test_expect_success 'clone non-utf8 repo with strict encoding' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4.py clone --dest=\"$git\" //depot@all 2>err &&\n+\ttest_must_fail git -c git-p4.metadataDecodingStrategy=strict p4-python3 clone --dest=\"$git\" //depot@all 2>err &&\n \tgrep \"Decoding perforce metadata failed!\" err\n '\n \n test_expect_success 'check utf-8 contents with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -100,7 +100,7 @@ test_expect_success 'check utf-8 contents with passthrough strategy' '\n test_expect_success 'check latin-1 contents corrupted in git with passthrough strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=passthrough p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=passthrough p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -114,7 +114,7 @@ test_expect_success 'check latin-1 contents corrupted in git with passthrough st\n test_expect_success 'check utf-8 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -126,7 +126,7 @@ test_expect_success 'check utf-8 contents with fallback strategy' '\n test_expect_success 'check latin-1 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -138,7 +138,7 @@ test_expect_success 'check latin-1 contents with fallback strategy' '\n test_expect_success 'check cp-1252 contents with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -150,7 +150,7 @@ test_expect_success 'check cp-1252 contents with fallback strategy' '\n test_expect_success 'check cp850 contents parsed with correct fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback -c git-p4.metadataFallbackEncoding=cp850 p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -162,7 +162,7 @@ test_expect_success 'check cp850 contents parsed with correct fallback' '\n test_expect_success 'check cp850-only contents escaped when cp1252 is fallback' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n@@ -174,7 +174,7 @@ test_expect_success 'check cp850-only contents escaped when cp1252 is fallback'\n test_expect_success 'check cp-1252 contents on later sync after clone with fallback strategy' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit -c git-p4.metadataDecodingStrategy=fallback p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit -c git-p4.metadataDecodingStrategy=fallback p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$cli\" &&\n \t\tP4USER=cp1252_author &&\n@@ -186,7 +186,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n \t(\n \t\tcd \"$git\" &&\n \n-\t\tgit p4.py sync --branch=master &&\n+\t\tgit p4-python3 sync --branch=master &&\n \n \t\tgit log p4/master >actual &&\n \t\tgrep \"sœme more cp-1252 tæxt\" actual &&\n@@ -202,7 +202,7 @@ test_expect_success 'check cp-1252 contents on later sync after clone with fallb\n test_expect_success 'fallback (both utf-8 and cp-1252 contents handled) is the default with python3' '\n \ttest_when_finished cleanup_git &&\n \ttest_when_finished remove_user_cache &&\n-\tgit p4.py clone --dest=\"$git\" //depot@all &&\n+\tgit p4-python3 clone --dest=\"$git\" //depot@all &&\n \t(\n \t\tcd \"$git\" &&\n \t\tgit log >actual &&\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509089","messageId":"20241213-pks-meson-ci-v2-7-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 7/8] t: introduce compatibility options to clar-based tests","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:22Z","receivedAt":"2024-12-13T10:41:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Our unit tests that don't yet use the clar unit testing framework ignore\nany option that they do not understand. It is thus fine to just pass\ntest options we set up globally to those unit tests as they are simply\nignored. This makes our life easier because we don't have to special\ncase those options with Meson, where test options are set up globally\nvia `meson test --test-args=`.\n\nBut our clar-based unit testing framework is way stricter here and will\nfail in case it is passed an unknown option. Stub out these options with\nno-ops to make our life a bit easier.\n\nNote that this also requires us to remove the `-x` short option for\n`--exclude`. This is because `-x` has another meaning in our integration\ntests, as it enables shell tracing. I doubt there are a lot of people\nout there using it as we only got a small hand full of clar tests in the\nfirst place. So better change it now so that we can in the long run\nimprove compatibility between the two different test drivers.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n parse-options.h          | 12 ++++++++++++\n t/unit-tests/unit-test.c | 19 ++++++++++++++++++-\n 2 files changed, 30 insertions(+), 1 deletion(-)\n\ndiff --git a/parse-options.h b/parse-options.h\nindex f0801d4532a175b65783689f2a68fb56da2c8e87..d01361ca97fd7227a0005b5c447d954fea472ca0 100644\n--- a/parse-options.h\n+++ b/parse-options.h\n@@ -353,6 +353,18 @@ struct option {\n \t.callback = parse_opt_noop_cb, \\\n }\n \n+static char *parse_options_noop_ignored_value MAYBE_UNUSED;\n+#define OPT_NOOP_ARG(s, l) { \\\n+\t.type = OPTION_CALLBACK, \\\n+\t.short_name = (s), \\\n+\t.long_name = (l), \\\n+\t.value = &parse_options_noop_ignored_value, \\\n+\t.argh = \"ignored\", \\\n+\t.help = N_(\"no-op (backward compatibility)\"), \\\n+\t.flags = PARSE_OPT_HIDDEN, \\\n+\t.callback = parse_opt_noop_cb, \\\n+}\n+\n #define OPT_ALIAS(s, l, source_long_name) { \\\n \t.type = OPTION_ALIAS, \\\n \t.short_name = (s), \\\ndiff --git a/t/unit-tests/unit-test.c b/t/unit-tests/unit-test.c\nindex a474cdcfd351d9d624178a769329252237f951b7..fa8818842a42478c7a8fa6f6ecbee0777bdf472f 100644\n--- a/t/unit-tests/unit-test.c\n+++ b/t/unit-tests/unit-test.c\n@@ -18,8 +18,25 @@ int cmd_main(int argc, const char **argv)\n \t\t\t N_(\"immediately exit upon the first failed test\")),\n \t\tOPT_STRING_LIST('r', \"run\", &run_args, N_(\"suite[::test]\"),\n \t\t\t\tN_(\"run only test suite or individual test <suite[::test]>\")),\n-\t\tOPT_STRING_LIST('x', \"exclude\", &exclude_args, N_(\"suite\"),\n+\t\tOPT_STRING_LIST(0, \"exclude\", &exclude_args, N_(\"suite\"),\n \t\t\t\tN_(\"exclude test suite <suite>\")),\n+\t\t/*\n+\t\t * Compatibility wrappers so that we don't have to filter\n+\t\t * options understood by integration tests.\n+\t\t */\n+\t\tOPT_NOOP_NOARG('d', \"debug\"),\n+\t\tOPT_NOOP_NOARG(0, \"github-workflow-markup\"),\n+\t\tOPT_NOOP_NOARG(0, \"no-bin-wrappers\"),\n+\t\tOPT_NOOP_ARG(0, \"root\"),\n+\t\tOPT_NOOP_ARG(0, \"stress\"),\n+\t\tOPT_NOOP_NOARG(0, \"tee\"),\n+\t\tOPT_NOOP_NOARG(0, \"with-dashes\"),\n+\t\tOPT_NOOP_ARG(0, \"valgrind\"),\n+\t\tOPT_NOOP_ARG(0, \"valgrind-only\"),\n+\t\tOPT_NOOP_NOARG('v', \"verbose\"),\n+\t\tOPT_NOOP_NOARG('V', \"verbose-log\"),\n+\t\tOPT_NOOP_ARG(0, \"verbose-only\"),\n+\t\tOPT_NOOP_NOARG('x', NULL),\n \t\tOPT_END(),\n \t};\n \tstruct strvec args = STRVEC_INIT;\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509090","messageId":"20241213-pks-meson-ci-v2-8-634affccc694@pks.im","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"[PATCH v2 8/8] ci: wire up Meson builds","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2024-12-13T10:41:23Z","receivedAt":"2024-12-13T10:41:44Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"Wire up CI builds for both GitLab and GitHub that use the Meson build\nsystem.\n\nWhile the setup is mostly trivial, one gotcha is the test output\ndirectory used to be in \"t/\", but now it is contained in the build\ndirectory. To unify the logic across Makefile- and Meson-based builds we\nexplicitly set up the `TEST_OUTPUT_DIRECTORY` variable so that it is the\nsame for both build systems.\n\nSigned-off-by: Patrick Steinhardt <ps@pks.im>\n---\n .github/workflows/main.yml |  7 +++++++\n .gitlab-ci.yml             |  8 ++++++++\n ci/install-dependencies.sh |  7 +++++++\n ci/lib.sh                  |  2 +-\n ci/print-test-failures.sh  |  2 +-\n ci/run-build-and-tests.sh  | 31 ++++++++++++++++++++++++-------\n 6 files changed, 48 insertions(+), 9 deletions(-)\n\ndiff --git a/.github/workflows/main.yml b/.github/workflows/main.yml\nindex 808ddc19b8a799abc414c6d6ba078a6e5be6bdfb..c231419abc670fb0bd096c2dce63fd1b66ab14b7 100644\n--- a/.github/workflows/main.yml\n+++ b/.github/workflows/main.yml\n@@ -286,6 +286,9 @@ jobs:\n           - jobname: osx-gcc\n             cc: gcc-13\n             pool: macos-13\n+          - jobname: osx-meson\n+            cc: clang\n+            pool: macos-13\n           - jobname: linux-gcc-default\n             cc: gcc\n             pool: ubuntu-latest\n@@ -298,11 +301,15 @@ jobs:\n           - jobname: linux-asan-ubsan\n             cc: clang\n             pool: ubuntu-latest\n+          - jobname: linux-meson\n+            cc: gcc\n+            pool: ubuntu-latest\n     env:\n       CC: ${{matrix.vector.cc}}\n       CC_PACKAGE: ${{matrix.vector.cc_package}}\n       jobname: ${{matrix.vector.jobname}}\n       distro: ${{matrix.vector.pool}}\n+      TEST_OUTPUT_DIRECTORY: ${{github.workspace}}/t\n     runs-on: ${{matrix.vector.pool}}\n     steps:\n     - uses: actions/checkout@v4\ndiff --git a/.gitlab-ci.yml b/.gitlab-ci.yml\nindex a1bc92893f27d6dd404133686b71c8061e55618c..3eec72ddc666f593521058b5f38eb6220f42ce0f 100644\n--- a/.gitlab-ci.yml\n+++ b/.gitlab-ci.yml\n@@ -20,6 +20,7 @@ test:linux:\n     - saas-linux-medium-amd64\n   variables:\n     CUSTOM_PATH: \"/custom\"\n+    TEST_OUTPUT_DIRECTORY: \"/tmp/test-output\"\n   before_script:\n     - ./ci/install-dependencies.sh\n   script:\n@@ -31,6 +32,7 @@ test:linux:\n       if test \"$CI_JOB_STATUS\" != 'success'\n       then\n         sudo --preserve-env --set-home --user=builder ./ci/print-test-failures.sh\n+        mv \"$TEST_OUTPUT_DIRECTORY\"/failed-test-artifacts t/\n       fi\n   parallel:\n     matrix:\n@@ -67,6 +69,9 @@ test:linux:\n         image: fedora:latest\n       - jobname: linux-musl\n         image: alpine:latest\n+      - jobname: linux-meson\n+        image: ubuntu:latest\n+        CC: gcc\n   artifacts:\n     paths:\n       - t/failed-test-artifacts\n@@ -104,6 +109,9 @@ test:osx:\n       - jobname: osx-reftable\n         image: macos-13-xcode-14\n         CC: clang\n+      - jobname: osx-meson\n+        image: macos-14-xcode-15\n+        CC: clang\n   artifacts:\n     paths:\n       - t/failed-test-artifacts\ndiff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh\nindex d020cb7aa5ef64e8cb9e4c580064a84f4b3d1bfb..d1cb9fa8785388b3674fcea4dd682abc0725c968 100755\n--- a/ci/install-dependencies.sh\n+++ b/ci/install-dependencies.sh\n@@ -58,6 +58,7 @@ ubuntu-*|ubuntu32-*|debian-*)\n \t\tmake libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \\\n \t\ttcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \\\n \t\tlibemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \\\n+\t\tlibpcre2-dev meson ninja-build pkg-config \\\n \t\t${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE\n \n \tcase \"$distro\" in\n@@ -90,6 +91,12 @@ macos-*)\n \tsudo xattr -d com.apple.quarantine \"$CUSTOM_PATH/p4\" \"$CUSTOM_PATH/p4d\" 2>/dev/null || true\n \trm helix-core-server.tgz\n \n+\tcase \"$jobname\" in\n+\tosx-meson)\n+\t\tbrew install meson ninja pcre2\n+\t\t;;\n+\tesac\n+\n \tif test -n \"$CC_PACKAGE\"\n \tthen\n \t\tBREW_PACKAGE=${CC_PACKAGE/-/@}\ndiff --git a/ci/lib.sh b/ci/lib.sh\nindex 2e7a5f0540b66f24bd0f5744311c2c48b472d63d..b436f855414226df7f27a1b5ce95702f227d0c53 100755\n--- a/ci/lib.sh\n+++ b/ci/lib.sh\n@@ -236,7 +236,7 @@ then\n \tCC=\"${CC_PACKAGE:-${CC:-gcc}}\"\n \tDONT_SKIP_TAGS=t\n \thandle_failed_tests () {\n-\t\techo \"FAILED_TEST_ARTIFACTS=t/failed-test-artifacts\" >>$GITHUB_ENV\n+\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts\" >>$GITHUB_ENV\n \t\tcreate_failed_test_artifacts\n \t\treturn 1\n \t}\ndiff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh\nindex b1f80aeac345dd70746b02b6ca1b5282a0c2a4aa..655687dd827e5b3e4d4879803b0d4499e7751380 100755\n--- a/ci/print-test-failures.sh\n+++ b/ci/print-test-failures.sh\n@@ -46,7 +46,7 @@ do\n \t\t\t;;\n \t\tgithub-actions)\n \t\t\tmkdir -p failed-test-artifacts\n-\t\t\techo \"FAILED_TEST_ARTIFACTS=t/failed-test-artifacts\" >>$GITHUB_ENV\n+\t\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts\" >>$GITHUB_ENV\n \t\t\tcp \"${TEST_EXIT%.exit}.out\" failed-test-artifacts/\n \t\t\ttar czf failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n \t\t\tcontinue\ndiff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh\nindex 2e28d02b20f2469afddc4e04fdbd18465babb1ef..c4a41bba0b84df57f6e60aeac2de29dbc0e27dc1 100755\n--- a/ci/run-build-and-tests.sh\n+++ b/ci/run-build-and-tests.sh\n@@ -48,12 +48,29 @@ pedantic)\n \t;;\n esac\n \n-group Build make\n-if test -n \"$run_tests\"\n-then\n-\tgroup \"Run tests\" make test ||\n-\thandle_failed_tests\n-fi\n-check_unignored_build_artifacts\n+case \"$jobname\" in\n+*-meson)\n+\tgroup \"Configure\" meson setup build . \\\n+\t\t--warnlevel 2 --werror \\\n+\t\t--wrap-mode nofallback\n+\tgroup \"Build\" meson compile -C build --\n+\tif test -n \"$run_tests\"\n+\tthen\n+\t\tgroup \"Run tests\" meson test -C build --print-errorlogs --test-args=\"$GIT_TEST_OPTS\" || (\n+\t\t\t./t/aggregate-results.sh \"${TEST_OUTPUT_DIRECTORY:-t}/test-results\"\n+\t\t\thandle_failed_tests\n+\t\t)\n+\tfi\n+\t;;\n+*)\n+\tgroup Build make\n+\tif test -n \"$run_tests\"\n+\tthen\n+\t\tgroup \"Run tests\" make test ||\n+\t\thandle_failed_tests\n+\tfi\n+\t;;\n+esac\n \n+check_unignored_build_artifacts\n save_good_tree\n\n-- \n2.47.1.668.gf74b3f243a.dirty\n\n"},{"id":"509108","messageId":"xmqqzfkza85c.fsf@gitster.g","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-7-634affccc694@pks.im","subject":"Re: [PATCH v2 7/8] t: introduce compatibility options to clar-based tests","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-12-13T15:56:47Z","receivedAt":"2024-12-13T15:56:51Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Note that this also requires us to remove the `-x` short option for\n> `--exclude`. This is because `-x` has another meaning in our integration\n> tests, as it enables shell tracing. I doubt there are a lot of people\n> out there using it as we only got a small hand full of clar tests in the\n> first place. So better change it now so that we can in the long run\n> improve compatibility between the two different test drivers.\n\nYup, even though we always hate to see a change that forces people\nto adjust to, this is a developer thing, and it certainly is better\nto do such a change, if we must, earlier.\n\nThanks.\n"},{"id":"509149","messageId":"87zfkwgehr.fsf@iotcl.com","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-0-634affccc694@pks.im","subject":"Re: [PATCH v2 0/8] ci: wire up support for Meson","fromName":"Toon Claes","fromEmail":"toon@iotcl.com","sentAt":"2024-12-16T09:32:16Z","receivedAt":"2024-12-16T09:32:30Z","isPatch":true,"sender":{"key":"toon@iotcl.com","avatar":"https://avatars.githubusercontent.com/u/121621?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n> Changes in v2:\n>\n>   - Improve a couple of commit messages.\n>   - Explain why we remove `-x` from the unit-test driver.\n>   - Remove unneeded `CC_PACKAGE` variable.\n>   - Improve error messages when tests weren't found.\n>   - Link to v1: https://lore.kernel.org/r/20241211-pks-meson-ci-v1-0-28d18b494374@pks.im\n>\n> The series is built on top of caacdb5dfd (The fifteenth batch,\n> 2024-12-10) with ps/build at 904339edbd (Introduce support for the Meson\n> build system, 2024-12-06) and cw/worktree-extension at 2037ca85ad\n> (worktree: refactor `repair_worktree_after_gitdir_move()`, 2024-11-29)\n> merged into it.\n>\n> Thanks!\n>\n> Patrick\n\nI went through the range-diff and looked at the individual patches, and\nI've got no more comments.\n\n-- \nToon\n"},{"id":"509169","messageId":"xmqqa5cv7fux.fsf@gitster.g","threadId":"62624","inReplyTo":"87zfkwgehr.fsf@iotcl.com","subject":"Re: [PATCH v2 0/8] ci: wire up support for Meson","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2024-12-16T16:27:34Z","receivedAt":"2024-12-16T16:27:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Toon Claes <toon@iotcl.com> writes:\n\n> Patrick Steinhardt <ps@pks.im> writes:\n>\n>> Changes in v2:\n>>\n>>   - Improve a couple of commit messages.\n>>   - Explain why we remove `-x` from the unit-test driver.\n>>   - Remove unneeded `CC_PACKAGE` variable.\n>>   - Improve error messages when tests weren't found.\n>>   - Link to v1: https://lore.kernel.org/r/20241211-pks-meson-ci-v1-0-28d18b494374@pks.im\n>>\n>> The series is built on top of caacdb5dfd (The fifteenth batch,\n>> 2024-12-10) with ps/build at 904339edbd (Introduce support for the Meson\n>> build system, 2024-12-06) and cw/worktree-extension at 2037ca85ad\n>> (worktree: refactor `repair_worktree_after_gitdir_move()`, 2024-11-29)\n>> merged into it.\n>>\n>> Thanks!\n>>\n>> Patrick\n>\n> I went through the range-diff and looked at the individual patches, and\n> I've got no more comments.\n\nThanks, both.  Let's mark the topic for 'next'.\n"},{"id":"522128","messageId":"xmqqa553alp1.fsf_-_@gitster.g","threadId":"62624","inReplyTo":"20241213-pks-meson-ci-v2-8-634affccc694@pks.im","subject":"[PATCH] ci: allow github-actions print test failures again","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2025-07-16T21:07:54Z","receivedAt":"2025-07-16T21:07:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"eab5dbab (ci: wire up Meson builds, 2024-12-13) added two instances\nof a very similar construct\n\n    FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts\n\none to ci/lib.sh and the other to ci/print-test-failures.sh\nUnfortunately, the latter had a typo causing shell to emit \"Bad\nsubstitution\".  Fix it.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n ci/print-test-failures.sh | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh\nindex dc910e5160..5545e77c13 100755\n--- a/ci/print-test-failures.sh\n+++ b/ci/print-test-failures.sh\n@@ -41,7 +41,7 @@ do\n \t\tcase \"$CI_TYPE\" in\n \t\tgithub-actions)\n \t\t\tmkdir -p failed-test-artifacts\n-\t\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts\" >>$GITHUB_ENV\n+\t\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts\" >>$GITHUB_ENV\n \t\t\tcp \"${TEST_EXIT%.exit}.out\" failed-test-artifacts/\n \t\t\ttar czf failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n \t\t\tcontinue\n-- \n2.50.1-447-g6271d3ee0b\n\n"},{"id":"522150","messageId":"aHh_c3KDGC9oQIzQ@pks.im","threadId":"62624","inReplyTo":"xmqqa553alp1.fsf_-_@gitster.g","subject":"Re: [PATCH] ci: allow github-actions print test failures again","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2025-07-17T04:43:31Z","receivedAt":"2025-07-17T04:43:38Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Wed, Jul 16, 2025 at 02:07:54PM -0700, Junio C Hamano wrote:\n> eab5dbab (ci: wire up Meson builds, 2024-12-13) added two instances\n> of a very similar construct\n> \n>     FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts\n> \n> one to ci/lib.sh and the other to ci/print-test-failures.sh\n> Unfortunately, the latter had a typo causing shell to emit \"Bad\n> substitution\".  Fix it.\n> \n> Signed-off-by: Junio C Hamano <gitster@pobox.com>\n> ---\n>  ci/print-test-failures.sh | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n> \n> diff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh\n> index dc910e5160..5545e77c13 100755\n> --- a/ci/print-test-failures.sh\n> +++ b/ci/print-test-failures.sh\n> @@ -41,7 +41,7 @@ do\n>  \t\tcase \"$CI_TYPE\" in\n>  \t\tgithub-actions)\n>  \t\t\tmkdir -p failed-test-artifacts\n> -\t\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts\" >>$GITHUB_ENV\n> +\t\t\techo \"FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts\" >>$GITHUB_ENV\n>  \t\t\tcp \"${TEST_EXIT%.exit}.out\" failed-test-artifacts/\n>  \t\t\ttar czf failed-test-artifacts/\"$test_name\".trash.tar.gz \"$trash_dir\"\n>  \t\t\tcontinue\n\nOh, indeed. Thanks for catching the mistake, the patch looks obviously\ngood to me.\n\nPatrick\n"}]}