Skip to content

Commit 780fa88

Browse files
authored
Adopt a new dependency updating strategy. (#990)
1 parent f8197e4 commit 780fa88

File tree

8 files changed

+136
-2118
lines changed

8 files changed

+136
-2118
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
## Rust
22
/target/
3+
Cargo.lock
34

45
## Intellij Idea
56
.idea/

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
132132
- Added a changelog containing development since the 0.5 release. ([#889] by [@finnerale])
133133
- Removed references to cairo on macOS. ([#943] by [@xStrom])
134134
- Updated screenshots in `README.md`. ([#967] by [@xStrom])
135+
- Added a section about dependencies to `CONTRIBUTING.md`. ([#990] by [@xStrom])
135136

136137
### Maintenance
137138

@@ -234,6 +235,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
234235
[#980]: https://github.com/xi-editor/druid/pull/980
235236
[#982]: https://github.com/xi-editor/druid/pull/982
236237
[#984]: https://github.com/xi-editor/druid/pull/984
238+
[#990]: https://github.com/xi-editor/druid/pull/990
237239
[#991]: https://github.com/xi-editor/druid/pull/991
238240

239241
## [0.5.0] - 2020-04-01

CONTRIBUTING.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,105 @@ Every pull request should document all changes made in the [changelog].
1818
If your name does not already appear in the [AUTHORS] file, please feel free to
1919
add it as part of your patch.
2020

21+
## Preparing for a new release
22+
23+
If you're already contributing to this project and want to do more,
24+
then there might be a chance to help out with the preparation of new releases.
25+
Whether you're new or have prepared druid releases many times already,
26+
it helps to follow a checklist of what needs to be done. This is that list.
27+
28+
### Changelog
29+
30+
- Add a new *Unreleased* section by copying the current one.
31+
Keep the sections, but delete the entries.
32+
- Rename the old *Unreleased* section to the target release version and add the release date.
33+
- Add the correct link for the target release revision to the bottom of the file.
34+
- Delete any empty sections.
35+
- Tidy up the entries, possibly reordering some for more logical grouping.
36+
37+
### Dependencies
38+
39+
**We only test and specify the newest versions of dependencies.** Read on for more details.
40+
41+
Rust dependencies like druid specify their own sub-dependencies in `Cargo.toml`.
42+
These specifications are usually version ranges according to [semver],
43+
stating that the dependency requires a sub-dependency of the specified version
44+
or any newer version that is still compatible. It is up to the final application
45+
to choose which actual versions get used via the `Cargo.lock` file of that application.
46+
47+
Because the final application chooses the sub-dependency versions and they are most likely
48+
going to be higher than the minimum that is specified in our `Cargo.toml` file,
49+
we need to make sure that druid works properly with these newer versions.
50+
Yes according to [semver] rules they should work, but library authors make mistakes
51+
and it won't be a good experience or a sign of druid quality if a new developer
52+
adds druid as a dependency and it won't even compile.
53+
For that reason our CI testing always uses the highest version that is still compatible.
54+
This mimics what a new developer would experience when they start using druid.
55+
56+
What about the the minimum supported version or all the versions between the minimum and maximum?
57+
It is not practical for us to test all the combinations of possible sub-dependency versions.
58+
Without testing there can easily be mistakes. Let's say our `Cargo.toml` specifies that
59+
we depend on the package `foo` version `^1.1.1` and the latest `foo` version is `1.1.3`.
60+
The CI tests with `1.1.3` and contributors have `1.1.3` in their local `Cargo.lock`.
61+
`Cargo.toml` specifies `1.1.1` as the minimum because that was the latest version
62+
when the dependency was added and `1.1.1` did work just fine originally.
63+
However it turns out that this specific version had a bug which doesn't interact well
64+
with some other package `bar`. Our CI testing or manual testing would never find this out,
65+
because we're already using `1.1.3` and deleting and regenerating `Cargo.lock` wouldn't change that.
66+
Just because `1.1.1` used to work back in the day doesn't mean that it will always keep working.
67+
68+
One partial solution to this problem is to be more precise in what we are actually promising.
69+
So whenever we release a new version we also update all our dependencies in `Cargo.toml`
70+
to match the versions that we are actually testing with. This will be much more accurate
71+
to the spirit of the version specification - druid will work with the specified version
72+
and any newer one if it's [semver] compatible. We're not testing the extremely big matrix of
73+
old versions of our sub-dependencies and so we shouldn't claim that the old versions will work.
74+
75+
#### Prerequisites for updating the dependency specifications
76+
77+
An easy way to do this is to use the `cargo upgrade` tool available via [cargo-edit].
78+
79+
```
80+
cargo install cargo-edit
81+
```
82+
83+
#### Performing the update
84+
85+
All of the following commands must be run from the root workspace.
86+
87+
First we want to update our `Cargo.lock` file to contain the newest versions
88+
which are still [semver] compatible with what we have specified in our `Cargo.toml` files.
89+
90+
If you just want to see what would happen you can add the `--dry-run` option.
91+
92+
```
93+
cargo update
94+
```
95+
96+
Next we'll update all the versions in the `Cargo.toml` files to match the versions
97+
specified in `Cargo.lock`. We'll do this using the `--to-lockfile` option of `cargo upgrade`.
98+
It's crucial that we use `--to-lockfile` because without it `cargo upgrade` won't respect semver.
99+
100+
If you just want to see what would happen you can add the `--dry-run` option.
101+
102+
```
103+
cargo upgrade --workspace --to-lockfile
104+
```
105+
106+
#### Semver incompatible updates
107+
108+
Incompatible version updates should be done manually after carefully reviewing the changes.
109+
However you can still use the `cargo upgrade` tool to find out which dependencies could be updated.
110+
111+
```
112+
cargo upgrade --workspace --dry-run
113+
```
114+
115+
Then based on the reported potential updates you should manually go and check out what has changed,
116+
plus how and if it makes sense to update to the newer version.
117+
21118
[GitHub Help]: https://help.github.com/articles/about-pull-requests/
22119
[AUTHORS]: AUTHORS
23120
[changelog]: CHANGELOG.md
121+
[cargo-edit]: https://github.com/killercup/cargo-edit
122+
[semver]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html

0 commit comments

Comments
 (0)