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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## Rust
/target/
Cargo.lock

## Intellij Idea
.idea/
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ This means that druid no longer requires cairo on macOS and uses Core Graphics i
- Added a changelog containing development since the 0.5 release. ([#889] by [@finnerale])
- Removed references to cairo on macOS. ([#943] by [@xStrom])
- Updated screenshots in `README.md`. ([#967] by [@xStrom])
- Added a section about dependencies to `CONTRIBUTING.md`. ([#990] by [@xStrom])

### Maintenance

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

## [0.5.0] - 2020-04-01
Expand Down
99 changes: 99 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,105 @@ Every pull request should document all changes made in the [changelog].
If your name does not already appear in the [AUTHORS] file, please feel free to
add it as part of your patch.

## Preparing for a new release

If you're already contributing to this project and want to do more,
then there might be a chance to help out with the preparation of new releases.
Whether you're new or have prepared druid releases many times already,
it helps to follow a checklist of what needs to be done. This is that list.

### Changelog

- Add a new *Unreleased* section by copying the current one.
Keep the sections, but delete the entries.
- Rename the old *Unreleased* section to the target release version and add the release date.
- Add the correct link for the target release revision to the bottom of the file.
- Delete any empty sections.
- Tidy up the entries, possibly reordering some for more logical grouping.

### Dependencies

**We only test and specify the newest versions of dependencies.** Read on for more details.

Rust dependencies like druid specify their own sub-dependencies in `Cargo.toml`.
These specifications are usually version ranges according to [semver],
stating that the dependency requires a sub-dependency of the specified version
or any newer version that is still compatible. It is up to the final application
to choose which actual versions get used via the `Cargo.lock` file of that application.

Because the final application chooses the sub-dependency versions and they are most likely
going to be higher than the minimum that is specified in our `Cargo.toml` file,
we need to make sure that druid works properly with these newer versions.
Yes according to [semver] rules they should work, but library authors make mistakes
Copy link
Member

Choose a reason for hiding this comment

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

I am inclined to trust reported semver versions, and also trust maintainers of crates we use (and those should generally be few crates, of a high standard) to yank releases that break semver.

and it won't be a good experience or a sign of druid quality if a new developer
adds druid as a dependency and it won't even compile.
For that reason our CI testing always uses the highest version that is still compatible.
This mimics what a new developer would experience when they start using druid.

What about the the minimum supported version or all the versions between the minimum and maximum?
It is not practical for us to test all the combinations of possible sub-dependency versions.
Without testing there can easily be mistakes. Let's say our `Cargo.toml` specifies that
we depend on the package `foo` version `^1.1.1` and the latest `foo` version is `1.1.3`.
The CI tests with `1.1.3` and contributors have `1.1.3` in their local `Cargo.lock`.
`Cargo.toml` specifies `1.1.1` as the minimum because that was the latest version
when the dependency was added and `1.1.1` did work just fine originally.
However it turns out that this specific version had a bug which doesn't interact well
with some other package `bar`. Our CI testing or manual testing would never find this out,
because we're already using `1.1.3` and deleting and regenerating `Cargo.lock` wouldn't change that.
Just because `1.1.1` used to work back in the day doesn't mean that it will always keep working.

One partial solution to this problem is to be more precise in what we are actually promising.
So whenever we release a new version we also update all our dependencies in `Cargo.toml`
to match the versions that we are actually testing with. This will be much more accurate
to the spirit of the version specification - druid will work with the specified version
and any newer one if it's [semver] compatible. We're not testing the extremely big matrix of
old versions of our sub-dependencies and so we shouldn't claim that the old versions will work.

#### Prerequisites for updating the dependency specifications

An easy way to do this is to use the `cargo upgrade` tool available via [cargo-edit].

```
cargo install cargo-edit
```

#### Performing the update

All of the following commands must be run from the root workspace.

First we want to update our `Cargo.lock` file to contain the newest versions
which are still [semver] compatible with what we have specified in our `Cargo.toml` files.

If you just want to see what would happen you can add the `--dry-run` option.

```
cargo update
```

Next we'll update all the versions in the `Cargo.toml` files to match the versions
specified in `Cargo.lock`. We'll do this using the `--to-lockfile` option of `cargo upgrade`.
It's crucial that we use `--to-lockfile` because without it `cargo upgrade` won't respect semver.

If you just want to see what would happen you can add the `--dry-run` option.

```
cargo upgrade --workspace --to-lockfile
```

#### Semver incompatible updates

Incompatible version updates should be done manually after carefully reviewing the changes.
However you can still use the `cargo upgrade` tool to find out which dependencies could be updated.

```
cargo upgrade --workspace --dry-run
```

Then based on the reported potential updates you should manually go and check out what has changed,
plus how and if it makes sense to update to the newer version.

[GitHub Help]: https://help.github.com/articles/about-pull-requests/
[AUTHORS]: AUTHORS
[changelog]: CHANGELOG.md
[cargo-edit]: https://github.com/killercup/cargo-edit
[semver]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html
Loading