You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Confusion would arise multiple times already around `scylla-cql`
versioning requirements. In particular, it's not always clear to all
that (and why) we **must not** release `scylla` with just minor bump if
it bumps `scylla-cql`'s major. I decided it deserves comprehensive
explanation in `MAINTENANCE.md`.
Copy file name to clipboardExpand all lines: MAINTENANCE.md
+24
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,30 @@ What needs to be considered for releasing:
28
28
- Versions of `scylla-cql` and `scylla-macros` MUST always be the same. `scylla-cql` MUST depend on EXACT version of `scylla-macros` (e.g. `version = "=1.0.0"` in `Cargo.toml`). This ensures that we can change the `_macro_internal` module in minor releases, and generally simplifies reasoning about those 2 crates. If Rust allowed it, they would be one crate.
29
29
- For simplicity of maintenance, and to avoid potential problems with mixed versioning, we decided to always release all 3 crates together, with the same version numbers. Important: it does not allow us to make breaking changes in `scylla-cql`! Older versions of `scylla` will pick up newer versions of `scylla-cql`, e.g. after we release `scylla-cql 1.2`, `scylla 1.0` may start using it.
30
30
31
+
### `scylla-cql` API considerations
32
+
33
+
`scylla-cql` is purposefully available on [crates.io](https://crates.io/). This is mainly because some other crates, including ours (e.g., https://github.com/scylladb/scylla-rust-udf), use `scylla-cql` only and we don't want force them to pay in needless overhead introduced by depending on the whole `scylla` crate.
34
+
As `scylla-cql` is publicly available, it must comply to semver.
35
+
36
+
`scylla-cql` has some `pub` APIs that are not `pub`-re-exported in `scylla`. One might think this allows us bumping `scylla-cql` major number while bumping only minor number of `scylla`**if only** the breaking changes introduced in `scylla-cql` aren't visible in `scylla` API. **This is, unfortunately, not true!** The following bad scenario is a possible result of such action:
37
+
38
+
Imagine if some crate `X` has both `scylla = "1.x"` and `scylla-cql = "1.x"` in dependencies, which is legal. It's even more likely if we take into account dependency transitivity, so the whole dependency tree must be considered. `X` can then use `scylla_cql` paths to operate on items that come from it, instead of using `scylla` re-exports. This is also legal.
39
+
If we now update `scylla` to `1.(x+1)`, and use `scylla-cql = 2.0` there (in `scylla 1.(x+1)`), then the user will suddenly get errors about incompatible types (because they come from different major versions of the crate).
40
+
41
+
To illustrate on a specific case, consider the following definition present in `X`:
42
+
`impl scylla_cql::serialize::row::SerializeRow for SomeStructDefinedInX { ... }`
43
+
Now, even if we introduced no breaking changes to `SerializeRow` between `scylla-cql` 1.0 and 2.0, we end up with two different trait named `SerializeRow`, so the compiler refuses to accept (pseudonotation) `scylla-cql<1.x>::SerializeRow` as `scylla-cql<2.0>::SerializeRow`.
44
+
45
+
Does this mean that we are stuck with the current (sadly, still far from perfect) `scylla-cql` API for the whole `scylla = 1.x`? **Fortunately, no!** Imagine we are dissatisfied with the API of a struct `A` defined in `scylla-cql`:
46
+
```rust
47
+
pubstructA {
48
+
pubfield:Typ,
49
+
}
50
+
```
51
+
Assuming `A` is **not** part of `scylla`'s public API (it does not matter if it's re-exported there or not), we can:
52
+
1. introduce `A2` in `scylla-cql`, which has a better new API compared to `A` - this is a non-breaking change, because it's adding something new to the API;
53
+
2. alter `scylla` code to use `A2` instead of `A` - this is non-breaking, because we've assumed `A` is not present in any `scylla` public API;
54
+
3. keep `A` in `scylla-cql`, as well as possible `A` re-exports in `scylla`. Even though it's now legacy, it doesn't hurt. If suitable, we can mark `A` as `#[deprecated]` and remove it in the next major release.
0 commit comments