🚧

[Rust] 互換性チェックはcargo-semver-checksが便利

2023/09/24に公開

cargoはSemVerを使用してバーション管理をしています。さらにSemVer Compatibilityにライブラリの互換性を保つためのルールが文章化されています。

SemVer Compatibilityでは変更を以下のように分類しています。

  • Major change
    SemVerでMAJORを増やすような大規模、壊滅的な変更。関数、構造体の削除など。
  • Minor change
    SemVerでMINOR、PATCHを増やすような互換性を保つ変更。関数、構造体の追加など。
  • Possibly-breaking change
    プロジェクトによってMajor changeかMinor changeかどうか分かれる変更。Rustのバーション変更など。

例えば既存の関数の削除などの壊滅的な変更をしておいて、バーションを1.0.1から1.0.2に上げました! みたいなことは許されないわけです。

これらはライブラリをアップデートするときに参考になるものですが1つ1つチェックしていくのは面倒です。そこで互換性ルールを自動でチェックするcargo-semver-checksが役に立ちます。

以下のようなケースを考えてみましょう。

あるクレートのバーション1.0.0ではErrorという名前の構造体がありました。

[1.0.0] lib.rs
pub struct Error {}

バーション1.1.0ではErrorConfigErrorという名前に変更したいとします。しかし互換性を保つためにタイプエイリアスを追加しようとしましたが、うっかり名前をErrorではなくErrにしてしまいました。これでは互換性が壊れてしまいます。

[1.1.0 mistaken] lib.rs
pub struct ConfigError {}

#[deprecated(note = "Use `ConfigError` instead.")]
pub type Err = ConfigError;

これは人がチェックしていたら見落としていまう可能があります。そんなときでもcargo-semver-checksを使えばバッチシ弾いてくれるわけです。

error
--- failure enum_missing: pub enum removed or renamed ---

Description:
A publicly-visible enum cannot be imported by its prior path. A `pub use` may have been removed, or the enum itself may have been renamed or removed entirely.
        ref: https://doc.rust-lang.org/cargo/reference/semver.html#item-remove
       impl: https://github.com/obi1kenobi/cargo-semver-checks/tree/v0.23.0/src/lints/enum_missing.ron

修正したものは以下になります。

[1.1.0 correct] lib.rs
pub struct ConfigError {}

#[deprecated(note = "Use `ConfigError` instead.")]
pub type Error = ConfigError;

GitHub Actionもあるので、とりあえず導入しておくと良いと思います。

GitHubで編集を提案

Discussion