Skip to content

Fix several bugs#31

Merged
joelbenway merged 15 commits intomasterfrom
dev
Dec 29, 2025
Merged

Fix several bugs#31
joelbenway merged 15 commits intomasterfrom
dev

Conversation

@joelbenway
Copy link
Copy Markdown
Owner

@joelbenway joelbenway commented Dec 29, 2025

Bugs for:

  • builder move constructor
  • barometric formula in stratosphere
  • errors in boatright spindrift calculation

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Enhanced input validation with specific error codes for out-of-range or missing parameters
    • Improved error messages identifying exact issues in ballistic calculations
    • Refined spin drift calculation conditions for improved accuracy
    • Adjusted high-altitude pressure formula computation
  • New Features

    • Expanded parameter validation across altitude, temperature, wind, and geometric inputs
    • More granular error reporting for troubleshooting

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 29, 2025

📝 Walkthrough

Walkthrough

This PR substantially refactors the ballistics calculation library's error-handling architecture, migrating runtime validation from individual setters to a centralized Build() phase with newly expanded error codes for specific out-of-range and missing-data conditions. It also adjusts atmospheric calculations, spin-drift triggering logic, and test expectations to reflect the refined behavior.

Changes

Cohort / File(s) Summary
Atmospheric Calculations
source/calc.hpp
Removed kMolarMassOfAir constant from BarometricFormula path for altitudes above tropopause, altering the exponentiation factor for high-altitude adjustments.
Builder Implementation Refactor
source/lob_builder.cpp
Reworked move semantics (constructor/assignment), removed runtime validations from individual setters, consolidated validation into Build() phase with early-return pattern, introduced new helper BuildOpticHeight(), expanded BuildEnvironment, BuildTable, BuildWind, BuildBoatright, and BuildZeroAngle with comprehensive range checks and corresponding ErrorT codes.
Solver Logic Updates
source/lob_solve.cpp
Changed Boatright spin-drift trigger from spindrift_factor > 0 to non-NaN check, adjusted Litz condition to explicit floating-point zero comparison.
Core Calculation Tests
test/source/calc_test.cpp
Expanded altitude data type from uint16_t to uint32_t, added new BarometricFormulaStratosphere test case with 14 altitude points and validation.
API Unit Tests
test/source/lob_api_test.cpp
Added edge-case test InchToDegZero verifying behavior when secondary parameter is 0.0.
Builder API Tests
test/source/lob_builder_test.cpp
Renamed tests from "Invalid" to "Missing" scenarios, expanded ErrorT enum with 25\+ new error variants (e.g., kInitialVelocityRequired, kAltitudeOfFiringSiteOOR, kZeroDistanceOOR, kBallisticCoefficientOOR), updated test expectations to validate specific error codes and range conditions across geometric/physical parameters.
Boatright Solution Tests
test/source/lob_cwaj_test.cpp
Updated numeric solution expectations across multiple precomputed test points, reflecting changes to velocity, energy, elevation, deflection, and time-of-flight values.
Spin-Drift Tests
test/source/lob_spin_drift_test.cpp
Updated deflection/elevation test expectations across multiple spin-drift scenarios; many entries adjusted to 0.00 or refined values.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • Add error handling to Builder #25: Both PRs directly modify builder validation and ErrorT enum in source/lob_builder.cpp and test expectations, introducing/relocating comprehensive error-handling logic.
  • Feature/lobber update #24: Both PRs modify atmospheric and ballistics calculation code, including BarometricFormula in calc.hpp and related Boatright/Litz implementations with overlapping logic changes.
  • boatright spin drift #22: Both PRs alter spin-drift and gyroscopic conditions in lob_solve.cpp and refactor aerodynamic-jump/Boatright computation plumbing with direct functional overlap.

Poem

🐰 A builder rewrites its foundry grand,
With errors caught by steadfast hand,
No spin-drift fog—just clarity's sphere,
And molar ghosts fade from the atmosphere!
Validation stands at build's own door,
Making promises once more.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.26% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title "Fix several bugs" is vague and does not clearly identify the primary changes in the changeset, which include builder move semantics, barometric formula corrections, and spindrift calculation fixes. Use a more specific title that highlights the main change, such as "Fix builder move semantics and barometric formula calculations" or focus on the most impactful fix if there is a primary concern.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

📜 Recent review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 775c22b and 778a3f1.

📒 Files selected for processing (2)
  • source/lob_solve.cpp
  • test/source/lob_spin_drift_test.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/source/lob_spin_drift_test.cpp
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-06-17T12:55:26.522Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 25
File: include/lob/lob.hpp:123-130
Timestamp: 2025-06-17T12:55:26.522Z
Learning: In the lob ballistics library, when Input::step_size is set to 0 (the default), the solver automatically sets an appropriate step size internally rather than failing with an assertion error.

Applied to files:

  • source/lob_solve.cpp
🧬 Code graph analysis (1)
source/lob_solve.cpp (1)
source/eng_units.hpp (4)
  • isnan (171-173)
  • isnan (171-171)
  • isnan (911-913)
  • isnan (911-911)
⏰ 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). (8)
  • GitHub Check: test (macos-latest, static)
  • GitHub Check: test (windows-latest, shared)
  • GitHub Check: test (macos-latest, shared)
  • GitHub Check: test (ubuntu-latest, static)
  • GitHub Check: test (windows-latest, static)
  • GitHub Check: test (ubuntu-latest, shared)
  • GitHub Check: sanitize
  • GitHub Check: coverage
🔇 Additional comments (2)
source/lob_solve.cpp (2)

55-62: Good improvement to floating-point comparison.

The change from != 0 to std::fabs(in.stability_factor) > 0.0 is a more robust floating-point comparison that correctly handles edge cases:

  • Explicitly excludes NaN values (unlike the previous != 0 check)
  • More semantically clear for floating-point comparisons

47-53: The condition change correctly enables left-hand spin drift handling.

The new condition !std::isnan(in.spindrift_factor) is intentional and correct. Negative spindrift_factor values represent left-hand spin (already tested with negative barrel twist values like -11.0 and -9.375 in test/source/lob_spin_drift_test.cpp), and zero values harmlessly result in no drift. The existing test suite validates both positive and negative spindrift_factor cases, confirming the change aligns with the Boatright-Ruiz model's physical behavior.


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
Copy Markdown

@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

🧹 Nitpick comments (2)
source/lob_solve.cpp (1)

9-9: Remove unused include.

The <iostream> header appears to be unused in this file. This may be a leftover from debugging.

🔎 Proposed fix
-#include <iostream>
test/source/lob_spin_drift_test.cpp (1)

462-462: Minor: Inconsistent decimal precision in expected value.

Line 462 uses 0.607 (3 decimal places) while other deflection values use 2 decimal places. This doesn't affect test correctness but is a minor formatting inconsistency. The same applies to line 590 with -0.607.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2290fd0 and 775c22b.

📒 Files selected for processing (13)
  • CMakeLists.txt
  • example/CMakeLists.txt
  • example/lobber.cpp
  • flake.nix
  • include/lob/lob.hpp
  • source/calc.hpp
  • source/lob_builder.cpp
  • source/lob_solve.cpp
  • test/source/calc_test.cpp
  • test/source/lob_api_test.cpp
  • test/source/lob_builder_test.cpp
  • test/source/lob_cwaj_test.cpp
  • test/source/lob_spin_drift_test.cpp
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-06-17T12:55:26.522Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 25
File: include/lob/lob.hpp:123-130
Timestamp: 2025-06-17T12:55:26.522Z
Learning: In the lob ballistics library, when Input::step_size is set to 0 (the default), the solver automatically sets an appropriate step size internally rather than failing with an assertion error.

Applied to files:

  • CMakeLists.txt
  • source/lob_solve.cpp
  • example/lobber.cpp
  • test/source/lob_builder_test.cpp
📚 Learning: 2025-04-15T13:11:22.842Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 15
File: source/calc.hpp:52-52
Timestamp: 2025-04-15T13:11:22.842Z
Learning: In lob, the `CalculateProjectileReferenceArea` function returns area in square inches (SqInT), but in some calculations like those in test/source/calc_test.cpp, this value is intentionally converted to square feet (SqFtT) when multiplied by air density in pounds per cubic foot (LbsPerCuFtT) to ensure proper unit cancellation.

Applied to files:

  • test/source/lob_api_test.cpp
  • test/source/calc_test.cpp
  • example/lobber.cpp
  • test/source/lob_builder_test.cpp
📚 Learning: 2025-05-23T12:16:39.175Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 22
File: source/boatright.cpp:72-81
Timestamp: 2025-05-23T12:16:39.175Z
Learning: In the lob codebase, std::pow has been overloaded in eng_units.hpp to work directly with strong unit types (like InchT, CaliberT, etc.), allowing expressions like std::pow(diameter / 2, 2) to compile correctly without needing to extract raw values using the Value() method.

Applied to files:

  • test/source/lob_api_test.cpp
  • source/lob_solve.cpp
📚 Learning: 2025-05-22T16:12:16.630Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 22
File: test/source/boatright_test.cpp:58-65
Timestamp: 2025-05-22T16:12:16.630Z
Learning: In the lob codebase, std::pow and potentially other standard library functions have been overloaded to work directly with strong types (like InchT, CaliberT, etc.), allowing expressions like std::pow(kD / 2, 2) to compile correctly without needing to extract the underlying value first.

Applied to files:

  • test/source/lob_api_test.cpp
  • source/lob_solve.cpp
📚 Learning: 2025-05-23T20:47:45.448Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 22
File: source/lob_solve.cpp:0-0
Timestamp: 2025-05-23T20:47:45.448Z
Learning: In lob_solve.cpp, the loop pattern that accesses pranges[index] is safe from out-of-bounds access because it checks if (index >= size) and breaks immediately after incrementing index, ensuring pranges[index] is never accessed with an invalid index.

Applied to files:

  • test/source/lob_cwaj_test.cpp
  • test/source/lob_spin_drift_test.cpp
📚 Learning: 2025-05-22T16:06:12.031Z
Learnt from: joelbenway
Repo: joelbenway/lob PR: 22
File: source/lob_builder.cpp:520-552
Timestamp: 2025-05-22T16:06:12.031Z
Learning: The `SolveStep` function in `solve_step.hpp` has an overload with a default argument of `FeetT(1)` for the step parameter: `void SolveStep(TrajectoryStateT* ps, SecT* pt, const Input& input, FeetT step = FeetT(1))`

Applied to files:

  • source/lob_builder.cpp
🧬 Code graph analysis (4)
test/source/lob_api_test.cpp (2)
include/lob/lob.hpp (1)
  • InchToDeg (593-593)
source/lob_convert.cpp (2)
  • InchToDeg (53-58)
  • InchToDeg (53-53)
test/source/calc_test.cpp (2)
source/calc.hpp (2)
  • BarometricFormula (33-55)
  • BarometricFormula (33-34)
source/eng_units.hpp (22)
  • FeetT (509-511)
  • FeetT (509-509)
  • FeetT (533-535)
  • FeetT (533-533)
  • FeetT (550-552)
  • FeetT (550-550)
  • FeetT (562-564)
  • FeetT (562-562)
  • FeetT (574-576)
  • FeetT (574-574)
  • InHgT (640-642)
  • InHgT (640-640)
  • InHgT (646-648)
  • InHgT (646-646)
  • InHgT (652-654)
  • InHgT (652-652)
  • DegFT (810-812)
  • DegFT (810-810)
  • DegFT (828-830)
  • DegFT (828-828)
  • DegFT (841-845)
  • DegFT (841-841)
source/lob_solve.cpp (1)
source/eng_units.hpp (4)
  • isnan (171-173)
  • isnan (171-171)
  • isnan (911-913)
  • isnan (911-911)
test/source/lob_builder_test.cpp (5)
test/source/lob_cwaj_test.cpp (1)
  • puut (61-61)
test/source/lob_spin_drift_test.cpp (1)
  • puut (60-60)
test/source/lob_env_test.cpp (1)
  • puut (50-50)
test/source/lob_coriolis_test.cpp (1)
  • puut (49-49)
test/source/lob_wind_test.cpp (1)
  • puut (49-49)
🔇 Additional comments (28)
example/CMakeLists.txt (1)

8-8: LGTM!

Version bump to 1.0.3 aligns with the broader PR changes and root project version update.

CMakeLists.txt (1)

11-11: LGTM!

Minor version bump to 0.7.0 is appropriate given the API changes to the ErrorT enum.

source/calc.hpp (1)

33-55: Barometric formula fix looks correct.

The stratosphere calculation now uses the proper isothermal barometric formula: P = P₀ × exp(-g×Δh/(R×T)). The removal of molar mass from the exponent term aligns with using the specific gas constant (1716.49 ft·lb/(slug·°R)) rather than the universal gas constant.

Please confirm the expected pressure values against reference data (e.g., the new BarometricFormulaStratosphere test) to validate the corrected formula.

test/source/calc_test.cpp (2)

20-22: LGTM!

Type change from uint16_t to uint32_t appropriately supports the expanded altitude range needed for stratosphere testing.


80-99: Good test coverage for the stratosphere fix.

The new BarometricFormulaStratosphere test validates the corrected formula at 14 altitude points from 35,000 to 100,000 ft with expected values from a reference source. This provides solid regression coverage for the barometric formula fix.

test/source/lob_cwaj_test.cpp (1)

421-431: Test expectation updates for Boatright spindrift fix.

The updated expected values in the Boatright tests reflect the corrected spindrift calculation. The changes are concentrated in deflection values at longer ranges where spin drift effects accumulate, which is expected behavior.

Confirm the new expected values were derived from the corrected Boatright-Ruiz calculation or validated against reference data.

source/lob_solve.cpp (2)

48-54: Boatright spindrift trigger fix is correct.

Changing from spindrift_factor > 0 to !std::isnan(spindrift_factor) correctly enables Boatright spindrift for both left-hand twist (negative factor) and right-hand twist (positive factor). This fixes the bug where left-hand twist spindrift was being ignored.


56-63: LGTM!

The Litz spin drift fallback logic remains correct. The change to > 0.0 is a minor style improvement for floating-point comparison consistency.

example/lobber.cpp (4)

19-23: LGTM!

Platform-specific includes for terminal detection are correctly guarded with _WIN32 preprocessor check.


76-83: Good cross-platform implementation.

The IsInteractive() function correctly uses the platform-appropriate APIs for terminal detection (_isatty/_fileno on Windows, isatty/STDIN_FILENO on POSIX).


644-661: Well-structured input handling logic.

The separation between interactive wizard mode and stdin JSON reading is clean. The std::cin.peek() check before attempting to parse avoids blocking on empty stdin.


664-668: Good error handling for missing input.

Provides clear error message and shows help when no input is provided, with appropriate exit code.

include/lob/lob.hpp (1)

63-91: Improved error taxonomy.

The expanded ErrorT enum provides more granular error categorization with clear semantics:

  • *Required for missing mandatory inputs
  • *OOR (Out Of Range) for validation failures
  • kInternalError for unexpected states

This enables better diagnostics and user feedback while maintaining the existing kNone and kNotFormed sentinel values.

flake.nix (1)

52-77: LGTM - New lobber derivation is well structured.

The derivation correctly builds the example binary with appropriate CMake flags and includes a runtime check to verify the binary exists before installation. This aligns with the PR objective of exposing a buildable tool.

test/source/lob_api_test.cpp (1)

194-198: LGTM - Good edge case coverage.

This test properly validates the InchToDeg function's handling of zero range, which returns 0 to avoid division by zero. The test aligns with the implementation in source/lob_convert.cpp that guards against range_ft == 0.0.

test/source/lob_spin_drift_test.cpp (1)

393-405: LGTM - Updated test expectations for Boatright spindrift bug fix.

The updated expected values align with the PR objective of fixing "errors in the Boatright spindrift calculation." The pattern correctly shows zero deflection at shorter ranges (0-900 yards) with increasing deflection at longer ranges.

source/lob_builder.cpp (6)

71-72: Move constructor fix looks correct.

The move constructor now properly move-constructs the Impl object from the moved-from builder's pimpl, which addresses the PR objective of fixing "the builder move constructor." The placement new with std::move(*other.pimpl_) correctly transfers ownership of the Impl's contents.


156-160: Good defensive default for invalid drag function.

Adding explicit handling for kG1 as a case label with a default fallthrough ensures that any invalid DragFunctionT value will safely default to G1 drags rather than potentially leaving undefined behavior. This matches the new test InvalidDragFunctionIsG1 in the test file.


507-530: Validation order in BuildStability may cause early exit before checking all prerequisites.

The function returns early at line 530 if twist is NaN or zero, which is correct. However, the validation at lines 507-525 checks velocity == 0, diameter <= 0, length <= 0, and mass <= 0 and sets errors. If diameter/length/mass are NaN (not set), the <= 0 comparisons with NaN will be false, so the code proceeds to line 527-530. This logic seems intentional - only set values are validated for being in range.


542-574: BuildCoriolis correctly handles partial inputs.

The function only computes Coriolis terms when both azimuth and latitude are provided, and properly zeroes out the terms otherwise. This is the correct approach since Coriolis calculations require both inputs to be meaningful.


730-737: Missing return after setting zero angle error on line 735.

When zero_angle is out of range, the error is set on line 734, but there's no return before line 736. The function continues to return on line 736 anyway, so the behavior is correct, but the pattern differs from other validation blocks that explicitly return after setting an error.


811-850: Build orchestration with sentinel pattern is well structured.

Using kNotFormed as a sentinel and checking after each build stage allows for clean early-exit error handling. The final conversion from kNotFormed to kNone at lines 846-848 ensures that a successful build doesn't leave the sentinel value in the output.

test/source/lob_builder_test.cpp (6)

130-155: LGTM - Tests renamed to reflect new error semantics.

The test renames from "Invalid" to "Missing" accurately reflect the new error taxonomy distinguishing between missing required inputs (kInitialVelocityRequired, kBallisticCoefficientRequired, kZeroDataRequired) versus out-of-range values.


157-170: Good coverage for invalid drag function handling.

This test validates that passing an invalid DragFunctionT value (0xFF) results in the G1 drag table being used as a safe default, matching the defensive implementation in BCDragFunction.


375-378: LGTM - Reset behavior test correctly updated.

The test now verifies that after a successful build (kNone), calling Reset() and then Build() produces an error because required inputs are cleared. This properly validates the reset functionality.


448-464: AzimuthError test now correctly requires latitude to trigger Coriolis validation.

The test adds LatitudeDeg(kLatitude) to ensure the Coriolis validation path is exercised. Without latitude, the azimuth would be ignored per the BuildCoriolis logic that requires both values.


543-559: LatitudeError test now correctly requires azimuth to trigger Coriolis validation.

Similar to the AzimuthError test, this adds AzimuthDeg(kAzimuth) to ensure both values are provided, triggering the latitude validation in BuildCoriolis.


703-719: WindHeadingError test updated with wind speed to ensure wind validation path is exercised.

Adding WindSpeedMph(kWindSpeed) and using a heading of kDegreesPerTurn * 3 (1080 degrees) correctly triggers the wind heading out-of-range validation.

Comment thread flake.nix
Comment on lines +192 to 210
clangd=$(cat <<-EOF
CompileFlags:
CompilationDatabase: build/dev
EOF
)

if [ ! -f ${CMakeUserPresetsFile} ]; then
echo "$json" > ${CMakeUserPresetsFile}
echo "${CMakeUserPresetsFile} created successfully"
else
echo "${CMakeUserPresetsFile} already exists"
fi

if [ ! -f ${clangdFile} ]; then
echo "$clangd" > ${clangdFile}
echo "${clangdFile} created successfully"
else
echo "${filename} already exists"
echo "${clangdFile} already exists"
fi
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# View the actual flake.nix at lines 192-210 with visible whitespace
sed -n '192,210p' flake.nix | cat -A

Repository: joelbenway/lob

Length of output: 703


🌐 Web query:

.clangd configuration file YAML format specification

💡 Result:

Short spec / summary — .clangd (YAML) configuration

  • File locations

    • Project: .clangd placed in a source-tree directory (searched up parent dirs).
    • User: config.yaml in OS-specific config dir (Windows %LocalAppData%\clangd\config.yaml; macOS ~/Library/Preferences/clangd/config.yaml; Linux $XDG_CONFIG_HOME/clangd/config.yaml). (clangd.llvm.org)
  • File format

    • YAML (JSON is a valid subset). Multiple fragments may appear in one file separated by "---". (clangd.llvm.org)
  • Top-level structure

    • Each fragment is a top-level mapping (key → mapping blocks). Blocks are key→mapping of related options. Where arrays of scalars are allowed, a single scalar is also accepted (e.g., Add: -Wall ≡ Add: [-Wall]). (clangd.llvm.org)
  • Common blocks / examples

    • CompileFlags:
      Add: [ ... ] # additional flags to apply
    • Diagnostics:
      ClangTidy:
      Add: [...]
      Remove: [...]
      CheckOptions: { key: value, ... } # clang-tidy check options (note format differs from .clang-tidy)
      UnusedIncludes: None | Strict
      MissingIncludes: None | Strict
    • InlayHints:
      Enabled: true|false
      ParameterNames: true|false
      DeducedTypes: true|false
      TypeNameLimit:
    • Many other blocks (Includes, CodePatterns, MissingIncludes, etc.); see docs for full list and allowed values. (clangd.llvm.org)
  • Scoping / precedence

    • Multiple fragments can include an If: condition to scope settings.
    • Precedence: user config (highest) → inner project → outer project. Configs are combined when sensible. Changes take effect immediately. (clangd.llvm.org)
  • Notes

    • Config errors are reported in clangd logs. Use the docs for exact allowed keys/enum values per block. (clangd.llvm.org)

For the full, authoritative schema, allowed keys and values, and examples, see the clangd configuration documentation. (clangd.llvm.org)

Citations:


The .clangd heredoc will produce invalid YAML due to leading whitespace.

The <<-EOF removes leading tabs but preserves leading spaces. The heredoc content has leading spaces from the script indentation (lines 194–195), which will appear in the generated .clangd file. YAML top-level mappings must start at column 0, not indented. Remove the leading spaces from the heredoc content, or use a different approach (e.g., cat with a separate file or printf without indentation).

🤖 Prompt for AI Agents
In flake.nix around lines 192 to 210 the here-doc for .clangd uses <<-EOF but
the indented content contains leading spaces which will be preserved and produce
invalid YAML (top-level keys must start at column 0); fix by writing the heredoc
content with no leading spaces (move the EOF marker and the content to column
0), or switch to a non-indented approach such as using a non-stripping heredoc
(<<'EOF') and left-align the YAML, or generate the file with printf/cat without
indentation so the resulting .clangd has "CompileFlags:" and
"CompilationDatabase:" starting at column 0.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@joelbenway joelbenway merged commit 47ceb6c into master Dec 29, 2025
12 checks passed
@joelbenway joelbenway deleted the dev branch December 29, 2025 04:04
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.

1 participant