Description
Feature Request 🛍️
Support imports across semver ranges.
Use Case
Allows less strict management of imports, meaning that when an imported namespace is referenced, if backwards compatible changes to the imported namespace are made, then the version number of the importing namespace does not have to be incremented.
Possible Solution
Support some form of semver range for import statements:
namespace person@1.0.0
concept Person {
o String name
}
With strict import (as today):
namespace vehicle@1.0.0
import person@1.0.0.{Person}
concept Vehicle {
o Person owner
}
With semver import:
namespace vehicle@1.0.0
import person@1.x.{Person}
concept Vehicle {
o Person owner
}
Context
Today you can run Concerto in two modes:
- Default: namespaces and imports are unversioned
- Strict: namespaces and imports are fully versioned
Strict mode is very useful in that it makes the dependency graph between concepts completely deterministic, given a single CTO file. I.e. you can take a single CTO file and follow all its versioned imports and build a deterministic graph of every element the model contains. The downside is that changes to namespaces that are "deep" in the dependency hierarchy cause a ripple of changes through out the entire graph. As the graph gets large this is untenable.
Detailed Description
By supporting semver range imports these ripple updates of import versions are minimised, imports only need to be updated when the semver range constraint no longer matches. The downside is that the dependency graph from a CTO file is no longer purely defined by the CTO file itself, it depends on what other CTO files are present, and their versions. The so-called "package-lock.json" problem - there may need to be another mechanism to ensure deterministic versions of imported packages are used, to ensure fully reproducible builds.
Ensuring Reproducible Builds
Below I illustrate an approach of writing back the resolved namespace version into the AST for the model, allowing semver imports to be "pinned" while maintaining them in the CTO or AST.
With semver import, with ability to specify a "resolved version" for an import:
namespace vehicle@1.0.0
@ResolvedVersion("1.0.1")
import person@1.x.{Person}
concept Vehicle {
o Person owner
}
Note: today we do not support decorators on imports, we should have to make changes to the meta model and the runtime to support this syntax.
- Create CTO files Parent@1.0.0 and Child@1.0.1
- Create a semver import of Child@1.x into Parent@1.0.0
- Create a ModelManager with options
strict:true
andsemverImports:true
set (do we want a flag for this? Perhaps it should just be supported by default?) - Add Parent and Child to the ModelManager
- Parent resolves imports from Child@1.0.1 and models validate
ModelManager.resolveMetamodel
is used to create an AST that has theResolvedVersion
decorator added to all semver imports, capturing the version of the namespace that was used- AST can be stored and converted back to CTO for debugging or audit
When a reproducible ModelManager is required:
- Create a ModelManager with options
strict:true
anduseResolvedImportVersions:true
set - Add the ModelFiles for Parent and Child
- The import of Child@1.x into Parent is ignored (because it has the
ResolvedVersion
decorator) and an import to version 1.0.1 is used. An exception is thrown if this exact version of the model file is not in the model manager.
When the ModelManager should pick up new namespace versions:
- Create a ModelManager with options
strict:true
set andsemverImports:true
- Add the updated ModelFiles to the ModelManager, for example Child@1.1.0
- Parent resolves imports from Child@1.1.0 and models validate
- Call
ModelManager.resolveMetamodel
to store this configuration, if necessary
Code Generation
When we generate code we will need to use the resolved imports, rather than imports than contain semver ranges.
Tasks
- Decide on semantics of semver imports (.x, ranges etc)
- Update the meta model to support semver imports
- Update the parser to support semver imports for CTO
- Convert AST back to CTO
- Update ModelFile to resolve imports with semver
- Update VSCode extension
- Update the meta model to support decorators on imports
- Update the runtime to support decorators on imports