Skip to content

Ensure no breakage of public API#715

Draft
castler wants to merge 8 commits into
mainfrom
js_api_surface
Draft

Ensure no breakage of public API#715
castler wants to merge 8 commits into
mainfrom
js_api_surface

Conversation

@castler

@castler castler commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

No description provided.

castler and others added 3 commits July 3, 2026 23:59
Adds a clang AST-based tool that extracts the public API surface of a
cc_library target and compares it against a committed lock file. This
catches accidental API breakage via 'bazel test' and allows intentional
updates via 'bazel run'.

Key features:
- Uses clang -ast-dump=json for robust C++ parsing (handles ifdefs, templates)
- Follows type aliases (using Foo = impl::Foo) to underlying class members
- Tracks documentation markers (\api and \brief doxygen tags)
- Integrates with Bazel build system via custom rules
- Skips std:: and internal namespace types when following aliases

Usage:
  bazel test //score/mw/com:api_surface_test    # Check for API changes
  bazel run //score/mw/com:api_surface_update   # Update lock file

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The lock file should only track the API shape (name, qualified_name,
kind, signature). File paths, line numbers, and documentation markers
cause noisy diffs unrelated to actual API changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add _get_public_members() for recursive base class walking
- Add _resolve_class_node() to resolve qualType strings to AST nodes
- Type aliases now expose inherited public members from base classes
- Template type aliases (e.g. SamplePtr<T>) correctly extract members
- Lock file updated: 63 documented + 87 undocumented symbols (was 45+62)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
import argparse
import difflib
import json
import sys
@castler
castler force-pushed the js_api_surface branch 5 times, most recently from 3ae8e5e to 49aaf7c Compare July 17, 2026 05:50
castler and others added 5 commits July 17, 2026 08:49
Add 8 test scenarios inspired by an internal astgard test suite:
1. Basic class: public methods extracted, private members excluded
2. Type alias: follows 'using Foo = impl::Foo' to underlying type
3. Inheritance: inherited public members from base classes
4. Template alias: template type alias member extraction
5. Private changes: private members/methods not tracked
6. Types in signatures: structs with public data fields
7. Enum and free functions: scoped enum values + namespace functions
8. Internal namespace filtering: detail::/internal:: excluded

Also fixes two extraction gaps found during testing:
- Add EnumConstantDecl to handled kinds (enum values now extracted)
- Add FieldDecl to handled kinds (public struct data members tracked)

All tests run via 'bazel test //quality/api_surface/tests/...'

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- remove manual hdrs from api_surface_test/api_surface_update
- derive analyzed headers from deps and pass header list via file
- include compile defines and keep full transitive headers as AST inputs
- stop suppressing clang failures in AST generation
- update tests BUILD calls and README docs

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- use explicit public com libraries as api_surface deps for score/mw/com
- add py_test to detect degraded int signatures and lock-size explosions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- replace shell diff_api wrapper with a py_binary-backed Python module
- keep the compare logic importable for unit tests
- add regression coverage for the compare path

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…target

Remove `api_surface_update` as a public macro. `api_surface_test` now
automatically creates an implicit `<name>.update` runnable target (via
`_api_surface_update_rule`) that shares the same `_gen` action.

The `lock_file_path` for the update target is derived automatically from
`native.package_name() + "/" + lock_file`, eliminating the need for
callers to duplicate that information.

Callers update:
- Remove all explicit `api_surface_update(...)" calls
- Drop `"api_surface_update"` from all `load()` statements
- Use `bazel run :<name>.update` instead of `bazel run :<name>_update`

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant