Slide 1

Slide 1 text

クレートを作って crates.ioに公開するまで Fukuoka.rs vol.6 〜LT会〜 pixiv Inc. Masaharu TASHIRO @tasshi820 2019.11.8

Slide 2

Slide 2 text

2 名前:田代雅治(たしろまさはる) Twitter: @tasshi820 所属:ピクシブ福岡オフィス(エンジニア) Like:Go, TypeScript, Docker, etc. Rust:最近業務で触り始めた > whoami

Slide 3

Slide 3 text

3 https://crates.io/crates/fitting 曲線近似ライブラリ(Pure Rust) 現在実装したもの ● 正規分布フィッティング ● 線形フィッティング ● 連立一次方程式のsolve それらしいクレートが 見当たらなかったので書いた Now in development

Slide 4

Slide 4 text

4 1. 実装する 2. ドキュメンテーションコメントを書く 3. メタデータを追加する 4. crate.ioのアカウントをセットアップする 5. クレートを公開する 参考:Publishing a Crate to Crates.io - The Rust Programming Language Recipe

Slide 5

Slide 5 text

5 1.実装する 実装する unwrapを消したり lib.rsをルートにしてモジュールを整理したり 単体・結合テストを書いたり 不要な依存を[dev-dependencies]に移したり

Slide 6

Slide 6 text

/// Returns a value of gaussian function. /// /// # Examples /// Returns a value of gaussian function. /// /// ``` /// use fitting::gaussian::val; /// /// let (mu, sigma, a): (f64, f64, f64) = (5., 3., 1.); /// let x = 5.; /// let y = val(x, mu, sigma, a); /// assert_eq!(y, a); /// /// ``` pub fn val(x: f64, mu: f64, sigma: f64, a: f64) -> f64 { a * (-(x - mu).powi(2) / (2. * sigma.powi(2))).exp() } 6 /// でドキュメント用のコメントを書く ・マークダウンをサポート ・Exampleセクション ❯ cargo test でテスト実行 ・ドキュメントの確認 ❯ cargo doc --open 参考: What is rustdoc? - 2.ドキュメンテーションコメント

Slide 7

Slide 7 text

7 The Manifest Format - The Cargo Book name:crates.ioでの名前 名前は早い者勝ち 名前が解放されることもない(たぶん) crates.io: Rust Package Registry Namespacing on Crates.io - Rust Internals license:MIT/Apache2.0が好ましい 参考: Necessities - Rust API Guidelines 3.メタデータを追加する [package] name = "fitting" version = "0.1.0" authors = ["Masaharu TASHIRO "] edition = "2018" description = "Pure Rust curve fitting library" documentation = "https://docs.rs/fitting/" homepage = "https://crates.io/crates/fitting" repository = "https://github.com/mshrtsr/fitting-rs" readme = "README.md" keywords = ["fitting","statistics","probability","distribution","math"] categories = ["science"] license = "MIT" [badges] maintenance = { status = "actively-developed" } [dependencies] ndarray = { version = "0.13.0", features = ["approx"] } approx = "0.3.2" failure = "0.1.6"

Slide 8

Slide 8 text

8 1. https://crates.ioのアカウント作成 2. https://crates.io/me にアクセス 3. API Access Tokenを生成 4. ローカルでターミナルを開く 5. ❯ cargo login 6.crate.ioのアカウントをセットアップする

Slide 9

Slide 9 text

9 公開したいプロジェクトのディレクトリで ❯ cargo publish ドキュメント、テストに問題がなければアップロードされて公開完了 crates.ioとdocs.rsで公開したクレートが見られるようになる 7.クレートを公開する

Slide 10

Slide 10 text

10 公開したけど、、、 継続的インテグレーション したくないですか?

Slide 11

Slide 11 text

11 お好きなCIサービスを使う Travis CIを使っているクレートが多い(目視) 複数環境でビルドするとBetter(Linux, Windows, Mac)(Stable, Nightly, Beta) crates.ioにビルドステータスを表示できるのは以下の 6サービス(2019年11月) Appveyor, CircleCI, Cirrus CI, GitLab, Azure DevOps, TravisCI (GitHub Actionsも対応して欲しい) ex1.CIを設定する

Slide 12

Slide 12 text

12 Travis CIの例(.travis.yml) `before_script` で fmt や clippy を行う build, testは勝手に実行される Building a Rust Project - Travis CI キャッシュを使わないと毎回ビルドが長い Travis CIでのRust cacheとうまく付き合う - Qiita 他のCIでも同じテクニックを使えば良さそう ex1.CIを設定する language: rust rust: - stable - beta - nightly cache: directories: - ${HOME}/.cargo - ${HOME}/.rustup before_cache: - rm -rf /home/travis/.cargo/registry jobs: allow_failures: - rust: nightly fast_finish: true before_script: | cargo fmt --version cargo fmt -- --check cargo clippy --version cargo clippy cargo clean Rustの実行環境を指定 キャッシュの設定 ビルド・テストの前に実行 される処理の指定

Slide 13

Slide 13 text

13 カバレッジサービス Codecov or Coveralls 計測ツール tarpaulin, cargo-kcov, cargo-cov の3つが主流そう tarpaulin, cargo-cov → Nightly only cargo-kcov → Personalityというシステムコールを使っていて、 Dockerコンテナ内ではこのsyscallは使えない ex2.コードカバレッジを取る

Slide 14

Slide 14 text

14 Travis CI + cargo-kcov + codecovの例 kcovをソースからビルドする必要がある 毎回すると長いのでキャッシュする codecovへのアップロードはサンプル通り https://github.com/codecov/example-rust ex2.コードカバレッジ cache: directories: - ${HOME}/kcov/ env: - PATH=$PATH:${HOME}/kcov/bin before_install: | if [ ! -d "${HOME}/kcov/bin" ]; then echo "Install kcov" && wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz && tar xzf master.tar.gz && cd kcov-master && mkdir build && cd build && cmake -DCMAKE_INSTALL_PREFIX=${HOME}/kcov .. && make && make install && cd ../.. && rm -rf kcov-master; fi after_success: | cargo kcov --no-clean-rebuild --verbose --all --no-fail-fast \ --output ./target/cov -- --verify --include-path=. --exclude-path=./target \ --exclude-region=kcov-ignore-begin:kcov-ignore-end --exclude-line=kcov-ignore-line && bash <(curl -s https://codecov.io/bash) && echo "Uploaded code coverage" キャッシュの設定 ${HOME}/kcov/bin が存在しない場合のみ kcovのビルドを行う

Slide 15

Slide 15 text

15 cargo installはパッケージの更新機能はない(同パッケージの installはエラーになる) リモートのバージョンとローカルのバージョンを比較 →更新するスクリプトを組む 後から知ったけど cargo-update を使うといいらしい ex2.コードカバレッジ before_install: | if ! type cargo-kcov > /dev/null; then echo "Install cargo-kcov" && cargo install cargo-kcov -f; else echo "Check cargo-kcov is latest" REMOTE_KCOV_VERSION=`cargo search cargo-kcov --limit 1 | sed -e 's/^cargo-kcov = "\(.*\)".*/\1/'` LOCAL_KCOV_VERSION=`cargo-kcov --version | sed -e 's/^cargo-kcov \(.*\).*/\1/'` if [ ! $REMOTE_KCOV_VERSION = $LOCAL_KCOV_VERSION ]; then echo "Upgrade cargo-kcov" && cargo install cargo-kcov -f; fi fi

Slide 16

Slide 16 text

16 仕上げにStatus Badgeを設定する README.md Cargo.toml CIの設定ファイルをexcludeする バージョンを上げて再度publicしたら完成 Status Badges [package] ... exclude = ["/.github/*", "./circleci/*", "/.travis.yml"] [badges] circle-ci = { repository = "mshrtsr/fitting-rs", branch = "master" } travis-ci = { repository = "mshrtsr/fitting-rs", branch = "master" } codecov = { repository = "mshrtsr/fitting-rs", branch = "master", service = "github" } # fitting-rs [![crates.io](https://img.shields.io/crates/v/fitt ing.svg)](https://crates.io/crates/fitting) [![docs.rs](https://docs.rs/fitting/badge.svg)](ht tps://docs.rs/fitting) [![Build Status](https://travis-ci.org/mshrtsr/fitting-rs.s vg?branch=master)](https://travis-ci.org/mshrtsr/f itting-rs) [![codecov](https://codecov.io/gh/mshrtsr/fitting- rs/branch/master/graph/badge.svg)](https://codecov .io/gh/mshrtsr/fitting-rs) Curve fitting library for Rust

Slide 17

Slide 17 text

17 ・ドキュメントがしっかりしていたので公開まで簡単 ・カバレッジあたりが鬼門だった(時間かかった) ・名前空間を占有している自覚を持って更新していく まとめ