crates.io
に自作のクレートを公開する際、README.md
などに記載しているクレートのバージョンをリリース時に書き換えることを忘れてしまうことが稀によくあります。以前はこのような事故を防ぐために cargo-release
で提供されている機能を使用していたのですが、リリース時にしか実行できない点などいまいち自分の好みと合わなかったので、バージョン番号のチェック・書き換えの部分だけを行う cargo サブコマンドを新しく作りました。
使い方
バージョン番号を書き換える対象となるファイルは、次のように Cargo.toml
内のメタデータとして指定します。このあたりの使用は cargo-release
で用いられていたものを参考にしました。
# package.metadata.version-sync.replacements という配列にバージョン番号を同期させたいターゲットを指定する(長い)。
[[package.metadata.version-sync.replacements]]
file = "README.md" # `CARGO_MANIFEST_DIR` からの相対パスを指定する
# ファイルの内容を書き換えるための replacer を指定する
# 将来的には潤沢させたい
replacers = [
# 組み込みの replacer
# target に指定可能な値は (0.0.2 時点では) 次の通り:
# - "markdown" : '{{package.name}} = "{{package.version}}"' というパターンを置き換える
# - "html-root-url" : docs.rs への URL を置き換える
{ type = "builtin", target = "markdown" },
]
[[package.metadata.version-sync.replacements]]
file = "src/lib.rs"
replacers = [
# 正規表現を用いた replacer
# 'search' には置換の対象となる正規表現、 'replace' には置換後の文字列を指定する
# 記述を簡略化するためのいくつかのプレースホルダーが使用可能:
# - {{name}} : Cargo.toml から抽出した package.name の値 ('search' と 'replace' 両方で使用可能)
# - {{version}} : クレートのバージョン ('replace' のみ)
# - {{date}} : コマンドの実行日時 ('replace' のみ)
{ type = "regex", search = "https://docs.rs/foo/[0-9a-z\\.-]+", replace = "https://docs.rs/foo/{{version}}" },
]
cargo-version-sync
を実行することでバージョン番号の更新を実行します。
$ cargo version-sync [--verbose]
cargo test
との連携
cargo test
実行時にバージョン番号の更新が行われているかを確認する方法です。後述する Git のカスタムフックと組み合わせることで、バージョン番号が更新されていない変更を誤ってコミット・マージしてしまうミスを防ぐことが出来ます。
[dev-dependencies]
cargo-version-sync = { version = "0.0.1", default-features = false }
extern crate cargo_version_sync;
#[test]
fn test_version_sync() {
cargo_version_sync::assert_sync();
}
cargo-husky
との連携
Git のカスタムフックを用いてコミット前にバージョン番号の更新を確認する方法です。ちょうど cargo-husky
という便利なクレートがあるので、これを併用してフックスクリプトのインストールを自動化してしまいます。
[dev-dependencies.cargo-husky]
version = "1"
default-features = false
features = ["user-hooks"]
cargo version-sync
には --check
というオプションが用意されており、これをつけて実行することでバージョン番号が全て更新されているかどうかをシェルスクリプト内で確認することが出来ます。例として、cargo-fmt
によるフォーマットチェックと併用したスクリプトは次のようになります。
#!/bin/bash
set -e
if cargo fmt --version >/dev/null 2>&1; then
cargo fmt -- --check
fi
if cargo version-sync --version >/dev/null 2>&1; then
cargo version-sync --check
fi