Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support yaml merge operator #1040

Merged
merged 7 commits into from
Sep 29, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
comment
  • Loading branch information
msbarry committed Sep 28, 2024
commit d36dad35be08eaaa6fdb82e8506bf2d13a96ef41
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ public static <T> T load(InputStream stream, Class<T> clazz) {
}
}

/**
* SnakeYaml doesn't handle the <a href="https://yaml.org/type/merge.html">merge operator</a> so manually post-process
* the parsed yaml object to merge referenced objects into the parent one.
*/
private static void handleMergeOperator(Object parsed) {
if (parsed instanceof Map<?, ?> map) {
Object toMerge = map.remove("<<");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this code, or similar, be used check if the merge operator is the first key in the mapping?!

Suggested change
Object toMerge = map.remove("<<");
// Check if the first key is a merge operator using an iterator
Iterator<String> keyIterator = map.keySet().iterator();
Object toMerge = null;
if (keyIterator.next().equals("<<")) {
toMerge = map.remove("<<");
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, when I read the merge operator draft again, it does not prohibit placing the merge operator at any location in a map. Neither does it prohibit multiple instances of merge operators in the same map.

Here is a YAML example where the use of the merge operator is not restricted, as in this suggestion:

- base: &base
    nested_mapping: &base_nested_mapping
      key1: value1
      nested_sequence:
        - item1
        - item2
- extension: &extension
    nested_mapping:
      <<: *base_nested_mapping
      key2: value2
      nested_sequence:
        - item3
        - item4
- merged_using_array:
    <<: [ *extension, *base]
- merged_separately:
    <<: *extension
    <<: *base
- merged_interleaved:
    start: marker1
    <<: *extension
    mid: marker2
    <<: *base
    end: marker3

According to YAML Lint, it would expand to

- base:
    nested_mapping:
      key1: value1
      nested_sequence:
        - item1
        - item2
- extension:
    nested_mapping:
      key1: value1
      nested_sequence:
        - item3
        - item4
      key2: value2
- merged_using_array:
    nested_mapping:
      key1: value1
      nested_sequence:
        - item3
        - item4
      key2: value2
- merged_separately:
    nested_mapping:
      key1: value1
      nested_sequence:
        - item3
        - item4
      key2: value2
- merged_interleaved:
    start: marker1
    nested_mapping:
      key1: value1
      nested_sequence:
        - item3
        - item4
      key2: value2
    mid: marker2
    end: marker3

Please feel free to reject this suggestion

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I noticed that playing around with pyyaml. Since this approach happens post-parsing and the parser throws a clear exception in this case and you can easily switch to <<: [*a, *b] I think it's an OK limitation. A more fully-thought-out merge operator might support things like merging maps in the order they are specified when the operator appears more than once (and working for lists) but that would require support at the parser level.

Expand Down
Loading