diff --git a/.github/workflows/test.sh b/.github/workflows/test.sh index 8ba124d..4fff2d1 100644 --- a/.github/workflows/test.sh +++ b/.github/workflows/test.sh @@ -3,11 +3,13 @@ set -e PLATFORM=$(python -c 'import sys; print(sys.platform)') RED="\033[31;1m" +BLUE="\033[34m" MAGENTA="\033[35m" NORMAL="\033[0m" ptest() { echo -e "\n${MAGENTA}[TEST] $@${NORMAL}\n" ; } -prun() { echo -e "$RED\$ $@ $NORMAL" ; "$@" ; } +perror() { echo -e "\n${RED}[ERROR] $@${NORMAL}\n" ; } +prun() { echo -e "${BLUE}\$ $@ ${NORMAL}" ; "$@" ; } prun cd example_pkg @@ -16,13 +18,32 @@ prun spin --version ptest build command runs pip install meson-python ninja -prun spin build + + +# Test spin build + debug builds +echo "Creating debug builds" +prun spin build --gcov +ptest Did the build folder get generated? +if [ ! -d "build" ] || [ ! -d "build-install" ]; then + perror build and/or build-install folders did not get generated + exit 1 +else + echo "Yes" +fi +ptest Does the debug build contain gcov files? +matching_files=$(find . -type f -name "*.gc*") +if [ -z "$matching_files" ]; then + perror Debug files did not get generated + exit 1 +else + echo "Yes" +fi ptest Does spin expand \$PYTHONPATH? SPIN_PYTHONPATH=$(spin run 'echo $PYTHONPATH') echo spin sees PYTHONPATH=\"${SPIN_PYTHONPATH}\" if [[ ${SPIN_PYTHONPATH} == "\$PYTHONPATH" ]]; then - echo "Expected Python path, but got $SPIN_PYTHONPATH instead" + perror Expected Python path, but got $SPIN_PYTHONPATH instead exit 1 fi @@ -39,7 +60,7 @@ VERSION=$(spin run python -c 'import sys; del sys.path[0]; import example_pkg; p if [[ $VERSION == "0.0.0dev0" ]]; then echo "Yes" else - echo "No, output is $VERSION" + perror No, output is $VERSION exit 1 fi @@ -49,7 +70,7 @@ OUT=$(spin run ls) if [[ $OUT == *"Warning! An editable installation"* ]]; then echo "Yes" else - echo "No" + perror No exit 1 fi prun pip uninstall --quiet -y example_pkg @@ -63,7 +84,7 @@ if [[ $PLATFORM == linux || $PLATFORM == darwin ]]; then if [[ $OUT == *"Did you mean to call"* ]]; then echo "Yes" else - echo "No, output is: $OUT" + perror No, output is: $OUT exit 1 fi fi diff --git a/spin/cmds/meson.py b/spin/cmds/meson.py index 0f4442a..84f2cf2 100644 --- a/spin/cmds/meson.py +++ b/spin/cmds/meson.py @@ -130,8 +130,24 @@ def _meson_version_configured(): @click.option( "-v", "--verbose", is_flag=True, help="Print detailed build and installation output" ) +@click.option( + "--gcov", + is_flag=True, + help="""Enable C code coverage via `gcov`. + + The meson-generated `build/build.ninja` has targets for compiling + coverage reports. + + E.g., to build an HTML report, in the `build` directory run + `ninja coverage-html`. + + To see a list all supported formats, run + `ninja -t targets | grep coverage-`. + + Also see https://mesonbuild.com/howtox.html#producing-a-coverage-report.""", +) @click.argument("meson_args", nargs=-1) -def build(meson_args, jobs=None, clean=False, verbose=False, quiet=False): +def build(meson_args, jobs=None, clean=False, verbose=False, gcov=False, quiet=False): """🔧 Build package with Meson/ninja and install MESON_ARGS are passed through e.g.: @@ -150,7 +166,12 @@ def build(meson_args, jobs=None, clean=False, verbose=False, quiet=False): CFLAGS="-O0 -g" spin build """ build_dir = "build" - setup_cmd = _meson_cli() + ["setup", build_dir, "--prefix=/usr"] + list(meson_args) + meson_args = list(meson_args) + + if gcov: + meson_args = meson_args + ["-Db_coverage=true"] + + setup_cmd = _meson_cli() + ["setup", build_dir, "--prefix=/usr"] + meson_args if clean: print(f"Removing `{build_dir}`") @@ -236,8 +257,15 @@ def _get_configured_command(command_name): is_flag=True, help="Generate a coverage report of executed tests. An HTML copy of the report is written to `build/coverage`.", ) +@click.option( + "--gcov", + is_flag=True, + help="Enable C code coverage via `gcov`. `gcov` output goes to `build/**/*.gc*`. " + "Reports can be generated using `ninja coverage*` commands. " + "See https://mesonbuild.com/howtox.html#producing-a-coverage-report", +) @click.pass_context -def test(ctx, pytest_args, n_jobs, tests, verbose, coverage=False): +def test(ctx, pytest_args, n_jobs, tests, verbose, coverage=False, gcov=False): """🔧 Run tests PYTEST_ARGS are passed through directly to pytest, e.g.: @@ -283,7 +311,7 @@ def test(ctx, pytest_args, n_jobs, tests, verbose, coverage=False): click.secho( "Invoking `build` prior to running tests:", bold=True, fg="bright_green" ) - ctx.invoke(build_cmd) + ctx.invoke(build_cmd, gcov=gcov) package = cfg.get("tool.spin.package", None) if (not pytest_args) and (not tests):