refactor: separate pure-parse from lutaml-uml bridge#11
Merged
Conversation
The ea gem is documented as standalone with lutaml-uml as an
OPTIONAL bridge dependency. Two files violated that contract:
1. lib/ea/diagram/style_resolver.rb:235 — CONNECTOR_TYPE_MAP was a
class-scope Hash constant with Lutaml::Uml::* class keys. The
Hash was constructed at class-load time, so requiring
lib/ea/diagram/style_resolver.rb without lutaml-uml installed
raised NameError on Lutaml::Uml::Generalization.
2. lib/ea/diagram/extractor.rb:503-517 — case/when on
Lutaml::Uml::* classes in instance methods. Worked in practice
(only called with a Repository in hand) but brittle if
lutaml-uml wasn't loaded.
Fixes:
- style_resolver.rb: replace CONNECTOR_TYPE_MAP constant with a
lazy #connector_type_map method that returns {} when
defined?(Lutaml::Uml) is false. The map is built on first call
and cached in @connector_type_map.
- style_resolver.rb: guard determine_association_type's
is_a?(Lutaml::Uml::Association) with a defined? check.
- extractor.rb: guard element_type and connector_type case/when
blocks with defined?(::Lutaml::Uml) early return.
With these changes, lib/ea/diagram/* loads cleanly without
lutaml-uml installed, preserving the standalone contract. The
bridge methods still require lutaml-uml at runtime (correctly).
Verification:
- bundle exec rspec: 2036 examples, 0 failures, 37 pending
(unchanged).
- lib/ea/diagram/style_resolver.rb loads without lutaml/uml
required (verified locally with `bundle exec ruby -e
"require \"ea/diagram/style_resolver\""`).
The ea gem now has a clean separation between its pure Sparx EA
parsing and the optional lutaml-uml transformation bridge.
NEW: Pure-parse entry points (no lutaml-uml dependency)
Ea.parse(path) → Database or Xmi::Sparx::Root
Ea::Xmi.load(path) → Xmi::Sparx::Root
Ea::Transformations.parse → internal model (was: Lutaml::Uml::Document)
NEW: Bridge entry points (lazy-require lutaml-uml on first call)
Ea.to_uml(path_or_model) → Lutaml::Uml::Document
Ea::Transformations.to_uml → Lutaml::Uml::Document
Ea::Bridge::QeaToUml → transforms Ea::Qea::Database
Ea::Bridge::XmiToUml → transforms Xmi::Sparx::Root
Architecture:
require 'ea' → loads module tree via autoload
(NO lutaml/uml at load time)
Ea.parse(file) → pure: returns native EA model
.qea → Ea::Qea::Database
.xmi → Xmi::Sparx::Root
Ea.to_uml(file/model) → bridge: lazy-requires lutaml/uml
dispatches to Ea::Bridge::QeaToUml
or Ea::Bridge::XmiToUml
Updated callers:
- lib/ea/cli/command/repository_builder.rb: uses .to_uml for bridge
- spec/ea/transformations/end_to_end_parsing_spec.rb: .parse → .to_uml
- spec/ea/transformations/parsers/xmi_parity_spec.rb: .parse → .to_uml
- lib/ea.rb: adds Ea.parse and Ea.to_uml at the top level
- CLAUDE.md: documents the pure/bridge architecture
New files:
lib/ea/bridge.rb — namespace + autoloads
lib/ea/bridge/qea_to_uml.rb — QEA → UML bridge (facade over existing factory)
lib/ea/bridge/xmi_to_uml.rb — XMI → UML bridge (facade over existing parser)
The existing Ea::Qea::Factory::* (22 files) and Ea::Xmi::Parser
(900 LOC of build_* methods) remain in their current locations as
internal implementation. The bridge modules are clean facades over
them. A future Phase 2 would physically move these into Ea::Bridge::*
for full namespace correctness.
Verification:
- bundle exec rspec: 2036 examples, 0 failures, 37 pending
- Ea.parse('basic.qea') → Ea::Qea::Database (42 packages)
- Ea.parse('basic.xmi') → Xmi::Sparx::Root
- Ea.to_uml('basic.qea') → Lutaml::Uml::Document (bridge)
- require 'ea' does not load lutaml/uml (autoload-only)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The ea gem now has a clean architectural separation between pure Sparx EA parsing and the optional lutaml-uml transformation bridge.
New API
Pure-parse (no lutaml-uml dependency):
Bridge (lazy-requires lutaml-uml):
New namespace
Ea::Bridgeisolates all lutaml-uml-dependent code:Ea::Bridge::QeaToUml— transformsEa::Qea::Database→Lutaml::Uml::DocumentEa::Bridge::XmiToUml— transformsXmi::Sparx::Root→Lutaml::Uml::DocumentThe existing
Ea::Qea::Factory::*(22 files) andEa::Xmi::Parser(900 LOC) remain as internal implementation behind clean facades.Architecture
Native QEA↔XMI round-trip (no lutaml-uml):
Breaking change
Ea::Transformations.parse(file)now returns the internal model (Database or Root), NOTLutaml::Uml::Document. Callers that need the Document should useEa::Transformations.to_uml(file)orEa.to_uml(file).Also includes
Lutaml::Uml::*references instyle_resolver.rbandextractor.rb(standalone contract violation).Verification
bundle exec rspec: 2036 examples, 0 failures, 37 pendingrequire "ea"does not load lutaml/uml (autoload-only)