Skip to content

Support mixins referencing other mixins - #70

Merged
cottsay merged 2 commits into
PiousCrossten/reverse-list-concatenationfrom
PiousCrossten/mixins-referencing-mixins
Aug 21, 2026
Merged

Support mixins referencing other mixins#70
cottsay merged 2 commits into
PiousCrossten/reverse-list-concatenationfrom
PiousCrossten/mixins-referencing-mixins

Conversation

@PiousCrossten

@PiousCrossten PiousCrossten commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Lets one mixin be built out of others. A mixin can now list other mixins under a reserved mixin key, instead of copy-pasting the same cmake-args into every variant.

Addresses #39.

So this becomes possible:

build:
  debug:
    cmake-args: ["-DCMAKE_BUILD_TYPE=Debug"]
  ccache:
    cmake-args: ["-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"]
  dev:
    mixin: ["debug", "ccache"]
    cmake-args: ["-DBUILD_TESTING=ON"]

colcon build --mixin dev applies debug, then ccache, then dev's own arguments - references first, so the mixin doing the referencing gets the last word and can override anything it inherits. Command line arguments still beat all of them.

How it works

colcon_mixin/mixin/order.py is a new standalone module that works out the application order with a depth-first post-order walk. Two details worth flagging for review:

  • A mixin reached through more than one path is applied once per path, so the returned list can contain duplicates. That's deliberate — it's what keeps last-one-wins consistent no matter how the graph is shaped.
  • Cycle detection only looks at the active recursion path, not everything visited so far, so legitimate re-application isn't mistaken for a cycle.

Circular references, unknown names, and a malformed mixin key each raise their own errthem into ordinary CLI errors rather than tracebacks.

In mixin_argument.py the reserved mixin key is skipped during the overlay, since it's metadata rather than an argument. Mixins that don't use the key behave exactly as before.

Tests

test/test_order.py covers the ordering algorithm and the error cases; test/test_mixin_argument.py adds nested references, scalar overrides, command line precedence, and the error paths through the parser.


Stacked on #71 - this PR targets that branch, so the diff here shows only the composition work. It'll retarget to master and be rebased once #71 lands.

Claude Opus (via Antigravity) was used for generating test cases and for architecture level testing. The design, implementation and final review are my own.

Add colcon_mixin/mixin/order.py, a standalone module that computes the
application order for a mixin together with the other mixins it
references through a 'mixin' key. It uses a depth-first, post-order
traversal with re-application: referenced mixins are recorded before the
mixin that references them, and a mixin reachable through multiple paths
is applied once per path to preserve last-applied-wins semantics. Cycle
detection uses the active recursion path only, so legitimate
re-application is never mistaken for a cycle. Circular references,
unknown references and malformed 'mixin' keys raise dedicated errors.

Add unit tests covering the ordering algorithm, the canonical reference
graph and error reporting.

Assisted-by: Claude Opus (Antigravity) for test case generation and
  architecture-level testing
Expand each requested mixin into its full application order using
colcon_mixin.mixin.order and apply the result in reverse, so the
prepend-based overlay produces the computed order while explicit command
line arguments keep precedence. A referencing mixin is applied
conceptually last and can override values inherited from its references.
Skip the reserved 'mixin' key during overlay since it is metadata, not
an argument. Report circular, unknown and malformed references as clean
CLI errors. Mixins without a 'mixin' key behave exactly as before.

Add parser integration tests covering nested references, scalar
overrides, command line precedence and error reporting.

Assisted-by: Claude Opus (Antigravity) for test case generation and
  architecture-level testing
@PiousCrossten
PiousCrossten changed the base branch from master to PiousCrossten/reverse-list-concatenation August 11, 2026 07:08

@knmcguire knmcguire left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See my comments here on the same PR but in your forked repo but I approve it on my end!

PiousCrossten#1

@PiousCrossten PiousCrossten changed the title Pious crossten/mixins referencing mixins Support mixins referencing other mixins via a reserved 'mixin' key Aug 11, 2026
@cottsay cottsay changed the title Support mixins referencing other mixins via a reserved 'mixin' key Support mixins referencing other mixins Aug 21, 2026
@cottsay
cottsay merged commit b02227c into master Aug 21, 2026
46 checks passed
cottsay pushed a commit that referenced this pull request Aug 21, 2026
* Add mixin ordering module for composing mixins

Add colcon_mixin/mixin/order.py, a standalone module that computes the
application order for a mixin together with the other mixins it
references through a 'mixin' key. It uses a depth-first, post-order
traversal with re-application: referenced mixins are recorded before the
mixin that references them, and a mixin reachable through multiple paths
is applied once per path to preserve last-applied-wins semantics. Cycle
detection uses the active recursion path only, so legitimate
re-application is never mistaken for a cycle. Circular references,
unknown references and malformed 'mixin' keys raise dedicated errors.

Add unit tests covering the ordering algorithm, the canonical reference
graph and error reporting.

Assisted-by: Claude Opus (Antigravity) for test case generation and
  architecture-level testing

* Apply referenced mixins in parse_args

Expand each requested mixin into its full application order using
colcon_mixin.mixin.order and apply the result in reverse, so the
prepend-based overlay produces the computed order while explicit command
line arguments keep precedence. A referencing mixin is applied
conceptually last and can override values inherited from its references.
Skip the reserved 'mixin' key during overlay since it is metadata, not
an argument. Report circular, unknown and malformed references as clean
CLI errors. Mixins without a 'mixin' key behave exactly as before.

Add parser integration tests covering nested references, scalar
overrides, command line precedence and error reporting.

Assisted-by: Claude Opus (Antigravity) for test case generation and
  architecture-level testing
PiousCrossten pushed a commit to PiousCrossten/gsoc-2026-colcon-mixin that referenced this pull request Aug 27, 2026
Final report for "Add Support for Mixin Composition in colcon-mixin",
Google Summer of Code 2026 with OSRF / Open Robotics.

Covers the merged work (colcon/colcon-mixin#70, #71), the open follow-ups
(#73 and colcon/colcon.readthedocs.org#113), the architecture and the
ordering alternatives that were considered and rejected, testing, and the
week-by-week project history.

The two working documents are archived under docs/ rather than linked
externally so they remain readable alongside the report. The project log
is lightly redacted: a recurring video-call link and a tokenised proposal
download URL were removed. No project content was altered.
@cottsay cottsay added this to the 0.3.0 milestone Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants