Skip to content

add support for musicxml 4.0 in mx::core#169

Merged
webern merged 20 commits into
masterfrom
musicxml-4.0
Jun 14, 2026
Merged

add support for musicxml 4.0 in mx::core#169
webern merged 20 commits into
masterfrom
musicxml-4.0

Conversation

@webern

@webern webern commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Initially I tried using AI to reverse-engineer the pseudo-hand-rolled original codegen. It worked but resulted in a 12k lines of unredeemable Python garbage with no room to maneuver from there. So, I started over and developed a gen/ program from the ground up using AI. I tried to keep it agnostic as to language target, so I think targeting other languages and use-cases is a real possibility now. Early on, I used Go and C as language targets to force the AI to think about extensibility. Those targets exist under gen/test, but are intended more as gen/ program regression tests than for actual MusicXML use.

For the replaced mx::core code, I prioritized compile time and better use of C++ features like variant and option. AI wanted to drop the ezxml abstraction and I guess it was time to let it go, so pugixml is promoted to mx::core interaction.

A test-core-dev target was used to allow the the AI to innovate on mx::core without worrying about mx::impl and mx::api (in fact, I deleted those layers during code-gen). Then I replaced those layers and burned tokens to preserve the mx::impl algorithms targeting the new set of mx::core classes.

References

Follow-ups:

  • surface more features in the mx/api layer. top priority is probably SMuFL
  • better packaging and distribution

@webern webern changed the title add support for musicxml in mx::core add support for musicxml 4.0 in mx::core Jun 13, 2026
@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit 4002b978f2e8ea03997771974c5cdf6cc3b29ac7.

@github-actions

Copy link
Copy Markdown

Coverage report

Core-dev coverage src/private/mx/core/

Metric Coverage Covered / Total
Lines 77.9% 28494 / 36571
Functions 74.4% 6354 / 8542
Branches 50.7% 22636 / 44653

API coverage src/private/mx/{api,impl,utility}/

Metric Coverage Covered / Total
Lines 68.7% 4734 / 6895
Functions 53.5% 1507 / 2816
Branches 40.3% 3851 / 9562

Core HTML report | API HTML report

Commit 4002b978f2e8ea03997771974c5cdf6cc3b29ac7.

@BoseGene

Copy link
Copy Markdown

Let me look into the XCode target. What I have in my fork is an updated script to build a XCFramework, but it might use the workspace as the input.

@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit b277cf72327de2e77aef0d909a7181ef7a596f4f.

@github-actions

Copy link
Copy Markdown

Coverage report

Core-dev coverage src/private/mx/core/

Metric Coverage Covered / Total
Lines 77.9% 28505 / 36590
Functions 74.4% 6354 / 8542
Branches 50.7% 22645 / 44673

API coverage src/private/mx/{api,impl,utility}/

Metric Coverage Covered / Total
Lines 68.7% 4734 / 6895
Functions 53.5% 1507 / 2816
Branches 40.3% 3851 / 9562

Core HTML report | API HTML report

Commit b277cf72327de2e77aef0d909a7181ef7a596f4f.

## Problem

The `Linux (Go + C targets)` CI job fails at the **Go corert suite**
step

([run](https://github.com/webern/mx/actions/runs/27506189030/job/81297724980)):

```
cd gen/test/go && MX_REPO_ROOT=/workspace go test -count=1 -v ./corert/
go: go: could not create module cache: mkdir /go: permission denied
make: *** [Makefile:355: test-go] Error 1
```

The `DOCKER_RUN` recipe runs the `mx-sdk` container as the caller's
`uid:gid`
(`--user 1001:1001` on the runner). That UID has no `/etc/passwd` entry,
so
`HOME` defaults to `/`. Go then derives `GOPATH=/go` and
`GOCACHE=/.cache/go-build`, neither of which the unprivileged user can
create.

The C++ jobs don't hit this because the Dockerfile already pins
`CCACHE_DIR`
to the writable `/workspace/build` volume; Go had no equivalent
override.

## Fix

Pin `GOPATH`, `GOCACHE`, and `GOMODCACHE` under the writable
`/workspace/build`
volume in the Dockerfile, exactly mirroring `CCACHE_DIR`. The Go module
is
vendored (`gen/test/go/vendor/`), so no network fetch is needed.

## Base

Targets `musicxml-4.0` so that merging this folds the fix into PR #169.
@github-actions

Copy link
Copy Markdown

gen-quality gen/

gen-quality: 84.5 / 100   (floor 84.5, +0.0)

  structure     86.5  x0.50   [fn 90.5 / file 82.6]
  cyclomatic    88.4  x0.25
  cognitive     76.6  x0.25

  409 functions across 31 files, 7702 lines (largest file 1044)
  max cc 56  max cognitive 44  max fn loc 152

Worst offenders (top 5 per axis; full lists in score.json):
  cyclomatic gen/xsd/analyze.py:311     report                             56
  cyclomatic gen/plates/build.py:956    _validate_config_against_ir        35
  cyclomatic gen/press/context.py:145   plate_context                      34
  cyclomatic gen/__main__.py:46         _ir                                23
  cyclomatic gen/tests/test_ir.py:102   _check_references                  20
  cognitive  gen/xsd/analyze.py:311     report                             44
  cognitive  gen/ir/resolve.py:119      flat_elements                      40
  cognitive  gen/tests/test_ir.py:102   _check_references                  38
  cognitive  gen/press/context.py:145   plate_context                      37
  cognitive  gen/xsd/analyze.py:207     _sccs                              37
  size       gen/xsd/analyze.py:311     report                             152
  size       gen/press/context.py:145   plate_context                      96
  size       gen/plates/build.py:533    _value_plate                       89
  size       gen/plates/build.py:956    _validate_config_against_ir        89
  size       gen/ir/resolve.py:119      flat_elements                      78

Commit 92f4638433dbde673d2042d13c23fb32ff629b42.

@github-actions

Copy link
Copy Markdown

Coverage report

Core-dev coverage src/private/mx/core/

Metric Coverage Covered / Total
Lines 77.9% 28505 / 36590
Functions 74.4% 6354 / 8542
Branches 50.7% 22645 / 44673

API coverage src/private/mx/{api,impl,utility}/

Metric Coverage Covered / Total
Lines 68.7% 4734 / 6895
Functions 53.5% 1507 / 2816
Branches 40.3% 3851 / 9562

Core HTML report | API HTML report

Commit 92f4638433dbde673d2042d13c23fb32ff629b42.

## Summary

Compile `mx` as a Swift package so a sibling consumer can depend on it
via
`.package(path:)` for local-checkout development.

- `Package.swift` vends the `Mx` library.
- `MX_LOCAL_CHECKOUT` selects the mode:
- When set, mx is a local sibling checkout and being compiled from local
source.
  - Unset is reserved for a future binary release mechanism.
- `swift-local` ci job builds the package in local mode

Also fixes the AppleClang charconv error on `from_chars` / `to_chars`

Base: `musicxml-4.0` (feeds #169).
@github-actions

Copy link
Copy Markdown

gen-quality gen/

(no report produced)

Commit 7f66e4c87a838800a57c1937253eb9e18bb59f97.

@webern webern merged commit 481995b into master Jun 14, 2026
0 of 7 checks passed
@webern webern deleted the musicxml-4.0 branch June 14, 2026 18:36
webern added a commit that referenced this pull request Jun 14, 2026
## Summary

The agents left behind a lot of stateful comments and files. This cleans
them up and provides a better entrypoint for new agents.

## References

- Cleans up after #169
- Progresses #58
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.

Generate MusicXML 4.0 code Deshittify the 12,000 lines of reverse engineered python code in gen/

2 participants