-
Notifications
You must be signed in to change notification settings - Fork 28
Adds a copy action #150
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
base: v1.1-dev
Are you sure you want to change the base?
Adds a copy action #150
Conversation
|
Here is an experimental implementation, it was fairly straightforward :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally really like this. It's simple nomenclature and implementation.
Annecdotally to me the alternative approach of using runtime expressions is more powerful in some ways, but also limiting in others. We've been using them at Speakeasy to represent complex concepts in Arazzo but unfortunately we've had to build escape hatches for places where they don't work (specifically the lack of conditionals). I'd propose we accept this as a minor version bump, and do that as an independent addition to this change as part of future work given a set of differing use-cases.
|
cc: @RobertCraigie @yjp20 Would be great to get your feedback on this one. |
cd596cc to
cbac889
Compare
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
…e of the schema definition Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
| actions: | ||
| - target: '$.paths["/some-items"]' | ||
| copy: '$.paths["/items"]' | ||
| description: 'copies recursively all elements from the "items" path item to the new "some-items" path item without ensuring the node exists before the copy' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens if the target does not exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case the target does not exist, same as remove/update, NO-OP
In case the copy does not exist, we could define this as NO-OP, or error? I'm happy either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the reasoning for making it a no-op/error instead of adding the node for you? Even if that just works for the direct target, and doesn't create parent nodes. (sorry if this is in the spec, I couldn't find it)
I'm asking as for our versions of "copy" transformations, we create the target node for you. Although admittedly our version is special cased for copying paths and schema objects, so creating the target node is very simple as we don't have to even define what the behaviour would be for recursively creating parent nodes.
I do think that creating the node if it didn't already exists would be pretty helpful as currently you would need to define two different actions with a different path syntax, instead of just one action, or even two actions with the same path.
Although this seems like a fundamental aspect of the Overlays design, so it probably does not make sense to try and figure this out just for copy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the target: I'm happy either way, I just want the behavior to be consistent with other kinds of actions. As far as I understand the current spec (v1.0), if the target yields 0 matches, the behavior is currently implementation specific (could be a NO-OP, could be a warning, could be an error). And changing that would probably represent a breaking change from a behavior standpoint. Please correct me if I missed anything.
As for the copy, as written right now, if the cardinality does not match what target found, it's an error. I think that's probably the safest behavior for implementers. There's no point erroring out when copy finds nothing, if at the same time the target found nothing. We might want to rephrase things to we don't need to error when copy finds more items than target.
src/overlay.md
Outdated
| | Field Name | Type | Description | | ||
| | ---- | :----: | ---- | | ||
| | <a name="action-target"></a>target | `string` | **REQUIRED** A JSONPath expression selecting nodes in the target document. | | ||
| | <a name="action-copy"></a>copy | `string` | A JSONPath expression selecting locations to copy target nodes to in the target document. If the `target` selects an object node, the value of this field MUST be an object with the properties and values to merge with the selected node. If the `target` selects an array, the value of this field MUST be an entry to append to the array. This field has no impact if the `remove` field of this action object is `true` or if the `update` field contains a value. When both the target and copy expressions match multiple nodes, the cardinality of the matches MUST be equal. Each copy node is applied to the corresponding target node in positional order: the first copy node to the first target node, the second to the second, and so forth. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the target selects nothing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(let's keep the conversation in the other thread until we come to a decision, and I'll revert back here to update the text once we have)
Co-authored-by: Ralf Handl <[email protected]>
src/overlay.md
Outdated
| | Field Name | Type | Description | | ||
| | ---- | :----: | ---- | | ||
| | <a name="action-target"></a>target | `string` | **REQUIRED** A JSONPath expression selecting nodes in the target document. | | ||
| | <a name="action-copy"></a>copy | `string` | A JSONPath expression selecting locations to copy target nodes to in the target document. If the `target` selects an object node, the value of this field MUST be an object with the properties and values to merge with the selected node. If the `target` selects an array, the value of this field MUST be an entry to append to the array. This field has no impact if the `remove` field of this action object is `true` or if the `update` field contains a value. When both the target and copy expressions match multiple nodes, the cardinality of the matches MUST be equal. Each copy node is applied to the corresponding target node in positional order: the first copy node to the first target node, the second to the second, and so forth. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd put this field in between update and remove in the table. All actions need target and description, so it's a bit weird to split them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated.
src/overlay.md
Outdated
|
|
||
| #### Copy example | ||
|
|
||
| Copy actions behave similarly to update actions but source the node to from the document being transformed. Copy actions MAY be combined with update or remove actions to perform more advanced transformations like moving or renaming nodes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps "used in sequence with" rather than "combined with" since the fields are mutually exclusive and can't be combined - so this could be confusing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
|
|
||
| This approach allows inversion of control as to where the Overlay updates apply to the target document itself. | ||
|
|
||
| #### Copy example |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to see a sentence before and after each code snippet explaining what is being illustrated in the snippet, and the outcome of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added sections, and resulting descriptions to all examples.
|
I'll stand up a new PR for the 1.1-dev setup changes soon, and once we merge it, this one should get easier to review and I'll address the other comments. Sorry about the "mess" I iterated my way through the changes to get this PR in an as advanced state as possible. |
|
There, I just pushed #180 |
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
|
|
||
| The properties of the `update` object MUST be compatible with the target object referenced by the JSONPath key. When the Overlay document is applied, the properties in the `update` object are recursively merged with the properties in the target object with the same names; new properties are added to the target object. | ||
|
|
||
| The properties of the resolved `copy` object MUST be compatible with the target object referenced by the JSONPath key. When the Overlay document is applied, the properties in the resolved `copy` object are recursively merged with the properties in the target object with the same names; new properties are added to the target object. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from the meeting, compatible is not explicitly defined, but this should be done as a separate PR, let's create a separate issue for that.
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
Signed-off-by: Vincent Biret <[email protected]>
|
@baywet — #justfyi I am working on an updated overlay.md to illustrate what I mentioned on the call today. I am adding some examples and changing some headings for consistency because with a table of examples the inconsistency stands out more. I also changed some text from passive to active voice because the ghost of my technical writing professor in university is always sitting on my shoulder commenting on my passive voice. Hope to have this available very soon, though I am not 100% sure how to submit a PR to a PR. Should I submit a PR to baywet/Overlay-Specification/feat/copy-node and then mention that I did so here? |
Signed-off-by: Vincent Biret <[email protected]>
|
For anybody following along, thanks for bearing with us while we clean up the branches/versions story. I've just "temporary aligned" things before retargeting to main (pending on #183). |
@mikeschinkel Thanks for doing this, yet a PR to my feature branch should be fine if it's a large set of changes, I just pushed a few new things since the call FYI. If the changes are smaller, suggestions (comments with suggestion) in this PR can work as well. |
Co-authored-by: Ralf Handl <[email protected]>
|
@baywet — I am getting my IDE flagging
|
|
@baywet — Here is the PR to your PR: baywet#1 I added a table listing the examples, and the rest of the changes followed from that to improve structure, clarity, and consistency (with no normative changes). Summary of changeds
All content above |
@mikeschinkel PR #118 contains a fix for that example. |
fixes #146
fixes #121
closes #140
Hi everyone,
I've tried to get to the simplest common denominator, and incorporate some of the feedback that was already provided:
I'm proposing to add a copy field to the action, that's mutually exclusive with remove or update. It's functionally equivalent to the update field except that it uses a JSON path to source the JSON Node instead of defining it inline.
I know there was some additional thinking about templating expressions, sourcing from env variables etc... But I think those can be considered orthogonal and be added in a separate PR by their champions. I'd like to get the smallest possible unit that brings a meaningful contribution through.
As an image is better than a thousand words, here are a couple of examples.
Copying a node to a node that already exists
Here the existing foo path item properties are being copied to the bar path item.
Copying a node to a node that DOES NOT already exists
Moving an item
A couple of todos if that gets consensus: