Skip to content

fix: raise OCCTSwiftIO cap to >=1.7.5, unblocking coexistence with OCCTSwiftTools#81

Merged
gsdali merged 1 commit into
mainfrom
fix/80-occtswiftio-cap-conflict
Jul 20, 2026
Merged

fix: raise OCCTSwiftIO cap to >=1.7.5, unblocking coexistence with OCCTSwiftTools#81
gsdali merged 1 commit into
mainfrom
fix/80-occtswiftio-cap-conflict

Conversation

@gsdali

@gsdali gsdali commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

Package.swift capped OCCTSwiftIO to .upToNextMinor(from: "1.0.0") (>=1.0.0, <1.1.0) since #69, to dodge the heavy mesh-IO stack (SwiftPMX/SwiftX/ThreeMF/SwiftGLTF) that OCCTSwiftIO 1.1.0+ pulls in via a MeshIO target. But OCCTSwiftTools >=1.6.1 now requires OCCTSwiftIO >=1.7.0 directly, so any consumer depending on both OCCTSwiftScripts and OCCTSwiftTools at once (e.g. OCCTMCP, for ScriptHarness/DrawingComposer and the BRepGraph bridge respectively) hit an unsatisfiable version conflict:

error: Dependencies could not be resolved because root depends on 'occtswiftscripts' 1.5.0..<2.0.0 and root depends on 'occtswiftio' 1.7.0..<2.0.0.
'occtswiftscripts' >= 1.5.0 practically depends on 'occtswiftio' 1.0.0..<1.1.0 ...

OCCTMCP currently works around this by pinning OCCTSwiftScripts back to 1.4.1 (and OCCTSwiftTools to 1.3.1, and adding its own root-level OCCTSwiftIO cap) — meaning it's stuck on a pre-BRepGraph-rename ScriptHarness/DrawingComposer. That workaround lives entirely in OCCTMCP's own manifest and is unaffected by this PR; OCCTMCP will need a separate follow-up change to actually take advantage of the raised floor.

Was a narrower OCCTSwiftIO product available?

Checked OCCTSwiftIO 1.7.5's Package.swift for a way to keep the cap's original intent (BREP/STEP core only, no mesh formats) via product-level granularity now that OCCTSwiftIO has split into two library products:

products: [
    .library(name: "OCCTSwiftIO", targets: ["OCCTSwiftIO"]),
    .library(name: "MeshIO", targets: ["MeshIO"]),
],
...
.target(
    name: "OCCTSwiftIO",
    dependencies: [
        .product(name: "OCCTSwift", package: "OCCTSwift"),
        .product(name: "SwiftJWW", package: "SwiftJWW"),
        .product(name: "SwiftDXF", package: "SwiftDXF"),
        "MeshIO",   // <- unconditional target dependency, not a product a consumer can decline
    ],
    ...
),

No — the OCCTSwiftIO target itself has an unconditional target dependency on MeshIO, not a product boundary a consumer can opt out of. Depending on just the OCCTSwiftIO product still resolves and checks out the full SwiftPMX/SwiftX/ThreeMF/SwiftGLTF stack (confirmed by both builds below, which show all of them compiling). There is no BREP/STEP-only product to depend on instead — lifting the cap does mean accepting that stack transitively, which is the real tradeoff this PR accepts. (For what it's worth, grepping OCCTSwiftIO's own source shows none of its files actually import MeshIO — the target dependency looks vestigial on OCCTSwiftIO's side — but that's a separate, out-of-scope cleanup for that repo, not something this PR can fix from the consumer side.)

The fix

  • occtDepUpToNextMinor("OCCTSwiftIO", from: "1.0.0")occtDep("OCCTSwiftIO", from: "1.7.5")
  • Removed the now-unused occtDepUpToNextMinor helper (no other dependency used it).
  • Floored at 1.7.5 rather than the bare 1.7.0 OCCTSwiftTools needs: 1.7.5 is OCCTSwiftIO's own TopologyGraph -> BRepGraph rename (mirroring OCCTSwift 1.15.0's rename, already required by this repo since rename: TopologyGraph -> BRepGraph, bump OCCTSwift floor to 1.15.0 #79), and 1.7.1-1.7.4 are pure OCCTSwift-floor repins for OCCT kernel crash/hang fixes already required transitively via our own OCCTSwift >=1.15.0 floor — no reason to admit an older OCCTSwiftIO minor.
  • Updated README.md Requirements table and CLAUDE.md's dependency writeup to match (same convention rename: TopologyGraph -> BRepGraph, bump OCCTSwift floor to 1.15.0 #79 followed).
  • Regenerated Package.resolved.

Cross-graph verification (the actual regression test for this bug)

A solo swift build of OCCTSwiftScripts wouldn't have caught the original conflict — it only appears when two consumers with different transitive OCCTSwiftIO requirements meet in one graph. So I built a throwaway root package depending on both this fixed OCCTSwiftScripts (via a local path override to this branch) and OCCTSwiftTools (from GitHub, latest), mirroring OCCTMCP's real shape:

dependencies: [
    .package(path: "../OCCTSwiftScripts"),   // this fix branch
    .package(url: "https://github.com/SecondMouseAU/OCCTSwiftTools.git", from: "1.0.0"),
],
targets: [
    .executableTarget(name: "CrossGraphTest", dependencies: [
        .product(name: "ScriptHarness", package: "OCCTSwiftScripts"),
        .product(name: "DrawingComposer", package: "OCCTSwiftScripts"),
        .product(name: "OCCTSwiftTools", package: "OCCTSwiftTools"),
    ]),
]

Built and resolved in an isolated clone (no sibling OCCT-family checkouts nearby, so every dependency resolved via its real URL + version constraint, not a local path override) — this exercises SwiftPM's real version resolver, the exact mechanism the original bug broke.

Result: swift package resolve and swift build both succeed. Package.resolved pins:

  • occtswiftio1.7.5 (satisfies both this repo's new >=1.7.5 floor and OCCTSwiftTools 1.6.1's >=1.7.0 floor simultaneously)
  • occtswifttools → 1.6.1 (latest)
  • occtswift → 1.15.0, occtswiftais → 1.3.1, occtswiftviewport → 1.1.26, occtswiftmesh → 1.1.6 (all latest-compatible)

Test plan

All run in an isolated clone with no sibling OCCT checkouts nearby, so every dependency resolved via URL + version (not a local path shortcut):

  • swift package resolve (solo, this repo) — resolves OCCTSwiftIO at 1.7.5
  • swift build — clean, 0 errors, 0 warnings
  • swift build --build-tests — clean, 0 errors, 0 warnings
  • swift test — 3/3 tests pass (DrawingComposerTests)
  • Cross-graph throwaway package (swift package resolve + swift build, Scripts+Tools together) — succeeds, OCCTSwiftIO lands on 1.7.5, 0 errors, 0 warnings

Closes #80

…CTSwiftTools

OCCTSwiftIO was capped to `.upToNextMinor(from: "1.0.0")` (>=1.0.0, <1.1.0)
since #69, to dodge the heavy mesh-IO stack (SwiftPMX/SwiftX/ThreeMF/
SwiftGLTF) that OCCTSwiftIO 1.1.0+ pulls in via a MeshIO target. But
OCCTSwiftTools >=1.6.1 now requires OCCTSwiftIO >=1.7.0 directly, so any
consumer depending on both OCCTSwiftScripts and OCCTSwiftTools at once
(e.g. OCCTMCP) hit an unsatisfiable version conflict.

Checked OCCTSwiftIO 1.7.5's manifest for a narrower product that would
preserve the cap's intent: it now ships two library products, OCCTSwiftIO
and MeshIO, but the OCCTSwiftIO target has an unconditional target
dependency on MeshIO — not a product a consumer can decline. So there is
no BREP/STEP-only product to opt into; lifting the cap does mean accepting
the full mesh-IO stack transitively.

Raised the floor to >=1.7.5 (open range, occtDep instead of
occtDepUpToNextMinor) rather than the bare 1.7.0 Tools needs: 1.7.5 is
OCCTSwiftIO's own TopologyGraph -> BRepGraph rename (mirroring OCCTSwift
1.15.0's rename), and 1.7.1-1.7.4 are pure OCCTSwift-floor repins for
crash/hang fixes already required transitively via our own OCCTSwift
>=1.15.0 floor. Removed the now-unused occtDepUpToNextMinor helper.

Closes #80
@gsdali
gsdali merged commit c8fc205 into main Jul 20, 2026
2 checks passed
@gsdali
gsdali deleted the fix/80-occtswiftio-cap-conflict branch July 20, 2026 12:39
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.

OCCTSwiftIO cap (<1.1.0) in v1.5.0 conflicts with OCCTSwiftTools >=1.6.1's own OCCTSwiftIO >=1.7.0 requirement

1 participant