Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
19 changes: 19 additions & 0 deletions docs/source/1.0/spec/core/behavior-traits.rst
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,25 @@ to request additional results from the operation.
A service MUST NOT evaluate authorization differently depending on the
presence, absence, or contents of a continuation token.


Backward compatibility
======================

Many tools use the ``paginated`` trait to expose additional functionality to
things like generated code. To support these use cases, the following changes
to the ``paginated`` trait are considered backward incompatible:

1. Removing the ``paginated`` trait.
2. Adding, removing, or changing the ``inputToken``, ``outputToken``, or
``items`` members.
3. Removing or changing the ``pageSize`` member.

The following changes are considered backward compatible:

1. Adding the ``paginated`` trait to an existing operation.
2. Adding the ``pageSize`` member to an existing ``paginated`` trait.


.. _UUID: https://tools.ietf.org/html/rfc4122


Expand Down
112 changes: 101 additions & 11 deletions smithy-diff/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,116 @@ because it adds new requirements that did not previously exist.

This library checks for the following tags on trait definitions:

* `diff.error.add`: An error is emitted when the trait is added to a shape.
* `diff.error.remove`: An error is emitted when the trait is removed
* `diff.error.add`: An error event is emitted when the trait is added to a
shape.
* `diff.error.remove`: An error event is emitted when the trait is removed
from a shape.
* `diff.error.update`: An error is emitted when the trait is updated or
modified in some way.
* `diff.error.const`: An error is emitted when the trait is added, removed,
or modified on a trait.
* `diff.error.update`: An error event is emitted when the trait is updated
or modified in some way.
* `diff.error.const`: An error event is emitted when the trait is added,
removed, or modified on a trait.
* `diff.danger.add`: A danger event is emitted when the trait is added to a
shape.
* `diff.danger.remove`: A danger event is emitted when the trait is removed
from a shape.
* `diff.danger.update`: A danger event is emitted when the trait is updated
or modified in some way.
* `diff.danger.const`: A danger event is emitted when the trait is added,
removed, or modified on a trait.
* `diff.warning.add`: A warning event is emitted when the trait is added to a
shape.
* `diff.warning.remove`: A warning event is emitted when the trait is removed
from a shape.
* `diff.warning.update`: A warning event is emitted when the trait is updated
or modified in some way.
* `diff.warning.const`: A warning event is emitted when the trait is added,
removed, or modified on a trait.

The following example defines a trait that configures this library to emit
an error event when `myTrait` is added to a shape.

```
namespace smithy.example

@tags(["diff.error.add"])
@trait
structure myTrait {}
```

## Nested trait diffs

The `diff.contents` tag is used to diff the contents of a trait value based
on diff tags applied to members of shapes used to define a trait. For example,
if it is a breaking change to update some members of a trait but not others,
this can be automatically validated using the `diff.contents` trait. When
evaluating the contents of a trait, only tags applied to members of lists,
sets, maps (value only), structures, and unions are considered.

The following example defines a trait that is configures this library to emit
an error event when the trait is added to a shape.
The following example defines a trait:

```
namespace smithy.example

trait myTrait {
selector: "*",
tags: [diff.error.add],
@aTrait(foo: "hi", baz: {foo: "bye"})
string Foo

// This tag is required on the trait definition in order to perform
// nested diff contents evaluation. It is also an error to add this
// trait to an existing shape because of the `diff.error.add` tag.
@tags(["diff.error.add", diff.contents"])
@trait
structure aTrait {
// It is an error to remove this member from a trait value.
@tags(["diff.error.remove"])
foo: String,

// It is a warning to add/remove/update this member on a trait value.
@tags(["diff.warning.const"])
bar: String,

// It's fine to add or remove this member.
baz: NestedTraitStruct
}

structure NestedTraitStruct {
// This nested trait value is also validated. A value provided for
// This member cannot be added removed or changed.
@tags(["diff.error.const"])
a: String,

// This member can be added or removed in any way whe used as
// part of a value for aTrait.
b: String,
}
```

Nested diffs also works with lists and sets. When diff tags are applied
to members of lists. For example, a trait could require that the order of
values is a backward compatibility contract; adding a value to the
beginning of a list of changing a value in a list is a breaking change.
The following trait only allows values to be appended to the `foo` list:

```
namespace smithy.example

// It is an error to remove this trait, and there are addional
// checks performed on nested trait values.
@tags(["diff.error.remove", "diff.contents"])
@trait
structure listTrait {
// You can't remove this value, but you can append to it.
@tags(["diff.error.remove"])
foo: ListTraitFoos,
}

list ListTraitFoos {
// A given member in a list must not change its position in the
// list nor can the value of a list member change. You can only
// append new values to the list.
@tags(["diff.danger.const"])
member: String,
}
```

# Adding a custom DiffEvaluator

Expand Down
Loading