Skip to content

Conversation

@davidlion
Copy link
Member

@davidlion davidlion commented Aug 23, 2025

  • Use checksum tasks to prevent unnecessary repetition of Boost tasks.
  • Remove quotes and spaces from Boost parameter strings.
  • Remove unused GENERATE_* arguments.
  • Update Boost unit tests to use 1.89.0.

Description

(Depends on #81.)

Previously, we avoided using taskfile sources and generates with build systems (CMake and Boost's b2) and deferred to them to decide what work to repeat. This has been somewhat acceptable for CMake projects, but causes long build times for projects using Boost.

This PR modifies the Boost tasks to use the existing checksum tasks to mark successful states of the build process, allowing future builds to skip running unnecessary tasks. A detailed header comment is added to exports/taskfiles/utils/checksum.yaml detailing the recommended usage.

In addition it makes a few small changes:

  • Remove quotes and spaces from Boost parameter strings, which would cause them to not work correctly.
  • Removes unused GENERATE_* arguments in preference of fixed versions.
  • Updates the Boost unit tests to use Boost 1.89.

Additional comments on updating checksums

Another approach considered, was to "snapshot" the state at the end of each task. This would be done by having each task copy the contents of its sources to a new location before mutating them. The main issue with this approach is that if any of these contents stored a path, the path would be made incorrect by the copy. This is not acceptable in many cases and prevents it from being a "general" solution. However, this approach may still be preferable in cases where it is important to recover from absolutely any stage.

Checklist

  • The PR satisfies the contribution guidelines.
  • This is a breaking change and that has been indicated in the PR title, OR this isn't a
    breaking change.
  • Necessary docs have been updated, OR no docs need to be updated.

Validation performed

Tested locally using the Boost unit tests and ystdlib-cpp by deleting certain fails and observing what tasks ran.
Added some unit tests for the checksum tasks to verify behaviour.

Summary by CodeRabbit

  • Chores

    • Upgraded Boost from 1.86.0 to 1.89.0.
    • Removed Boost.System from test dependencies.
  • Refactor

    • Restructured download/build/install flows to a tar-based, single-source model with unified source/build/install directories.
    • Added per-stage checksum and sentinel artifacts for stronger artifact validation.
  • Chores

    • Enabled stricter shell error handling and recursive globbing in checksum tooling.

@davidlion davidlion requested a review from a team as a code owner August 23, 2025 06:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 23, 2025

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Refactors Boost taskfiles to use SOURCE_DIR/BUILD_DIR/INSTALL_PREFIX (and WORK_DIR/TAR inputs), add per-stage checksum files and a SOURCE_SENTINEL_FILE, replace GENERATE_DIR flow with in-place generation, switch download to a tar-based flow (Boost 1.89.0), update Boost.Process include, and remove Boost.System component.

Changes

Cohort / File(s) Summary
Taskfile API: unified source/build/install model
exports/taskfiles/utils/boost.yaml
Reworked generate, build-and-install, and download-and-install signatures: removed GENERATE_DIR/GENERATE_CHECKSUM_FILE, introduced SOURCE_DIR/BUILD_DIR/INSTALL_PREFIX (and WORK_DIR/TAR_*), added per-stage checksum files (SOURCE_CHECKSUM_FILE, BUILD_CHECKSUM_FILE, INSTALL_CHECKSUM_FILE) and SOURCE_SENTINEL_FILE; narrowed sources to the taskfile; updated dependency checksum:validate usages to include SOURCE_DIR.
Download flow: tar-based extraction
exports/taskfiles/utils/boost.yaml (download-and-install section), taskfiles/boost/tests.yaml
Replaced FILE_SHA256/URL with TAR_SHA256/TAR_URL; added WORK_DIR, EXTRACTION_DIR; remote:download-and-extract-tar writes to EXTRACTION_DIR which becomes SOURCE_DIR for subsequent generate/build steps; label and public inputs updated to include TAR_URL and WORK_DIR; tests updated to use Boost 1.89.0 tarball.
Build flow: in-place bootstrap -> b2 with build dir
exports/taskfiles/utils/boost.yaml
Commands run in SOURCE_DIR (no separate GENERATE_DIR copy), use b2 --build-dir to BUILD_DIR, install to INSTALL_PREFIX, touch SOURCE_SENTINEL_FILE, and compute SOURCE/BUILD/INSTALL checksum files.
Boost CMake cleanup
taskfiles/boost/CMakeLists.txt
Removed system from Boost COMPONENTS in find_package(...) and removed Boost::system from target_link_libraries(...) for boost-test.
Boost tests: include path & target list update
taskfiles/boost/test_boost.cpp, taskfiles/boost/tests.yaml
Updated include from boost/process/v2.hpp to boost/process/v2/process.hpp and changed usage to boost::process::v2::process_stdio{...}; removed system from TARGETS in tests.yaml and adjusted WORK_DIR placement.
Checksum utility shell settings
exports/taskfiles/utils/checksum.yaml
Added shell options set: ["u","pipefail"] and shopt: ["globstar"] for stricter error handling and recursive globbing; removed inline pipefail note.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CI as CI/task runner
  participant Remote as remote:download-and-extract-tar
  participant FS as Filesystem (EXTRACTION_DIR / SOURCE_DIR)
  participant Generate as generate task
  participant Build as build-and-install task

  CI->>Remote: request TAR_URL (verify TAR_SHA256)
  Remote-->>FS: extract -> EXTRACTION_DIR
  CI->>Generate: run generate (SOURCE_DIR = EXTRACTION_DIR)
  Generate-->>FS: write generated artifacts\ntouch SOURCE_SENTINEL_FILE\nwrite SOURCE_CHECKSUM_FILE
  CI->>Build: run build-and-install (SOURCE_DIR = EXTRACTION_DIR, BUILD_DIR)
  Build-->>FS: run b2 --build-dir BUILD_DIR\ninstall to INSTALL_PREFIX\nwrite BUILD_CHECKSUM_FILE\nwrite INSTALL_CHECKSUM_FILE
  CI->>CI: run checksum:validate for SOURCE, BUILD, INSTALL
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title is partially related to the changeset. It mentions updating and refactoring Boost tasks and adding a checksum header comment, which are real parts of the changes, but the title is truncated and incomplete, cutting off mid-sentence. Complete the pull request title to fully convey the main objectives. The current title appears to be cut off; provide the complete title that describes all key changes in this pull request.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
exports/taskfiles/utils/checksum.yaml (1)

89-95: Missing-path check can pass incorrectly; make each test -e failure fatal within the subshell

Inside the validation subshell you loop over all INCLUDE_PATTERNS and run test -e "$path" for each. The subshell’s exit status becomes the status of the last test, so a missing earlier path can be masked by a later successful test. This makes checksum validation and the subsequent FAIL/cleanup logic unreliable.

Apply this diff to fail fast on any missing path:

-          for path in {{.}}; do
-            test -e "$path"
-          done
+          for path in {{.}}; do
+            test -e "$path" || exit 1
+          done
exports/taskfiles/utils/boost.yaml (3)

7-8: Enable fail-fast: add -e to set flags.

Currently only -u and -o pipefail are enabled. Without -e, failed commands in a multi-line cmds block may be ignored, causing subtle corruption of checksums or partial installs.

Apply:

-set: ["u", "pipefail"]
+set: ["e", "u", "pipefail"]

42-53: Replace pushd/popd with POSIX-safe subshell to avoid Bash dependency.

pushd/popd and shopt are Bash-specific. If the global shell isn’t guaranteed to be Bash, the step may fail. A subshell with cd is portable and avoids side effects.

-      - >-
-        pushd "{{.SOURCE_DIR}}";
-        ./bootstrap.sh
-        --prefix="{{.INSTALL_PREFIX}}"
-        --exec-prefix="{{.INSTALL_PREFIX}}"
-        --with-libraries={{(join "," .TARGETS)}}
-        {{- range .EXTRA_ARGS}}
-          "{{.}}"
-        {{- end}};
-        popd
+      - >
+        (
+          cd "{{.SOURCE_DIR}}" &&
+          ./bootstrap.sh
+            --prefix="{{.INSTALL_PREFIX}}"
+            --exec-prefix="{{.INSTALL_PREFIX}}"
+            --with-libraries={{(join "," .TARGETS)}}
+            {{- range .EXTRA_ARGS}}
+              "{{.}}"
+            {{- end}}
+        )

119-131: Same portability concern: replace pushd/popd with a subshell.

-      - >-
-        pushd "{{.SOURCE_DIR}}";
-        ./b2
-        install
-        --build-dir="{{.BUILD_DIR}}"
-        {{- range .EXTRA_ARGS}}
-          "{{.}}"
-        {{- end}}
-        {{- if .JOBS}}
-          "-j{{.JOBS}}"
-        {{- end}};
-        popd;
+      - >
+        (
+          cd "{{.SOURCE_DIR}}" &&
+          ./b2 install
+            --build-dir="{{.BUILD_DIR}}"
+            {{- range .EXTRA_ARGS}}
+              "{{.}}"
+            {{- end}}
+            {{- if .JOBS}}
+              "-j{{.JOBS}}"
+            {{- end}}
+        );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e121a57 and c8d706c.

📒 Files selected for processing (7)
  • exports/taskfiles/utils/boost.yaml (3 hunks)
  • exports/taskfiles/utils/checksum.yaml (2 hunks)
  • taskfiles/boost/CMakeLists.txt (0 hunks)
  • taskfiles/boost/test_boost.cpp (1 hunks)
  • taskfiles/boost/tests.yaml (1 hunks)
  • taskfiles/checksum/tests.yaml (1 hunks)
  • taskfiles/tests.yaml (2 hunks)
💤 Files with no reviewable changes (1)
  • taskfiles/boost/CMakeLists.txt
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}

⚙️ CodeRabbit configuration file

  • Prefer false == <expression> rather than !<expression>.

Files:

  • taskfiles/boost/test_boost.cpp
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (macos-15)
🔇 Additional comments (8)
taskfiles/boost/test_boost.cpp (1)

14-14: Header change to v2/process.hpp looks good

Switching from the umbrella v2 header to the specific v2/process.hpp is appropriate and keeps compile surfaces tighter. No behaviour change implied.

exports/taskfiles/utils/checksum.yaml (1)

49-51: Good addition: configurable failure vs. auto-clean on mismatch

The new behaviour—failing when FAIL="true" and otherwise removing the stale checksum file—matches the PR goals (skip when possible, rerun when necessary) and keeps downstream tasks simple.

taskfiles/boost/tests.yaml (2)

55-63: Removing the 'system' target is consistent; confirm linking remains header-only across platforms

Boost.System has been effectively header-only for years, but some environments can still link a libboost_system artefact depending on build flags. Since test_boost.cpp includes <boost/system.hpp> and uses boost::system::result, please confirm no link errors arise on all supported platforms/compilers.


51-53: Verify the pinned Boost tarball SHA256

The sandbox environment doesn’t include sha256sum, so the previous script couldn’t compute the checksum. Please re-verify the hash to avoid CI surprises. For example, from a clean directory:

#!/usr/bin/env bash
set -euo pipefail

url="https://github.com/boostorg/boost/releases/download/boost-1.89.0/boost-1.89.0-b2-nodocs.tar.gz"
expected="aa25e7b9c227c21abb8a681efd4fe6e54823815ffc12394c9339de998eb503fb"

curl -Ls "$url" -o boost.tar.gz

# Option 1: using openssl (most CI images include this)
actual=$(openssl dgst -sha256 boost.tar.gz | awk '{print $2}')

# Option 2: using Python 3 if openssl isn’t available
# actual=$(python3 -c "import hashlib; print(hashlib.sha256(open('boost.tar.gz','rb').read()).hexdigest())")

if [ "$actual" != "$expected" ]; then
  echo "SHA mismatch: $actual != $expected"
  exit 1
fi

echo "OK: $actual"
taskfiles/tests.yaml (2)

5-5: Nice: checksum test suite exposed publicly

Adding the checksum include keeps the test surface coherent with the new checksum tasks.


14-14: Good ordering: run checksum tests after Boost

Running checksum after Boost mirrors real-world usage where checksum gating influences subsequent build steps.

taskfiles/checksum/tests.yaml (1)

135-139: Dependency pattern is sound; confirm Bash availability due to process substitution elsewhere

create-dir-with-checksum correctly uses checksum:validate as a dep plus sources/generates to enable skipping. Given other commands in this file previously used process substitution, please ensure CI sets the task shell to Bash (or address the portability issues noted above).

exports/taskfiles/utils/boost.yaml (1)

32-41: The scripts above will:

  • Print the first 80 lines of the boost.yaml you’re modifying, so we can see its full context.
  • Check whether method: is explicitly set in boost.yaml or in any root-level Taskfile (to determine if you’re globally using the timestamp method instead of the default checksum).
  • Search under exports/ for any occurrences of method: timestamp.

Once we have that output, we can confirm if your up-to-date logic indeed depends on mtime heuristics (and thus risks false skips) or if you’re already using the checksum method (where “generates” doesn’t factor into up-to-date checks).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

♻️ Duplicate comments (2)
taskfiles/checksum/tests.yaml (2)

64-65: Replace Bash-only process substitution and non-portable date -r with cross-platform stat

Process substitution breaks under /bin/sh. Also, date -r FILE is GNU-specific (macOS/BSD date uses -r for epoch input). Use stat with a GNU/BSD fallback to compare mtimes portably.

-      - "date -r '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'"
+      - |-
+        # Write mtime seconds; works on BSD/macOS (stat -f) and GNU (stat -c).
+        mtime="$( { stat -f '%m' '{{.CHECKSUM_FILE}}' 2>/dev/null || stat -c '%Y' '{{.CHECKSUM_FILE}}'; } )"
+        printf '%s\n' "$mtime" > '{{.CHECKSUM_MOD_TS}}'

-      - "diff '{{.CHECKSUM_MOD_TS}}' <(date -r '{{.CHECKSUM_FILE}}')"
+      - |-
+        # Compare stored mtime with current mtime without Bash-only features.
+        current_mtime="$( { stat -f '%m' '{{.CHECKSUM_FILE}}' 2>/dev/null || stat -c '%Y' '{{.CHECKSUM_FILE}}'; } )"
+        test "$(cat '{{.CHECKSUM_MOD_TS}}')" = "$current_mtime"

Also applies to: 73-73


123-124: Dangerous glob: rm -rf {{.OUTPUT_DIR}} can remove unintended siblings*

Trailing globs can nuke paths sharing the prefix (e.g., /tmp/out-old). Delete the exact directory.

-      - "rm -rf {{.OUTPUT_DIR}}*"
-      - "mkdir -p '{{.OUTPUT_DIR}}'"
+      - "rm -rf '{{.OUTPUT_DIR}}'"
+      - "mkdir -p '{{.OUTPUT_DIR}}'"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between c8d706c and aca9e63.

📒 Files selected for processing (1)
  • taskfiles/checksum/tests.yaml (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: sitaowang1998
PR: y-scope/yscope-dev-utils#64
File: exports/taskfiles/utils/boost.yaml:31-37
Timestamp: 2025-06-08T17:55:11.362Z
Learning: For Boost builds in yscope-dev-utils, symlinking only the top-level directories from SOURCE_DIR to BUILD_DIR is sufficient for the build to succeed. Recursive symlinking of all nested files and directories is not necessary.
📚 Learning: 2024-10-28T19:02:02.131Z
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Applied to files:

  • taskfiles/checksum/tests.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (macos-15)
  • GitHub Check: unit-tests (ubuntu-22.04)
🔇 Additional comments (2)
taskfiles/checksum/tests.yaml (2)

1-14: Solid test harness structure and focus

Good job composing a self-contained suite with clear orchestration (default → rerun/skip/update) and isolating temp artefacts under G_OUTPUT_DIR. Using generates with the validate dep to exercise the skip path is clean.


20-21: No action required: .md5 extension is correct

The checksum task in exports/taskfiles/utils/checksum.yaml invokes md5sum to generate the checksum (see line 45), so the .md5 filename extension accurately reflects the algorithm in use. You can safely ignore the original suggestion to change the extension.

Likely an incorrect or invalid review comment.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (4)
taskfiles/checksum/tests.yaml (4)

44-47: Portability: use cmp -s instead of GNU-only --silent

cmp --silent is not available on macOS/BSD. Use the portable -s flag.

Apply this diff:

-        if cmp --silent "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF}}"; then
+        if cmp -s "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF}}"; then
           echo "'{{.CHECKSUM_FILE}}' and '{{.CHECKSUM_FILE_REF}}' should differ."
           exit 1
         fi

112-116: Portability: replace cmp --silent with cmp -s

Same portability issue; also standardize all equality checks on cmp -s.

Apply this diff:

-      - "cmp --silent  '{{.FILE_0}}'  '{{.CHECKSUM_FILE_REF0}}'"
-      - "cmp --silent '{{.CHECKSUM_FILE}}' '{{.CHECKSUM_FILE_REF1}}'"
+      - "cmp -s '{{.FILE_0}}' '{{.CHECKSUM_FILE_REF0}}'"
+      - "cmp -s '{{.CHECKSUM_FILE}}' '{{.CHECKSUM_FILE_REF1}}'"
@@
-        if cmp --silent "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF0}}"; then
+        if cmp -s "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF0}}"; then
           echo "'{{.CHECKSUM_FILE}}' and '{{.CHECKSUM_FILE_REF0}}' should differ."
           exit 1
         fi

125-125: Risky cleanup: avoid globbing with rm -rf {{.OUTPUT_DIR}}*

Using a trailing * can delete unintended siblings (e.g., /tmp/foo-old). Remove the exact target directory instead and always quote variables.

Apply this diff:

-      - "rm -rf {{.OUTPUT_DIR}}*"
+      - "rm -rf '{{.OUTPUT_DIR}}'"

137-141: Tighten validation: enforce failure on checksum mismatch

If checksum:validate supports a FAIL flag (per PR description), pass it so mismatches hard-fail and guard against silent drifts in dependencies.

Apply this diff:

       - task: "checksum:validate"
         vars:
           CHECKSUM_FILE: "{{.CHECKSUM_FILE}}"
           INCLUDE_PATTERNS: ["{{.DIR}}"]
+          FAIL: "true"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between aca9e63 and b0ea5bc.

📒 Files selected for processing (2)
  • .github/workflows/unit-tests.yaml (1 hunks)
  • taskfiles/checksum/tests.yaml (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#80
File: exports/taskfiles/utils/boost.yaml:20-27
Timestamp: 2025-08-24T14:25:42.393Z
Learning: In the Boost taskfiles (exports/taskfiles/utils/boost.yaml), sentinel files are intentionally placed inside directories that the task needs to modify (e.g., "{{.SOURCE_DIR}}/{{.TASK}}.sentinel"). This is by design - the sentinel indicates that the task has altered the directory contents. It would be a logical bug for upstream workflows to call these tasks while expecting the directories to remain unchanged.
Learnt from: sitaowang1998
PR: y-scope/yscope-dev-utils#64
File: exports/taskfiles/utils/boost.yaml:31-37
Timestamp: 2025-06-08T17:55:11.362Z
Learning: For Boost builds in yscope-dev-utils, symlinking only the top-level directories from SOURCE_DIR to BUILD_DIR is sufficient for the build to succeed. Recursive symlinking of all nested files and directories is not necessary.
📚 Learning: 2024-10-28T19:02:02.131Z
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Applied to files:

  • taskfiles/checksum/tests.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (macos-15)
🔇 Additional comments (2)
.github/workflows/unit-tests.yaml (1)

41-42: Switching to verbose test output is fine

Using task test -v improves CI diagnosability when tests fail. No issues spotted.

taskfiles/checksum/tests.yaml (1)

66-66: Fix non-POSIX timestamp checks; avoid Bash-only process substitution and GNU date -r

date -r file is GNU-only and fails on macOS; process substitution <(...) requires Bash. Use a stat-based fallback that works on both GNU/Linux and BSD/macOS.

Apply this diff:

-      - "date -r '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'"
+      - |-
+        # Write mtime (epoch seconds) in a GNU/BSD portable way
+        if stat -c %Y '{{.CHECKSUM_FILE}}' >/dev/null 2>&1; then
+          stat -c %Y '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'
+        else
+          stat -f %m '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'
+        fi
@@
-      - "cmp --silent '{{.CHECKSUM_MOD_TS}}' <(date -r '{{.CHECKSUM_FILE}}')"
+      - |-
+        # Compare saved mtime to current mtime (portable)
+        if stat -c %Y '{{.CHECKSUM_FILE}}' >/dev/null 2>&1; then
+          mtime="$(stat -c %Y '{{.CHECKSUM_FILE}}')"
+        else
+          mtime="$(stat -f %m '{{.CHECKSUM_FILE}}')"
+        fi
+        test "$(cat '{{.CHECKSUM_MOD_TS}}')" = "$mtime"

Also applies to: 75-75

⛔ Skipped due to learnings
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#70
File: taskfiles/remote/tests.yaml:62-72
Timestamp: 2025-07-12T05:52:11.439Z
Learning: The `date -r <file>` command is supported on both Linux and macOS to get file modification times, making it portable across these platforms.
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (10)
taskfiles/boost/test_boost.cpp (1)

106-106: v2::process_stdio fix resolves the namespace mismatch; confirm C++20 designated-initializer support

Aligning the stdio type with the v2 namespace addresses the earlier compilation hazard. One follow-up: the designated-initializer syntax requires C++20—please verify the project enforces C++20 (or newer) so this remains portable across compilers/CI.

Run this script from repo root to confirm the C++ standard settings used by CMake/tooling:

#!/bin/bash
set -euo pipefail

echo "Searching CMake files for explicit standard settings..."
fd -t f CMakeLists.txt -0 2>/dev/null | xargs -0 rg -nP 'CMAKE_CXX_STANDARD\s*[:=]\s*(\d+)|target_compile_features\([^)]*\bcxx_std_(\d+)\b' -C2 || true
fd -t f -e cmake -0 2>/dev/null | xargs -0 rg -nP 'CMAKE_CXX_STANDARD\s*[:=]\s*(\d+)|target_compile_features\([^)]*\bcxx_std_(\d+)\b' -C2 || true

echo
echo "Scanning for explicit compiler flags selecting C++20/23..."
rg -nP --glob '!**/build/**' '-std=c\+\+2(0|3|a|b)' -S || true

echo
echo "If no occurrences show C++20 (20/23), consider setting:"
echo "  set(CMAKE_CXX_STANDARD 20)"
echo "or:"
echo "  target_compile_features(<target> PRIVATE cxx_std_20)"
exports/taskfiles/utils/boost.yaml (4)

58-71: Docs: clarify checksum failure semantics (SOURCE = strict, BUILD/INSTALL = advisory).

State explicitly that SOURCE_CHECKSUM_FILE is validated with FAIL=true (hard guard for “generate was run”), while BUILD/INSTALL validations are advisory by design and do not fail the task unless the caller opts in.

Suggested addition to the docblock:

@@
-# Fails if the caller has not successfully called `generate` on `SOURCE_DIR`.
+# Fails if the caller has not successfully called `generate` on `SOURCE_DIR`.
+# Checksum semantics:
+# - SOURCE_CHECKSUM_FILE: validated with FAIL=true to ensure `generate` ran and the source tree
+#   matches the recorded state.
+# - BUILD_CHECKSUM_FILE and INSTALL_CHECKSUM_FILE: validated without FAIL by default (advisory);
+#   mismatches trigger recomputation at the end but do not stop the task unless explicitly set.

98-103: Do not list checksum files under generates; keep only the sentinel.

Including the checksum files as generates can cause the task to be skipped before deps/validate run, depending on mtimes and runner version. Use the sentinel as the single generate.

Apply:

   generates:
-    - "{{.BUILD_CHECKSUM_FILE}}"
-    - "{{.INSTALL_CHECKSUM_FILE}}"
-    - "{{.SOURCE_CHECKSUM_FILE}}"
     - "{{.SOURCE_SENTINEL_FILE}}"

200-206: Create CMAKE_SETTINGS_DIR before writing Boost.cmake.

Without ensuring the directory exists, the echo redirection will fail when the directory is absent.

Apply:

-      {{- if .CMAKE_SETTINGS_DIR}}
-        echo "set(Boost_ROOT
+      {{- if .CMAKE_SETTINGS_DIR}}
+        mkdir -p "{{.CMAKE_SETTINGS_DIR}}" &&
+        echo "set(Boost_ROOT
           \"{{.INSTALL_PREFIX}}\"
           CACHE PATH
           \"Package root for Boost.\"
         )" > "{{.CMAKE_SETTINGS_DIR}}/Boost.cmake"
       {{- end}}

33-35: Do not list CHECKSUM_FILE under generates; it can short‑circuit validation.

When CHECKSUM_FILE is a generated artefact, Task may mark the task up‑to‑date purely by mtimes and skip running deps/validate even if the directory contents changed. Rely on the sentinel as the sole generate instead.

Apply:

   generates:
-    - "{{.CHECKSUM_FILE}}"
     - "{{.SOURCE_SENTINEL_FILE}}"
taskfiles/checksum/tests.yaml (5)

25-27: Remove no-op defer that references an undefined variable

.EXIT_CODE is not defined here; this prints nothing and adds noise. Drop the block.

-      - defer: |-
-          echo "[debug] rerun {{.EXIT_CODE}}"

44-48: Make the test actually fail on unexpected equality and use portable cmp -s

Two issues:

  • The test only echoes when checksums unexpectedly match; it does not fail.
  • cmp --silent is GNU-specific; use portable cmp -s.
-      - |-
-        if cmp --silent "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF}}"; then
-          echo "'{{.CHECKSUM_FILE}}' and '{{.CHECKSUM_FILE_REF}}' should differ."
-        else
-          echo "[debug] cmp failed successfully."
-        fi
+      - |-
+        if cmp -s "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF}}"; then
+          echo "'{{.CHECKSUM_FILE}}' and '{{.CHECKSUM_FILE_REF}}' should differ."
+          exit 1
+        else
+          echo "[debug] cmp failed successfully."
+        fi

77-77: Avoid Bash-only process substitution; compare mtimes with POSIX command substitution

<(...) requires Bash and breaks under plain /bin/sh. Also switch to cmp -s/test semantics for portability.

-      - "cmp --silent '{{.CHECKSUM_MOD_TS}}' <(date -r '{{.CHECKSUM_FILE}}')"
+      - "test \"$(cat '{{.CHECKSUM_MOD_TS}}')\" = \"$(date -r '{{.CHECKSUM_FILE}}')\""

114-120: Portability: prefer cmp -s over GNU-only --silent

Replace all cmp --silent with cmp -s. Logic unchanged; exit(1) on unexpected equality is already present.

-      - "cmp --silent  '{{.FILE_0}}'  '{{.CHECKSUM_FILE_REF0}}'"
-      - "cmp --silent '{{.CHECKSUM_FILE}}' '{{.CHECKSUM_FILE_REF1}}'"
+      - "cmp -s '{{.FILE_0}}' '{{.CHECKSUM_FILE_REF0}}'"
+      - "cmp -s '{{.CHECKSUM_FILE}}' '{{.CHECKSUM_FILE_REF1}}'"

-        if cmp --silent "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF0}}"; then
+        if cmp -s "{{.CHECKSUM_FILE}}" "{{.CHECKSUM_FILE_REF0}}"; then
           echo "'{{.CHECKSUM_FILE}}' and '{{.CHECKSUM_FILE_REF0}}' should differ."
           exit 1
         fi

139-143: Enforce validation failures to fail loudly

If checksum:validate supports a strict mode (as per PR), pass it so stale checksums cause a hard failure, tightening the test oracle.

       - task: "checksum:validate"
         vars:
           CHECKSUM_FILE: "{{.CHECKSUM_FILE}}"
           INCLUDE_PATTERNS: ["{{.DIR}}"]
+          FAIL: "true"
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between b0ea5bc and ea102c7.

📒 Files selected for processing (3)
  • exports/taskfiles/utils/boost.yaml (3 hunks)
  • taskfiles/boost/test_boost.cpp (2 hunks)
  • taskfiles/checksum/tests.yaml (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{cpp,hpp,java,js,jsx,tpp,ts,tsx}

⚙️ CodeRabbit configuration file

  • Prefer false == <expression> rather than !<expression>.

Files:

  • taskfiles/boost/test_boost.cpp
🧠 Learnings (2)
📚 Learning: 2025-08-24T14:25:42.393Z
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#80
File: exports/taskfiles/utils/boost.yaml:20-27
Timestamp: 2025-08-24T14:25:42.393Z
Learning: In the Boost taskfiles (exports/taskfiles/utils/boost.yaml), sentinel files are intentionally placed inside directories that the task needs to modify (e.g., "{{.SOURCE_DIR}}/{{.TASK}}.sentinel"). This is by design - the sentinel indicates that the task has altered the directory contents. It would be a logical bug for upstream workflows to call these tasks while expecting the directories to remain unchanged.

Applied to files:

  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2024-10-28T19:02:02.131Z
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Applied to files:

  • taskfiles/checksum/tests.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (macos-15)
🔇 Additional comments (7)
taskfiles/boost/test_boost.cpp (1)

14-16: Use of fine-grained v2 headers — LGTM

Switching from the umbrella header to <boost/process/v2/process.hpp> (with stdio in a separate header) is correct for this translation unit and can reduce compile time. No further action needed.

exports/taskfiles/utils/boost.yaml (3)

26-27: Sentinel in SOURCE_DIR is acceptable (intent confirmed).

Acknowledged the intentional placement of the sentinel under SOURCE_DIR for tasks that mutate that tree, per maintainer clarification and stored learnings. No change requested.


104-117: Decide whether stale BUILD/INSTALL checksums should fail the task.

If a drift in BUILD_DIR or INSTALL_PREFIX must force remediation instead of proceeding, opt into FAIL=true for those validations. Otherwise, keep current advisory behaviour, but ensure the docblock calls it out (see earlier comment).

Apply if strict failure is desired:

       - task: "checksum:validate"
         vars:
           CHECKSUM_FILE: "{{.BUILD_CHECKSUM_FILE}}"
           INCLUDE_PATTERNS: ["{{.BUILD_DIR}}"]
+          FAIL: "true"
       - task: "checksum:validate"
         vars:
           CHECKSUM_FILE: "{{.INSTALL_CHECKSUM_FILE}}"
           INCLUDE_PATTERNS: ["{{.INSTALL_PREFIX}}"]
+          FAIL: "true"

165-165: Label fix looks good.

label now references .TAR_URL (not .URL). Thanks for correcting the undefined variable.

taskfiles/checksum/tests.yaml (3)

127-129: Good: safe cleanup without risky globs

Using rm -rf '{{.OUTPUT_DIR}}' avoids the dangerous * suffix that can nuke sibling paths with the same prefix.


1-14: Overall: solid, self-contained test flows

The three scenarios (rerun, skip, update) clearly exercise checksum semantics using Task’s deps/sources/generates. Variable quoting and path handling look correct.


15-24: Add a requires guard for G_OUTPUT_DIR, or confirm it’s always provided by the test harness

All three checksum‐test tasks in taskfiles/checksum/tests.yaml compute OUTPUT_DIR from .G_OUTPUT_DIR. If that variable were ever unset or empty, future cleanup steps could operate on the wrong directory. To prevent this:

• In each of the following tasks, immediately after the vars: block, add a:

requires:
  vars: ["G_OUTPUT_DIR"]

– checksum-test-rerun (lines 15–24)
– checksum-test-skip (lines 51–60)
– checksum-test-update (lines 79–89)

• If the test harness already guarantees that .G_OUTPUT_DIR is always set, you may safely omit these guards. Otherwise, including them is a cheap, low‐risk safety net.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
exports/taskfiles/utils/boost.yaml (2)

42-52: Prefer Task’s dir: over pushd/popd; safer shells, cleaner logs

Use dir: to run bootstrap in SOURCE_DIR and avoid relying on bash-only builtins. This also improves portability across shells.

-      - >-
-        pushd "{{.SOURCE_DIR}}";
-        ./bootstrap.sh
+      - dir: "{{.SOURCE_DIR}}"
+        cmd: >-
+          ./bootstrap.sh
         --prefix="{{.INSTALL_PREFIX}}"
         --exec-prefix="{{.INSTALL_PREFIX}}"
         --with-libraries={{(join "," .TARGETS)}}
         {{- range .EXTRA_ARGS}}
           "{{.}}"
         {{- end}};
-        popd

118-129: Use dir: instead of pushd/popd for b2 invocation

Same rationale as generate; this removes bash-only builtins and makes the step more robust.

-      - >-
-        pushd "{{.SOURCE_DIR}}";
-        ./b2
+      - dir: "{{.SOURCE_DIR}}"
+        cmd: >-
+          ./b2
         install
         --build-dir="{{.BUILD_DIR}}"
         {{- range .EXTRA_ARGS}}
           "{{.}}"
         {{- end}}
         {{- if .JOBS}}
           "-j{{.JOBS}}"
-        {{- end}};
-        popd;
+        {{- end}};
♻️ Duplicate comments (10)
.github/workflows/unit-tests.yaml (1)

41-42: Gate verbosity by event to keep scheduled/push logs lean

Split the test step into two mutually exclusive steps so only PRs run verbose output; keep scheduled/push runs quiet.

-      - name: "Run unit tests"
-        run: "task test --concurrency 1 --verbose"
+      - name: "Run unit tests (PR, verbose)"
+        if: ${{ github.event_name == 'pull_request' }}
+        run: task test --concurrency 1 --verbose
+
+      - name: "Run unit tests (non-PR)"
+        if: ${{ github.event_name != 'pull_request' }}
+        run: task test --concurrency 1
exports/taskfiles/utils/boost.yaml (9)

58-61: Docs: call out strict failure only for source checksum; others are advisory

Explicitly state here that only SOURCE_CHECKSUM_FILE validation uses FAIL: "true"; BUILD/INSTALL checksum mismatches are advisory and the build proceeds. This avoids ambiguity for future maintainers.


67-71: Docs: same clarification for checksum parameters

Mirror the clarification that SOURCE checksum is strict; BUILD/INSTALL are advisory unless explicitly opted into FAIL.


98-103: “generates” with checksum files can skip validate; prefer a single sentinel or status

As with generate, declaring the checksum files as generates can prevent checksum:validate from running due to mtimes. Either:

  • keep only a single sentinel under generates and add a status block invoking checksum:validate for BUILD/INSTALL/SOURCE, or
  • remove generates entirely and rely on status for up‑to‑date detection.

This avoids stale runs slipping through.

Example:

-    generates:
-      - "{{.BUILD_CHECKSUM_FILE}}"
-      - "{{.INSTALL_CHECKSUM_FILE}}"
-      - "{{.SOURCE_CHECKSUM_FILE}}"
-      - "{{.SOURCE_SENTINEL_FILE}}"
+    generates:
+      - "{{.SOURCE_SENTINEL_FILE}}"
+    status:
+      - task: checksum:validate
+        vars: { CHECKSUM_FILE: "{{.BUILD_CHECKSUM_FILE}}", INCLUDE_PATTERNS: ["{{.BUILD_DIR}}"] }
+      - task: checksum:validate
+        vars: { CHECKSUM_FILE: "{{.INSTALL_CHECKSUM_FILE}}", INCLUDE_PATTERNS: ["{{.INSTALL_PREFIX}}"] }
+      - task: checksum:validate
+        vars: { CHECKSUM_FILE: "{{.SOURCE_CHECKSUM_FILE}}", INCLUDE_PATTERNS: ["{{.SOURCE_DIR}}"], FAIL: "true" }

104-117: Decide on strictness for BUILD/INSTALL drift

If manual edits or unexpected changes in BUILD_DIR/INSTALL_PREFIX should fail the job, add FAIL: "true" to those validations. Otherwise, leave relaxed as a conscious choice.

       - task: "checksum:validate"
         vars:
           CHECKSUM_FILE: "{{.BUILD_CHECKSUM_FILE}}"
           INCLUDE_PATTERNS: ["{{.BUILD_DIR}}"]
+          FAIL: "true"
       - task: "checksum:validate"
         vars:
           CHECKSUM_FILE: "{{.INSTALL_CHECKSUM_FILE}}"
           INCLUDE_PATTERNS: ["{{.INSTALL_PREFIX}}"]
+          FAIL: "true"

156-159: TARGETS optionality: align docs, requires, and call‑sites

If empty TARGETS should be allowed (common when building a minimal set), make it optional end‑to‑end and guard the command flag accordingly; else update docs to say “Required”.

Command guard (if made optional):

-        --with-libraries={{(join "," .TARGETS)}}
+        {{- if gt (len .TARGETS) 0 -}}
+        --with-libraries={{(join "," .TARGETS)}}
+        {{- end -}}

172-177: Drop hard require on TARGETS if optional in docs

If you keep TARGETS optional, remove it from requires.vars and provide a default empty list to avoid call‑site failures.

     requires:
       vars:
         - "TAR_SHA256"
         - "TAR_URL"
-        - "TARGETS"
         - "WORK_DIR"

200-207: Ensure CMAKE_SETTINGS_DIR exists before writing Boost.cmake

Create the directory to avoid failures when the path is absent.

-      - >-
-        {{- if .CMAKE_SETTINGS_DIR}}
-          echo "set(Boost_ROOT
+      - >-
+        {{- if .CMAKE_SETTINGS_DIR}}
+          mkdir -p "{{.CMAKE_SETTINGS_DIR}}" &&
+          echo "set(Boost_ROOT
             \"{{.INSTALL_PREFIX}}\"
             CACHE PATH
             \"Package root for Boost.\"
           )" > "{{.CMAKE_SETTINGS_DIR}}/Boost.cmake"
         {{- end}}

81-88: Expose combined checksum override (optional)

If you intended a single file to represent both BUILD and INSTALL states, surface an explicit mapping to reduce API confusion; otherwise, ignore.

       BUILD_CHECKSUM_FILE: >-
         {{default (printf "%s.md5" .BUILD_DIR) .BUILD_CHECKSUM_FILE}}
       INSTALL_CHECKSUM_FILE: >-
         {{default (printf "%s.md5" .INSTALL_PREFIX) .INSTALL_CHECKSUM_FILE}}
+      # Optional: allow a single combined checksum file to be used for both
+      {{- if .BUILD_AND_INSTALL_CHECKSUM_FILE }}
+      BUILD_CHECKSUM_FILE: "{{.BUILD_AND_INSTALL_CHECKSUM_FILE}}"
+      INSTALL_CHECKSUM_FILE: "{{.BUILD_AND_INSTALL_CHECKSUM_FILE}}"
+      {{- end }}
       SOURCE_CHECKSUM_FILE: >-
         {{default (printf "%s.md5" .SOURCE_DIR) .SOURCE_CHECKSUM_FILE}}

33-41: Avoid short‑circuiting generate via “generates”; ensure validate always runs

Listing the checksum file under generates can cause the task (and its deps) to be considered up‑to‑date based solely on mtimes of TASKFILE vs. CHECKSUM_FILE. To guarantee the checksum validation runs when SOURCE_DIR changes, prefer a status check that delegates to checksum:validate (or remove generates for the checksum and keep a single sentinel as the generate output).

If you want to keep a single generated artifact while ensuring validation runs, consider:

     sources: ["{{.TASKFILE}}"]
-    generates:
-      - "{{.CHECKSUM_FILE}}"
-      - "{{.SOURCE_SENTINEL_FILE}}"
+    generates:
+      - "{{.SOURCE_SENTINEL_FILE}}"
+    status:
+      - task: checksum:validate
+        vars:
+          CHECKSUM_FILE: "{{.CHECKSUM_FILE}}"
+          INCLUDE_PATTERNS: ["{{.SOURCE_DIR}}"]

This way, generate re-executes when the checksum is stale, and only the sentinel governs up‑to‑date detection.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 7c9701d and 9e3b981.

📒 Files selected for processing (2)
  • .github/workflows/unit-tests.yaml (1 hunks)
  • exports/taskfiles/utils/boost.yaml (3 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-24T14:25:42.393Z
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#80
File: exports/taskfiles/utils/boost.yaml:20-27
Timestamp: 2025-08-24T14:25:42.393Z
Learning: In the Boost taskfiles (exports/taskfiles/utils/boost.yaml), sentinel files are intentionally placed inside directories that the task needs to modify (e.g., "{{.SOURCE_DIR}}/{{.TASK}}.sentinel"). This is by design - the sentinel indicates that the task has altered the directory contents. It would be a logical bug for upstream workflows to call these tasks while expecting the directories to remain unchanged.

Applied to files:

  • exports/taskfiles/utils/boost.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (ubuntu-22.04)
  • GitHub Check: unit-tests (macos-15)
  • GitHub Check: unit-tests (ubuntu-24.04)
🔇 Additional comments (2)
exports/taskfiles/utils/boost.yaml (2)

26-27: Sentinel in SOURCE_DIR acknowledged as intentional

SOURCE_SENTINEL_FILE under SOURCE_DIR is consistent with the documented design intent (signals the task mutated the directory). No change requested.


165-165: Label fix looks good

Switched to .TAR_URL; avoids undefined .URL. No action needed.

@davidlion
Copy link
Member Author

@coderabbitai pause

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (2)
taskfiles/checksum/tests.yaml (2)

38-41: Use portable cmp -s instead of GNU-only --silent

cmp --silent is GNU-only; cmp -s is portable across GNU/BSD/macOS and expresses the same intent.

-      - "! cmp --silent '{{.CHECKSUM_FILE}}' '{{.CHECKSUM_FILE_REF}}'"
+      - "! cmp -s '{{.CHECKSUM_FILE}}' '{{.CHECKSUM_FILE_REF}}'"

66-70: Bashism and GNUism: process substitution and cmp --silent break on /bin/sh and BSD

  • <(…) requires Bash; /bin/sh on many systems (e.g., Debian’s dash) will error.
  • cmp --silent is GNU-only. Use cmp -s and POSIX command substitution.
-      - "cmp --silent '{{.CHECKSUM_MOD_TS}}' <(date -r '{{.CHECKSUM_FILE}}')"
+      - 'test "$(cat "{{.CHECKSUM_MOD_TS}}")" = "$(python3 -c '\''import os,sys; print(int(os.path.getmtime(sys.argv[1])))'\'' "{{.CHECKSUM_FILE}}")"'

If you prefer avoiding Python, pair this with the stat-based line suggested for Line 60 and mirror it here.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 9e3b981 and 6740397.

📒 Files selected for processing (1)
  • taskfiles/checksum/tests.yaml (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-10-28T19:02:02.131Z
Learnt from: AVMatthews
PR: y-scope/yscope-dev-utils#13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Applied to files:

  • taskfiles/checksum/tests.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (macos-15)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (ubuntu-22.04)
🔇 Additional comments (6)
taskfiles/checksum/tests.yaml (6)

8-14: Well-structured default target orchestrating the three scenarios

Clear sequencing of rerun/skip/update keeps the suite readable and maintainable. Nice separation of concerns.


15-37: Test flow and variable naming are clear

Good use of per-test OUTPUT_DIR and explicit FILE_0/FILE_1 variables. The “rename checksum to reference, then recompute” pattern convincingly asserts rerun behaviour.


82-101: Solid update test; good use of intermediate references

The “cat checksum into FILE_0 + recompute” trick is clever to force a content-based delta without introducing timing flakiness.


111-118: Safe cleanup (no trailing globs) — good

Explicitly removing OUTPUT_DIR without a trailing wildcard avoids accidental sibling deletions.


133-140: Helper is clear and idempotent; pairs well with checksum tasks

The “wipe dir, create file, then compute checksum” flow is easy to reason about and makes the tests deterministic.


60-60: Non-portable: date -r FILE is GNU-only; use a portable mtime probe

On macOS/BSD, date -r expects an epoch, not a filename. This will fail there. Prefer a cross-platform stat or a tiny Python one-liner to read mtime.

Option A (portable via Python, typically available in CI/macOS/Linux):

-      - "date -r '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'"
+      - "python3 -c 'import os,sys; print(int(os.path.getmtime(sys.argv[1])))' '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'"

Option B (pure shell with stat on both GNU/BSD):

-      - "date -r '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'"
+      - >-
+        sh -c 'stat -c %Y "$1" 2>/dev/null || stat -f %m "$1"' -- '{{.CHECKSUM_FILE}}' > '{{.CHECKSUM_MOD_TS}}'
⛔ Skipped due to learnings
Learnt from: davidlion
PR: y-scope/yscope-dev-utils#70
File: taskfiles/remote/tests.yaml:62-72
Timestamp: 2025-07-12T05:52:11.439Z
Learning: The `date -r <file>` command is supported on both Linux and macOS to get file modification times, making it portable across these platforms.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 24, 2025

✅ Actions performed

Reviews paused.

@davidlion
Copy link
Member Author

@coderabbitai resume

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 17, 2025

✅ Actions performed

Reviews resumed.

@davidlion davidlion changed the title feat(taskfiles)!: Use checksum tasks to prevent unnecessary repetition of Boost tasks; Add checksum unit tests. feat(taskfiles)!: Update and refactor Boost tasks: Nov 17, 2025
@davidlion davidlion changed the title feat(taskfiles)!: Update and refactor Boost tasks: feat(taskfiles)!: Add checksum header comment; Update and refactor Boost tasks by: Nov 22, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (1)
exports/taskfiles/utils/boost.yaml (1)

197-203: Ensure CMAKE_SETTINGS_DIR exists before writing Boost.cmake. The code writes directly to "{{.CMAKE_SETTINGS_DIR}}/Boost.cmake" without creating the parent directory first. If the caller passes a non-existent path, the write will fail silently or with a cryptic error.

Create the directory before writing the CMake settings file:

      - >-
        {{- if .CMAKE_SETTINGS_DIR}}
+         mkdir -p "{{.CMAKE_SETTINGS_DIR}}" &&
          echo "set(Boost_ROOT
            \"{{.INSTALL_PREFIX}}\"
            CACHE PATH
            \"Package root for Boost.\"
          )" > "{{.CMAKE_SETTINGS_DIR}}/Boost.cmake"
        {{- end}}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d9efd11 and 310401e.

📒 Files selected for processing (3)
  • exports/taskfiles/utils/boost.yaml (1 hunks)
  • exports/taskfiles/utils/checksum.yaml (1 hunks)
  • taskfiles/boost/tests.yaml (2 hunks)
🧰 Additional context used
🧠 Learnings (9)
📓 Common learnings
Learnt from: sitaowang1998
Repo: y-scope/yscope-dev-utils PR: 64
File: exports/taskfiles/utils/boost.yaml:31-37
Timestamp: 2025-06-08T17:55:11.362Z
Learning: For Boost builds in yscope-dev-utils, symlinking only the top-level directories from SOURCE_DIR to BUILD_DIR is sufficient for the build to succeed. Recursive symlinking of all nested files and directories is not necessary.
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 80
File: exports/taskfiles/utils/boost.yaml:20-27
Timestamp: 2025-08-24T14:25:42.436Z
Learning: In the Boost taskfiles (exports/taskfiles/utils/boost.yaml), sentinel files are intentionally placed inside directories that the task needs to modify (e.g., "{{.SOURCE_DIR}}/{{.TASK}}.sentinel"). This is by design - the sentinel indicates that the task has altered the directory contents. It would be a logical bug for upstream workflows to call these tasks while expecting the directories to remain unchanged.
📚 Learning: 2024-10-28T19:02:02.131Z
Learnt from: AVMatthews
Repo: y-scope/yscope-dev-utils PR: 13
File: taskfiles/utils.yml:149-149
Timestamp: 2024-10-28T19:02:02.131Z
Learning: In `taskfiles/utils.yml`, avoid using GNU-specific options like `-r` and `--no-run-if-empty` with `xargs` for better portability; instead, use `find`'s `-exec` option.

Applied to files:

  • exports/taskfiles/utils/checksum.yaml
  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2024-11-15T02:34:27.126Z
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 16
File: taskfiles/utils.yml:296-299
Timestamp: 2024-11-15T02:34:27.126Z
Learning: In `taskfiles/utils.yml`, tasks are configured to fail if any command fails, so adding explicit error handling within commands is unnecessary.

Applied to files:

  • exports/taskfiles/utils/checksum.yaml
  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2025-10-13T19:09:44.404Z
Learnt from: Bill-hbrhbr
Repo: y-scope/yscope-dev-utils PR: 91
File: exports/taskfiles/utils/misc.yaml:70-90
Timestamp: 2025-10-13T19:09:44.404Z
Learning: In the yscope-dev-utils repository Taskfiles, prefer minimal guardrails that only protect against benevolent mistakes (e.g., enforcing absolute paths where required) rather than defensive checks like rejecting root paths, empty paths, or validating file vs directory types.

Applied to files:

  • exports/taskfiles/utils/checksum.yaml
  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2024-10-30T22:08:49.844Z
Learnt from: AVMatthews
Repo: y-scope/yscope-dev-utils PR: 13
File: taskfiles/utils.yml:0-0
Timestamp: 2024-10-30T22:08:49.844Z
Learning: In `taskfiles/utils.yml`, when using `xargs`, we are removing the `-r` flag entirely without replacing it with `--no-run-if-empty`.

Applied to files:

  • exports/taskfiles/utils/checksum.yaml
📚 Learning: 2025-08-24T14:25:42.436Z
Learnt from: davidlion
Repo: y-scope/yscope-dev-utils PR: 80
File: exports/taskfiles/utils/boost.yaml:20-27
Timestamp: 2025-08-24T14:25:42.436Z
Learning: In the Boost taskfiles (exports/taskfiles/utils/boost.yaml), sentinel files are intentionally placed inside directories that the task needs to modify (e.g., "{{.SOURCE_DIR}}/{{.TASK}}.sentinel"). This is by design - the sentinel indicates that the task has altered the directory contents. It would be a logical bug for upstream workflows to call these tasks while expecting the directories to remain unchanged.

Applied to files:

  • taskfiles/boost/tests.yaml
  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2025-06-08T17:55:11.362Z
Learnt from: sitaowang1998
Repo: y-scope/yscope-dev-utils PR: 64
File: exports/taskfiles/utils/boost.yaml:31-37
Timestamp: 2025-06-08T17:55:11.362Z
Learning: For Boost builds in yscope-dev-utils, symlinking only the top-level directories from SOURCE_DIR to BUILD_DIR is sufficient for the build to succeed. Recursive symlinking of all nested files and directories is not necessary.

Applied to files:

  • taskfiles/boost/tests.yaml
  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2025-10-14T12:14:41.400Z
Learnt from: Bill-hbrhbr
Repo: y-scope/yscope-dev-utils PR: 91
File: exports/taskfiles/utils/misc.yaml:55-63
Timestamp: 2025-10-14T12:14:41.400Z
Learning: In Task (go-task/task), when using `run: when_changed`, the fingerprint is composed of the task identity (name/label) AND the variable values. To distinguish different invocations with different variable values, include those variables in the task label. For example, `label: "{{.TASK}}:{{.DIR_PATH}}"` ensures each unique `DIR_PATH` gets its own cache entry.

Applied to files:

  • exports/taskfiles/utils/boost.yaml
📚 Learning: 2025-02-14T11:49:28.430Z
Learnt from: Bill-hbrhbr
Repo: y-scope/yscope-dev-utils PR: 24
File: taskfiles/utils-remote.yaml:56-61
Timestamp: 2025-02-14T11:49:28.430Z
Learning: In Task YAML files, having duplicate checks in both `status` and `cmds` sections can be intentional. The `status` section is silent and used for dependency tracking, while the same check in `cmds` provides user feedback.

Applied to files:

  • exports/taskfiles/utils/boost.yaml
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: unit-tests (ubuntu-24.04)
  • GitHub Check: unit-tests (macos-15)
  • GitHub Check: unit-tests (ubuntu-22.04)
🔇 Additional comments (4)
exports/taskfiles/utils/checksum.yaml (1)

3-4: Shell options and documentation are well-chosen. The added set: ["u", "pipefail"] enforces strict error handling (undefined variables, pipeline failures), and shopt: ["globstar"] enables recursive globbing for future patterns. The comprehensive documentation clearly explains the checksum+sentinel pattern, directory mutation expectations, and implicit-dependency validation—excellent guidance for maintainers.

Also applies to: 6-36

taskfiles/boost/tests.yaml (1)

50-62: Tarball-based flow and target list align well with boost.yaml refactor. The switch to TAR_SHA256/TAR_URL and addition of WORK_DIR are consistent with the unified BUILD_DIR/SOURCE_DIR/INSTALL_PREFIX model. Removal of the "system" component matches the changes in other build files. The target list (filesystem, headers, iostreams, process, program_options, regex, url) appears sound based on the related Boost.Process v2 header updates.

Please verify that the SHA256 checksum for Boost 1.89.0 tarball (aa25e7b9c227c21abb8a681efd4fe6e54823815ffc12394c9339de998eb503fb) matches the official release from boostorg/boost.

exports/taskfiles/utils/boost.yaml (2)

11-56: Label now correctly references SOURCE_DIR instead of undefined variable. The generate task's refactor to use per-stage checksums and sentinels is sound. The sentinel placement in SOURCE_DIR is intentional per learnings (indicating directory mutation). Default checksum file path {{.SOURCE_DIR}}.md5 is sensible. Checksum validation in deps (line 37-40) ensures upstream consistency.


58-140: Per-stage checksum tracking enables fine-grained caching. The three checksums (BUILD, INSTALL, SOURCE) with sentinel tracking are well-designed. The docblock (lines 58–72) clearly states that only SOURCE_CHECKSUM_FILE enforces strict validation (FAIL: "true" at line 114), while BUILD and INSTALL mismatches are advisory—this is the correct trade-off and matches the design intent. Command flow (touch sentinel, compute all three checksums) is consistent.

Comment on lines +3 to +4
set: ["u", "pipefail"]
shopt: ["globstar"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know we removed these in the last PR, but after some debate it is easier to have our guideline be to just always include these lines despite them only doing anything in the root taskfile. I'll update the guidelines when I get a chance.

Sorry.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@exports/taskfiles/utils/boost.yaml`:
- Around line 76-78: Fix the spelling mistake "ommitted" -> "omitted" in the
boost.yaml description for the JOBS parameter (the comment that starts with
"@param {int} [JOBS=0] The maximum number of concurrent processes...") and also
correct the identical typo in the second occurrence of the same explanatory
comment later in the file; update both comment lines so they read "omitted".
- Line 36: The pipeline fails because the Task `dir` fields are YAML sequences
instead of strings; replace both occurrences of dir: ["{{.SOURCE_DIR}}"] with a
string value dir: "{{.SOURCE_DIR}}" so `dir` is a string (referencing the same
{{.SOURCE_DIR}} template variable) — update both places where the `dir` key uses
a list to use the quoted string form instead.

- "{{.GENERATE_CHECKSUM_FILE}}"
- "{{.CHECKSUM_FILE}}"
- "{{.SOURCE_SENTINEL_FILE}}"
dir: ["{{.SOURCE_DIR}}"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

dir must be a string, not a list — this is the root cause of the pipeline failure.

The dir field in Task expects a string value, but ["{{.SOURCE_DIR}}"] is a YAML sequence. This triggers the lint error: "cannot unmarshal !!seq into string at line 21."

The same issue exists on line 101.

🐛 Proposed fix

Line 36:

-    dir: ["{{.SOURCE_DIR}}"]
+    dir: "{{.SOURCE_DIR}}"

Line 101:

-    dir: ["{{.SOURCE_DIR}}"]
+    dir: "{{.SOURCE_DIR}}"
🤖 Prompt for AI Agents
In `@exports/taskfiles/utils/boost.yaml` at line 36, The pipeline fails because
the Task `dir` fields are YAML sequences instead of strings; replace both
occurrences of dir: ["{{.SOURCE_DIR}}"] with a string value dir:
"{{.SOURCE_DIR}}" so `dir` is a string (referencing the same {{.SOURCE_DIR}}
template variable) — update both places where the `dir` key uses a list to use
the quoted string form instead.

Comment on lines +76 to 78
# @param {int} [JOBS=0] The maximum number of concurrent processes to use when building. If 0, the
# b2 flag is ommitted and the default is used. Before 1.76.0, the number was 1. Since 1.76.0, the
# default is the number of cores.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Typo: "ommitted" → "omitted".

Same typo appears on line 158.

📝 Proposed fix
-  # b2 flag is ommitted and the default is used. Before 1.76.0, the number was 1. Since 1.76.0, the
+  # b2 flag is omitted and the default is used. Before 1.76.0, the number was 1. Since 1.76.0, the
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# @param {int} [JOBS=0] The maximum number of concurrent processes to use when building. If 0, the
# b2 flag is ommitted and the default is used. Before 1.76.0, the number was 1. Since 1.76.0, the
# default is the number of cores.
# `@param` {int} [JOBS=0] The maximum number of concurrent processes to use when building. If 0, the
# b2 flag is omitted and the default is used. Before 1.76.0, the number was 1. Since 1.76.0, the
# default is the number of cores.
🤖 Prompt for AI Agents
In `@exports/taskfiles/utils/boost.yaml` around lines 76 - 78, Fix the spelling
mistake "ommitted" -> "omitted" in the boost.yaml description for the JOBS
parameter (the comment that starts with "@param {int} [JOBS=0] The maximum
number of concurrent processes...") and also correct the identical typo in the
second occurrence of the same explanatory comment later in the file; update both
comment lines so they read "omitted".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants