Skip to content

Releases: mboworks/mbo

0.14.0

Choose a tag to compare

@github-actions github-actions released this 30 Aug 19:33
0.14.0
4eef7f8

Version 0.14.0

Changelog

  • Updated the bundled LLVM setup to the official toolchains_llvm 1.9.0 prerelease commit while
    its BCR publication is pending, removing the remaining helly25/toolchains_llvm fork 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 to mboworks_mbo, and
    migrated shell tests to mboworks_bashtest@0.6.1. Historical helly25_mbo releases 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/**/bar matches foo/bar and any number of intervening directory levels.
  • Added mbo::StringOrView, a read-only string-like value that either owns a std::string or
    borrows a std::string_view. It exposes the full applicable string/string-view interface,
    comparisons, C++23-style contains/subview, stream and Abseil formatting, plus Abseil and
    std::hash integration.
  • Fixed OptionalDataOrRef construction and assignment so borrowed values cannot silently become
    dangling references; added the corresponding lifetime constraints and tests.
  • Fixed Required replacement and generic operations, including move-only values and converting
    construction/assignment, while preserving its configurable failure behavior.
  • Fixed NoDestruct construction 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 NormalizePath preserve the filesystem's native character type instead of assuming narrow
    characters.
  • Made GetContents report seek failures and GetMaxLines report 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 rated GOOD, including mbo/types at 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 aggregate done gate.
  • 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 over std::size_t capacities while the class takes auto: instances spelled via MakeLimitedVector/LimitedOptions or an int literal matched no operator at all and failed to compile.
  • Enabled cppcoreguidelines-pro-bounds-avoid-unchecked-container-access: unchecked operator[] 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 scoped NOLINT blocks.
  • Fixed LimitedVector comparison operators (==, <=>, <), which looped to min of the CAPACITIES instead of the sizes: comparing partially-filled vectors read uninitialized slots (or threw in a require-throws build). Found by pro-bounds-avoid-unchecked-container-access.
  • Converted unchecked operator[] to .at()/std::get (or a reasoned NOLINT in benchmarks' timed loops and compile-time code) across the hash, digest, json, types and container libraries.
  • Converted unchecked operator[] to .front()/.at() (or a reasoned NOLINT on hot paths) across the diff, strings, log, mope, file and testing libraries, preparing pro-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 in decompose_count.h) are annotated __extension__ in code. The bazel-7/8 compat CI rungs relax it because those bazels half-apply external_include_paths and leak external-header findings.
  • Removed the temporary hash_tembo.h allowlist 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, with missing-field-initializers suppressed as the deliberate designated-init idiom; previously only -Werror was 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-symbolizer via runfiles so a fresh LLVM fetch location cannot break asan/tsan.
  • Added a headers-claimed pre-commit check: every tracked header must be listed in its package's BUILD file. Found hash_tembo.h orphaned since #306 on its first run (temporarily allowlisted; re-listed by #311).
  • Replaced the reachability-based library-test-coverage hook with xff's strict rule: every cc_library needs a test in its own package with a direct dependency; exceptions live in the tool's _ALLOWLIST with 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 (_cc naming, per-package tests, no braced-init-list iteration, lhs/rhs comparator parameters).
  • Added tests for hash_extra_cc, hash_internal_util_cc, mope_cc, ini_cc, runfiles_dir_cc, extend_cc, extender_cc and test_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-argument suppression: the hermetic toolchain resolves libc++ headers via -cxx-isystem and 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 official toolchains_llvm 1.9.0 prerelease selected by git_override until BCR publication.
  • Removed the redundant --cxxopt=-stdlib=libc++ from the clang-tidy bazel config; the hermetic toolchain already passes it, so it appeared twice and produced "unused argument" warnings.
  • Fixed mbo::file::GetMTime on...
Read more

0.13.2

Choose a tag to compare

@github-actions github-actions released this 16 Jul 23:53
1a161d9

Version 0.13.2

Changelog

  • Added BmHash128Throughput (128-bit bounded-range throughput) and guarded the 64-/128-bit benchmark paths by HasGetHash64/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 BmHash64Throughput reporting bytes/s over two documented length distributions (Short ≤128 B, Web ≤4096 B) truncated to each upper bound; the per-exact-length BmHash64/BmHash128 remain the latency view. Distributions are exported as the throughput_dists context.
  • Added a compare command reporting per-case Δ% and a geomean between two datasets.
  • Made tables/plot/compare/quality accept a bundle .tgz or a results JSON, positionally or via --results/--bundle.
  • Added plot --kind (throughput/latency/all) and --scale (log-log/linear-log).
  • Expanded the benchmark kFullSizes and swept latency over the full set (dense ns-vs-length latency curve).
  • Added a quality command generating the overview + SMHasher3 Results tables from hash_algorithms.json and a measured bundle; --check gates them.
  • Added a consistency command verifying same-source-SHA bundles agree on SMHasher3 verdicts.
  • Fixed SMHasher3 parsing: a bad name or crash reads as ERROR not a false PASS; score and failing families parse from the Summary; legacy names aliased.
  • Integrated mbo/hash/measurements as a normal dev package (still release-stripped) with a quality_sh_test gating the tables; test CI fetches the LFS bundles.
  • Added a no-deps-on-measurements pre-commit guard.
  • Ported mumbo (64-bit) to Starlark (hash.mumbo), byte-identical to C++; hash.bzl now offers mumbo, dumbo, and fnv1a.

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

Choose a tag to compare

@github-actions github-actions released this 12 Jul 20:37
72b1f20

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.in and hash_mangle_seed_default_test, so a version bump no longer needs a committed regeneration. hash_mangle.h includes the generated header directly (missing is an #error; clangd falls back under -DIS_CLANGD).
  • Added Starlark ports of the dumbo and fnv1a hashes in //mbo/hash:hash.bzl (the public hash struct), byte-identical to C++ and verified against it.
  • Switched the mangle version/seed fold from FNV-1a to the in-house dumbo hash.
  • Added //mbo/hash:hash_tool, a minimal <algo> [<data>] hash CLI (plain GetHash64, 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

Choose a tag to compare

@github-actions github-actions released this 11 Jul 23:07
0.13.0
8facf9f

Version 0.13.0

Changelog

  • Added DiffOptions::ignore_missing_final_newline (the mbo::diff --ignore_missing_final_newline flag and the diff_test ignore_missing_final_newline attribute): a file with and one without a trailing newline compare equal (the \ No newline at end of file marker is suppressed). It only ignores the terminator, so an empty file stays distinct from a single empty line. Honored identically by all three algorithms (shared Data preprocessing).
  • mbo::diff now treats an empty DiffOptions::time_format as "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-empty time_format is unchanged, and time_format stays 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 myers tokenizer: interning keys are now std::string_views into the preprocessed line cache hashed with mbo::hash::GetHash64 (previously every line was copied into a std::string-keyed map), and ignore_case folds 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 the tokenize_* cases in //mbo/diff:diff_benchmark (whitespace-ignore variants included; ignore_all_space now also builds its stripped line in place instead of via an extra copy).
  • The mbo::diff binary follows the POSIX diff exit code contract: 0 = equal, 1 = different, 2 = trouble (unreadable input, internal error, bad usage; previously conflated with 1). The bazel diff_test rule gained the minimal attribute, and mbo/diff/TODO.md records the remaining optional features and explicit non-goals.
  • Rounded out the mbo::diff CLI/test surface: new --minimal flag (DiffOptions::minimal) guaranteeing minimal myers diffs by disabling the cost cap (like GNU diff --minimal); the usage message names all algorithms and formats; the bazel diff_test rule gained width and skip_left_deletions attributes; 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_length and time_format intentionally stay library-only.
  • Renamed the previous default mbo::diff algorithm from unified to 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 value unified remains supported as a deprecated alias that now selects myers - matching its historic "like diff -u" promise - and enforces --format=unified.
  • Verified the mbo::diff feature/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 under naive, myers and direct, and all three output formats work with every algorithm. One documented corner case: combining ignore_case with a case-sensitive ignore_matching_lines expression - a matching and a non-matching line differing only in case compare equal under naive but not under the token-based myers; write such expressions case-insensitively ((?i)...). max_diff_chunk_length only applies to naive (myers uses an internal cost cap, direct needs no bound).
  • Added mbo::diff output formats: next to the default unified format, DiffOptions::output_format selects context format (diff -c) or normal format (plain diff). The diff binary and the diff_test bazel rule gained the matching --format=unified|context|normal flag / format attribute (normal format defaults --context to 0 and emits no file headers; context format uses ***/--- file headers). Both new formats reproduce GNU diff output byte for byte and apply cleanly with patch.
  • Fixed mbo::diff unified 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. Previously patch applied such hunks one line too late.
  • Split the mbo::diff chunk rendering out of mbo/diff/internal/chunk.cc into mbo/diff/internal/output.{h,cc} (diff_internal::AppendChunk); Chunk now only accumulates and filters.
  • Added mbo::hash::GetHash64(std::string_view) / GetHash128(std::string_view) and the mbo::hash::Hash128 result type - constexpr-safe, non-cryptographic hashing; the default algorithm is the in-house mumbo (see below).
  • Renamed the legacy in-house hash mbo::hash::simple to mbo::hash::dumbo and redesigned it into a compact single-lane MUM hash. Nothing-up-my-sleeve constants (golden ratio, sqrt-prime fractions), a widening Mul128Fold64 step 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 to mumbo, not a replacement (see mbo/hash/README.md for the measured design iterations). The deprecated simple::GetHash wrapper and the mbo::hash::simple namespace are removed outright - pre-1.0, so no compatibility alias is kept and existing mbo::hash::simple::* users must migrate. Use mbo::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::hash entry points (GetHash64, GetHash128, GetHash) are now templates over an algorithm struct (default DefaultHashAlgorithm, i.e. mbo::hash::mumbo). Every algorithm provides a <ns>::Algorithm struct with static GetHash64/GetHash128 members; the concepts HasGetHash64/HasGetHash128/IsHashAlgorithm detect what is available, and Hasher<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), and mbo::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 from murmur3::GetHash128 (whose GetHash64 is the canonical h1 truncation instead).
  • Added the build-seed mangle as its own entry point mbo/hash/hash_mangle.h (//mbo/hash:hash_mangle_cc): GetHash<Algo, Seed> and MangledHasher<Algo> XOR ONE build-selected constant into GetHash64 values (still constexpr), so values deliberately do not compare across independently configured builds; plain hash.h / :hash_cc stays 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 from MODULE.bazel via native.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 (default 8; 0 disables the mangle making GetHash == GetHash64, 1 pins 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 of absl/std hash containers with heterogeneous std::string_view lookup.
  • Added mbo::hash::CombineHashes(uint64_t, uint64_t) (order-dependent, well-mixed combine) and hash_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...
Read more

0.12.0

Choose a tag to compare

@github-actions github-actions released this 27 Jun 17:47
1343daf

Version 0.12.0

Changelog

  • Fixed visibility of already-documented APIs whose Bazel cc_library targets had defaulted to //visibility:private since they were added, so external code could not deps them. Now //visibility:public: //mbo/types:optional_ref_cc (OptionalRef), //mbo/types:optional_data_or_ref_cc (OptionalDataOrRef / OptionalDataOrConstRef), and the //mbo/json:json / :json_cc library - all added in 0.10.0.
  • Made //mbo/types:stringify_ostream_cc public (stringify_ostream.h): the ostream << integration for Stringify / Extend types plus the SetStringifyOstreamOutputMode / SetStringifyOstreamOptions configuration functions.
  • Renamed the module repo to helly25_mbo and dropped the com_helly25_mbo alias (repo_name). The last internal user (the ini_file golden 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_bashtest 0.3.1 -> 0.4.0 and dropped its com_helly25_bashtest repo alias (a WORKSPACE-era compatibility name); BUILD files now load("@helly25_bashtest//bashtest:bashtest.bzl", ...). mbo is bzlmod-only (--noenable_workspace, no WORKSPACE file).
  • Bumped rules_cc 0.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

Choose a tag to compare

@github-actions github-actions released this 19 Jun 14:33
0.11.1
4792a8b

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

Choose a tag to compare

@github-actions github-actions released this 15 Jun 21:26
0.11.0
861bbf4

Version 0.11.0

Changelog

  • Added mbo::testing::IsElementOf(container) — element-on-the-left orientation of gmock's Contains. Iterates with raw operator== (with a std::pair component-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 to IsKeyOf for mapped values. Failure messages report "is a value of {…}".
  • Bumped Bazel to 9.1.1 (.bazelversion).
  • Updated module dependencies: bazel_skylib 1.8.2 → 1.9.0, platforms 1.0.0 → 1.1.0, rules_cc 0.2.14 → 0.2.19, rules_shell 0.6.1 → 0.8.0, re2 2025-11-05 → 2025-11-05.bcr.1, googletest 1.17.0 → 1.17.0.bcr.2, google_benchmark 1.9.4 → 1.9.5, helly25_bashtest 0.1.0 → 0.3.0, toolchains_llvm 1.5.0 → 1.7.0, depend_on_what_you_use 0.7.0 → 0.16.0, and the hedron_compile_commands pin.
  • helly25_bashtest 0.3.0 loads the sh_* rules from @rules_shell directly, so Bazel 9 (which no longer autoloads the legacy native sh_* rules) needs no --incompatible_autoload_externally workaround.
  • Bumped abseil-cpp 20250814.1 → 20250814.2. Held at the 20250814 series because newer Abseil (20260107+) deprecates the absl::MutexLock(Mutex*) constructor that re2 2025-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_test builds with cfg=exec); 20.1.x links cleanly and compiles the tree without new -Werror warnings.
  • Migrated the _diff_test is_windows select off the deprecated @bazel_tools//src/conditions:host_windows to @platforms//os:windows.
  • Fixed compilation under clang 21 (e.g. Apple clang on macOS 26): its tightened constexpr rules reject placement-construct_at into a const-qualified object, so struct_names_clang.h and limited_vector.h now 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 done job into a real aggregating gate by @helly25 in #184
  • chore(deps): Bazel 9.1.1 toolchain + module updates by @helly25 in #185
  • Fix CI done gate 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 done gate 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

Choose a tag to compare

@github-actions github-actions released this 15 Nov 09:37
0.10.0
2d9fdc4

Version 0.10.0

Changelog

  • Bumped minimum GCC to 13.
  • Added mbo/json which 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-exceptions irrespective of config setting.
  • Added support for ASAN symbolizer with --config=clang.
  • Added AbslStringify and hash support to NoDestruct, RefWrap, Required.
  • Added struct OptionalDataOrRef similar to std::optional but can hold std::nullopt, a type T or a reference T&/const T&.
  • Added struct OptionalDataOrConstRef similar to std::optional but can hold std::nullopt, a type T or a const reference const T&.
  • Added struct OptionalRef similar to std::optional but can hold std::nullopt or a reference T&/const T&.
  • Improved Stringify (breaking change):
    • Improved control for Stringify with Json output.
    • Updated StringifyOptions (breaking change).
    • Updated StringifyWithFieldNames (breaking change).
    • Moved StringifyOptions factories to Stringify so 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 MboTypesStringifyOptions signatures.
    • Added StringifyFieldOptions which holds outer and inner StringifyOptions.
    • Added Stringify::AsJsonPretty() and StringifyOptions::AsJsonPretty().
    • Added API extension point functoin MboTypesStringifyValueAccess which allows to replace a struct with a single value in Stringify processing.
    • Added Stringify support for empty types and types that match IsStringKeyedContainer.
    • Fixed Stringify null* representations to stream as 'null' as opposed to 0.
    • Added ability to sort string keyed containers.
    • Added function SetStringifyOstreamOutputMode which sets global Stringify stream options by mode.
    • Added function SetStringifyOstreamOptions which sets global Stringify stream options.
    • Changed Stringify::ToString and Stringify::Stream to not depend on any mutable member of Stringify.
  • Improved traits:
    • Added concept ConstructibleFrom implements a variant of std::constructible_from that works around its limitations to deal with array args.
    • Added concept IsEmptyType determines whether a type is empty (calls std::is_empty_v).
    • Fixed concept IsAggregate (breaking change).
    • Added concept IsStringKeyedContainer which determines whether a type is a container whose elements are pairs and whose keys are convertible to a std::string_view.
    • Added concept IsReferenceWrapper determines whether a type is a std::reference_wrapper.
    • Added concept IsSameAsAnyOf which determines whether a type is the same as one of a list of types. Similar to IsSameAsAnyOfRaw but using exact types.
    • Added template struct TypedView a wrapper for STL views that provides type definitions, most importantly value_type. That allows such views to be used with GoogleTest container matchers.
    • Added concept IsOptionalDataOrRef which determines whether a type is a OptionalDataOrRef.
    • Added concept IsOptionalRef which determines whether a type is a OptionalRef.
    • Added function CompareArithmetic which compares two values that are scalar-numbers (including foat/double, excluding pointers and references).
    • Added function CompareIntegral which compares two values that are integral-numbers (no float/double, no pointers, no references).
    • Added function CompareScalar which compares two values that are scalar-numbers (including float/double and pointers, excluding references).
    • Added concept IsArithmetic uses std::is_arithmetic_v<T>.
    • Added concept IsIntegral uses std::integral<T>.
    • Added concept IsScalar uses std::is_scalar_v<T>.
    • Added concept IsFloatingPoint determines whether a type is a floating point type (uses std::floating_point).
    • Added concept ThreeWayComparableTo which is similar to std::three_way_comparable_with but we only verify that L <=> R can be interpreted as Cat in the presented argument order.
  • Added Demangle to log de-mangled typeid names.
  • Added struct Overloaded which implements an Overload handler for std::visit(std::variant<...>) and std::variant::visit (technically moved).
  • Added function CompareFloat which can compare two float, double or long double values returning std::strong_ordering.
  • Added function WeakToStrong which converts a std::weak_ordering to a std::strong_ordering.
  • Fixed some IWYU pragmas.
  • Fixed some template requirements.
  • Fixed bug in mbo::strings::ParseString with access past end of string_view for 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 2

What's Changed

Full Changelog: 0.9.0...0.10.0

0.9.0

Choose a tag to compare

@github-actions github-actions released this 04 Jun 07:11
1c50ead

Version 0.9.0

Changelog

  • Added gmomck-matcher mbo::testing::EqualsText which compares text using line by line unified text diff.
  • Added gmock-matcher-modifier mbo::testing::WithDropIndent which modifies EqualsText so that mbo::strings::DropIndent will 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 2

What's Changed

Full Changelog: 0.8.0...0.9.0

0.8.0

Choose a tag to compare

@github-actions github-actions released this 05 May 17:23
b5eecc5

Version 0.8.0

Changelog

  • Renamed diff tooling options ignore_space_change to `ignore_trailing_space.
  • Renamed lhs_regex_replace and rhs_regex_replace to regex_replace_lhs and regex_replace_rhs respectively.
  • Added regex_replace_lhs and regex_replace_rhs to bzl rules //mbo/diff:diff_test and //mbo/diff/tests:diff_test_test.
  • Renamed mbo::diff::UnifiedDiff to mbo::diff::Diff.
  • Implemented diff algorithm kDirect which performs a direct side by side comparison.
  • Renamed //mbo/diff/unified_diff(_main).cc/h to //mbo/diff/diff(_main).cc/h.
  • Renamed //mbo/diff:unified_diff to //mbo/diff.
  • Renamed unified to context for 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 2

What's Changed

Full Changelog: 0.7.0...0.8.0