Skip to content

A relative MetadataUrl on an OData client is stored as an absolute file:// URL, so the model carries the authoring machine's path #1499

Open

Description

@ako

Measured on 020f4572b and on PR #1497's head and base; not specific to any of them. Found while re-executing a project's full script set in a container whose checkout path had changed.

What happens

The script writes a relative path, which is portable:

create or modify odata client F1Cached.CachedApi (
  MetadataUrl: './contracts/f1-metadata.xml',
  …
);

The stored client holds it resolved against the working directory of whichever machine ran the script:

$ mxcli -p Formula1Frontend.mpr -c "describe odata client F1Cached.CachedApi"
  MetadataUrl: 'file:///workspaces/mxcli-formula1/Formula1Frontend/contracts/f1-metadata.xml',

That path is from the devcontainer the model was authored in. This container mounts the same repository at /home/user/mxcli-formula1, so re-executing the same unchanged script rewrites every client:

-  MetadataUrl: 'file:///workspaces/mxcli-formula1/Formula1Frontend/contracts/f1-metadata.xml',
+  MetadataUrl: 'file:///home/user/mxcli-formula1/Formula1Frontend/contracts/f1-metadata.xml',

Five OData clients in this project, so five documents of churn on a run that should have written nothing — 5 of the 20 writes a full re-exec produces.

Why it stays invisible

Nothing fails. The metadata file is only read when the contract is refreshed, so check passes, the build is clean, the app boots, and the services serve. The committed model simply contains an absolute path that exists on no other machine, and nobody notices until the environment moves — which for this project was a container change between sessions.

Two consequences worth separating:

  1. The model is not portable. A fresh clone on a different path carries a MetadataUrl pointing into someone else's filesystem. Anyone who then refreshes the contract from the model gets a dead path rather than the file sitting right there in the repository.
  2. Re-exec is not idempotent across checkout paths. For a project whose method is "edit the script, re-exec, converge", a document that rewrites itself because the repository moved is noise in every diff, and it defeats byte-level verification of everything else.

What I would ask for

I do not know whether Mendix requires an absolute URL in ConsumedODataService's metadata property — if it does, the first consequence may be unavoidable, and storing a relative path is off the table.

If so, the narrower fix is enough and is clearly right: leave the stored value alone when it resolves to the same file. The statement said ./contracts/f1-metadata.xml, the stored URL already points at that exact file, so there is nothing to change and the write should be elided the way every other unchanged document is (ADR-0008). That alone removes the churn and keeps exec idempotent wherever the repository is checked out.

If a relative or project-relative form can be stored, better still — then the committed model is portable too, and describe → exec round-trips without baking in a path.

Either way describe currently prints the absolute form, so a describe → exec round trip spreads the authoring machine's path into any script generated from the model.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions