mxrb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.de-DE.md +108 -0
- data/README.md +172 -0
- data/README.pt-BR.md +109 -0
- data/bin/mxrb +1613 -0
- data/docs/README.md +10 -0
- data/docs/de-DE/README.md +24 -0
- data/docs/de-DE/architectural-patterns.md +26 -0
- data/docs/de-DE/architectural-standard.md +48 -0
- data/docs/de-DE/architecture.md +76 -0
- data/docs/de-DE/compiler.md +162 -0
- data/docs/de-DE/conventions.md +19 -0
- data/docs/de-DE/design-system.md +52 -0
- data/docs/de-DE/entity-dsl.md +53 -0
- data/docs/de-DE/native-runtime-quality-report.md +74 -0
- data/docs/de-DE/oql-sql.md +211 -0
- data/docs/de-DE/platform-api-integration.md +36 -0
- data/docs/de-DE/platform-operations.md +243 -0
- data/docs/de-DE/project-structure.md +32 -0
- data/docs/de-DE/ruby-first-roadmap.md +116 -0
- data/docs/de-DE/scaffolds.md +59 -0
- data/docs/de-DE/semantic-refactoring.md +56 -0
- data/docs/de-DE/team-server.md +33 -0
- data/docs/de-DE/validation-matrix.md +64 -0
- data/docs/de-DE/vetclinic-acceptance.md +24 -0
- data/docs/de-DE/writing.md +138 -0
- data/docs/en-US/README.md +24 -0
- data/docs/en-US/architectural-patterns.md +151 -0
- data/docs/en-US/architectural-standard.md +89 -0
- data/docs/en-US/architecture.md +170 -0
- data/docs/en-US/compiler.md +157 -0
- data/docs/en-US/conventions.md +82 -0
- data/docs/en-US/design-system.md +163 -0
- data/docs/en-US/entity-dsl.md +53 -0
- data/docs/en-US/native-runtime-quality-report.md +73 -0
- data/docs/en-US/oql-sql.md +201 -0
- data/docs/en-US/platform-api-integration.md +36 -0
- data/docs/en-US/platform-operations.md +244 -0
- data/docs/en-US/project-structure.md +49 -0
- data/docs/en-US/ruby-first-roadmap.md +186 -0
- data/docs/en-US/scaffolds.md +57 -0
- data/docs/en-US/semantic-refactoring.md +198 -0
- data/docs/en-US/team-server.md +32 -0
- data/docs/en-US/validation-matrix.md +257 -0
- data/docs/en-US/vetclinic-acceptance.md +23 -0
- data/docs/en-US/writing.md +655 -0
- data/docs/pt-BR/README.md +24 -0
- data/docs/pt-BR/architectural-patterns.md +25 -0
- data/docs/pt-BR/architectural-standard.md +533 -0
- data/docs/pt-BR/architecture.md +300 -0
- data/docs/pt-BR/compiler.md +162 -0
- data/docs/pt-BR/conventions.md +19 -0
- data/docs/pt-BR/design-system.md +65 -0
- data/docs/pt-BR/entity-dsl.md +116 -0
- data/docs/pt-BR/native-runtime-quality-report.md +73 -0
- data/docs/pt-BR/oql-sql.md +208 -0
- data/docs/pt-BR/platform-api-integration.md +36 -0
- data/docs/pt-BR/platform-operations.md +260 -0
- data/docs/pt-BR/project-structure.md +32 -0
- data/docs/pt-BR/ruby-first-roadmap.md +239 -0
- data/docs/pt-BR/scaffolds.md +104 -0
- data/docs/pt-BR/semantic-refactoring.md +55 -0
- data/docs/pt-BR/team-server.md +59 -0
- data/docs/pt-BR/validation-matrix.md +86 -0
- data/docs/pt-BR/vetclinic-acceptance.md +50 -0
- data/docs/pt-BR/writing.md +177 -0
- data/examples/sudoku_evaluation.rb +14 -0
- data/examples/sudoku_functional_test.rb +28 -0
- data/lib/mxrb/architecture/graph.rb +124 -0
- data/lib/mxrb/architecture/validator.rb +98 -0
- data/lib/mxrb/benchmark.rb +33 -0
- data/lib/mxrb/compare.rb +390 -0
- data/lib/mxrb/compiler/adapter.rb +96 -0
- data/lib/mxrb/compiler/artifact_document_compiler.rb +102 -0
- data/lib/mxrb/compiler/artifact_materializer.rb +53 -0
- data/lib/mxrb/compiler/client_model_materializer.rb +42 -0
- data/lib/mxrb/compiler/code_action_document_compiler.rb +64 -0
- data/lib/mxrb/compiler/code_action_materializer.rb +35 -0
- data/lib/mxrb/compiler/code_action_type_compiler.rb +32 -0
- data/lib/mxrb/compiler/combo_box_bundle_compiler.rb +314 -0
- data/lib/mxrb/compiler/compatibility_analyzer.rb +169 -0
- data/lib/mxrb/compiler/constants_materializer.rb +111 -0
- data/lib/mxrb/compiler/data_grid_bundle_compiler.rb +290 -0
- data/lib/mxrb/compiler/database_connector_action_compiler.rb +280 -0
- data/lib/mxrb/compiler/deployment_asset_copier.rb +60 -0
- data/lib/mxrb/compiler/deployment_bootstrapper.rb +208 -0
- data/lib/mxrb/compiler/deployment_materializer.rb +43 -0
- data/lib/mxrb/compiler/deployment_metadata.rb +64 -0
- data/lib/mxrb/compiler/domain_document_compiler.rb +153 -0
- data/lib/mxrb/compiler/domain_model_materializer.rb +35 -0
- data/lib/mxrb/compiler/domain_security_compiler.rb +82 -0
- data/lib/mxrb/compiler/gallery_bundle_compiler.rb +190 -0
- data/lib/mxrb/compiler/generic_widget_bundle_compiler.rb +281 -0
- data/lib/mxrb/compiler/image_bundle_compiler.rb +216 -0
- data/lib/mxrb/compiler/java_proxy_generator.rb +509 -0
- data/lib/mxrb/compiler/legacy_data_grid_compiler.rb +267 -0
- data/lib/mxrb/compiler/legacy_page_builder.rb +287 -0
- data/lib/mxrb/compiler/mda.rb +99 -0
- data/lib/mxrb/compiler/microflow_document_compiler.rb +85 -0
- data/lib/mxrb/compiler/microflow_materializer.rb +48 -0
- data/lib/mxrb/compiler/microflow_node_compiler.rb +250 -0
- data/lib/mxrb/compiler/model_package.rb +116 -0
- data/lib/mxrb/compiler/model_values.rb +67 -0
- data/lib/mxrb/compiler/nanoflow_program_compiler.rb +483 -0
- data/lib/mxrb/compiler/navigation_document_compiler.rb +93 -0
- data/lib/mxrb/compiler/packager.rb +100 -0
- data/lib/mxrb/compiler/page_bundle_builder.rb +56 -0
- data/lib/mxrb/compiler/page_bundle_compiler.rb +2004 -0
- data/lib/mxrb/compiler/page_document_compiler.rb +77 -0
- data/lib/mxrb/compiler/portable_packager.rb +356 -0
- data/lib/mxrb/compiler/project_jar_archive.rb +84 -0
- data/lib/mxrb/compiler/project_jar_builder.rb +121 -0
- data/lib/mxrb/compiler/project_materializer.rb +139 -0
- data/lib/mxrb/compiler/project_model_orderer.rb +52 -0
- data/lib/mxrb/compiler/runtime_data_types.rb +31 -0
- data/lib/mxrb/compiler/runtime_model_schema.rb +90 -0
- data/lib/mxrb/compiler/schemas/runtime-10.24.0.73019.json +1052 -0
- data/lib/mxrb/compiler/schemas/runtime-11.json +1215 -0
- data/lib/mxrb/compiler/schemas/runtime-6.10.8.json +1148 -0
- data/lib/mxrb/compiler/schemas/runtime-7.17.0.json +1144 -0
- data/lib/mxrb/compiler/schemas/runtime-7.5.0.json +1215 -0
- data/lib/mxrb/compiler/schemas/runtime-9.6.1.29396.json +868 -0
- data/lib/mxrb/compiler/schemas/system-model-10.24.0.73019.b64 +1135 -0
- data/lib/mxrb/compiler/schemas/system-model-11.12.1.b64 +815 -0
- data/lib/mxrb/compiler/schemas/system-model-6.10.8.b64 +497 -0
- data/lib/mxrb/compiler/schemas/system-model-7.17.0.b64 +519 -0
- data/lib/mxrb/compiler/schemas/system-model-7.5.0.b64 +504 -0
- data/lib/mxrb/compiler/schemas/system-model-9.6.1.29396.b64 +816 -0
- data/lib/mxrb/compiler/security_materializer.rb +104 -0
- data/lib/mxrb/compiler/settings_document_compiler.rb +45 -0
- data/lib/mxrb/compiler/settings_materializer.rb +25 -0
- data/lib/mxrb/compiler/source_model.rb +128 -0
- data/lib/mxrb/compiler/system_model_seed.rb +88 -0
- data/lib/mxrb/compiler/system_queue_materializer.rb +54 -0
- data/lib/mxrb/compiler/system_text_materializer.rb +49 -0
- data/lib/mxrb/compiler/translation_materializer.rb +95 -0
- data/lib/mxrb/compiler/web_bundle_builder.rb +155 -0
- data/lib/mxrb/compiler/web_list_data_source.rb +139 -0
- data/lib/mxrb/compiler/web_operation_compiler.rb +614 -0
- data/lib/mxrb/compiler/web_shell_materializer.rb +194 -0
- data/lib/mxrb/compiler/widget_package_extractor.rb +63 -0
- data/lib/mxrb/doctor.rb +116 -0
- data/lib/mxrb/dsl/builder.rb +1636 -0
- data/lib/mxrb/errors.rb +18 -0
- data/lib/mxrb/evaluation.rb +131 -0
- data/lib/mxrb/exporter.rb +1716 -0
- data/lib/mxrb/frontend/migrator.rb +775 -0
- data/lib/mxrb/functional.rb +307 -0
- data/lib/mxrb/github/annotator.rb +161 -0
- data/lib/mxrb/initializer.rb +257 -0
- data/lib/mxrb/integrity/validator.rb +136 -0
- data/lib/mxrb/io/bson_codec.rb +145 -0
- data/lib/mxrb/io/mpr_file.rb +558 -0
- data/lib/mxrb/io/mxunit_codec.rb +42 -0
- data/lib/mxrb/marketplace.rb +380 -0
- data/lib/mxrb/model/association.rb +98 -0
- data/lib/mxrb/model/attribute.rb +100 -0
- data/lib/mxrb/model/connector.rb +17 -0
- data/lib/mxrb/model/design_materializer.rb +133 -0
- data/lib/mxrb/model/design_migration.rb +126 -0
- data/lib/mxrb/model/design_system.rb +111 -0
- data/lib/mxrb/model/domain_model.rb +51 -0
- data/lib/mxrb/model/entity.rb +180 -0
- data/lib/mxrb/model/menu.rb +38 -0
- data/lib/mxrb/model/microflow.rb +100 -0
- data/lib/mxrb/model/module.rb +142 -0
- data/lib/mxrb/model/navigation.rb +127 -0
- data/lib/mxrb/model/page.rb +410 -0
- data/lib/mxrb/model/project.rb +187 -0
- data/lib/mxrb/model/unit.rb +48 -0
- data/lib/mxrb/module_initializer.rb +75 -0
- data/lib/mxrb/official_marketplace/content_api.rb +292 -0
- data/lib/mxrb/official_marketplace/dependency_resolver.rb +329 -0
- data/lib/mxrb/official_marketplace/lifecycle.rb +367 -0
- data/lib/mxrb/official_marketplace/module_package_importer.rb +318 -0
- data/lib/mxrb/official_marketplace/widget_package_installer.rb +414 -0
- data/lib/mxrb/official_marketplace.rb +720 -0
- data/lib/mxrb/oql/analyzer.rb +155 -0
- data/lib/mxrb/oql/index_advisor.rb +85 -0
- data/lib/mxrb/oql/plan_analyzer.rb +185 -0
- data/lib/mxrb/oql/server.rb +132 -0
- data/lib/mxrb/oql/sql_server_plan_analyzer.rb +190 -0
- data/lib/mxrb/oql/sql_server_workload_analyzer.rb +80 -0
- data/lib/mxrb/oql/workload_analyzer.rb +175 -0
- data/lib/mxrb/oql/workload_baseline.rb +60 -0
- data/lib/mxrb/oql.rb +424 -0
- data/lib/mxrb/project_lifecycle.rb +76 -0
- data/lib/mxrb/protocols/plan.rb +86 -0
- data/lib/mxrb/protocols.rb +123 -0
- data/lib/mxrb/runtime/database_workspace.rb +677 -0
- data/lib/mxrb/runtime/docker_executor.rb +41 -0
- data/lib/mxrb/runtime/docker_workspace.rb +29 -0
- data/lib/mxrb/runtime/executor.rb +169 -0
- data/lib/mxrb/runtime/java_locator.rb +26 -0
- data/lib/mxrb/runtime/native.rb +474 -0
- data/lib/mxrb/runtime/sql_server_database.rb +146 -0
- data/lib/mxrb/runtime/toolchain.rb +82 -0
- data/lib/mxrb/scaffold/cli.rb +113 -0
- data/lib/mxrb/scaffold/generator.rb +246 -0
- data/lib/mxrb/scaffold/help.rb +80 -0
- data/lib/mxrb/scaffold/page_templates.rb +54 -0
- data/lib/mxrb/scaffold/recipes.rb +198 -0
- data/lib/mxrb/scaffold/registry.rb +82 -0
- data/lib/mxrb/scaffold/templates.rb +723 -0
- data/lib/mxrb/scaffold/transaction.rb +84 -0
- data/lib/mxrb/schema/tables.rb +55 -0
- data/lib/mxrb/semantic/analyzer.rb +473 -0
- data/lib/mxrb/semantic/batch_plan.rb +68 -0
- data/lib/mxrb/semantic/domain_mutator.rb +419 -0
- data/lib/mxrb/semantic/embedder.rb +51 -0
- data/lib/mxrb/semantic/extractor.rb +290 -0
- data/lib/mxrb/semantic/index.rb +623 -0
- data/lib/mxrb/semantic/inliner.rb +216 -0
- data/lib/mxrb/semantic/mover.rb +153 -0
- data/lib/mxrb/semantic/onnx_embedder.rb +34 -0
- data/lib/mxrb/semantic/remover.rb +70 -0
- data/lib/mxrb/semantic/renamer.rb +211 -0
- data/lib/mxrb/semantic/tfidf_embedder.rb +46 -0
- data/lib/mxrb/semantic/vec_store.rb +75 -0
- data/lib/mxrb/team_server.rb +390 -0
- data/lib/mxrb/templates/project/10.24.0.73019.json +32 -0
- data/lib/mxrb/templates/project/11.12.1.json +32 -0
- data/lib/mxrb/templates/project/6.10.8.json +50 -0
- data/lib/mxrb/templates/project/7.17.0.json +50 -0
- data/lib/mxrb/templates/project/7.5.0.json +50 -0
- data/lib/mxrb/templates/project/9.6.1.29396.json +50 -0
- data/lib/mxrb/version.rb +5 -0
- data/lib/mxrb/widget_package.rb +338 -0
- data/lib/mxrb/widget_synchronizer.rb +31 -0
- data/lib/mxrb/writer.rb +3775 -0
- data/lib/mxrb.rb +188 -0
- data/marketplace/catalog.json +10 -0
- data/marketplace/modules/shared-kernel/domain/README.md +4 -0
- data/marketplace/modules/shared-kernel/module.rb +5 -0
- data/marketplace/modules/shared-kernel/mxrb-module.json +9 -0
- metadata +447 -0
|
@@ -0,0 +1,655 @@
|
|
|
1
|
+
# Writing projects
|
|
2
|
+
|
|
3
|
+
[Português](../pt-BR/writing.md) · **English** · [Deutsch](../de-DE/writing.md)
|
|
4
|
+
|
|
5
|
+
For the complete module, layer and round-trip structure, see
|
|
6
|
+
[project architecture](architecture.md).
|
|
7
|
+
|
|
8
|
+
`mxrb generate` evaluates a Ruby definition and creates or updates the target
|
|
9
|
+
MPR. Existing modules, entities, attributes, associations, pages and
|
|
10
|
+
microflows are matched by name, so applying the same definition repeatedly
|
|
11
|
+
does not duplicate them.
|
|
12
|
+
|
|
13
|
+
Start from an empty directory with:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
mxrb init vet_clinic
|
|
17
|
+
cd vet_clinic
|
|
18
|
+
bundle install
|
|
19
|
+
bundle exec mxrb generate project.rb
|
|
20
|
+
bundle exec mxrb validate VetClinic.mpr
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`init` accepts snake_case or PascalCase and creates `Gemfile`, `project.rb`,
|
|
24
|
+
and the main `modules/VetClinic` module. The scaffold contains application code
|
|
25
|
+
only: `System` is implicit in the Runtime, while Administration and Atlas are
|
|
26
|
+
marketplace modules. The command aborts without changing an existing directory.
|
|
27
|
+
|
|
28
|
+
Add another application module from the project root with:
|
|
29
|
+
|
|
30
|
+
```sh
|
|
31
|
+
mxrb module new appointments
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The command creates `modules/Appointments`, reuses the same domain/application
|
|
35
|
+
scaffold, and connects its `module.rb` in `project.rb`. It aborts atomically if
|
|
36
|
+
the module already exists or the project file cannot be updated. Use
|
|
37
|
+
`--target DIR` when running outside the project root.
|
|
38
|
+
|
|
39
|
+
Artifact, presentation, infrastructure, test, design, and CI generators are
|
|
40
|
+
listed in the [scaffold catalog](scaffolds.md). See the complete
|
|
41
|
+
[entity DSL reference](entity-dsl.md) for entity files.
|
|
42
|
+
|
|
43
|
+
```ruby
|
|
44
|
+
# shop.rb
|
|
45
|
+
Mxrb.define("Shop.mpr") do
|
|
46
|
+
mendix_version "10.17.0"
|
|
47
|
+
|
|
48
|
+
self.module :Sales do
|
|
49
|
+
entity :Customer do
|
|
50
|
+
string :Name, documentation: "Customer display name"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
entity :Order do
|
|
54
|
+
decimal :Total, default: 0
|
|
55
|
+
association "Sales.Customer", name: "Order_Customer"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
page :OrderList do
|
|
59
|
+
title "Orders"
|
|
60
|
+
layout "Atlas_Default"
|
|
61
|
+
allowed_roles "Sales.User"
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
microflow :CreateOrder do
|
|
65
|
+
parameter :Order, type: :Order
|
|
66
|
+
return_type :Order
|
|
67
|
+
allowed_roles "Sales.User"
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Apply it using the path in the definition:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
bundle exec mxrb generate shop.rb
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Or override the output path:
|
|
80
|
+
|
|
81
|
+
```sh
|
|
82
|
+
bundle exec mxrb generate shop.rb output/Shop.mpr
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Integrity validation
|
|
86
|
+
|
|
87
|
+
Run the internal integrity check after generation or round-trip work:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
bundle exec mxrb validate path/to/App.mpr
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
For MPR v1, the validator reads unit contents directly from the SQLite
|
|
94
|
+
`Unit.Contents` column and checks the unit tree, content hashes, and
|
|
95
|
+
`$ID`/`$Type` identity. For MPR v2, it performs the same checks against the
|
|
96
|
+
external `.mxunit` payloads in `mprcontents/`.
|
|
97
|
+
|
|
98
|
+
Compare two MPRs structurally without external tooling:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
bundle exec mxrb compare original.mpr rebuilt.mpr
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
The comparator reports differences in project metadata, security roles, unit
|
|
105
|
+
tree, modules, entities (including native attribute metadata and access rules),
|
|
106
|
+
associations, pages/widgets/events, menus, microflows, nanoflows and allowed
|
|
107
|
+
module roles. Microflow and nanoflow bodies are normalized before comparison:
|
|
108
|
+
volatile UUIDs and canvas coordinates are ignored, while objects, actions,
|
|
109
|
+
properties and control-flow edges remain part of the snapshot.
|
|
110
|
+
|
|
111
|
+
For external Mendix validation on Linux, use the `mx` and `mxbuild` binaries
|
|
112
|
+
matching the exact model version:
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
mx check App.mpr --warnings --deprecations --best-practice --json check.json
|
|
116
|
+
mxbuild \
|
|
117
|
+
--java-home=/path/to/jdk-21 \
|
|
118
|
+
--java-exe-path=/path/to/jdk-21/bin/java \
|
|
119
|
+
--target=package \
|
|
120
|
+
--output=App.mda \
|
|
121
|
+
--write-errors=mxbuild-errors.json \
|
|
122
|
+
App.mpr
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Compare the diagnostic JSON with the original project, not merely the exit
|
|
126
|
+
code: `mx check` combines warnings, deprecations and recommendations into a
|
|
127
|
+
nonzero status even when there are zero errors.
|
|
128
|
+
|
|
129
|
+
## Ruby model evaluations
|
|
130
|
+
|
|
131
|
+
Model expectations live in ordinary Ruby files:
|
|
132
|
+
|
|
133
|
+
```ruby
|
|
134
|
+
# evaluation.rb
|
|
135
|
+
artifact "Sales.Order", kind: :entity
|
|
136
|
+
reference from: "Sales.Order_Overview", to: "Sales.Order"
|
|
137
|
+
no_call_cycles
|
|
138
|
+
no_missing_internal_references
|
|
139
|
+
maximum_unreferenced 20, severity: :warning
|
|
140
|
+
forbid_dependency from: :Domain, to: :Presentation
|
|
141
|
+
|
|
142
|
+
check "orders expose a status attribute" do |project|
|
|
143
|
+
project.find_artifact("Sales.Order.Status", kind: :attribute) != nil
|
|
144
|
+
end
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Run them with:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
bundle exec mxrb evaluate path/to/App.mpr evaluation.rb
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Error checks produce a failing exit status; warning checks affect the score but
|
|
154
|
+
do not fail the command. See `examples/sudoku_evaluation.rb` for an executable
|
|
155
|
+
example validated against the public Sudoku fixture.
|
|
156
|
+
|
|
157
|
+
## Functional microflow tests
|
|
158
|
+
|
|
159
|
+
Runtime tests are ordinary Ruby files. The first functional slice verifies that
|
|
160
|
+
each selected microflow completes without an unhandled runtime exception:
|
|
161
|
+
|
|
162
|
+
```ruby
|
|
163
|
+
# functional_test.rb
|
|
164
|
+
microflow "creates an order",
|
|
165
|
+
call: "Sales.ACT_CreateOrder",
|
|
166
|
+
before: { call: "Sales.TEST_Prepare" },
|
|
167
|
+
after: { call: "Sales.TEST_Cleanup" },
|
|
168
|
+
expect: {
|
|
169
|
+
return: "true",
|
|
170
|
+
count: { entity: "Sales.Order", xpath: "[Status = 'Open']", equals: 1 }
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The `pass:` values are Mendix expressions and must supply every parameter of
|
|
175
|
+
the target microflow. MXRB validates the names before compilation. No JUnit,
|
|
176
|
+
Java test module or MDL is involved: MXRB generates a temporary `MxrbTests`
|
|
177
|
+
module, executes it as the after-startup microflow and parses its structured
|
|
178
|
+
runtime log back into immutable Ruby results.
|
|
179
|
+
|
|
180
|
+
Run locally with the exact Mendix toolchain and Java selected by the project:
|
|
181
|
+
|
|
182
|
+
```sh
|
|
183
|
+
JAVA_HOME=/path/to/zulu-21 \
|
|
184
|
+
bundle exec mxrb test App.mpr functional_test.rb
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Or keep JDK, MxBuild and runtime execution inside containers:
|
|
188
|
+
|
|
189
|
+
```sh
|
|
190
|
+
bundle exec mxrb test App.mpr functional_test.rb --docker
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
For the Ruby model Runtime, with no Java, `mx`, or `mxbuild`, use:
|
|
194
|
+
|
|
195
|
+
```sh
|
|
196
|
+
bundle exec mxrb test App.mpr functional_test.rb --native
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Native mode currently interprets the core data path (create/change/retrieve,
|
|
200
|
+
commit/delete, variables, decisions, microflow calls, aggregates and logging)
|
|
201
|
+
in a transactional in-memory store. Unsupported Java, REST, UI and connector
|
|
202
|
+
activities fail explicitly and roll back the test case.
|
|
203
|
+
|
|
204
|
+
Docker mode builds one lightweight builder image per Java family and reuses it
|
|
205
|
+
for compatible Mendix versions. The exact Mendix toolchain is mounted
|
|
206
|
+
read-only because it is version-specific and licensed separately. The source
|
|
207
|
+
project is never changed: instrumentation, portable package, HSQLDB and
|
|
208
|
+
uploaded-file storage live in a temporary copy that is deleted after the run.
|
|
209
|
+
|
|
210
|
+
Inspect version selection and the planned container mounts without executing:
|
|
211
|
+
|
|
212
|
+
```sh
|
|
213
|
+
bundle exec mxrb test App.mpr functional_test.rb --plan
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The Java executor now builds the deployment, `project.jar`, web bundles, and
|
|
217
|
+
portable Runtime package through MXRB's native compiler; it does not invoke
|
|
218
|
+
`mx` or `mxbuild`. Both execution modes stop at `[MXRB_TEST] DONE`, terminate
|
|
219
|
+
the Runtime, and return a failing exit status if any case failed, compilation
|
|
220
|
+
failed, the suite did not finish, or its aggregate timeout expired.
|
|
221
|
+
Use `--json result.json` and/or `--junit result.xml` for CI reports. JUnit is
|
|
222
|
+
only the XML interchange format here; MXRB writes it directly in Ruby and does
|
|
223
|
+
not install or execute the Java JUnit framework.
|
|
224
|
+
|
|
225
|
+
## Test coverage
|
|
226
|
+
|
|
227
|
+
The default suite runs with `bundle exec rspec`. The strict coverage gate
|
|
228
|
+
uses Ruby's native `Coverage` API:
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
MXRB_COVERAGE=1 MXRB_LINE_COVERAGE_MIN=100 MXRB_BRANCH_COVERAGE_MIN=100 bundle exec rspec
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
It writes `coverage/coverage.json`; CI requires 100% lines and 100% branches,
|
|
235
|
+
while the helper defaults to 100/100 if no thresholds are supplied.
|
|
236
|
+
`bundle exec ruby script/branch_report.rb` lists an uncovered branch by source
|
|
237
|
+
file and line. `bundle exec rubocop` is the gradual static-quality gate.
|
|
238
|
+
|
|
239
|
+
## Ruby module marketplace
|
|
240
|
+
|
|
241
|
+
```sh
|
|
242
|
+
mxrb module search
|
|
243
|
+
mxrb module search security
|
|
244
|
+
mxrb module add shared-kernel
|
|
245
|
+
mxrb module add ./local-package --target ./exported-project
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
Catalogs are JSON files loaded from the gem, a local path or HTTPS through
|
|
249
|
+
`--registry`. Packages contain `mxrb-module.json`; sources may be built in,
|
|
250
|
+
local directories or Git repositories. Installation uses a staging directory,
|
|
251
|
+
rejects unsafe paths and writes `.mxrb/modules.lock.json` with version, source,
|
|
252
|
+
ref and a SHA-256 digest of installed files.
|
|
253
|
+
|
|
254
|
+
## Native baseline and editable deep structures
|
|
255
|
+
|
|
256
|
+
`mxrb export` writes `.mxrb/native_units.json` with the original BSON payloads
|
|
257
|
+
as a lossless baseline and `.mxrb/native_units.rb` with every payload expanded
|
|
258
|
+
as editable Ruby. The generated project loads both:
|
|
259
|
+
`project.rb` loads it with:
|
|
260
|
+
|
|
261
|
+
```ruby
|
|
262
|
+
native_units File.join(__dir__, ".mxrb", "native_units.json")
|
|
263
|
+
evaluate File.join(__dir__, ".mxrb", "native_units.rb")
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
Each Ruby entry uses `native_unit` and `deep_structure` to expose all BSON
|
|
267
|
+
fields, including binary values through `bson_binary`. Editing this Ruby hash
|
|
268
|
+
overrides the baseline before typed writers run. Images, constants, datasets,
|
|
269
|
+
services, project settings, templates and newly introduced Mendix unit types
|
|
270
|
+
therefore remain both lossless and directly editable even without a concise
|
|
271
|
+
typed abstraction.
|
|
272
|
+
Microflow/nanoflow bodies and page/widget trees have an additional editable
|
|
273
|
+
representation described below.
|
|
274
|
+
|
|
275
|
+
Every flow body in the current public matrix is exported as typed Ruby. The
|
|
276
|
+
exporter records a canonical `body_fingerprint`: if the body is unchanged,
|
|
277
|
+
MXRB reuses the exact native graph; if the Ruby body changes, the fingerprint
|
|
278
|
+
no longer matches and the writer regenerates that graph. The fingerprint line
|
|
279
|
+
is generated bookkeeping and normally should not be edited by hand.
|
|
280
|
+
|
|
281
|
+
Editable flow activities currently include:
|
|
282
|
+
|
|
283
|
+
```ruby
|
|
284
|
+
create_object "Sales.Order", as: :order
|
|
285
|
+
change_object :order, set: { Status: "'Open'" }
|
|
286
|
+
retrieve_objects "Sales.Order", as: :orders, xpath: "[Active = true]", limit: 100
|
|
287
|
+
commit :order, with_events: false
|
|
288
|
+
delete :order
|
|
289
|
+
call_microflow "Sales.Process", as: :result, pass: { Order: :order }
|
|
290
|
+
create_variable :message, type: :string, value: "'Created'"
|
|
291
|
+
change_variable :message, to: "'Updated'"
|
|
292
|
+
show_message "Done", type: :information, blocking: true
|
|
293
|
+
log_message "Completed", level: :info, node: "'MXRB'"
|
|
294
|
+
decision "$order/Total > 100" do
|
|
295
|
+
on(true) { call_microflow "Sales.ApplyDiscount" }
|
|
296
|
+
end
|
|
297
|
+
loop_over :orders, as: :order do
|
|
298
|
+
commit :order
|
|
299
|
+
end
|
|
300
|
+
rescue_all { log_message "Failed", level: :error }
|
|
301
|
+
return_value :result
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
The DSL also covers database/association retrieval and sorting, Java,
|
|
305
|
+
JavaScript, nanoflow and app-service calls, show/close page, REST calls,
|
|
306
|
+
aggregates, casts, rollback, list operations, validation feedback, boolean and
|
|
307
|
+
multi-value decisions, inheritance/type decisions, iterators, while loops,
|
|
308
|
+
error/continue events, annotations and nested flows.
|
|
309
|
+
|
|
310
|
+
For MPR v2 exports, the manifest records the source format and `mxrb generate`
|
|
311
|
+
creates `mprcontents/*.mxunit` automatically for the rebuilt project.
|
|
312
|
+
|
|
313
|
+
## Page widgets
|
|
314
|
+
|
|
315
|
+
New pages and pages composed only of core controls use concise methods:
|
|
316
|
+
`text_box`, `number_input`, `text_area`, `check_box`, `date_picker`,
|
|
317
|
+
`reference_selector`, `drop_down`, `button`, `text`, `container`, `snippet`,
|
|
318
|
+
`tab_control`/`tab_page`, and `data_grid`/`column`. Tab pages may contain the
|
|
319
|
+
same nested widgets as containers. Inputs, actions and containers are written
|
|
320
|
+
using the Mendix 11 modern Forms model. `data_grid` emits Data Grid 2, while
|
|
321
|
+
`drop_down` and `reference_selector` emit Combo Box widgets.
|
|
322
|
+
|
|
323
|
+
Pluggable widgets need their `.mpk` packages in the project's `widgets/`
|
|
324
|
+
directory. Synchronize their version-specific schemas and apply the Ruby
|
|
325
|
+
properties in one command:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
bundle exec mxrb widgets sync project.rb MyApp.mpr
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Use `pluggable_widget` for another MPK by widget id and property map. Imported
|
|
332
|
+
widgets that MXRB does not recognize are emitted as `native_widget` with an
|
|
333
|
+
editable `deep_structure`, so export/generate preserves every native property.
|
|
334
|
+
|
|
335
|
+
Every imported page also exports its complete page internals as a structured
|
|
336
|
+
Ruby hash:
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
page :Dashboard do
|
|
340
|
+
title "Dashboard"
|
|
341
|
+
deep_structure({
|
|
342
|
+
"FormCall" => {
|
|
343
|
+
"$Type" => "Forms$LayoutCall",
|
|
344
|
+
"Arguments" => [
|
|
345
|
+
2,
|
|
346
|
+
{
|
|
347
|
+
"$Type" => "Forms$FormCallArgument",
|
|
348
|
+
"Widgets" => [
|
|
349
|
+
3,
|
|
350
|
+
{
|
|
351
|
+
"$Type" => "CustomWidgets$CustomWidget",
|
|
352
|
+
"Name" => "Map",
|
|
353
|
+
"Object" => { "Zoom" => 12 }
|
|
354
|
+
}
|
|
355
|
+
]
|
|
356
|
+
}
|
|
357
|
+
]
|
|
358
|
+
}
|
|
359
|
+
})
|
|
360
|
+
end
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
The concise declarations remain an architectural/readability view; when
|
|
364
|
+
`deep_structure` is present, edit that hash for storage-level page changes.
|
|
365
|
+
It is intentionally verbose but not opaque: every property can be inspected
|
|
366
|
+
and changed as Ruby data. BSON binary values appear as
|
|
367
|
+
`bson_binary("...", subtype: :generic)`. The deep structure is authoritative
|
|
368
|
+
when present, so edits are written instead of being overwritten by the native
|
|
369
|
+
baseline.
|
|
370
|
+
|
|
371
|
+
Imported menu documents follow the same rule: concise `item` declarations are
|
|
372
|
+
emitted for readability and dependency analysis, while their complete native
|
|
373
|
+
caption/action/translation structure remains editable and authoritative.
|
|
374
|
+
|
|
375
|
+
Buttons can call microflows/nanoflows or native page actions:
|
|
376
|
+
|
|
377
|
+
```ruby
|
|
378
|
+
button :saveButton, caption: "Save" do
|
|
379
|
+
on_click action: :save_changes
|
|
380
|
+
end
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
Supported native actions are `:save_changes`, `:cancel_changes`, `:delete`,
|
|
384
|
+
and `:close_page`.
|
|
385
|
+
|
|
386
|
+
## Navigation and security
|
|
387
|
+
|
|
388
|
+
Menu documents are exported as module-level presentation navigation:
|
|
389
|
+
|
|
390
|
+
```ruby
|
|
391
|
+
menu :Submenu do
|
|
392
|
+
item "Accounts", page: "Administration.Account_Overview"
|
|
393
|
+
end
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Project security user roles are exported at `app/security/security.rb`:
|
|
397
|
+
|
|
398
|
+
```ruby
|
|
399
|
+
security do
|
|
400
|
+
security_level "CheckEverything"
|
|
401
|
+
user_role :Administrator, module_roles: ["System.Administrator"], admin: true
|
|
402
|
+
end
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
Module security roles are exported per module at `modules/<Module>/security/security.rb`:
|
|
406
|
+
|
|
407
|
+
```ruby
|
|
408
|
+
module_role :User
|
|
409
|
+
module_role :Administrator, description: "Full module access"
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
Page, microflow and nanoflow access can be edited with `allowed_roles`, using
|
|
413
|
+
qualified module role names:
|
|
414
|
+
|
|
415
|
+
```ruby
|
|
416
|
+
page :Account_Overview do
|
|
417
|
+
allowed_roles "Administration.Administrator"
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
microflow :ChangeMyPassword do
|
|
421
|
+
allowed_roles "Administration.Administrator", "Administration.User"
|
|
422
|
+
allow_concurrent_execution false
|
|
423
|
+
mark_as_used true
|
|
424
|
+
excluded false
|
|
425
|
+
end
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
`allow_concurrent_execution`, `mark_as_used` and `excluded` are exported
|
|
429
|
+
explicitly for every imported microflow/nanoflow. They are editable booleans,
|
|
430
|
+
so reference/example flows that are intentionally excluded are not silently
|
|
431
|
+
reactivated during regeneration.
|
|
432
|
+
|
|
433
|
+
Entity access rules support `create`, `delete`, `read`, `write` and `xpath`.
|
|
434
|
+
Rules that cannot be represented completely—particularly legacy rules without
|
|
435
|
+
resolvable role names—remain native as a complete collection rather than being
|
|
436
|
+
partially exported.
|
|
437
|
+
|
|
438
|
+
Attribute round-trip preserves version-specific key casing and native details
|
|
439
|
+
that are not yet first-class DSL options, including string length, enumeration
|
|
440
|
+
references, date localization and calculated-value definitions. `float` and
|
|
441
|
+
`binary` are accepted attribute types in addition to the existing types.
|
|
442
|
+
|
|
443
|
+
## MPR v2
|
|
444
|
+
|
|
445
|
+
When an `mprcontents/` directory exists beside the MPR, unit contents are read
|
|
446
|
+
and written at:
|
|
447
|
+
|
|
448
|
+
```text
|
|
449
|
+
mprcontents/aa/bb/aabbccdd-....mxunit
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
Writes use a temporary file followed by an atomic rename, while SQLite keeps
|
|
453
|
+
`Contents` null and stores the content hash. The current codec accepts BSON
|
|
454
|
+
unit payloads. Mendix `.mxunit` encodings that are not BSON are rejected
|
|
455
|
+
explicitly; they are never silently replaced.
|
|
456
|
+
|
|
457
|
+
External tools such as `mxcli`
|
|
458
|
+
can still be useful as a manual comparison oracle when researching Studio Pro
|
|
459
|
+
behavior, but they are not part of the mxrb runtime or regression workflow.
|
|
460
|
+
|
|
461
|
+
See the [validation matrix](validation-matrix.md) for the public-project
|
|
462
|
+
round-trip matrix and the exact confidence boundary of the current engine.
|
|
463
|
+
# Semantic analysis in Ruby
|
|
464
|
+
|
|
465
|
+
MXRB does not require a separate query language. An opened MPR exposes its
|
|
466
|
+
semantic index directly as Ruby objects:
|
|
467
|
+
|
|
468
|
+
```ruby
|
|
469
|
+
Mxrb.open("app.mpr") do |project|
|
|
470
|
+
project.references_to("Sales.Order").each do |reference|
|
|
471
|
+
puts "#{reference.source.qualified_name} (#{reference.relation})"
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
project.callers_of("Sales.Recalculate").each do |caller|
|
|
475
|
+
puts caller.qualified_name
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
project.callees_of("Sales.Checkout").each do |callee|
|
|
479
|
+
puts callee.qualified_name
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
project.impact_of("Sales.Order").artifacts.each do |affected|
|
|
483
|
+
puts affected.qualified_name
|
|
484
|
+
end
|
|
485
|
+
end
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
The same operations have convenience commands: `mxrb refs`, `mxrb callers`,
|
|
489
|
+
`mxrb callees` and `mxrb impact`. The Ruby API is the source of truth.
|
|
490
|
+
|
|
491
|
+
When a project is opened with `readonly: false`, the first semantic-index build
|
|
492
|
+
stores a compact cache in the MPR. Later opens reuse it while unit contents and
|
|
493
|
+
containment remain unchanged. Semantic mutations invalidate the in-memory index,
|
|
494
|
+
and the persisted fingerprint prevents stale results after edits or moves.
|
|
495
|
+
Read-only projects can consume an existing cache but never create one.
|
|
496
|
+
|
|
497
|
+
## Deep rename
|
|
498
|
+
|
|
499
|
+
Writing requires an explicitly writable project and can be reviewed before
|
|
500
|
+
touching the MPR:
|
|
501
|
+
|
|
502
|
+
```ruby
|
|
503
|
+
Mxrb.open("app.mpr", readonly: false) do |project|
|
|
504
|
+
plan = project.plan_rename("Sales.Order", to: "Invoice")
|
|
505
|
+
|
|
506
|
+
plan.changes.each do |change|
|
|
507
|
+
puts "#{change.path.join(".")}: #{change.before} -> #{change.after}"
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
plan.apply!
|
|
511
|
+
end
|
|
512
|
+
```
|
|
513
|
+
|
|
514
|
+
The plan updates the declaration and deep references, including Mendix member
|
|
515
|
+
paths such as `Sales.Order/Number`. The project index is rebuilt automatically
|
|
516
|
+
after applying it.
|
|
517
|
+
|
|
518
|
+
The equivalent CLI command only shows a preview:
|
|
519
|
+
|
|
520
|
+
```sh
|
|
521
|
+
bundle exec mxrb rename app.mpr Sales.Order Invoice
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
To write:
|
|
525
|
+
|
|
526
|
+
```sh
|
|
527
|
+
bundle exec mxrb rename app.mpr Sales.Order Invoice --apply
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
## Safe removal
|
|
531
|
+
|
|
532
|
+
Removal is also previewed before writing:
|
|
533
|
+
|
|
534
|
+
```ruby
|
|
535
|
+
Mxrb.open("app.mpr", readonly: false) do |project|
|
|
536
|
+
plan = project.plan_remove("Sales.UnusedFlow")
|
|
537
|
+
plan.apply! if plan.safe?
|
|
538
|
+
end
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
`mxrb remove app.mpr Sales.UnusedFlow` reports incoming references and child
|
|
542
|
+
units. Adding `--apply` writes only when both collections are empty. Embedded
|
|
543
|
+
entities, attributes and associations require a typed domain-model mutation.
|
|
544
|
+
|
|
545
|
+
## Safe move
|
|
546
|
+
|
|
547
|
+
Move a standalone unit between folders in its current module:
|
|
548
|
+
|
|
549
|
+
```ruby
|
|
550
|
+
plan = project.plan_move("Sales.Process", to: "Sales.Automation")
|
|
551
|
+
plan.apply!
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
The CLI equivalent is
|
|
555
|
+
`mxrb move app.mpr Sales.Process Sales.Automation [--apply]`. Folder cycles,
|
|
556
|
+
cross-module moves and non-container targets are rejected before writing.
|
|
557
|
+
|
|
558
|
+
## Lint and coupling
|
|
559
|
+
|
|
560
|
+
The semantic report is a Ruby object:
|
|
561
|
+
|
|
562
|
+
```ruby
|
|
563
|
+
report = Mxrb.open("app.mpr", &:analyze)
|
|
564
|
+
|
|
565
|
+
report.diagnostics.each do |diagnostic|
|
|
566
|
+
puts "#{diagnostic.severity}: #{diagnostic.message}"
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
report.module_dependencies.each do |dependency|
|
|
570
|
+
puts "#{dependency.from} -> #{dependency.to}: #{dependency.references.size}"
|
|
571
|
+
end
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
Project-specific rules are Ruby as well:
|
|
575
|
+
|
|
576
|
+
```ruby
|
|
577
|
+
public_name_rule = lambda do |_project, index|
|
|
578
|
+
index.artifacts.filter_map do |artifact|
|
|
579
|
+
next unless artifact.kind == :microflow
|
|
580
|
+
next if artifact.name.match?(/\A[A-Z]/)
|
|
581
|
+
|
|
582
|
+
Mxrb::Semantic::Diagnostic.new(
|
|
583
|
+
:public_name,
|
|
584
|
+
:warning,
|
|
585
|
+
"microflow must start with uppercase: #{artifact.qualified_name}",
|
|
586
|
+
[artifact],
|
|
587
|
+
{}
|
|
588
|
+
)
|
|
589
|
+
end
|
|
590
|
+
end
|
|
591
|
+
|
|
592
|
+
Mxrb.open("app.mpr") do |project|
|
|
593
|
+
report = project.analyze(rules: [public_name_rule])
|
|
594
|
+
end
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
In the CLI, `mxrb lint app.mpr` shows diagnostics and
|
|
598
|
+
`mxrb report app.mpr` summarizes references and coupling between modules.
|
|
599
|
+
Built-in lint rules also cover persistent entities without access rules,
|
|
600
|
+
secured pages/flows without roles, undocumented public contracts, missing
|
|
601
|
+
navigation targets and duplicate module-role mappings. Custom Ruby rules are
|
|
602
|
+
appended to these checks.
|
|
603
|
+
|
|
604
|
+
The semantic index is fingerprinted and can be inspected or maintained without
|
|
605
|
+
guessing its state:
|
|
606
|
+
|
|
607
|
+
```sh
|
|
608
|
+
mxrb cache status app.mpr
|
|
609
|
+
mxrb cache warm app.mpr --json
|
|
610
|
+
mxrb cache clear app.mpr
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
## Semantic diff for Git
|
|
614
|
+
|
|
615
|
+
`Mxrb.diff` returns typed changes without exposing unstable UUIDs and visual
|
|
616
|
+
coordinates:
|
|
617
|
+
|
|
618
|
+
```ruby
|
|
619
|
+
result = Mxrb.diff("main.mpr", "feature.mpr")
|
|
620
|
+
|
|
621
|
+
result.changes.each do |change|
|
|
622
|
+
puts "#{change.operation} #{change.path.join(".")}"
|
|
623
|
+
end
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
Each `Mxrb::Compare::Change` provides `operation`, `path`, `before` and `after`.
|
|
627
|
+
Convenience filters are available through `result.added`, `result.removed` and
|
|
628
|
+
`result.changed`.
|
|
629
|
+
|
|
630
|
+
```sh
|
|
631
|
+
bundle exec mxrb diff main.mpr feature.mpr
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
The command exits with status zero when the snapshots are semantically
|
|
635
|
+
identical and status one when differences exist.
|
|
636
|
+
|
|
637
|
+
## Structural navigation
|
|
638
|
+
|
|
639
|
+
```ruby
|
|
640
|
+
Mxrb.open("app.mpr") do |project|
|
|
641
|
+
matches = project.search_artifacts("order", kind: :microflow)
|
|
642
|
+
details = project.describe_artifact("Sales.CreateOrder")
|
|
643
|
+
|
|
644
|
+
details.incoming.each { puts "from #{_1.source.qualified_name}" }
|
|
645
|
+
details.outgoing.each { puts "to #{_1.target.qualified_name}" }
|
|
646
|
+
end
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
In the CLI:
|
|
650
|
+
|
|
651
|
+
```sh
|
|
652
|
+
bundle exec mxrb find app.mpr order
|
|
653
|
+
bundle exec mxrb describe app.mpr Sales.CreateOrder
|
|
654
|
+
bundle exec mxrb tree app.mpr Sales
|
|
655
|
+
```
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Documentação do MXRB
|
|
2
|
+
|
|
3
|
+
**Português** · [English](../en-US/README.md) · [Deutsch](../de-DE/README.md)
|
|
4
|
+
|
|
5
|
+
- [Arquitetura de projetos](architecture.md)
|
|
6
|
+
- [Padrão arquitetural](architectural-standard.md)
|
|
7
|
+
- [Estrutura do projeto exportado](project-structure.md)
|
|
8
|
+
- [Padrões arquiteturais](architectural-patterns.md)
|
|
9
|
+
- [Refatoração semântica](semantic-refactoring.md)
|
|
10
|
+
- [Navegação e design system](design-system.md)
|
|
11
|
+
- [OQL, visão SQL e banco local](oql-sql.md)
|
|
12
|
+
- [Convenções](conventions.md)
|
|
13
|
+
- [Roadmap Ruby-first](ruby-first-roadmap.md)
|
|
14
|
+
- [Matriz de validação](validation-matrix.md)
|
|
15
|
+
- [Compilador nativo e Runtime](compiler.md)
|
|
16
|
+
- [Relatório de qualidade do build e Runtime](native-runtime-quality-report.md)
|
|
17
|
+
- [Criação e edição de projetos](writing.md)
|
|
18
|
+
- [Scaffolds de projeto](scaffolds.md)
|
|
19
|
+
- [DSL de entidades](entity-dsl.md)
|
|
20
|
+
- [Operação, lifecycle e Marketplace](platform-operations.md)
|
|
21
|
+
- [Avaliação de integração das APIs Mendix](platform-api-integration.md)
|
|
22
|
+
- [Aceitação end-to-end do VetClinic](vetclinic-acceptance.md)
|
|
23
|
+
|
|
24
|
+
[Voltar ao README do projeto](../../README.pt-BR.md)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Padrões arquiteturais
|
|
2
|
+
|
|
3
|
+
**Português** · [English](../en-US/architectural-patterns.md) · [Deutsch](../de-DE/architectural-patterns.md)
|
|
4
|
+
|
|
5
|
+
O MXRB usa Ruby como única interface pública do modelo e organiza
|
|
6
|
+
responsabilidades em domínio, aplicação, apresentação e infraestrutura.
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
apresentação ─┐
|
|
10
|
+
├─> aplicação ─> domínio
|
|
11
|
+
infraestrutura┘
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Entidades e regras guardam o estado de negócio. Microflows são casos de uso
|
|
15
|
+
quando coordenam esse estado. Páginas, navegação e nanoflows ficam em
|
|
16
|
+
apresentação; HTTP, banco externo, Java e integrações ficam em infraestrutura.
|
|
17
|
+
|
|
18
|
+
Repositórios são úteis em fronteiras externas reais, não como cerimônia ao
|
|
19
|
+
redor do CRUD Mendix comum. Chamadas e dependências permanecem visíveis no
|
|
20
|
+
grafo semântico e podem ser validadas contra o modelo real.
|
|
21
|
+
|
|
22
|
+
Security, navigation e design system são políticas transversais em `app/`.
|
|
23
|
+
A navegação declarada também é gravada no documento nativo Mendix.
|
|
24
|
+
|
|
25
|
+
[Voltar ao índice](README.md)
|