Repository navigation
Integrate wave 1 of the upstream PRs (mendixlabs/mxcli #1574 #1575 #1572 #1570 #1563 #1561 #1568 #1566 #1368) - #1490
Merged
Merged
Conversation
ParseTestDir skipped every sub-directory, so `mxcli test tests` found nothing when suites live in tests/<Module>/*.test.mdl. It now walks the tree in lexical order, skipping hidden folders; the "no tests found" hint walks the same way. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nd nothing (#1363) Folders starting with `_` below the folder you name are skipped, like dot-folders (the Go toolchain's rule), so a deliberate positive-control suite in tests/unit/_control stays out of the default run; naming it runs it. The skipped folders are reported on the line after "Found N test(s)" in a run and in --list, and in the "no tests found" hint, so nothing disappears silently. `mxcli test <dir> --list` over a tree with no tests now prints the reason on stderr. Its exit status stays 0; a real run with no tests already exits 1. ListTests takes a second writer for that hint. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Review of #1368. With discovery recursive, one unreadable folder (a locked folder, a root-owned one in a mounted volume) made ParseTestDir return a hard error and dropped every test in the other folders. Only an error on the root is fatal now; below it the error is that folder's: it is added to FileErrors (Dir set), the run goes red through it, and the readable tests are kept. The messages say "could not be read" for a folder, not "failed to parse". Also: - testFilesMTime (--watch) walks with walkTestTree, so hidden and _ folders and the root rule cannot drift from discovery. - Errors, FileErrors and tests report paths under the name the user typed when the root is a symlink, not the resolved target. - Document that discovery is fully recursive (point at the tests folder, not the project root) and that symlinked subfolders are not followed. Tests inject the walk error through a seam so Windows and root CI cover the logic; the real chmod 000 test skips there. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ild generates them `create javascript action ... (Url: String, ReadOnly: Boolean)` wrote `export async function JS_Open(Url, ReadOnly)`. mxbuild and Studio Pro regenerate the signature and the JSDoc from the model with the first character of each parameter name lower-cased and keep the body, so after a build the signature read `JS_Open(url, readOnly)` and a body using `Url` threw ReferenceError at run time. check, mx check and the build were all clean. Rewriting a Studio Pro-authored action through MDL did the same in reverse: `Geocode(address, ...)` became `Geocode(Address, ...)` over a body that still read `address`. JavaScriptParameterName lower-cases the first rune only, which is what mxbuild 11.12.5 does (URL -> uRL, MyID -> myID, Some_Name -> some_Name, XMLData -> xMLData, _Lead unchanged). GenerateJavaScriptSource uses it for the signature and the @PARAM tags. The model parameter keeps its declared name, so describe prints it as declared and describe -> exec is stable, and bodies are not rewritten. Tests: the measured table, the generated signature, a rewrite over a Studio Pro-style file, and goldens of what mxbuild left for two actions. A check warning for bodies that use the declared case is a separate change. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A bare `returns Module.Name` is recorded by the parser as an entity
reference. exec retried it as an enumeration for parameters but not for the
return types of a microflow, a nanoflow or a rule, so a script that
`check -p --references` accepted failed with "entity 'M.E' not found for
return type". For a rule, check refused it as well ("a rule must return a
Boolean or an enumeration, not Entity").
The three create handlers now resolve a return type through the helper the
parameter path uses (entity first, then enumeration), and the rule check
applies the same retyping before validateRule. The stored return type equals
the one `returns enum M.E` stores. An unknown name now reports "entity or
enumeration 'M.X' not found for return type".
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The detached run was created with DETACHED_PROCESS, which gives it no console, so Windows allocated a new, visible console for every console program it started (java, mxbuild, gradle). Create it with CREATE_NO_WINDOW instead: the run gets one console with no window, and its children inherit it. Windows ignores CREATE_NO_WINDOW when it is combined with DETACHED_PROCESS, so the old flag is dropped, not supplemented. The new test starts a helper through setDetachAttrs and has the helper and a console child of it report their console (GetConsoleCP, GetConsoleWindow, GetConsoleProcessList): the run must have a console without a window, and the child must share it. Fixes mendixlabs#1484 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…itability `Editable: '$currentObject/Locked = false'` on an input widget passed check, exec said "Created page", and the widget was stored `Editable: Always` with no ConditionalEditabilitySettings, so a field meant to be locked stayed editable. `Visible: '<expr>'` was stored as a conditional visibility: its consumer (pages.StaticVisibleExpression) returns any other string as the condition, while Editable's (pages.CanonicalEditability) knew only Always|Never|Conditional and the builder skipped every other string without a word. New pages.StaticEditability is the Editable counterpart: an enum word, a boolean (false is Never, true is Always) or, for any other string, the condition. A list view's and a grid column's Editable stays their own plain bool. check now refuses what still cannot be stored (a misspelt word, a quoted text that is not an expression, `Conditional` with no condition) as MDL-WIDGET19 naming the accepted spellings, and a quoted condition gets the checks the bare one gets (MDL-WIDGET13, MDL-BUTTON02, MDL-WIDGET41, MDL-WIDGET20). describe prints the stored condition bare, so describe -> exec is stable. ALTER PAGE set (Editable: '<expr>') keeps its loud refusal. Control: same script on the pre-fix binary stores Always/null for the quoted widgets; with the fix they are byte-equal (ids stripped) to the bare spelling and mx check reports 0 errors on Mendix 11.12.5. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r pluggable and data view Follow-up to the quoted Editable expression fix. MDL-WIDGET31 still tested the raw string for "Never", so an input marked `editable: false` (now Never) in a read-only list view kept earning the warning that tells it to mark itself Never; it reads the same resolved value as the builder now. Tests added for the shapes a review asked about: a pluggable widget that declares Editability is refused the same unstorable values by MDL-WIDGET19, and a data view carries the quoted condition exactly as the bare one (its static Never/Always is stored from its own ReadOnly flag, which this change does not touch). CHANGELOG, finding record updated to match. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
… names (mendixlabs#1569) A navigation profile points at documents in six places: the home page (and one per user role), a home flow, the login page, the not-found page and every menu item at any depth. A standalone menu document carries the same menu items. Nothing resolved any of them, so `check -p` said "Check passed!", `exec` wrote the profile, and only `mx check` objected (CE1613 "The selected page ... no longer exists.", once for the home page and once per menu item). CREATE OR REPLACE NAVIGATION rewrites the whole profile, and the menu builder stores a target by name and never fails on it. check -p now reports each unresolved target with the profile or menu document, the menu item path and the missing name, using the lookups every other page, microflow, nanoflow and entity reference is resolved with. exec runs the same check in the handler before it reads or writes anything, so `exec --no-check` is covered too. A menu document stored as excluded only warns. A target the script creates resolves. One created further down also resolves in a run that rolls back (plain exec, check), as a call to a flow created further down does (#1405): upstream accepts a navigation written before its pages and mx check reports 0 errors for it, so refusing it would break a working script. exec --continue-on-error, the REPL and -c cannot roll back and refuse it, from validateForwardDefRefs. Measured on a Mendix 11.12.5 app: 4 x CE1613 before for the reported script, refused by check -p and exec after, and a valid navigation (existing pages, a Marketplace-module page, a page created in the same script) still passes check and exec with 0 errors from mx check. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…its context (mendixlabs#1571) `describe page` printed the association as the context entity of a data container bound over an association: dataview dvInner (DataSource: $currentObject/Shop.Order_Customer) { -- Context: $currentObject (Shop.Order_Customer) <- the association dataSourceEntityContext used the datasource reference as the entity for every kind but a flow. The reference means a different thing per kind: the entity for a database source, the flow for a microflow/nanoflow source (fixed in 6e59e0e), the association for an association source. The page was always correct; only the comment, and the association-name spelling that depends on the context, was wrong. The entity an association source reaches is stored on its last hop (EntityRef.Steps[last].DestinationEntity), which is already right from either end of the association, for a reference set, and for a specialization of the association's end, so it is read instead of re-derived from the domain model. associationSourcePath saw each step's destination but kept only the association names; rawDataSource.Destination now carries the last one, set where both association sources are built (Forms$AssociationSource / data view and the pluggable XPath source). A source with no stored destination keeps the reference, as the flow fix does. The `DataSource:` text is unchanged. Tests: owner-to-child reference, the reverse direction, reference set with its selection variable, specialization, two hops, a page-parameter start, the pluggable source, the no-destination fallback, and database/flow controls. Against upstream/main the association cases fail with the reported symptom. Verified on a Mendix 11.12.5 project: both directions describe the entity, describe -> exec reports "Unchanged page", mx check 0 errors. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ndixlabs#1573) `mxcli check` without `-p` warned, for every setting a Data grid 2 takes by its own key, widget `dgAttr` (datagrid) property `configurationAttribute` is not recognized and will be silently dropped on write [MDL-WIDGET07] although `exec -p` stores it and `check -p` accepts it, and it refused an Expression-typed one (`rowClass`, a column's `columnClass`) as an MDL-WIDGET42 ERROR, "a plain-value property cannot hold the expression". A script exec takes therefore failed `make check-mdl` (exit 1 with 2 errors, measured), and so would the output of `describe page` once it prints such settings. DATAGRID has no embedded definition: its .def.json is generated from the project's own package, and an embedded one would take precedence over that package on every write (RefreshWidgetDefinitions skips a widget id the registry already holds), so adding one would change the write path to fix a check. Without a project the keyword resolved to no definition at all and was judged against the vocabulary of the built-in widgets. The check now reads the property list of the Data grid 2 template mxcli embeds, for the grid's own keys and, for a `column` inside one, the item type of `columns`. A key the template declares (or the `<key>Params` of a text template) is accepted, and its declared type decides MDL-WIDGET42. The template is the oldest-supported baseline, so a key it does not declare is still reported by MDL-WIDGET07, with a did-you-mean from the template's names, but as what is true without a project: it cannot be verified, and is dropped on write unless the installed widget declares it. The Data grid 2 template carries the same 40 grid keys and 21 column keys as the 11.12.5 package. With a project, and for every other widget, nothing changes. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…r widget key (mendixlabs#1573) A pluggable widget takes every one of its settings under the key its package declares, and exec stores them: datagrid dg (DataSource: database Shop.Ord, configurationStorageType: localStorage, itemSelectionMethod: rowClick, refreshInterval: 30) `describe page` printed only the properties MDL has a keyword for (PageSize, Pagination, Selection, onClick), so executing the description wrote the widget's default over each of the others. Measured on Mendix 11.12.5: a grid with 22 settings changed came back with the 4 that have keywords, with `mx check` at 0 errors throughout, and a Studio Pro-authored grid lost its `onClickTrigger: double`. The describers for datagrid2 and gallery now also print every setting whose stored value differs from the default, under its key: enumerations and plain values, text templates with their `{N}` parameters, expressions, attributes, a column's own settings (minWidth, minWidthLimit, allowEventPropagation, …) and the empty-state placeholder slot. The default is read from the widget's own stored definition (Type.ObjectType, and the item type of `columns`), not from a list. It is not always the schema's DefaultValue: four text templates have '' there and store the text the widget ships for them, so a text template counts as default when it holds that text, and a grid that sets none of the settings describes byte for byte as before (16 pages of a Studio Pro-authored project and 16 of the committed PedApp: the one that differs is a marketplace page, by the setting it had been losing). An Expression prints unquoted, except an expression that is only a string literal, which would be read back as the string and stored without its quotes. An attribute prints bare where exec resolves a bare name (inside a data container) and qualified where it would not. A setting with no spelling (an attribute reached over associations) is named in a `-- NOT re-executable` comment. Selection-typed keys are carried by `Selection:` and not repeated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…s without a project (mendixlabs#1573) CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…lery's settings by their widget key (mendixlabs#1573) CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…data source reaches as its context (mendixlabs#1571) CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…gation or menu document names (mendixlabs#1569) CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…in exec, as check does CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…parameters the way mxbuild generates them CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…r in MDL-WIDGET31, cover pluggable and data view CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…a console window per child CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…t cannot read (#1363) CHANGELOG.md conflict resolved by keeping both sides. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
The no-project check (mendixlabs#1574) and the describe-by-key tests (mendixlabs#1575) loaded the template from sdk/widgets, while every other executor path, and exec itself, reads modelsdk/widgets. The two datagrid.json copies declare the same keys today, so this changes no result; it makes check judge a key against the copy exec writes from. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…cefully mendixlabs#1566 gave the run a hidden console (CREATE_NO_WINDOW) instead of none, so "console-less" no longer described it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
…check Review note on mendixlabs#1570: the len(known) == 0 guard reads like a gap. It is the price of not turning a failed read into a false "not found". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
Part of 4a3b6ce moved this test fixture to modelsdk/widgets as well. In the full executor package run the grid it builds then carries a non-default columnsFilterable, so three TestDataGridByKey_* tests fail; the JSON files differ only by AllowUpload, so something in the package changes what the modelsdk copy yields. The fixture goes back to what mendixlabs#1575 shipped with; the production check keeps the modelsdk import. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
mendixlabs#1570 makes exec refuse a navigation target it cannot find, and the doctype example named the login page Administration.login. The page is Administration.Login, as everywhere else in the repo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
b43f1d7 renamed the login page to Administration.Login, but the test project has no such page in either case: CI refused it as "page not found: Administration.Login" while Administration.Account_Overview resolved. mx check never flagged the missing login page, so the example had named a nonexistent page all along. The script now creates NavTest.NavTest_Login and the profiles use it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
mendixlabs#1570 resolved the login page like the home and not-found pages. The sign-in page may be the theme's static login.html rather than a page document, so a login page the project does not have is not a dangling reference, and mx check accepts it: the doctype navigation example names Administration.login, which the test project does not have, and builds clean. The check refused it. The login page is no longer a target. A new test pairs a login page outside the project (accepted) with a missing not-found page (still refused) as its control, and the "login page" case leaves the every-kind table. The navigation example goes back to main's version (undoing b43f1d7 and 2f9876b), so it now also covers a login page outside the project. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn
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.
This branch merges nine open bug-fix PRs from mendixlabs/mxcli and adds review follow-ups. The goal is to prove the PRs work together before they are merged upstream one by one.
Merged, in this order
Each PR's own commits are kept as they are. The only conflict was
CHANGELOG.md, resolved by keeping both sides.checkwithout a project accepts a Data grid 2's own settings (mendixlabs#1573, check half)describeprints Data grid 2 / Gallery settings by widget key, non-default values only (mendixlabs#1573, describe half)describenames the entity an association data source reaches as its context (mendixlabs#1571)check -p/execresolve the pages and flows a navigation profile or menu names (mendixlabs#1569)exec, ascheckdoes (mendixlabs#1562)Editable: '<expr>'is stored as a conditional editability (mendixlabs#1567)run --detachon Windows no longer opens a console window per child (#1484)mxcli testfinds test files in subfolders (#1363)Follow-ups on top
fix(check): fix(check): accept a Data grid 2's own settings without a project mendixlabs/mxcli#1574 reads the Data grid 2 template frommodelsdk/widgets, the copyexecwrites from.test(describe): fix(describe): print a Data grid 2's and a Gallery's settings by their widget key mendixlabs/mxcli#1575's test fixture stays onsdk/widgets. In the full package run themodelsdkcopy yields a non-defaultcolumnsFilterable; that is unexplained and needs a separate look.docs(run)/docs(check): comment corrections on fix(run): --detach on Windows no longer opens a console window per child mendixlabs/mxcli#1566'sterminateProcessand fix(check): resolve the pages and flows a navigation or menu document names mendixlabs/mxcli#1570's empty-list guard.fix(check): fix(check): resolve the pages and flows a navigation or menu document names mendixlabs/mxcli#1570 no longer checks a profile's login page.login.html, which is not a page document, andmx checkaccepts any name there. The doctype navigation example usesAdministration.login, which the test project does not have, and fix(check): resolve the pages and flows a navigation or menu document names mendixlabs/mxcli#1570 refused it.Review and validation
go buildandgo vet.Build, Test & Lint) and were green ona1fb0d8a.Not included
_-folder rule: included as written, so it still needs a maintainer decision.Editable: Conditionalwithout a condition is still written underexec --no-check.🤖 Generated with Claude Code
https://claude.ai/code/session_01QiMsnXa9crge2qnSk9S7Zn