Skip to content

Conversation

@Vigilans
Copy link
Owner

@Vigilans Vigilans commented Dec 23, 2024

This PR adds support for named mappings to loader package's model loading process, with properly implemented interpolate after merge mechanism.

Embed model fields with contexts

Since compose has complex mechanisms for dealing with multiple configurations files:

  1. Multiple config files by -f
  2. Extends
  3. Include

It would be difficult to know in final merged dict that a specific field derives from which config file.

To solves this issue, a new concept is introduced: Embed each field of model dict with a context, and let the contexts participate into computations (Merge, Canonical, etc.) with fields. After all computations are done, unwrap the contexts from the dict, then we can answer questions like which config is this field from? giving any specific field.

Run interpolate after merge

Interpolation is now run after the final merged dict is ready, to retrieve correct and thorough information when resolving.

It is properly implemented with the help of embedded contexts, to retain scope information of each field, so variables like ${project[working-dir]}, ${compose[config-dir]} can return correctly value.

Some operations is dependent on the interpolated value, like transform.transformVolumeMount in Canonical, gojsonschema.Validate, they're also moved out to run after interpolation (thus after merge).

ResolveGlobal method for Resolver interface

A new method, ResolveGlobal(ctx, opts), is introduced in NamedMappingsResolver interface. It is run before model dict is even available, to provide information that can be known at global level, like env, project mappings. So partial interpolation can happen during extends and include.

Related Issues

* `mergeExtraHosts` is removed and splited into `mergeToSequence` + `extraHostsIndexer`

Signed-off-by: Vigilans <[email protected]>
…e`, `OmitEmpty` and `ResolveEnvironment` process

Signed-off-by: Vigilans <[email protected]>
…field's working dir at specific path

Signed-off-by: Vigilans <[email protected]>
…ay traversal

* Implemented match logic for `tree.PathMatchAll`

Signed-off-by: Vigilans <[email protected]>
…d-aware working dirs for path resolution

* Integrates `utils.Pair` into `ApplyExtends` and `ApplyInclude`
* `ApplyExtends` and `ApplyInclude` will now use absolute working dir, instead of relative dir to the upper extends/include stack

Signed-off-by: Vigilans <[email protected]>
* `transform.transformVolumeMount` relies on volume string interpolated to correctly parse, therefore need to run after interpolate

Signed-off-by: Vigilans <[email protected]>
* Filename is retrieved by looking up field's source config file by error's deriving field path

Signed-off-by: Vigilans <[email protected]>
* `include.*.env_file` is supported with `interpolate.Options.LookupValueMapping`

Signed-off-by: Vigilans <[email protected]>
* `env` and `project` named mappings are moved to `ResolveGlobal`

Signed-off-by: Vigilans <[email protected]>
* `project[name]` and `project[working-dir]` is fixed to take `include` into account

Signed-off-by: Vigilans <[email protected]>
@ndeloof
Copy link

ndeloof commented Jan 8, 2025

We already tried to introduce "interpolate after merge" but this always introduced regressions one way or the other 😓

@Vigilans
Copy link
Owner Author

Vigilans commented Jan 8, 2025

We already tried to introduce "interpolate after merge" but this always introduced regressions one way or the other 😓

Yes, I've already seen your past effort in docker/compose#11925 (comment) and compose-spec#666 (comment)...

I've added all regressions introduced in last attempt as test in commit cde7729, to ensure my attempt will not cause past regressions once more...

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants