Releases: mboworks/mbo
Release list
0.14.0
Version 0.14.0
Changelog
- Updated the bundled LLVM setup to the official
toolchains_llvm1.9.0 prerelease commit while
its BCR publication is pending, removing the remaininghelly25/toolchains_llvmfork dependency. - Added live per-translation-unit clang-tidy progress with parallel worker counts, completion
percentages, failure-only diagnostics, configurable concurrency, and complete interruption
cleanup. A fail-closed clang-tidy database removes redundant fuzz-transition commands only when
their semantic compiler arguments match the ordinary build. - Transferred the project to
mboworks/mbo, renamed the Bazel module tomboworks_mbo, and
migrated shell tests tomboworks_bashtest@0.6.1. Historicalhelly25_mboreleases remain
available unchanged. - Extended SHGLOB braces with bounded ascending and descending integer and ASCII-letter sequences,
including signed and zero-padded integers. Expansions above 10,000 terms are rejected, and the
optional Bash increment form remains literal. - Replaced the previous glob translation with the canonical fast GLOB/SHGLOB implementation. It
provides locale-independent structural bracket parsing, positive and negated character classes,
precise validation, nested SHGLOB alternatives, and complete-component**; notably,
foo/**/barmatchesfoo/barand any number of intervening directory levels. - Added
mbo::StringOrView, a read-only string-like value that either owns astd::stringor
borrows astd::string_view. It exposes the full applicable string/string-view interface,
comparisons, C++23-stylecontains/subview, stream and Abseil formatting, plus Abseil and
std::hashintegration. - Fixed
OptionalDataOrRefconstruction and assignment so borrowed values cannot silently become
dangling references; added the corresponding lifetime constraints and tests. - Fixed
Requiredreplacement and generic operations, including move-only values and converting
construction/assignment, while preserving its configurable failure behavior. - Fixed
NoDestructconstruction and its formatting/hash customizations for non-copyable and
explicitly constructed values. - Added strict INI parsing: malformed sections, missing keys, and invalid trailing content now
return diagnostics instead of being partially accepted. - Fixed JSON value-iterator assignment and made JSON's configurable requirement failures testable
through the exception-enabled configuration without weakening the default fatal behavior. - Fixed alphabetic hexadecimal escapes so the full accepted digit set is decoded correctly.
- Fixed independently quoted option parsing: quoting one option no longer changes how subsequent
options are parsed. - Rejected truncated and structurally malformed glob ranges rather than passing altered semantics
to RE2. - Made
NormalizePathpreserve the filesystem's native character type instead of assuming narrow
characters. - Made
GetContentsreport seek failures andGetMaxLinesreport read failures instead of
returning incomplete data as success. - Corrected cache-cleanup prefix matching so one branch or configuration cannot select unrelated
cache entries. - Added fuzz targets for glob conversion, string parsing, INI parsing, diff inputs/options, and
digest checksum parsing. - Added LCOV line/function/branch coverage enforcement for the overall tree, logical modules, and
changed code. Reports use a shared policy and baseline, publish durable per-PR HTML detail to
GitHub Pages, and fail with actionable uncovered-line/branch diagnostics. - Raised measured coverage across every core module through behavioral tests rather than production
exclusions: overall coverage is 98.11% lines, 98.63% functions, and 89.32% branches; every module
is ratedGOOD, includingmbo/typesat 86.12% branch coverage. - Bounded CI cache entries below 500 MB and made cache cleanup best-effort, so cleanup API failures
cannot turn an otherwise successful job red. - Enabled UndefinedBehaviorSanitizer explicitly in the AddressSanitizer configuration.
- Updated the compile-command extractor and reused the clang-tidy Bazel configuration, eliminating
an avoidable configuration switch while keeping header-only changes in clang-tidy's scope. - Adopted the shared contributor style guides and enforcement: matcher-based tests, named typed and
parameterized cases, explicit test sizes, aligned Markdown tables, and pre-commit rejection of
forbidden GoogleTest comparison macros and spelling errors in C++ and documentation. - Added repository Git orchestration rules for dependency-graph-aware autonomous PR handling,
synchronized-head validation, conflict resolution, and safe parent/child merge sequencing. - Made pull-request validation run in pull-request context, cancel superseded runs, and retain the
final aggregatedonegate. - Hardened release automation: release bumps retain required review protection, only the requested
tag is published, and temporary Git indexes use a portable private directory. - Documented the policy of using readable GitHub Actions version tags rather than commit hashes
unless a concrete security or reproducibility reason requires pinning. - Silenced external-header warnings in exec-configuration builds without relaxing warnings for
first-party code. - Fixed
LimitedVector's comparison operators, which were declared overstd::size_tcapacities while the class takesauto: instances spelled viaMakeLimitedVector/LimitedOptionsor anintliteral matched no operator at all and failed to compile. - Enabled
cppcoreguidelines-pro-bounds-avoid-unchecked-container-access: uncheckedoperator[]is now a clang-tidy error. Containers that bounds-check themselves (LimitedMap,LimitedVector,Json) and insert-semantics maps (absl's) are excluded by class; the hash/digest kernels and other in-range-by-construction code carry scopedNOLINTblocks. - Fixed
LimitedVectorcomparison operators (==,<=>,<), which looped tominof the CAPACITIES instead of the sizes: comparing partially-filled vectors read uninitialized slots (or threw in a require-throws build). Found bypro-bounds-avoid-unchecked-container-access. - Converted unchecked
operator[]to.at()/std::get(or a reasonedNOLINTin benchmarks' timed loops and compile-time code) across the hash, digest, json, types and container libraries. - Converted unchecked
operator[]to.front()/.at()(or a reasonedNOLINTon hot paths) across the diff, strings, log, mope, file and testing libraries, preparingpro-bounds-avoid-unchecked-container-access. - Re-measured
pro-bounds-avoid-unchecked-container-access(task: attempt to enable): 2,953 findings, ~2,500 in hash/digest kernels where indices are in-range by construction; stays disabled with the data recorded in.clang-tidy. - Enabled
-Wpedantic(as errors) on all first-party code. Two named carve-outs for absl macros expanding in our translation units (ABSL_FLAG's__COUNTER__,ABSL_CHECK's_Nullable); the repo's own deliberate GNU extensions (__int128, statement expressions indecompose_count.h) are annotated__extension__in code. The bazel-7/8 compat CI rungs relax it because those bazels half-applyexternal_include_pathsand leak external-header findings. - Removed the temporary
hash_tembo.hallowlist entry from the headers-claimed check; #311 lists the header in a target again. - The warning set is now owned by the repo: explicit
-Wall -Wextra(as errors) on all first-party code, withmissing-field-initializerssuppressed as the deliberate designated-init idiom; previously only-Werrorwas ours and the set came from each toolchain's defaults. - CI no longer caches the hermetic LLVM (ported from helly25/xff #409+#411): jobs cache bazel's disk cache instead of the output root, non-clang cells keep a small repo cache, and the symbolizer wrapper resolves
llvm-symbolizervia runfiles so a fresh LLVM fetch location cannot break asan/tsan. - Added a
headers-claimedpre-commit check: every tracked header must be listed in its package's BUILD file. Foundhash_tembo.horphaned since #306 on its first run (temporarily allowlisted; re-listed by #311). - Replaced the reachability-based
library-test-coveragehook with xff's strict rule: everycc_libraryneeds a test in its own package with a direct dependency; exceptions live in the tool's_ALLOWLISTwith reasons. - Converted assert-status-then-dereference in the new tests to
IsOkAndHolds/MBO_ASSERT_OK_AND_ASSIGN, and imported four rules from helly25/xff's style guide (_ccnaming, per-package tests, no braced-init-list iteration,lhs/rhscomparator parameters). - Added tests for
hash_extra_cc,hash_internal_util_cc,mope_cc,ini_cc,runfiles_dir_cc,extend_cc,extender_ccandtest_types_cc- every library now has a test in its own package. - Added tests for all ten diff libraries: the three algorithms (
diff_direct_cc,diff_myers_cc,diff_naive_cc), the shared plumbing (base_diff_cc,chunked_diff_cc) and the internals (chunk_cc,context_cc,data_cc,output_cc,update_absl_log_flags_cc). - Removed every
-stdlib=libc++and every-Wno-unused-command-line-argumentsuppression: the hermetic toolchain resolves libc++ headers via-cxx-isystemand links libc++ explicitly, so the flag was inert (driver-confirmed) at compile and link alike; the one formerly load-bearing upstream copy is fixed in the officialtoolchains_llvm1.9.0 prerelease selected bygit_overrideuntil BCR publication. - Removed the redundant
--cxxopt=-stdlib=libc++from theclang-tidybazel config; the hermetic toolchain already passes it, so it appeared twice and produced "unused argument" warnings. - Fixed
mbo::file::GetMTimeon...
0.13.2
Version 0.13.2
Changelog
- Added
BmHash128Throughput(128-bit bounded-range throughput) and guarded the 64-/128-bit benchmark paths byHasGetHash64/HasGetHash128. - Reworked the measurement report around the latency (ns at exact length) / throughput (GiB/s over the Short/Web bounded distributions) split: each renders as chart + table per hash width, absent sections dropped; the report re-distills a bundle from its raw on read, so old bundles still yield latency tables and bundles need no re-packing when the tool changes.
- Reworked the hash mixed-length benchmark: dropped the hash-indexed key walk that collapsed into a rho-cycle (near-zero anomalies) and added
BmHash64Throughputreporting bytes/s over two documented length distributions (Short ≤128 B, Web ≤4096 B) truncated to each upper bound; the per-exact-lengthBmHash64/BmHash128remain the latency view. Distributions are exported as thethroughput_distscontext. - Added a
comparecommand reporting per-case Δ% and a geomean between two datasets. - Made
tables/plot/compare/qualityaccept a bundle.tgzor a results JSON, positionally or via--results/--bundle. - Added
plot --kind(throughput/latency/all) and--scale(log-log/linear-log). - Expanded the benchmark
kFullSizesand swept latency over the full set (dense ns-vs-length latency curve). - Added a
qualitycommand generating the overview + SMHasher3 Results tables fromhash_algorithms.jsonand a measured bundle;--checkgates them. - Added a
consistencycommand verifying same-source-SHA bundles agree on SMHasher3 verdicts. - Fixed SMHasher3 parsing: a bad name or crash reads as
ERRORnot a falsePASS; score and failing families parse from the Summary; legacy names aliased. - Integrated
mbo/hash/measurementsas a normal dev package (still release-stripped) with aquality_sh_testgating the tables; test CI fetches the LFS bundles. - Added a
no-deps-on-measurementspre-commit guard. - Ported
mumbo(64-bit) to Starlark (hash.mumbo), byte-identical to C++;hash.bzlnow offersmumbo,dumbo, andfnv1a.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.13.2")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")Using the provided development modules
Copy dev.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it. It provides the dev-only Hedron compile-commands extractor (generates compile_commands.json for clangd) and depend_on_what_you_use.
include("//:dev.MODULE.bazel")What's Changed
- Bump version from 0.13.1 to 0.13.2 by @helly25 in #254
- feat(hash): generate the SMHasher3 Results table (+ compact column, parser fix) by @helly25 in #255
- feat(hash): generate the README quality tables from JSON + a measured bundle; measurements as a dev package by @helly25 in #256
- feat(hash): port mumbo to Starlark (hash.mumbo) by @helly25 in #257
- feat(hash): add compare command, bundle inputs, and plot --kind/--scale by @helly25 in #258
- feat(hash): rework hash benchmark - fix latency, add bounded-range throughput by @helly25 in #259
- feat(hash): latency + throughput (Short/Web) rendering; 128-bit throughput by @helly25 in #260
- Final benchmark visualizations for 0.13.2 release by @helly25 in #261
- Add docs for the mbo/diff sub-library by @helly25 in #262
- More docs and benchmark options by @helly25 in #263
- Show extra compiler config and flags by @helly25 in #264
Full Changelog: 0.13.1...0.13.2
0.13.1
Version 0.13.1
Changelog
- Switched the build-seed mangle constant header to per-build generation (no longer committed): removed
internal/hash_mangle_seed.h.inandhash_mangle_seed_default_test, so a version bump no longer needs a committed regeneration.hash_mangle.hincludes the generated header directly (missing is an#error; clangd falls back under-DIS_CLANGD). - Added Starlark ports of the
dumboandfnv1ahashes in//mbo/hash:hash.bzl(the publichashstruct), byte-identical to C++ and verified against it. - Switched the mangle version/seed fold from FNV-1a to the in-house
dumbohash. - Added
//mbo/hash:hash_tool, a minimal<algo> [<data>]hash CLI (plainGetHash64, no mangle). - Excluded dev-only files from the release archive (
mbo/hash/measurements,.trunk, and git metadata).
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.13.1")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")Using the provided development modules
Copy dev.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it. It provides the dev-only Hedron compile-commands extractor (generates compile_commands.json for clangd) and depend_on_what_you_use.
include("//:dev.MODULE.bazel")What's Changed
- Bump version from 0.13.0 to 0.13.1 by @helly25 in #252
- Release mechanics: per-build mangle-seed header, Starlark hash ports, leaner archive by @helly25 in #253
Full Changelog: 0.13.0...0.13.1
0.13.0
Version 0.13.0
Changelog
- Added
DiffOptions::ignore_missing_final_newline(thembo::diff--ignore_missing_final_newlineflag and thediff_testignore_missing_final_newlineattribute): a file with and one without a trailing newline compare equal (the\ No newline at end of filemarker is suppressed). It only ignores the terminator, so an empty file stays distinct from a single empty line. Honored identically by all three algorithms (sharedDatapreprocessing). mbo::diffnow treats an emptyDiffOptions::time_formatas "omit the timestamp": the unified/context file header becomes a git-style--- name/+++ name(name only, no per-file mtime), so the output is reproducible across machines and time zones. A non-emptytime_formatis unchanged, andtime_formatstays library-only.- Added a Myers diff algorithm (
mbo::diff::DiffMyers, "An O(ND) Difference Algorithm and Its Variations", the algorithm behind GNU diff and git) and made it the default (DiffOptions::Algorithm::kMyers,--algorithm=myers). Lines are interned into integer tokens (honoring all ignore/strip/replace options), the linear-space middle-snake divide and conquer produces minimal diffs, and past a cost cap of max(64, sqrt(L+R)) a git-style furthest-reaching split bounds pathological inputs. Compared to the previous default the common scattered-edits case is >2x faster and the disjoint-files worst case drops from ~16s to <1ms (2k lines,//mbo/diff:diff_benchmark). - Sped up the
myerstokenizer: interning keys are nowstd::string_views into the preprocessed line cache hashed withmbo::hash::GetHash64(previously every line was copied into astd::string-keyed map), andignore_casefolds each line once into a reused buffer with stable storage only for distinct lines. Tokenize-heavy inputs (20k distinct 120-char lines) run ~16% faster; see thetokenize_*cases in//mbo/diff:diff_benchmark(whitespace-ignore variants included;ignore_all_spacenow also builds its stripped line in place instead of via an extra copy). - The
mbo::diffbinary follows the POSIX diff exit code contract: 0 = equal, 1 = different, 2 = trouble (unreadable input, internal error, bad usage; previously conflated with 1). The bazeldiff_testrule gained theminimalattribute, andmbo/diff/TODO.mdrecords the remaining optional features and explicit non-goals. - Rounded out the
mbo::diffCLI/test surface: new--minimalflag (DiffOptions::minimal) guaranteeing minimalmyersdiffs by disabling the cost cap (like GNUdiff --minimal); the usage message names all algorithms and formats; the bazeldiff_testrule gainedwidthandskip_left_deletionsattributes; and a CLI bashtest now checks the full algorithm x format matrix against per-engine expected outputs, so an untested or unsupported combination fails by name.max_diff_chunk_lengthandtime_formatintentionally stay library-only. - Renamed the previous default
mbo::diffalgorithm fromunifiedto what it is:naive(DiffOptions::Algorithm::kNaive,mbo::diff::DiffNaive,mbo/diff/impl/diff_naive.*). It greedily resynchronizes on the closest matching line and does not produce minimal diffs. The flag/attribute valueunifiedremains supported as a deprecated alias that now selectsmyers- matching its historic "likediff -u" promise - and enforces--format=unified. - Verified the
mbo::difffeature/algorithm support matrix with tests: all comparison options (ignore_case,ignore_all_space,ignore_consecutive_space,ignore_trailing_space,ignore_blank_lines,ignore_matching_lines,strip_comments,regex_replace_*) work identically undernaive,myersanddirect, and all three output formats work with every algorithm. One documented corner case: combiningignore_casewith a case-sensitiveignore_matching_linesexpression - a matching and a non-matching line differing only in case compare equal undernaivebut not under the token-basedmyers; write such expressions case-insensitively ((?i)...).max_diff_chunk_lengthonly applies tonaive(myersuses an internal cost cap,directneeds no bound). - Added
mbo::diffoutput formats: next to the default unified format,DiffOptions::output_formatselects context format (diff -c) or normal format (plaindiff). Thediffbinary and thediff_testbazel rule gained the matching--format=unified|context|normalflag /formatattribute (normal format defaults--contextto 0 and emits no file headers; context format uses***/---file headers). Both new formats reproduce GNU diff output byte for byte and apply cleanly withpatch. - Fixed
mbo::diffunified output for empty ranges (pure insertions or deletions, visible with--context=0): the chunk header now references the line preceding the gap (e.g.@@ -2,0 +3 @@instead of@@ -3,0 +3 @@), matching GNU diff. Previouslypatchapplied such hunks one line too late. - Split the
mbo::diffchunk rendering out ofmbo/diff/internal/chunk.ccintombo/diff/internal/output.{h,cc}(diff_internal::AppendChunk);Chunknow only accumulates and filters. - Added
mbo::hash::GetHash64(std::string_view)/GetHash128(std::string_view)and thembo::hash::Hash128result type - constexpr-safe, non-cryptographic hashing; the default algorithm is the in-housemumbo(see below). - Renamed the legacy in-house hash
mbo::hash::simpletombo::hash::dumboand redesigned it into a compact single-lane MUM hash. Nothing-up-my-sleeve constants (golden ratio, sqrt-prime fractions), a wideningMul128Fold64step over 8-byte words, and a two-multiply seed-injected finalizer take it from the legacy SMHasher3 40/188 to a clean PASS 188/188 (all three in-house hashes are now clean), ~2-3x faster than the legacy hash for >=8 B, and the fastest hash in the suite for tiny keys - single-lane, so it slows on large keys; a deliberately minimal companion tomumbo, not a replacement (seembo/hash/README.mdfor the measured design iterations). The deprecatedsimple::GetHashwrapper and thembo::hash::simplenamespace are removed outright - pre-1.0, so no compatibility alias is kept and existingmbo::hash::simple::*users must migrate. Usembo::hash::GetHash64(mumbo) as the default;mbo::hash::dumbo::GetHash64(data, seed)is the seeded, SMHasher3-clean minimal option. Values are not stable across library versions. - All
mbo::hashentry points (GetHash64,GetHash128,GetHash) are now templates over an algorithm struct (defaultDefaultHashAlgorithm, i.e.mbo::hash::mumbo). Every algorithm provides a<ns>::Algorithmstruct with staticGetHash64/GetHash128members; the conceptsHasGetHash64/HasGetHash128/IsHashAlgorithmdetect what is available, andHasher<Algo>completes partial algorithms with fallbacks (128->64 fold; for a missing 128 two decorrelated 64-bit passes where the second skips the first up-to-8 bytes and injects them via the seed, so both lanes cover every byte and differ even for seed-ignoring algorithms). - Added constexpr-safe, canonical implementations of further hash algorithms, all usable as algorithm structs with
GetHash64<Algo>:mbo::hash::fnv1a::GetHash64(FNV-1a 64),mbo::hash::xxh64::GetHash64(XXH64),mbo::hash::xxh3::GetHash64(XXH3 64-bit, scalar), andmbo::hash::murmur3::GetHash64/GetHash128(MurmurHash3 x64 128). All produce the published reference values on every platform (little-endian defined). - Exposed
mbo::hash::Hash128To64(Hash128): folds a 128-bit hash into a well-mixed 64-bit one, e.g. to derive a fold-mixed 64-bit value frommurmur3::GetHash128(whoseGetHash64is the canonicalh1truncation instead). - Added the build-seed mangle as its own entry point
mbo/hash/hash_mangle.h(//mbo/hash:hash_mangle_cc):GetHash<Algo, Seed>andMangledHasher<Algo>XOR ONE build-selected constant intoGetHash64values (still constexpr), so values deliberately do not compare across independently configured builds; plainhash.h/:hash_ccstays fully deterministic and is never exposed to (or rebuilt for) seed variation. The constant lives in one generated header per configuration (consistent per program by construction), folding the module's own version (read fromMODULE.bazelvianative.module_version()- no duplicated version declaration, correct also when consumed via BCR - so every release rotates mangled values at zero marginal cost: a release recompiles dependents anyway) with the custom Bazel flags--//mbo/hash:mangle_seed(any printable-ASCII string; folded to a bucket inside the header-generation rule, so build/remote caches see a bounded set of variants no matter what rotates through the flag) and--//mbo/hash:mangle_seed_buckets(default8;0disables the mangle makingGetHash == GetHash64,1pins one stable constant across releases and seeds). - Runtime loads use
memcpy(gcc never folded the byte-assembly loads - roughly 3x on gcc for all algorithms) and tail loads use branch-lite overlapping reads; constant evaluation keeps the byte-assembly path (values identical, guarded by tests). Hasher<Algo>is also a transparent functor, usable directly as the hash parameter ofabsl/stdhash containers with heterogeneousstd::string_viewlookup.- Added
mbo::hash::CombineHashes(uint64_t, uint64_t)(order-dependent, well-mixed combine) andhash_internal::Mul128Fold64(constexpr 64x64->128 fold, xxh3/wyhash family core). - Test framework additions: seed-bit avalanche (SMHasher-style; skipped for seedless algorithms) and structured/sparse-key distinctness (all-zero lengths, single-bit keys, cyclic patterns).
- Added canonical, constexpr-safe
mbo::hash::xxh3::GetHash128(XXH3_128bits[_withSeed], the modern fast file-checksum format), verified against reference vectors and differentially aga...
0.12.0
Version 0.12.0
Changelog
- Fixed visibility of already-documented APIs whose Bazel
cc_librarytargets had defaulted to//visibility:privatesince they were added, so external code could notdepsthem. Now//visibility:public://mbo/types:optional_ref_cc(OptionalRef),//mbo/types:optional_data_or_ref_cc(OptionalDataOrRef/OptionalDataOrConstRef), and the//mbo/json:json/:json_cclibrary - all added in 0.10.0. - Made
//mbo/types:stringify_ostream_ccpublic (stringify_ostream.h): the ostream<<integration forStringify/Extendtypes plus theSetStringifyOstreamOutputMode/SetStringifyOstreamOptionsconfiguration functions. - Renamed the module repo to
helly25_mboand dropped thecom_helly25_mboalias (repo_name). The last internal user (theini_filegolden test) now resolves its runfiles via the repo-relative//mbo/file/ini:tests/test.ini, so nothing depends on the old name. Consumers referencing@com_helly25_mbo//...must switch to@helly25_mbo//.... - Bumped
helly25_bashtest0.3.1 -> 0.4.0 and dropped itscom_helly25_bashtestrepo alias (a WORKSPACE-era compatibility name); BUILD files nowload("@helly25_bashtest//bashtest:bashtest.bzl", ...). mbo is bzlmod-only (--noenable_workspace, noWORKSPACEfile). - Bumped
rules_cc0.2.19 -> 0.2.20.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.12.0")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")Using the provided development modules
Copy dev.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it. It provides the dev-only Hedron compile-commands extractor (generates compile_commands.json for clangd) and depend_on_what_you_use.
include("//:dev.MODULE.bazel")What's Changed
- Bump version from 0.11.1 to 0.11.2 by @helly25 in #198
- fix(tools): resolve clang-format from the hermetic toolchain first by @helly25 in #199
- docs: split C++ style into STYLE_CPP.md (clang configs + gtest conventions) by @helly25 in #200
- C++ style guide, conformance, and 0.12.0 public-API exports by @helly25 in #201
- Drop the com_helly25_mbo repo alias (0.13.0) by @helly25 in #202
- Prepare 0.12.0 release: deps refresh + WORKSPACE-alias cleanup by @helly25 in #203
- ci: one-click Trigger Release (dispatcher) by @helly25 in #204
Full Changelog: 0.11.1...0.12.0
0.11.1
Version 0.11.1
Changelog
- Release/packaging fixes (no API changes): self-contained release archives; hardened
trigger_release.sh.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.11.1")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")Using the provided development modules
Copy dev.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it. It provides the dev-only Hedron compile-commands extractor (generates compile_commands.json for clangd) and depend_on_what_you_use.
include("//:dev.MODULE.bazel")What's Changed
- ci: harden the release path by @helly25 in #194
- Bump version from 0.11.0 to 0.11.1 by @helly25 in #195
- ci(release): make release archives self-contained by @helly25 in #196
- chore(release): 0.11.1 changelog note + trunk linter bump by @helly25 in #197
Full Changelog: 0.11.0...0.11.1
0.11.0
Version 0.11.0
Changelog
- Added
mbo::testing::IsElementOf(container)— element-on-the-left orientation of gmock'sContains. Iterates with rawoperator==(with astd::paircomponent-wise fallback) so heterogeneous subject types (string literals,std::string_view, etc.) compile without caller-side conversion, on both libc++ and libstdc++. - Added
mbo::testing::IsKeyOf(map)— convenience matcher for "is this value among the keys of the map?". Failure messages report"is a key of {…}". - Added
mbo::testing::IsValueOf(map)— parallel toIsKeyOffor mapped values. Failure messages report"is a value of {…}". - Bumped Bazel to 9.1.1 (
.bazelversion). - Updated module dependencies:
bazel_skylib1.8.2 → 1.9.0,platforms1.0.0 → 1.1.0,rules_cc0.2.14 → 0.2.19,rules_shell0.6.1 → 0.8.0,re22025-11-05 → 2025-11-05.bcr.1,googletest1.17.0 → 1.17.0.bcr.2,google_benchmark1.9.4 → 1.9.5,helly25_bashtest0.1.0 → 0.3.0,toolchains_llvm1.5.0 → 1.7.0,depend_on_what_you_use0.7.0 → 0.16.0, and thehedron_compile_commandspin. helly25_bashtest0.3.0 loads thesh_*rules from@rules_shelldirectly, so Bazel 9 (which no longer autoloads the legacy nativesh_*rules) needs no--incompatible_autoload_externallyworkaround.- Bumped
abseil-cpp20250814.1 → 20250814.2. Held at the 20250814 series because newer Abseil (20260107+) deprecates theabsl::MutexLock(Mutex*)constructor thatre22025-11-05 still uses, which fails under--cxxopt=-Werror. - Bumped the pinned LLVM toolchain 17.0.4 → 20.1.8. LLVM 17.0.4's bundled linker segfaults against the macOS 26 SDK when building tools in the exec configuration (e.g.
//mbo/diff:diff, which_diff_testbuilds withcfg=exec); 20.1.x links cleanly and compiles the tree without new-Werrorwarnings. - Migrated the
_diff_testis_windowsselect off the deprecated@bazel_tools//src/conditions:host_windowsto@platforms//os:windows. - Fixed compilation under clang 21 (e.g. Apple clang on macOS 26): its tightened constexpr rules reject placement-
construct_atinto a const-qualified object, sostruct_names_clang.handlimited_vector.hnow store the non-const value type.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.11.0")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")Using the provided development modules
Copy dev.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it. It provides the dev-only Hedron compile-commands extractor (generates compile_commands.json for clangd) and depend_on_what_you_use.
include("//:dev.MODULE.bazel")What's Changed
- Drop GCC 12 testing. by @helly25 in #179
- chore: track trunk meta-linter config by @helly25 in #180
- feat(testing): add IsElementOf / IsKeyOf / IsValueOf matchers by @helly25 in #181
- ci: Node 24 actions + tighten trunk vs pre-commit lint ownership by @helly25 in #182
- ci: harden
donejob into a real aggregating gate by @helly25 in #184 - chore(deps): Bazel 9.1.1 toolchain + module updates by @helly25 in #185
- Fix CI
donegate and make decompose_count clang-format-stable by @helly25 in #186 - Remove remaining WORKSPACE support; enforce done-gate job coverage by @helly25 in #187
- ci: add self-check to
donegate by @helly25 in #189 - Verify macOS clang+asan via toolchains_llvm #767 (@loader_path rpath fix) by @helly25 in #188
- feat(testing): allow StatusIs() to accept a status-code matcher by @helly25 in #190
- ci: auto-publish releases to the BCR via reusable workflow by @helly25 in #191
- ci(bcr): test on macos_arm64 and add Bazel 9.x by @helly25 in #192
Full Changelog: 0.10.0...0.11.0
0.10.0
Version 0.10.0
Changelog
- Bumped minimum GCC to 13.
- Added
mbo/jsonwhich adds JSon write support for almost any structured type. If anything is missing it can easily be added on the client side. - Added direct support for
-fno-exceptionsirrespective of config setting. - Added support for ASAN symbolizer with
--config=clang. - Added AbslStringify and hash support to
NoDestruct,RefWrap,Required. - Added struct
OptionalDataOrRefsimilar tostd::optionalbut can holdstd::nullopt, a typeTor a referenceT&/const T&. - Added struct
OptionalDataOrConstRefsimilar tostd::optionalbut can holdstd::nullopt, a typeTor a const referenceconst T&. - Added struct
OptionalRefsimilar tostd::optionalbut can holdstd::nulloptor a referenceT&/const T&. - Improved
Stringify(breaking change):- Improved control for
Stringifywith Json output. - Updated
StringifyOptions(breaking change). - Updated
StringifyWithFieldNames(breaking change). - Moved
StringifyOptionsfactories toStringifyso they can be constexpr even in C++20. - Modified
MboTypesStringifyOptions(breaking change) to be more flexible - but users must deal with the change. - Added ability to detect bad
MboTypesStringifyOptionssignatures. - Added
StringifyFieldOptionswhich holds outer and innerStringifyOptions. - Added
Stringify::AsJsonPretty()andStringifyOptions::AsJsonPretty(). - Added API extension point functoin
MboTypesStringifyValueAccesswhich allows to replace a struct with a single value inStringifyprocessing. - Added
Stringifysupport for empty types and types that matchIsStringKeyedContainer. - Fixed
Stringifynull* representations to stream as'null'as opposed to0. - Added ability to sort string keyed containers.
- Added function
SetStringifyOstreamOutputModewhich sets global Stringify stream options by mode. - Added function
SetStringifyOstreamOptionswhich sets global Stringify stream options. - Changed
Stringify::ToStringandStringify::Streamto not depend on any mutable member ofStringify.
- Improved control for
- Improved traits:
- Added concept
ConstructibleFromimplements a variant ofstd::constructible_fromthat works around its limitations to deal with array args. - Added concept
IsEmptyTypedetermines whether a type is empty (callsstd::is_empty_v). - Fixed concept
IsAggregate(breaking change). - Added concept
IsStringKeyedContainerwhich determines whether a type is a container whose elements are pairs and whose keys are convertible to a std::string_view. - Added concept
IsReferenceWrapperdetermines whether a type is astd::reference_wrapper. - Added concept
IsSameAsAnyOfwhich determines whether a type is the same as one of a list of types. Similar toIsSameAsAnyOfRawbut using exact types. - Added template struct
TypedViewa wrapper for STL views that provides type definitions, most importantlyvalue_type. That allows such views to be used with GoogleTest container matchers. - Added concept
IsOptionalDataOrRefwhich determines whether a type is aOptionalDataOrRef. - Added concept
IsOptionalRefwhich determines whether a type is aOptionalRef. - Added function
CompareArithmeticwhich compares two values that are scalar-numbers (including foat/double, excluding pointers and references). - Added function
CompareIntegralwhich compares two values that are integral-numbers (no float/double, no pointers, no references). - Added function
CompareScalarwhich compares two values that are scalar-numbers (including float/double and pointers, excluding references). - Added concept
IsArithmeticusesstd::is_arithmetic_v<T>. - Added concept
IsIntegralusesstd::integral<T>. - Added concept
IsScalarusesstd::is_scalar_v<T>. - Added concept
IsFloatingPointdetermines whether a type is a floating point type (usesstd::floating_point). - Added concept
ThreeWayComparableTowhich is similar tostd::three_way_comparable_withbut we only verify thatL <=> Rcan be interpreted asCatin the presented argument order.
- Added concept
- Added
Demangleto log de-mangled typeid names. - Added struct
Overloadedwhich implements an Overload handler forstd::visit(std::variant<...>)andstd::variant::visit(technically moved). - Added function
CompareFloatwhich can compare twofloat,doubleorlong doublevalues returningstd::strong_ordering. - Added function
WeakToStrongwhich converts astd::weak_orderingto astd::strong_ordering. - Fixed some IWYU pragmas.
- Fixed some template requirements.
- Fixed bug in
mbo::strings::ParseStringwith access past end ofstring_viewfor illegal hex and oct escape sequences (introduced in 0.9.0). - Updated various dependencies.
- Renamed old dependency naming styles to new (matching bzlmod and other deps' needs) styles where possible.
- Removed WORKSPACE support.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.10.0")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")For Bazel WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_helly25_mbo",
url = "https://github.com/helly25/mbo/releases/download/0.10.0/mbo-0.10.0.tar.gz",
sha256 = "52d2cfe222244092688b06793d44dec4f8c551b5589f730bb251bc18b8c06b47",
strip_prefix = "mbo-0.10.0",
)Initializing the required modules
The project depends on some additional external repositories that can be added
manually of by calling the support functions in the user' WORKSPACE file:
load("@com_helly25_mbo//bzl/workspace:load_modules.bzl", "helly25_mbo_load_modules")
helly25_mbo_load_modules()
load("@com_helly25_mbo//bzl/workspace:init_modules.bzl", "helly25_mbo_init_modules")
helly25_mbo_init_modules()Initializing optional extra modules
The project further has some re-usable external components:
load("@com_helly25_mbo//bzl/workspace:load_extras.bzl", "helly25_mbo_load_extras")
helly25_mbo_load_extras() # Adds Hedron + LLVM
load("@com_helly25_mbo//bzl/workspace:init_extras.bzl", "helly25_mbo_init_extras")
helly25_mbo_init_extras() # Init Hedron + LLVM
load("@com_helly25_mbo//bzl/workspace:init_extras_llvm.bzl", "helly25_mbo_init_extras_llvm")
helly25_mbo_init_extras_llvm() # Init LLVM/Part 2What's Changed
- Bump version from 0.9.0 to 0.9.1 by @helly25 in #147
- Improved control for
Stringifywith Json output. by @helly25 in #148 - Added
Stringify::AsJsonPretty()andStringifyOptions::AsJsonPretty(). by @helly25 in #149 - Enable test also for clang. by @helly25 in #150
- Improved Stringify control by @helly25 in #151
- Added New Optional{Ref|DataOrRef|DataOrConstRef} by @helly25 in #152
- Switch shell formatting to shfmt by @helly25 in #153
- Allow key_use_name to take a function (as value). by @helly25 in #154
- Improve StringifyOptions by @helly25 in #155
- Stringify improvements by @helly25 in #156
- Reenable GCC 12 by @helly25 in #157
- Optimize and Cleanup. by @helly25 in #159
- Fixes and cleanup by @helly25 in #160
- More C++20 constexpr by @helly25 in #161
- Improve Stringify by @helly25 in #162
- Improve stringify by @helly25 in #163
- Added ConstructibleFrom by @helly25 in #164
- Added TypedView by @helly25 in #165
- Improve Stringify by @helly25 in #166
- Improved comparison support by @helly25 in #167
- Added IsFloatingPoint by @helly25 in #168
- Update docs by @helly25 in #169
- Improve TypedView by making it itself an actual valid view. by @helly25 in #170
- Implemented ThreeWayComparableTo by @helly25 in #171
- Cleanup by @helly25 in #172
- Fixed bug in
mbo::strings::ParseStringwith access past end ofstring_viewfor illegal hex and oct escape sequences (introduced in 0.9.0). by @helly25 in #173 - Various dependency updates by @helly25 in #174
- Fix workspace builds by @helly25 in #175
- Drop workspace support: It creates too many issues in too many configurations. by @helly25 in #176
- Add Json write support by @helly25 in #177
- Update next version computation by @helly25 in #178
Full Changelog: 0.9.0...0.10.0
0.9.0
Version 0.9.0
Changelog
- Added gmomck-matcher
mbo::testing::EqualsTextwhich compares text using line by line unified text diff. - Added gmock-matcher-modifier
mbo::testing::WithDropIndentwhich modifiesEqualsTextso thatmbo::strings::DropIndentwill be applied to the expected text.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.9.0")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")For Bazel WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_helly25_mbo",
url = "https://github.com/helly25/mbo/releases/download/0.9.0/mbo-0.9.0.tar.gz",
sha256 = "3c856c7f457cec9a59f89c48ff6f26966d6f4ef97a16cf7a96f4e612add6b72e",
strip_prefix = "mbo-0.9.0",
)Initializing the required modules
The project depends on some additional external repositories that can be added
manually of by calling the support functions in the user' WORKSPACE file:
load("@com_helly25_mbo//bzl/workspace:load_modules.bzl", "helly25_mbo_load_modules")
helly25_mbo_load_modules()
load("@com_helly25_mbo//bzl/workspace:init_modules.bzl", "helly25_mbo_init_modules")
helly25_mbo_init_modules()Initializing optional extra modules
The project further has some re-usable external components:
load("@com_helly25_mbo//bzl/workspace:load_extras.bzl", "helly25_mbo_load_extras")
helly25_mbo_load_extras() # Adds Hedron + LLVM
load("@com_helly25_mbo//bzl/workspace:init_extras.bzl", "helly25_mbo_init_extras")
helly25_mbo_init_extras() # Init Hedron + LLVM
load("@com_helly25_mbo//bzl/workspace:init_extras_llvm.bzl", "helly25_mbo_init_extras_llvm")
helly25_mbo_init_extras_llvm() # Init LLVM/Part 2What's Changed
- Bump version from 0.8.0 to 0.8.1 by @helly25 in #145
- Added gmock-matcher EqualsText by @helly25 in #146
Full Changelog: 0.8.0...0.9.0
0.8.0
Version 0.8.0
Changelog
- Renamed diff tooling options
ignore_space_changeto `ignore_trailing_space. - Renamed
lhs_regex_replaceandrhs_regex_replacetoregex_replace_lhsandregex_replace_rhsrespectively. - Added
regex_replace_lhsandregex_replace_rhsto bzl rules//mbo/diff:diff_testand//mbo/diff/tests:diff_test_test. - Renamed
mbo::diff::UnifiedDifftombo::diff::Diff. - Implemented diff algorithm
kDirectwhich performs a direct side by side comparison. - Renamed
//mbo/diff/unified_diff(_main).cc/hto//mbo/diff/diff(_main).cc/h. - Renamed
//mbo/diff:unified_diffto//mbo/diff. - Renamed
unifiedtocontextfor flags and attributes. - Reorganized files and rules in directory
mbo/diff.
For Bazel MODULES.bazel
bazel_dep(name = "helly25_mbo", version = "0.8.0")Using the provided LLVM
Copy llvm.MODULE.bazel to your repository's root directory and add the following line to your MODULES.bazel file or paste the whole contents into it.
include("//:llvm.MODULE.bazel")For Bazel WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "com_helly25_mbo",
url = "https://github.com/helly25/mbo/releases/download/0.8.0/mbo-0.8.0.tar.gz",
sha256 = "d7eb28285e16ca6e5bea9261bad7064b12c457991fbb70f9fd65444649133dae",
strip_prefix = "mbo-0.8.0",
)Initializing the required modules
The project depends on some additional external repositories that can be added
manually of by calling the support functions in the user' WORKSPACE file:
load("@com_helly25_mbo//bzl/workspace:load_modules.bzl", "helly25_mbo_load_modules")
helly25_mbo_load_modules()
load("@com_helly25_mbo//bzl/workspace:init_modules.bzl", "helly25_mbo_init_modules")
helly25_mbo_init_modules()Initializing optional extra modules
The project further has some re-usable external components:
load("@com_helly25_mbo//bzl/workspace:load_extras.bzl", "helly25_mbo_load_extras")
helly25_mbo_load_extras() # Adds Hedron + LLVM
load("@com_helly25_mbo//bzl/workspace:init_extras.bzl", "helly25_mbo_init_extras")
helly25_mbo_init_extras() # Init Hedron + LLVM
load("@com_helly25_mbo//bzl/workspace:init_extras_llvm.bzl", "helly25_mbo_init_extras_llvm")
helly25_mbo_init_extras_llvm() # Init LLVM/Part 2What's Changed
- Bump version from 0.7.0 to 0.7.1 by @helly25 in #137
- Always process lines. by @helly25 in #138
- Add regex_replace to diff_test by @helly25 in #139
- Shell quoting for diff_test by @helly25 in #140
- Implement direct diff algorithm by @helly25 in #141
- Finish renaming unified_diff to just diff by @helly25 in #142
- Add diff headers to direct algorithm by @helly25 in #143
- Reorg mbo/diff by @helly25 in #144
Full Changelog: 0.7.0...0.8.0