<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Rust on blog.kyu08.com</title>
    <link>https://blog.kyu08.com/pr-344/tags/rust/</link>
    <description>Recent content in Rust on blog.kyu08.com</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>ja</language>
    <copyright>blog.kyu08.com</copyright>
    <lastBuildDate>Mon, 22 Dec 2025 00:13:06 +0900</lastBuildDate><atom:link href="https://blog.kyu08.com/pr-344/tags/rust/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/rust-web-app-book/</link>
      <pubDate>Mon, 22 Dec 2025 00:13:06 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/rust-web-app-book/</guid>
      <description>『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだので感じたことをメモしておく。 『ＲｕｓｔによるＷｅｂアプリケー</description>
      <content>&lt;p&gt;『RustによるWebアプリケーション開発 設計からリリース・運用まで』を読んだので感じたことをメモしておく。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://dvs-cover.kodansha.co.jp/0000398182/qlwQ4BgoUFJKQBFNNIbAbFmXHhhSS0R338o5wVij.jpg&#34; alt=&#34;『ＲｕｓｔによるＷｅｂアプリケーション開発　設計からリリース・運用まで』（豊田　優貴,松本　健太郎,吉川　哲史）　製品詳細　講談社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;『ＲｕｓｔによるＷｅｂアプリケーション開発　設計からリリース・運用まで』（豊田　優貴,松本　健太郎,吉川　哲史）　製品詳細　講談社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;★Rustによるアプリケーション開発のベストプラクティス！ 　Rustを現場で使うときがきた！ Rust経験豊富な筆者が、貴重な知識とテクニックを惜しみなく伝授。 「蔵書管理アプリケーション」の実装を通じて、Rustによる設計、開発、保守、運用までをハンズオンで学ぶ！ コードも丁寧に解説。 【目次】 第1章　本書で開発するもの 第2章　開発環境の構築 第3章　最小構成アプリケーションの実装 第4章　蔵書管理サーバーアプリケーションの設計 第5章　蔵書管理サーバーの実装 第6章　システムの結合とテスト 第7章　アプリケーションの運用 第8章　エコシステムの紹介&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.kodansha.co.jp/book/products/0000398182&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;モチベーション&#34;&gt;モチベーション&lt;/h2&gt;
&lt;p&gt;Rustという言語の開発体験がかなり好きでRustでサーバーサイドを書くのがどんな感じなのか純粋に気になっていたので読んでみた。（筆者がサーバーサイドの開発でガッツリ書いたことがあるのはほぼGoのみで、RustはCLIやTUIの開発にしか使ったことがないというバックグラウンド）&lt;/p&gt;
&lt;h2 id=&#34;本書の概要&#34;&gt;本書の概要&lt;/h2&gt;
&lt;p&gt;本書はRustで蔵書管理アプリケーションのサーバーサイドを実装しながらRustでのWebアプリケーション開発の仕方を学ぶことができる本。&lt;/p&gt;
&lt;p&gt;ただ動くものを作る、というよりは業務の実際のサーバーサイドの開発でよく出くわす課題をRustではどう実装するのかが豊富に紹介されている。(DIやエラーハンドリングなど)&lt;/p&gt;
&lt;p&gt;設計面ではレイヤードアーキテクチャを採用しており、レイヤー間の責務などが考慮された設計になっている。その意味でも実務での開発に近い内容になっていると言える。&lt;/p&gt;
&lt;p&gt;あとはステップごとのコード差分が丁寧に書かれているので、本書に従って実装を進めるとWeb Serverの実装が出来上がる（はず）。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;コンパイル時間短縮の工夫
&lt;ul&gt;
&lt;li&gt;アプリケーションを複数のクレートに分割することで変更があったクレートだけ再コンパイルすればよくなるためコンパイル時間が短縮できる。&lt;/li&gt;
&lt;li&gt;たとえば本書ではレイヤードアーキテクチャのレイヤーごとにクレートを分割していた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Web開発で有用なクレート
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/derive-new&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;derive_new&lt;/code&gt;&lt;/a&gt;: &lt;code&gt;new&lt;/code&gt;関数を実装してくれる。デフォルト値の設定などもできる模様。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/serde&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;serde&lt;/code&gt;&lt;/a&gt;: 言わずと知れたシリアライズ/デシリアライズのためのクレート。&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://crates.io/crates/sqlx&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;sqlx&lt;/code&gt;&lt;/a&gt;: SQLを型安全に扱うことができる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;エラーハンドリングの方法
&lt;ul&gt;
&lt;li&gt;クライアントに返すエラーはthiserrorで定義し、それ以外のエラーはanyhowを使って表現する。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;RustでどうDIを実装すべきか
&lt;ul&gt;
&lt;li&gt;ジェネリクスを用いてDIするパターン（静的ディスパッチ）
&lt;ul&gt;
&lt;li&gt;動的ディスパッチと比較すると記述量が増える&lt;/li&gt;
&lt;li&gt;動的ディスパッチと比較するとパフォーマンスが高い&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;トレイトオブジェクト（&lt;code&gt;dyn &amp;lt;トレイト名&amp;gt;&lt;/code&gt;）を利用するパターン（動的ディスパッチ）
&lt;ul&gt;
&lt;li&gt;静的ディスパッチと比較すると記述量が減る&lt;/li&gt;
&lt;li&gt;静的ディスパッチと比較するとパフォーマンス面で不利&lt;/li&gt;
&lt;li&gt;本書ではWeb開発において動的ディスパッチのコストが問題になることは少ないことを理由にこちらを採用していた。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;実際にrustでweb-serverを書いてみた感想主にgoとの比較&#34;&gt;実際にRustでWeb Serverを書いてみた感想（主にGoとの比較）&lt;/h2&gt;
&lt;p&gt;※なお、筆者のRustスキルは趣味レベルなのでRustを深く理解したうえでの感想ではありません。間違っている点や他の重要な観点などがある可能性があります。また、主には個人的な考えのスナップショットを自分用に残す目的で書いているので説明を端折っている箇所がある可能性があります。&lt;/p&gt;
&lt;h3 id=&#34;ポジ&#34;&gt;ポジ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;enumやパターンマッチ等を使って仕様をスマートに書ける。&lt;/li&gt;
&lt;li&gt;null安全なので他の言語のnull相当の概念を型安全に扱うことができる。&lt;/li&gt;
&lt;li&gt;if式を始めとした関数型ライクな言語機能のおかげで開発体験が良い。&lt;/li&gt;
&lt;li&gt;変数がデフォルトでimmutableなので、mutableな変数を目立たせやすいし、自然とimmutableなコードが書きやすい。&lt;/li&gt;
&lt;li&gt;あらゆるシンボルがデフォルトでprivateなのでカプセル化するようなコードが若干書きやすい。（意識的に&lt;code&gt;pub&lt;/code&gt;を付けなければprivateになってくれる点で強い理由がなければprivateになりやすくなる、と考えている）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;ネガ&#34;&gt;ネガ&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;コンパイル時間が長い。&lt;/li&gt;
&lt;li&gt;コンパイル時間短縮のためにcrate分割が推奨されているが、依存関係の増減があるたびに&lt;code&gt;Cargo.toml&lt;/code&gt;を手書きで編集しないといけないのが若干面倒。
&lt;ul&gt;
&lt;li&gt;もしかしたらコードアクション等、エディタの支援が得られるのかもしれないがそこまで調べられていない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Goに慣れているとRustのマクロやアトリビュートが若干黒魔術的に感じる。これらに慣れるまでは認知負荷が高そう。例えば以下。（『RustによるWebアプリケーション開発 設計からリリース・運用まで』より引用）
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;#[derive(Error, Debug)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;pub&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;AppError&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnprocessableEntity(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    EntityNotFound(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ValidationError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; garde::Report),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;トランザクションを実行できませんでした。&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    TransactionError(&lt;span style=&#34;color:#75715e&#34;&gt;#[source]&lt;/span&gt; sqlx::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;データベース処理実行中にエラーが発生しました。&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    SpecificOperationError(&lt;span style=&#34;color:#75715e&#34;&gt;#[source]&lt;/span&gt; sqlx::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;No rows affected: {0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    NoRowsAffectedError(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    KeyValueStoreError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; redis::RedisError),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    BcryptError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; bcrypt::BcryptError),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ConvertToUuidError(&lt;span style=&#34;color:#75715e&#34;&gt;#[from]&lt;/span&gt; uuid::Error),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ログインに失敗しました&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnauthenticatedError,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;認可情報が誤っています&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    UnauthorizedError,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;許可されていない操作です&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ForbiddenOperation,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#75715e&#34;&gt;#[error(&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{0}&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ConversionEntityError(String),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;DIが若干複雑
&lt;ul&gt;
&lt;li&gt;Goならinterface使うだけなので考えることが少なくて済む。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;非同期処理
&lt;ul&gt;
&lt;li&gt;これもRustの非同期処理の仕組みへの理解&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;が大変浅いのであまり具体的に書けないが、自分の現状のRustスキルだとGoに比べて意図通りに動く非同期処理を書くのに数倍時間がかかる。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;本書を読むまではRustがWebサーバーサイド開発の銀の弾丸、とまでは言わないもののかなりいい選択肢の1つのように思えていた。主に型の表現力のおかげでドメインがうまく表現できたり、所有権などの言語機能や発達したリンターによって内部品質を高く保つことができ、その結果開発生産性が高まると考えていた。&lt;/p&gt;
&lt;p&gt;しかし実際に本書でRustでサーバーを書いてみると上記のメリットはありつつも意外とRustでの実装でも手間や複雑なポイントがあり、Goのシンプルさや手軽さの良さを改めて認識した。&lt;/p&gt;
&lt;p&gt;結果はともあれ実際にRustでサーバーを書くのがどんな感じなのかを知ることが本書を読んだ目的だったので解像度を高めることができてよかった。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;5章の途中までしかやっていないので「はず」と書いている。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;あるいは単にコンピュータの仕組みへの理解が浅いとも言えるのかもしれない。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;もちろんもっとDeep Diveしたら違う感想を持つかも知れないが、あくまで今時点の自分の感想としては上記のような感じ。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>『コンセプトから理解するRust』を読んだ</title>
      <link>https://blog.kyu08.com/pr-344/posts/understanding-rust-from-concepts/</link>
      <pubDate>Mon, 15 Dec 2025 19:21:35 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/understanding-rust-from-concepts/</guid>
      <description>Rustのことをもっと理解りたくて『コンセプトから理解するRust』を読んだ。 コンセプトから理解するRust | 技術評論社Rustはメモリ安全</description>
      <content>&lt;p&gt;&lt;img src=&#34;./book.webp&#34; alt=&#34;book&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Rustのことをもっと理解りたくて『コンセプトから理解するRust』を読んだ。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://gihyo.jp/book/2022/978-4-297-12562-2&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://gihyo.jp/assets/images/ogp/2022/9784297125622.jpg&#34; alt=&#34;コンセプトから理解するRust | 技術評論社&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;コンセプトから理解するRust | 技術評論社&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;Rustはメモリ安全、スレッド安全を保ちつつ、高パフォーマンスなプログラムを開発できるプログラミング言語です。また、手続き型、オブジェクト指向型、関数型でのプログラミングに対応できるマルチパラダイムの言語でもあります。ただ、そういったRustのポテンシャルを引き出すには、所有権やライフタイム、ジェネリクスやトレイトといった特徴的な仕様の理解が求められ、これらは初学者の壁にもなっています。本書ではそれら難解な仕様をピックアップし、他のプログラミング言語とコードレベルで比較しながら、「なぜそのような仕様になっているか」という言語のコンセプトからRustの理解を試みます。加えて、Rustのこまやかなエラーメッセージを読みつつ、Rustをうまく書くための知識もお伝えします。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://gihyo.jp/book/2022/978-4-297-12562-2&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;前提&#34;&gt;前提&lt;/h2&gt;
&lt;p&gt;筆者のRustの知識は&lt;a href=&#34;https://tourofrust.com/00_ja.html&#34; target=&#34;_blank&#34; &gt;Tour of Rust&lt;/a&gt;や&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだり簡単なツール&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;を作ったことがある程度で、非同期処理をスラスラ書けたり、スムーズに人に教えたりできるレベルではない。&lt;/p&gt;
&lt;p&gt;過去に&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt;を読んだときもスマートポインターまわりなどは飛ばしつつ読んでいたので本書での学びは多かった。&lt;/p&gt;
&lt;h2 id=&#34;学び&#34;&gt;学び&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Box&lt;/code&gt;について理解した。&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Rc&lt;/code&gt;, &lt;code&gt;RefCell&lt;/code&gt;, &lt;code&gt;Weak&lt;/code&gt;周りをなんとなく理解した。たぶん空では書けないが、エラーになったら調べて解決できるくらいの理解にはなったはず。&lt;/li&gt;
&lt;li&gt;トレイト境界についてちょっとわかった。&lt;/li&gt;
&lt;li&gt;クロージャ, &lt;code&gt;Fn&lt;/code&gt;, &lt;code&gt;FnMut&lt;/code&gt;, &lt;code&gt;FnOnce&lt;/code&gt;について理解できた。&lt;/li&gt;
&lt;li&gt;簡単な非同期処理の仕組みがわかった。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;今まで全然わかっていなかったこれらの概念が少しだけわかった。やはりコードを書き散らかすだけでなく体系的なインプットも大事&amp;hellip;。（それはそう）&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;おそらく今後Rustを書いたりコンパイラと対話したりしていくともう少し深く理解していけると思う。&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;全体を通してコード例が豊富だったので手元で動かしながら理解しやすくてとてもありがたかった。&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;Rustの力がまた少しついた。&lt;/p&gt;
&lt;p&gt;Rustを学ぶとRust自体への理解が深まるだけでなく、少なからずコンピュータの仕組みに近い低レイヤな部分の理解も一緒に深まるので勉強になる感覚があって楽しめた。&lt;/p&gt;
&lt;p&gt;非同期処理周りはあまりちゃんと勉強したことがないので次はこの本を読んでみようと思う。（サンプルコードが主にRustで書かれているらしいのでこの本での学びも活かせそう）&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://www.oreilly.co.jp/books/9784873119595/&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://www.oreilly.co.jp/books/9784873119595/&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://www.oreilly.co.jp/books/images/picture_large978-4-87311-959-5.jpeg&#34; alt=&#34;並行プログラミング入門&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;並行プログラミング入門&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;複数のプログラムを同時に実行する「並行プログラミング」は、処理速度を飛躍的に向上させる手法で、タスク管理、プロセス管理、スレッド管理をはじめ、複雑な仕組みについての幅広い知識とテクニックが必要となります。本書はRustとアセンブリ、そして一部Cを用い、CPUのアトミック命令、グリーンスレッド、アクターモデル、π計算、ソフトウェア・トランザクショナルメモリ、async/awaitなど、並行プログラミングに関する理論的な背景から実装までをカバー。さらに、アセンブリ実装の理解を深めるため、AArch64とx86-64アーキテクチャの説明も付録として収録。一歩一歩、着実に理解できるように、その仕組みから順を追って詳しく説明します。GitHub上で公開されているソースコードを実際に動かしながら、並行プログラミングの知識と理解を深めることができます。&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://www.oreilly.co.jp/books/9784873119595/&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;おまけ&#34;&gt;おまけ&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The name &amp;ldquo;Tokio&amp;rdquo; is derived from Tokyo and mio, and the Tokio logo vaguely resembles the city emblem of Tokyo.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Tokio_%28software%29&#34; target=&#34;_blank&#34; &gt;https://en.wikipedia.org/wiki/Tokio_(software)&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Rustの非同期ランタイムのtokioの名前の由来の一部は東京らしい。&lt;/p&gt;
&lt;p&gt;あとロゴも東京都の紋章を彷彿とさせるデザインになっているらしい。（実際調べてみたら似ているというかほぼ同じだったw）&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;fzf-make&lt;/a&gt;というTUIツールを書いている。あとそういえば&lt;a href=&#34;https://github.com/kyu08/sunaba/tree/main/rust/nand2tetris&#34; target=&#34;_blank&#34; &gt;nand2tetris&lt;/a&gt;もRustで書いていた。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;趣味のプログラミングなのでRustを覚え始めた頃は楽しさ優先でまあ動けばOKという気持ちで書いていたが最近になってちゃんと理解したくなってきたので学んでいる。&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;あるいは各種概念を自作するという選択肢もあるかもしれない。Arcとか非同期ランタイムとか&amp;hellip;。&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;他には&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814400515/&#34; target=&#34;_blank&#34; &gt;詳解 Rustアトミック操作とロック&lt;/a&gt;、&lt;a href=&#34;https://www.oreilly.co.jp/books/9784814401185/&#34; target=&#34;_blank&#34; &gt;Async Rust
&lt;/a&gt;、&lt;a href=&#34;https://www.kodansha.co.jp/book/products/0000398182&#34; target=&#34;_blank&#34; &gt;RustによるWebアプリケーション開発　設計からリリース・運用まで
&lt;/a&gt;あたりもとても気になっている。&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>関数型まつり2025に参加した</title>
      <link>https://blog.kyu08.com/pr-344/posts/fp-matsuri-2025/</link>
      <pubDate>Sun, 15 Jun 2025 05:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/fp-matsuri-2025/</guid>
      <description>2025/06/14(土)、2025/06/15(日)に中野セントラルパークで行われた関数型まつり2025に参加した。 筆者はElmやRust</description>
      <content>&lt;p&gt;2025/06/14(土)、2025/06/15(日)に中野セントラルパークで行われた関数型まつり2025に参加した。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;nakano-central-park.webp&#34; alt=&#34;nakano-central-park&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;pop.webp&#34; alt=&#34;pop&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;筆者はElmやRustの開発体験を気に入っており、Webアプリケーションのサーバーサイドを関数型言語で書くことに興味があったので参加してみた。&lt;/p&gt;
&lt;h2 id=&#34;関数型言語テイスティング-haskell-scala-clojure-elixirを比べて味わう関数型プログラミングの旨さ---lagénorhynqueカマイルカさん&#34;&gt;関数型言語テイスティング: Haskell, Scala, Clojure, Elixirを比べて味わう関数型プログラミングの旨さ - lagénorhynque/カマイルカさん&lt;/h2&gt;
&lt;p&gt;lagénorhynque/カマイルカさんによるHaskell, Scala, Clojure, Elixirの紹介と比較を行う発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container docswell&#34;&gt;
      &lt;div class=&#34;docswell-placeholder&#34; data-src=&#34;https://www.docswell.com/s/lagenorhynque/Z6VX6E-functional-language-tasting-haskell-scala-clojure-elixir?slide=1&#34; style=&#34;width:100%;height:569px;background:#f0f0f0;display:flex;align-items:center;justify-content:center;color:#666;&#34;&gt;Loading...&lt;/div&gt;
    &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;部分適用や関数合成やパイプ演算子などElmで便利だった言語機能を思い出しながら聞いていた。&lt;/p&gt;
&lt;p&gt;文法を見ていると、Elmの文法はかなりHaskellに近いようだった。(ML系と呼ばれるらしい)&lt;/p&gt;
&lt;p&gt;あとは関数型かつ動的型付け言語の実際のアプリケーション開発での書き味が全然想像がつかないのでちょっとElixirやClojureを書いてみたくなった。質疑応答でも触れられていたが、実際にML系の言語とlispなどの動的型付け言語の関数型言語ではメンタルモデルが違うらしい。&lt;/p&gt;
&lt;p&gt;発表の最後に関数型プログラマのメンタルモデルとして以下のようなことを紹介されていて、自分が関数型言語から得た学びと重なる部分が多かった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;適切な制約が解放をもたらす
&lt;ul&gt;
&lt;li&gt;純粋関数を基本にしてコードを組み立てていく&lt;/li&gt;
&lt;li&gt;いつでもどこでも破壊的に更新できるデータ構造は怖いため不変/永続データを基本に&lt;/li&gt;
&lt;li&gt;適切な型を定義することで不正値を表現不能にしてより型安全に&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;単純で安定したブロックを基礎に全体を構成したい
&lt;ul&gt;
&lt;li&gt;式思考、宣言的、合成可能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;関数型言語を採用し維持し継続する---松澤-有さん&#34;&gt;関数型言語を採用し、維持し、継続する - 松澤 有さん&lt;/h2&gt;
&lt;p&gt;Siiibo証券株式会社のCTOである松澤さんによる自社プロダクトのフロントエンド、バックエンドの開発言語として関数型言語(Elm, Elixir)をなぜ採用したのか、そしていかにして維持し、継続しているかについての発表。実は主にこの発表を聞くために関数型まつりに参加したので良い発表を聞けてよかった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://zenn.dev/siiibo_tech/articles/adopting-fp-languages&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://zenn.dev/siiibo_tech/articles/adopting-fp-languages&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://res.cloudinary.com/zenn/image/upload/s--264zsvWh--/c_fit%2Cg_north_west%2Cl_text:notosansjp-medium.otf_55:%25E9%2596%25A2%25E6%2595%25B0%25E5%259E%258B%25E8%25A8%2580%25E8%25AA%259E%25E3%2582%2592%25E6%258E%25A1%25E7%2594%25A8%25E3%2581%2597%25E3%2580%2581%25E7%25B6%25AD%25E6%258C%2581%25E3%2581%2597%25E3%2580%2581%25E7%25B6%2599%25E7%25B6%259A%25E3%2581%2599%25E3%2582%258B%2Cw_1010%2Cx_90%2Cy_100/g_south_west%2Cl_text:notosansjp-medium.otf_34:Yu%2520Matsuzawa%2Cx_220%2Cy_108/bo_3px_solid_rgb:d6e3ed%2Cg_south_west%2Ch_90%2Cl_fetch:aHR0cHM6Ly9zdG9yYWdlLmdvb2dsZWFwaXMuY29tL3plbm4tdXNlci11cGxvYWQvYXZhdGFyLzBmMzgxMmZkZWEuanBlZw==%2Cr_20%2Cw_90%2Cx_92%2Cy_102/co_rgb:6e7b85%2Cg_south_west%2Cl_text:notosansjp-medium.otf_30:Siiibo%25E3%2583%2586%25E3%2583%2583%25E3%2582%25AF%25E3%2583%2596%25E3%2583%25AD%25E3%2582%25B0%2Cx_220%2Cy_160/bo_4px_solid_white%2Cg_south_west%2Ch_50%2Cl_fetch:aHR0cHM6Ly9saDMuZ29vZ2xldXNlcmNvbnRlbnQuY29tL2EtL0FPaDE0R2dwd3pXbm9hSUl4bEVZcUtBSnRicVVheWljRmlJVExYVGZNN0EyPXMyNTAtYw==%2Cr_max%2Cw_50%2Cx_139%2Cy_84/v1627283836/default/og-base-w1200-v2.png?_a=BACAGSGT&#34; alt=&#34;関数型言語を採用し、維持し、継続する&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;関数型言語を採用し、維持し、継続する&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://zenn.dev/siiibo_tech/articles/adopting-fp-languages&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;結局はラストマンシップを持って自分がなんとかするという気概が重要だという話が一番印象的だった。これは関数型言語を業務で書いているわけではない自分にも大いに参考になる話だと思っていて、結局どんな技術を採用したかやCTOかメンバーかなどにかかわらず、このラストマンシップを持っているエンジニアが多ければ多いほど開発組織は強固になるんだろうなと思った。&lt;/p&gt;
&lt;p&gt;また「アウトリーチを怠らなければ意外と世の中にちゃんと仲間はいる」ということをおっしゃっていて、使用言語がメインストリームであろうとなかろうと外部発信を通してコミュニティに貢献したり認知を獲得することの重要性を改めて感じた。やっていき。&lt;/p&gt;
&lt;p&gt;総じて松澤さんのエンジニアとしてのマインドセット的な部分がとても参考になった。&lt;/p&gt;
&lt;p&gt;技術的な内容に関しては、コードレビューの話とUpkeepの話が参考になった。&lt;/p&gt;
&lt;p&gt;コードレビューに関しては以下のようなことをおっしゃっていて、とても参考になった。特に2番目に関しては、前提としてコード品質を重要視するマインドがチームに装備されている必要があると思っていて、それをどう実現しているのか気になった。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自分がいいと思う技術であっても、それを伝道できなければあとが続かない&lt;/li&gt;
&lt;li&gt;チームにとって良いコードとはどのようなものか、ということを感覚、信念として共有できる状態に持っていくことを目指している&lt;/li&gt;
&lt;li&gt;人は忘れるし、一度言っただけで身につくことは誰であれないので繰り返し伝えていくことが重要&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Upkeepとは維持費の意味で、ここでは依存ライブラリや言語自体のバージョンアップなどのことを指す。こまめにバージョンアップ作業をやっておくことでいざというときに言語やライブラリの新機能をすぐ取り込めたり、巨大なバージョンアップのせいでデグレするリスクを低減できたりと良いこと尽くめだと改めて感じた。（もちろん簡単ではないが）&lt;/p&gt;
&lt;p&gt;あとはバージョンを最新に保つという行為に名前をつけたことがなかったのでUpkeepという語で表現するのはいいなーと思った。&lt;/p&gt;
&lt;p&gt;以下発表を聞きながら取ったメモ。(発表を聞きつつスライドを見ながら書いたメモなので誤りが含まれる場合があります🙇)&lt;/p&gt;
&lt;h3 id=&#34;技術選定の方針&#34;&gt;技術選定の方針&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;CTO, Founding Engineerが技術構成を選ぶにあたっての観点
&lt;ul&gt;
&lt;li&gt;まともなモノを継続的に提供するに足る機能があるか&lt;/li&gt;
&lt;li&gt;それを実際につくるヒトを継続的に集められるか&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;（スタートアップなら）
&lt;ul&gt;
&lt;li&gt;（上記2点を説得材料として）カネを集められるか&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;非メインストリーム言語でどうやっていくか&#34;&gt;非メインストリーム言語でどうやっていくか&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ElixirやElmはメインストリームと目されているとは言えず、モノ・ヒト・カネの要素を自信を持って揃えるには弱い&lt;/li&gt;
&lt;li&gt;とはいえ、良いと感じた技術があって、良いものを作れると検証できたのであればあとは自分がやるかどうかでしかない
&lt;ul&gt;
&lt;li&gt;勝手に機会は降ってこない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;勇気と周りを巻き込んで走り続ける力が重要&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;コードレビューの技術&#34;&gt;コードレビューの技術&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;自分がいいと思う技術であっても、それを伝道できなければあとが続かない&lt;/li&gt;
&lt;li&gt;健全で有意義なコードレビューのやり取りがどのようなものか？という経験とその内面化が重要&lt;/li&gt;
&lt;li&gt;どういうコードがチームにとって良いコードかを伝道する
&lt;ul&gt;
&lt;li&gt;感覚、信念として共有できる状態に持っていきたい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;以下の理由でコードレビューで繰り返し伝えていくことが重要
&lt;ul&gt;
&lt;li&gt;人は忘れる&lt;/li&gt;
&lt;li&gt;新しい人は入る&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;一度言っただけで身につくことは誰であれ、ない&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;upkeep&#34;&gt;Upkeep&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Upkeepとは維持費の意味で、ここでは依存ライブラリや言語自体のバージョンアップなどのことを指す。&lt;/li&gt;
&lt;li&gt;Upkeep恐怖症にならずにこまめにやれる環境をつくる。&lt;/li&gt;
&lt;li&gt;(バージョンアップ作業がやりやすいのは言語の大きな加点項目)&lt;/li&gt;
&lt;li&gt;Elixirで静的型検査の導入が2022年に発表された
&lt;ul&gt;
&lt;li&gt;Upkeepしておくと、こういった新機能もすぐに取り込める&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;情報収集&#34;&gt;情報収集&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;言語公式フォーラム, ML, Slack, Discordのウォッチ
&lt;ul&gt;
&lt;li&gt;そもそもコミュニティがデカすぎないので最新動向をすべて追うのがそこまで大変ではない&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コンパイラ、主要ライブラリのissue trackerも購読する
&lt;ul&gt;
&lt;li&gt;チーム内で抱えてる課題と似たような話題も出たりする&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Twitter&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;コミュニティ還元&#34;&gt;コミュニティ還元&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;フォーラムでの質問を見るだけでなく回答もする
&lt;ul&gt;
&lt;li&gt;小さいコミュニティなので自分が第一人者、Front Runnerである可能性もある&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;国内外の勉強会参加、主催協力も積極的に行う&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;採用&#34;&gt;採用&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;やれることをやり、アウトリーチもすることが採用に直結する&lt;/li&gt;
&lt;li&gt;非メインストリーム言語だとその言語を業務で書くにはそもそも会社の選択肢が少なかったりするので、意外とマッチングしやすかったりもする&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;続けていく気概&#34;&gt;続けていく気概&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;結局大事なのは言いだしっぺがケツを持つ気概があるかどうか&lt;/li&gt;
&lt;li&gt;アウトリーチを怠らなければ意外と世の中にちゃんと仲間はいる&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;産業機械をelixirで制御する---菊池-豊さん&#34;&gt;産業機械をElixirで制御する - 菊池 豊さん&lt;/h2&gt;
&lt;p&gt;菊池 豊さんによる複数の水力発電の制御ソフトウェアをElixirで書いた経験を紹介する発表。&lt;/p&gt;
&lt;p&gt;Elixirは書きやすく、コミュニティも盛り上がっているという話を聞いてちょっと書いてみたくなった。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;h3 id=&#34;課題&#34;&gt;課題&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python
&lt;ul&gt;
&lt;li&gt;並行プログラミングができなかった&lt;/li&gt;
&lt;li&gt;コンパイラでの支援が期待できなかった&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;リプレイス先の候補はGo, Rust, Haskell, Erlang, Elm
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://qiita.com/kikuyuta/items/96c3f91a850e9274b0e9&#34; target=&#34;_blank&#34; &gt;Elixir を使うようになった経緯 〜電力システム制御の現場から〜&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;why-elixir&#34;&gt;Why Elixir&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;世俗型関数型言語
&lt;ul&gt;
&lt;li&gt;関数型であることにこだわりすぎず使いやすさがある&lt;/li&gt;
&lt;li&gt;コミュニティも楽しかった&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;並行性
&lt;ul&gt;
&lt;li&gt;アクターモデル&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;パイプ演算子&lt;/li&gt;
&lt;li&gt;パターンマッチ&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;elixirにないもの&#34;&gt;Elixirにないもの&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;型
&lt;ul&gt;
&lt;li&gt;静的型解析がほしい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;lean言語は新世代の純粋関数型言語になれるか---井上亜星さん&#34;&gt;Lean言語は新世代の純粋関数型言語になれるか？ - 井上亜星さん&lt;/h2&gt;
&lt;p&gt;井上亜星さんによるLean言語の紹介の発表。&lt;/p&gt;
&lt;p&gt;この発表でLean言語という言語の存在を知った。純粋関数型言語でありながらforループやwhileループを書けるのはユニークだなーと思った。&lt;/p&gt;
&lt;h2 id=&#34;what-i-have-learned-from-15-years-of-functional-programming---scott-wlaschinさん&#34;&gt;What I have learned from 15 years of functional programming - Scott Wlaschinさん&lt;/h2&gt;
&lt;p&gt;Scott Wlaschinさんによる関数型プログラミングでの学びを共有する発表。&lt;/p&gt;
&lt;p&gt;「直和型とレコード型を駆使しドメインモデリングを正確に表現することで保守性が向上するだけでなく動作可能なドキュメントとしても機能する」という話が印象に残った。&lt;/p&gt;
&lt;p&gt;前者のメリットは以前から感じていたが、後者の観点はなかったので面白かった。（言われてみればそれはそうという感じだが）&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;パイプライン指向で書くことで保守性の高いコードを書くことができる
&lt;ul&gt;
&lt;li&gt;以前はSOLID原則を満たすことを意識しすぎてしまいうまくいかなかったが、パイプライン的な志向でコードを書くことで自然と綺麗なコードを書くことができ、SOLID原則も自然と満たすことができるようになったとのこと&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ドメインモデリング
&lt;ul&gt;
&lt;li&gt;直和型をうまく使ってドメインモデルを正確に表現する
&lt;ul&gt;
&lt;li&gt;保守性が高くなり、バグが減る&lt;/li&gt;
&lt;li&gt;実行可能なドキュメントとしても機能する&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Railway Oriented Programmingを使うことでエラー処理を伴う処理を保守性高く書くことができる&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fの設計と妥協点---net上で実現する関数型パラダイム---猪股-健太郎さん&#34;&gt;F#の設計と妥協点 - .NET上で実現する関数型パラダイム - 猪股 健太郎さん&lt;/h2&gt;
&lt;p&gt;猪股 健太郎さんによるF#の言語設計の特徴、設計意図を紹介する発表。&lt;/p&gt;
&lt;p&gt;純粋関数型言語なのかと思っていたが、命令形っぽい書き方もできることは知らなかった。他の.NET言語との相互運用性があるのも便利そう。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;h3 id=&#34;概要&#34;&gt;概要&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;OCamlに大きな影響を受けている&lt;/li&gt;
&lt;li&gt;金融工学、データサイエンス、科学計算、Webアプリなどで活用されている&lt;/li&gt;
&lt;li&gt;F#をJavaScriptにトランスパイルするコンパイラもあり、フロントエンドも書ける&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;fの特徴&#34;&gt;F#の特徴&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;静的型付けの非純粋関数型言語である。
&lt;ul&gt;
&lt;li&gt;デフォルトはイミュータブルだがmutableにもできる&lt;/li&gt;
&lt;li&gt;.NETランタイムは仮想マシン型
&lt;ul&gt;
&lt;li&gt;C#, F#など複数言語を.NETランタイム上で動かす前提で設計されており共通中間言語、共通型システム、共通言語仕様を備える&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ホスト環境との相互運用性
&lt;ul&gt;
&lt;li&gt;F#で書かれたコードは他の.NET言語から自然かつ安全に利用可能&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;マルチパラダイム言語
&lt;ul&gt;
&lt;li&gt;関数型プログラミングのパラダイムを核に、オブジェクト指向プログラミングの要素も備える&lt;/li&gt;
&lt;li&gt;クラスや構造体も書ける&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;言語設計の意図&#34;&gt;言語設計の意図&lt;/h3&gt;
&lt;p&gt;プログラマーが命令的なコーディングから関数型のコーディングへ移行する際のハードルを下げることを意識した設計になっているらしい。&lt;/p&gt;
&lt;h2 id=&#34;マイクロサービス内で動くapiをfで書いている---ayato-pさん&#34;&gt;マイクロサービス内で動くAPIをF#で書いている - ayato-pさん&lt;/h2&gt;
&lt;p&gt;ayato-pさんによるマイクロサービスの1サービスをF#で書く際の設計や悩みどころを紹介する発表。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;embed-container speakerdeck&#34;&gt;
        &lt;iframe src=&#34;https://speakerdeck.com/player/9efe648f23514385a48f5c5608d5f1c3&#34; allowfullscreen=&#34;true&#34; mozallowfullscreen=&#34;true&#34; webkitallowfullscreen=&#34;true&#34;&gt;&lt;/iframe&gt;
      &lt;/div&gt;&lt;/p&gt;
&lt;p&gt;ドメイン設計の際に容易にOptionを使わずにenumの別のvariantとして表現する、という考え方はRustなどでも活かせそうだと思った。別の概念であれば別の型として表現するのが大事そう。&lt;/p&gt;
&lt;p&gt;以下メモ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;どんなチームで採用したのか
&lt;ul&gt;
&lt;li&gt;ペアプログラミングを中心に100人超の組織で開発している&lt;/li&gt;
&lt;li&gt;モノリス -&amp;gt; マイクロサービスの移行をやっている&lt;/li&gt;
&lt;li&gt;マイクロサービスの各APIは多種多様な言語で書かれている&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F#導入以前のプロダクトチーム
&lt;ul&gt;
&lt;li&gt;JVM系、Elixir, Go, Rust, OCaml, Haskellなども採用&lt;/li&gt;
&lt;li&gt;.NET系の言語は採用されていなかった&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;どう導入したのか
&lt;ul&gt;
&lt;li&gt;システムのコアにいきなり採用するのはリスキーだったのでなにかあってもまずは影響が少ないサブシステムで採用&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;なぜF#か
&lt;ul&gt;
&lt;li&gt;静的型付け&lt;/li&gt;
&lt;li&gt;シンタックスが簡素&lt;/li&gt;
&lt;li&gt;.NETの資産を活用できる&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;F#らしさを活かした設計
&lt;ul&gt;
&lt;li&gt;Optionなどを入れずに判別共用体を使って設計する&lt;/li&gt;
&lt;li&gt;e.g. 上場企業と非上場企業を表現するときに&lt;code&gt;isListed: bool&lt;/code&gt;, &lt;code&gt;listedAt: Option&amp;lt;DateTime&amp;gt;&lt;/code&gt;のように表現するのではなく&amp;hellip;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fsharp&#34; data-lang=&#34;fsharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Company&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; id&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; CompanyId
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    isListed&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    listedAt&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; Option&lt;span style=&#34;color:#f92672&#34;&gt;&amp;lt;&lt;/span&gt;DateTime&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;そもそも別のvariantとして表現する
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-fsharp&#34; data-lang=&#34;fsharp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Listed&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; Listed &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; listedAt&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; DateTime
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;CompanyProfile&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;{&lt;/span&gt; id&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; CompanyId
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;[&amp;lt;&lt;/span&gt;RequireQualifiedAccess&lt;span style=&#34;color:#f92672&#34;&gt;&amp;gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;Company&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; Listed &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; CompanyProfile &lt;span style=&#34;color:#f92672&#34;&gt;*&lt;/span&gt; Listed
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;|&lt;/span&gt; UnListed &lt;span style=&#34;color:#66d9ef&#34;&gt;of&lt;/span&gt; CompanyProfile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;スポンサーブース&#34;&gt;スポンサーブース&lt;/h2&gt;
&lt;p&gt;Jane Streetのエンジニアの方にお聞きしたがJane StreetではフロントエンドとサーバーサイドをOCamlで書いているらしい（！）ブースでお話した方も関数型言語が書きたくて入社したそうで、関数型言語への愛を感じた。&lt;/p&gt;
&lt;p&gt;ブースでいただいたノベルティのTシャツもめっちゃOCamlだった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;jane-street.webp&#34; alt=&#34;jane-street&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;ノベルティ&#34;&gt;ノベルティ&lt;/h2&gt;
&lt;p&gt;入場時にロゴ入りのトートバッグがもらえた。
&lt;img src=&#34;bag.webp&#34; alt=&#34;bag&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;Nulabさんのノベルティのマイクロファイバークロス。実用的でありがたい。
&lt;img src=&#34;nulab.webp&#34; alt=&#34;nulab&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;今は業務で関数型言語を使うことはないが、関数型言語の考え方を取り入れることで非関数型言語でもより良いコードを書けるようになると改めて感じた。&lt;/p&gt;
&lt;p&gt;個人で初めてオフラインの勉強会/カンファレンスに参加したが普通に楽しかったのでまた行ってみようと思う。&lt;/p&gt;
&lt;h2 id=&#34;つけ麺情報&#34;&gt;つけ麺情報&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://tabelog.com/tokyo/A1319/A131902/13115487&#34; target=&#34;_blank&#34; &gt;二代目えん寺&lt;/a&gt;がとても美味しかった。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;tsukemen.webp&#34; alt=&#34;tsukemen&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://sporto.github.io/elm-patterns/advanced/railway.html&#34; target=&#34;_blank&#34; &gt;Elm Patternsでも紹介されていた&lt;/a&gt;のを思い出した。改めて読み直してみよう。&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>cargoプロジェクトで依存関係を継続的に管理する</title>
      <link>https://blog.kyu08.com/pr-344/posts/manage-cargo-dependencies/</link>
      <pubDate>Tue, 20 May 2025 15:00:00 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/manage-cargo-dependencies/</guid>
      <description>OSSに依存するプロジェクトでは依存しているライブラリのライセンス表記が必要になることがある。（体感的にはほとんどのライブラリはライセンス表</description>
      <content>&lt;p&gt;OSSに依存するプロジェクトでは依存しているライブラリのライセンス表記が必要になることがある。（体感的にはほとんどのライブラリはライセンス表記を求めているように思う）&lt;/p&gt;
&lt;p&gt;そのため、依存ライブラリが増えた場合にはライセンス表記を更新する必要があるが、依存ライブラリの依存ライブラリに対しても再帰的にライセンス表記を見に行って自リポジトリの依存ライセンス表記ファイルを更新して&amp;hellip;という作業を行うのは現実的ではない。&lt;/p&gt;
&lt;p&gt;他にもうっかりコピーレフトなライブラリに依存してしまうとプロジェクトのライセンスを変更しなければならなかったりと案外注意すべきポイントが多い。&lt;/p&gt;
&lt;p&gt;cargoプロジェクトにおいてこれらの労力を削減してくれるツールがいくつか存在している。&lt;/p&gt;
&lt;p&gt;筆者は趣味プロジェクトとして&lt;code&gt;fzf-make&lt;/code&gt;というmake targetやpnpm script, yarn script, just recipeをfuzzy finder形式で選択、実行できるCLIツール&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;をRustで開発しており、このプロジェクトで最近それらのツールを導入したので使い方とともに紹介する。&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;以下のチェックをCIで実行することでcargoプロジェクトの依存関係を継続的に省力で管理できる。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/bnjbvr/cargo-machete&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;cargo-machete&lt;/code&gt;&lt;/a&gt;: 不要な依存関係がないか&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-deny&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;cargo-deny&lt;/code&gt;&lt;/a&gt;: 依存ライブラリに許容しないライセンスが含まれていないか&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-about&#34; target=&#34;_blank&#34; &gt;&lt;code&gt;cargo-about&lt;/code&gt;&lt;/a&gt;: リポジトリのライセンス表記ファイルに更新漏れがないか&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;それぞれ紹介する。なお、コード例はそれぞれ以下のランナーを想定している。&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;環境&lt;/th&gt;
&lt;th&gt;ランナー&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ローカル&lt;/td&gt;
&lt;td&gt;make&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI&lt;/td&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;cargo-macheteで不要な依存関係を検出する&#34;&gt;&lt;code&gt;cargo-machete&lt;/code&gt;で不要な依存関係を検出する&lt;/h2&gt;
&lt;h3 id=&#34;why&#34;&gt;why&lt;/h3&gt;
&lt;p&gt;ある程度の期間開発を続けていると以前追加した依存関係が不要になったことに気付かずに&lt;code&gt;cargo.toml&lt;/code&gt;の&lt;code&gt;dependencies&lt;/code&gt;や&lt;code&gt;dev-dependencies&lt;/code&gt;に残ったままになることがある。
不要な依存関係が残ったままになっているとrenovateやdependabotによるバージョン更新の手間が不必要に増えてしまうのでPRの時点で気付けるようにしたい。&lt;/p&gt;
&lt;h3 id=&#34;what&#34;&gt;what&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/bnjbvr/cargo-machete&#34; target=&#34;_blank&#34; &gt;cargo-machete&lt;/a&gt;を使って&lt;code&gt;cargo.toml&lt;/code&gt;に記述されている依存関係のうち、プロジェクトが実際には依存していない依存関係を検出する。&lt;/p&gt;
&lt;h3 id=&#34;howローカル&#34;&gt;how(ローカル)&lt;/h3&gt;
&lt;p&gt;以下のようなmake targetを定義しておくと&lt;code&gt;make detect-unused-dependencies&lt;/code&gt;で不要な依存関係を検出できる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-detect-unused-dependencies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;tool-detect-unused-dependencies&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@if ! which cargo-machete &amp;gt; /dev/null; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;		cargo install --locked cargo-machete; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; detect-unused-dependencies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;detect-unused-dependencies&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-detect-unused-dependencies
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	cargo machete
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;以下は不必要な依存関係として&lt;code&gt;tempfile&lt;/code&gt;が検出されている様子。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;cargo-machete.webp&#34; alt=&#34;cargo-machete&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;howci&#34;&gt;how(CI)&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを定義しておくと不要な依存関係がある場合にCIが落ちてくれる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Detect unused dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;pull_request&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;detect-unused-dependencies&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Checkout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Machete&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;bnjbvr/cargo-machete@v0.8.0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cargo-denyで依存ライブラリに許容しないライセンスが含まれていないか検証する&#34;&gt;&lt;code&gt;cargo-deny&lt;/code&gt;で依存ライブラリに許容しないライセンスが含まれていないか検証する&lt;/h2&gt;
&lt;h3 id=&#34;why-1&#34;&gt;why&lt;/h3&gt;
&lt;p&gt;筆者は&lt;code&gt;fzf-make&lt;/code&gt;をより自由に利用してほしいと考えているためMITライセンスでプロジェクトを公開したい。
コピーレフトのライセンスに依存してしまうとライセンス変更を余儀なくされるため、コピーレフトのライブラリに依存することを避けたい。&lt;/p&gt;
&lt;h3 id=&#34;what-1&#34;&gt;what&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-deny&#34; target=&#34;_blank&#34; &gt;cargo-deny&lt;/a&gt;は依存関係のlint機能を提供する。&lt;code&gt;fzf-make&lt;/code&gt;では、&lt;code&gt;cargo deny check licenses&lt;/code&gt;を用いてホワイトリストに登録したライセンス以外のライセンスが依存ライブラリに含まれていないか検証している。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-toml&#34; data-lang=&#34;toml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#75715e&#34;&gt;# deny.toml&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[&lt;span style=&#34;color:#a6e22e&#34;&gt;licenses&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;allow&lt;/span&gt; = [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;MIT&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ISC&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Apache-2.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;MPL-2.0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;BSD-2-Clause&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;BSD-3-Clause&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;Unicode-DFS-2016&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;OpenSSL&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;confidence-threshold&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;0.8&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;exceptions&lt;/span&gt; = []
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;[[&lt;span style=&#34;color:#a6e22e&#34;&gt;licenses&lt;/span&gt;.&lt;span style=&#34;color:#a6e22e&#34;&gt;clarify&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;name&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;ring&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;expression&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;MIT AND ISC AND OpenSSL&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;license-files&lt;/span&gt; = [
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { &lt;span style=&#34;color:#a6e22e&#34;&gt;path&lt;/span&gt; = &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;LICENSE&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a6e22e&#34;&gt;hash&lt;/span&gt; = &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;xbd0eed23&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;howローカル-1&#34;&gt;how(ローカル)&lt;/h3&gt;
&lt;p&gt;以下のようなmake targetを定義しておくと&lt;code&gt;make check-licenses&lt;/code&gt;で依存ライブラリに許容しないライセンスが含まれていないかを検証できる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-check-licenses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;tool-check-licenses&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@if ! which cargo-deny &amp;gt; /dev/null; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;		cargo install --locked cargo-deny; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; check-licenses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;check-licenses&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-check-licenses
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	cargo deny check licenses
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;許可していないライセンスのライブラリに依存していることがわかると以下のようなエラーが出力される。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;cargo-deny.webp&#34; alt=&#34;cargo-deny.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h3 id=&#34;howci-1&#34;&gt;how(CI)&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを定義しておくと不要な依存関係があるとCIが落ちてくれる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check licenses&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;pull_request&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;check-licenses&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;EmbarkStudios/cargo-deny-action@v2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#f92672&#34;&gt;with&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;command&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;check licenses&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;cargo-aboutでリポジトリのライセンス表記が最新か検証する&#34;&gt;&lt;code&gt;cargo-about&lt;/code&gt;でリポジトリのライセンス表記が最新か検証する&lt;/h2&gt;
&lt;h3 id=&#34;why-2&#34;&gt;why&lt;/h3&gt;
&lt;p&gt;冒頭でも触れた通り、多くのOSSでは依存ライブラリのライセンス表記を求めている。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fzf-make&lt;/code&gt;では&lt;code&gt;CREDITS.html&lt;/code&gt;というファイルを用意しておりそこに依存ライブラリのライセンス表記を記載している。&lt;/p&gt;
&lt;p&gt;これまでは依存ライブラリを追加/削除した際に手作業でライセンス表記ファイルを更新していたが、漏れがちになっていた。&lt;/p&gt;
&lt;p&gt;また、本来は依存ライブラリの依存ライブラリを再帰的にチェックしてすべてのライセンス表記をすべきなのだと思うが、手作業でそれをする気にはなれなかったので直接依存しているライブラリのライセンスしか表記できていなかった。&lt;/p&gt;
&lt;p&gt;これらの課題を&lt;code&gt;cargo-about&lt;/code&gt;を用いることで解決できそうだったので導入してみた。&lt;/p&gt;
&lt;h3 id=&#34;what-2&#34;&gt;what&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-about&#34; target=&#34;_blank&#34; &gt;cargo-about&lt;/a&gt;は依存ライブラリのライセンス表記ファイルを自動生成する機能を提供する。&lt;/p&gt;
&lt;p&gt;以下のようなテンプレートを用意し、&lt;code&gt;cargo about generate about.hbs &amp;gt; CREDITS.html&lt;/code&gt;を実行すると&lt;code&gt;CREDITS.html&lt;/code&gt;にライセンス表記を出力してくれる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;style&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            @&lt;span style=&#34;color:#66d9ef&#34;&gt;media&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;prefers-color-scheme&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#f92672&#34;&gt;dark&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;)&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;background&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;#333&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;white&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &lt;span style=&#34;color:#66d9ef&#34;&gt;color&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;skyblue&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            .&lt;span style=&#34;color:#a6e22e&#34;&gt;container&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;font-family&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;sans-serif&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;max-width&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;800&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;margin&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#66d9ef&#34;&gt;auto&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            .&lt;span style=&#34;color:#a6e22e&#34;&gt;intro&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;text-align&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;center&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            .&lt;span style=&#34;color:#a6e22e&#34;&gt;licenses-list&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;list-style-type&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;none&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;margin&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;padding&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            .&lt;span style=&#34;color:#a6e22e&#34;&gt;license-used-by&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;margin-top&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;-10&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            .&lt;span style=&#34;color:#a6e22e&#34;&gt;license-text&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;max-height&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;200&lt;/span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;px&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;overflow-y&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;scroll&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &lt;span style=&#34;color:#66d9ef&#34;&gt;white-space&lt;/span&gt;: &lt;span style=&#34;color:#66d9ef&#34;&gt;pre-wrap&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;style&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;head&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;main&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;container&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;intro&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;Third Party Licenses&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;This page lists the licenses of the projects used in fzf-make.&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;Overview of licenses:&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;licenses-overview&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{#each overview}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;#{{id}}&amp;#34;&lt;/span&gt;&amp;gt;{{name}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt; ({{count}})&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{/each}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;All license text:&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h2&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;licenses-list&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{#each licenses}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;license&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h3&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{id}}&amp;#34;&lt;/span&gt;&amp;gt;{{name}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h3&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h4&lt;/span&gt;&amp;gt;Used by:&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h4&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;license-used-by&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        {{#each used_by}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;href&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{#if crate.repository}} {{crate.repository}} {{else}} https://crates.io/crates/{{crate.name}} {{/if}}&amp;#34;&lt;/span&gt;&amp;gt;{{crate.name}} {{crate.version}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;a&lt;/span&gt;&amp;gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                        {{/each}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;pre&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;license-text&amp;#34;&lt;/span&gt;&amp;gt;{{text}}&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;pre&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;li&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                {{/each}}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;ul&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;main&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;body&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;html&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;howローカル-2&#34;&gt;how(ローカル)&lt;/h3&gt;
&lt;p&gt;以下のようなmake targetを定義しておくと&lt;code&gt;make update-license-file&lt;/code&gt;で依存ライブラリのライセンス表記が最新か検証できる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-makefile&#34; data-lang=&#34;makefile&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-update-license-file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;tool-update-license-file&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	@if ! which cargo-about &amp;gt; /dev/null; &lt;span style=&#34;color:#66d9ef&#34;&gt;then&lt;/span&gt; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;		cargo install --locked cargo-about; &lt;span style=&#34;color:#ae81ff&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#ae81ff&#34;&gt;&lt;/span&gt;	&lt;span style=&#34;color:#66d9ef&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;.PHONY&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; update-license-file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a6e22e&#34;&gt;update-license-file&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;:&lt;/span&gt; tool-update-license-file
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	cargo about generate about.hbs &amp;gt; CREDITS.html
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;howci-2&#34;&gt;how(CI)&lt;/h3&gt;
&lt;p&gt;以下のようなyamlを定義しておくと依存ライブラリのライセンス表記が最新でないとCIが落ちてくれる。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check license file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;on&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;push&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;branches&lt;/span&gt;: [ &lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;main&amp;#34;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;pull_request&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;jobs&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#f92672&#34;&gt;check-license-file&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;runs-on&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;ubuntu-latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#f92672&#34;&gt;steps&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Checkout&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;uses&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;actions/checkout@v4&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;run&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;make update-license-file&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#f92672&#34;&gt;name&lt;/span&gt;: &lt;span style=&#34;color:#ae81ff&#34;&gt;Check diff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#f92672&#34;&gt;run&lt;/span&gt;: |&lt;span style=&#34;color:#e6db74&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          git add .
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;          git diff --cached --exit-code&lt;/span&gt;          
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;なお、デフォルトだと以下の部分の&lt;code&gt;This page...fzf-make&lt;/code&gt;の部分が&lt;code&gt;This page lists the licenses of the projects used in cargo-about.&lt;/code&gt;として出力される。そのため、そのまま利用すると「&lt;code&gt;cargo-about&lt;/code&gt;プロジェクトでは以下のライセンスに依存しています」という意味の表示になってしまうためユーザーが忘れずに&lt;code&gt;cargo-about&lt;/code&gt;の部分をプロジェクト名に変更する必要があるという問題がある。&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt; &lt;span style=&#34;color:#a6e22e&#34;&gt;class&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;intro&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;Third Party Licenses&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;h1&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;This page lists the licenses of the projects used in fzf-make.&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;p&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;/&lt;span style=&#34;color:#f92672&#34;&gt;div&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;これに関しては以下のissueを立ててみたので&lt;code&gt;cargo-about&lt;/code&gt;側と意見が一致したら修正するPRを送ってみようと思う。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/EmbarkStudios/cargo-about/issues/281&#34; target=&#34;_blank&#34; &gt;[Feature request] change &lt;code&gt;cargo about init&lt;/code&gt; to generate the statement including user&amp;rsquo;s project name.&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;おわりに&#34;&gt;おわりに&lt;/h2&gt;
&lt;p&gt;繰り返しの定型タスクをCIに任せることができたので開発により集中できるようになった。（趣味開発だと数ヶ月ぶりにコミットするとかもザラにあり、開発に必要なタスクを忘れがちなのでそういった意味でも自動化の範囲を増やすことができてよかった）&lt;/p&gt;
&lt;p&gt;便利ツールをOSSとして公開してくれている人/企業に感謝しつつ利用するだけでなく自分にできる貢献はやっていきたい。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;code&gt;fzf-make&lt;/code&gt;の紹介記事: &lt;a href=&#34;https://zenn.dev/kyu08/articles/974fd8bc25c303&#34; target=&#34;_blank&#34; &gt;[make,pnpm,yarn,justに対応]コマンドをfuzzy finder形式で選択できるCLIツール fzf-makeの紹介&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;そして実際に&lt;a href=&#34;https://github.com/search?q=%22This&amp;#43;page&amp;#43;lists&amp;#43;the&amp;#43;licenses&amp;#43;of&amp;#43;the&amp;#43;projects&amp;#43;used&amp;#43;in&amp;#43;cargo-about.%22&amp;amp;type=code&#34; target=&#34;_blank&#34; &gt;90件近くのプロジェクトで&lt;code&gt;cargo-about&lt;/code&gt;のままになっている。&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>GitHub Sponsorsの寄付先にratatuiを追加した</title>
      <link>https://blog.kyu08.com/pr-344/posts/renew-oss-sponsoring/</link>
      <pubDate>Mon, 23 Sep 2024 15:02:46 +0000</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/renew-oss-sponsoring/</guid>
      <description>OSSへの寄付の月予算を$10にした - laiso こちらの記事で寄付するOSSプロジェクトの選び方として次のような基準が紹介されていた。 寄付するプロジ</description>
      <content>&lt;p&gt;&lt;a href=&#34;https://laiso.hatenablog.com/entry/2022/02/25/gihutown&#34; target=&#34;_blank&#34; &gt;OSSへの寄付の月予算を$10にした - laiso&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;こちらの記事で寄付するOSSプロジェクトの選び方として次のような基準が紹介されていた。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;寄付するプロジェクトはこういう基準で選んでる&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自分が使っていてなくなったら困る&lt;/li&gt;
&lt;li&gt;マイナーであまり寄付されていない&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;今まで前者の基準に則って&lt;a href=&#34;https://github.com/sponsors/neovim&#34; target=&#34;_blank&#34; &gt;neovim&lt;/a&gt;に寄付していたが、後者の観点を持てていなかったことに気付いた。そこで自分もOSSへの寄付を見直してみようと思った。&lt;/p&gt;
&lt;h2 id=&#34;というわけで&#34;&gt;というわけで&lt;/h2&gt;
&lt;p&gt;タイトルの通りだが、GitHub Sponsorsの寄付先に&lt;a href=&#34;https://github.com/sponsors/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;を追加した。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/ratatui/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;とは、手軽にTUIアプリケーションを作成できるRust用のライブラリで、筆者が個人開発しているOSSである&lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; &gt;fzf-make&lt;/a&gt;でも利用している。&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://raw.githubusercontent.com/kyu08/fzf-make/main/static/demo.gif&#34; alt=&#34;fzf-make-demo.gif&#34; loading=&#34;lazy&#34; /&gt;
&lt;a href=&#34;https://github.com/ratatui/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;のおかげでこんな感じのUIを手軽に実装できている。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;p&gt;Rust製のTUIツールでは非常に幅広く利用されている印象だが、現在のスポンサー数が9人と少なかったので少しでも力になれればということで寄付先に追加した。長期間メンテされる状態が続いてくれると嬉しい。自分にもできそうなバグ修正があれば挑戦してみようと思う。&lt;/p&gt;
&lt;!-- textlint-disable ja-technical-writing/ja-no-weak-phrase --&gt;
&lt;p&gt;&lt;img src=&#34;ratatuis-10th-sponsor.webp&#34; alt=&#34;ratatuis-10th-sponsor.webp&#34; loading=&#34;lazy&#34; /&gt;
10番目のスポンサーになった様子。&lt;/p&gt;
&lt;p&gt;これで現在の寄付額は$10/月で、&lt;a href=&#34;https://github.com/sponsors/neovim&#34; target=&#34;_blank&#34; &gt;neovim&lt;/a&gt;と&lt;a href=&#34;https://github.com/sponsors/ratatui&#34; target=&#34;_blank&#34; &gt;ratatui&lt;/a&gt;にそれぞれ$5ずつ寄付していることになる。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;github-sponsors-logos.webp&#34; alt=&#34;github-sponsors-logos.webp&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;他にも寄付したいプロジェクトは山ほどあるので山ほど稼いでいきたい。(あと円高頼む&amp;hellip;)&lt;/p&gt;
&lt;h2 id=&#34;まとめ&#34;&gt;まとめ&lt;/h2&gt;
&lt;p&gt;今後ともOSSコミュニティの持続可能性を高めていきたい。&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;make targetをプレビューウィンドウ付きであいまい検索によって選択&amp;amp;実行できるツール。brewやcargoでインストールできるのでぜひ。 &lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </item>
    
    <item>
      <title>Makefileに定義されたtargetをfzfで選択して実行するCLIツールをRustでつくった</title>
      <link>https://blog.kyu08.com/pr-344/posts/fzf-make/</link>
      <pubDate>Fri, 31 Mar 2023 01:15:48 +0900</pubDate>
      
      <guid>https://blog.kyu08.com/pr-344/posts/fzf-make/</guid>
      <description>(2024/12/14追記) 内容を更新した紹介記事をZennに投稿しました。 [make,pnpm,yarnに対応]タスクランナーのコマンドを</description>
      <content>&lt;blockquote&gt;
&lt;h1 id=&#34;20241214追記-内容を更新した紹介記事をzennに投稿しました&#34;&gt;(2024/12/14追記) 内容を更新した紹介記事をZennに投稿しました。&lt;/h1&gt;
&lt;p&gt;&lt;a href=&#34;https://zenn.dev/kyu08/articles/974fd8bc25c303&#34; target=&#34;_blank&#34; &gt;[make,pnpm,yarnに対応]タスクランナーのコマンドをfuzzy finder形式で選択できるCLIツール fzf-makeの紹介&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Makefileに定義されたtargetをfzfで選択して実行するCLIツールをRustでつくった。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;こんな感じで動く。&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;fzf-make-demo.gif&#34; alt=&#34;fzf-make-demo&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;h2 id=&#34;fzf-makeがやっていること&#34;&gt;fzf-makeがやっていること&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Makefile&lt;/code&gt;からtargetを正規表現で抜き出す&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skim&lt;/code&gt;(※)に実行オプションとtargetたちを渡す&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skim&lt;/code&gt;がプレビューウィンドウ付きのfuzzy-finderを表示&lt;/li&gt;
&lt;li&gt;&lt;code&gt;skim&lt;/code&gt;から選択されたtargetが返ってくるので&lt;code&gt;make ${target}&lt;/code&gt;を実行&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;基本的な動作はすべて&lt;code&gt;skim&lt;/code&gt;任せになっていてRust側でやっているのは&lt;code&gt;skim&lt;/code&gt;とのやりとりくらいになっている。&lt;/p&gt;
&lt;p&gt;※&lt;a href=&#34;https://github.com/lotabout/skim&#34; target=&#34;_blank&#34; &gt;lotabout/skim&lt;/a&gt;&amp;hellip;Rust製のfuzzy-finder。Rustのライブラリとして利用することもできる。&lt;/p&gt;
&lt;p&gt;(makeの文法が思ったより多彩っぽかったので自分が必要とするごく簡単なユースケース以外をカバーするのは&lt;a href=&#34;https://twitter.com/kyu08_/status/1639986936407531525&#34; target=&#34;_blank&#34; &gt;早々に諦めた。&lt;/a&gt;(makeで1冊本が書けるぐらいだしそれはそうという感じではある))&lt;/p&gt;
&lt;p&gt;brewコマンドでインストールできるので気になる方はぜひ。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew tap kyu08/tap
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;brew install kyu08/tap/fzf-make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ソースも公開しているので、「こう書くといいよ」とかバグとかありましたらぜひissueやPRで教えてください。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;GitHub - kyu08/fzf-make: A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task.&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;実装&#34;&gt;実装&lt;/h2&gt;
&lt;p&gt;上述の通り処理の大部分はskim任せになっている。(書いたコードはテストを含めても200行程度)&lt;/p&gt;
&lt;p&gt;ただskimをライブラリとして利用する実装サンプルがあまりなかったのがちょっと大変だった。特にプレビューウィンドウの表示にfzfの候補文字列を変数としたシェルコマンドの形で渡すことができることに気づくまでに時間がかかった&lt;/p&gt;
&lt;p&gt;↓の&lt;code&gt;{}&lt;/code&gt;にtarget名が入るイメージ。&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-rust&#34; data-lang=&#34;rust&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#66d9ef&#34;&gt;let&lt;/span&gt; preview_command &lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#e6db74&#34;&gt;r&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;line=$(bat Makefile | grep -nE &amp;#39;^{}\s*:&amp;#39; | sed -e &amp;#39;s/:.*//g&amp;#39;); bat --style=numbers --color=always --line-range $line: --highlight-line $line Makefile&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L18&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L18&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L18&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;p&gt;あとはgoでいつもやっている感じでテーブル駆動テストっぽくテストを書いてみた。可読性も保守性も高いので割と気に入っている。&lt;/p&gt;
&lt;p&gt;&lt;div class=&#34;blogcard&#34; data-url=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L145&#34; data-auto-fetch=&#34;false&#34;&gt;
  &lt;a href=&#34;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L145&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34; class=&#34;blogcard-link&#34;&gt;&lt;div class=&#34;blogcard-thumbnail&#34;&gt;
      &lt;img src=&#34;https://repository-images.githubusercontent.com/611369838/a30cf798-2e08-47a5-9443-978329275d2c&#34; alt=&#34;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&#34; loading=&#34;lazy&#34;&gt;
    &lt;/div&gt;&lt;div class=&#34;blogcard-content&#34;&gt;
      &lt;div class=&#34;blogcard-title&#34;&gt;fzf-make/src/misc.rs at 3a627d0a1aa75b1bf1ff87f3443f63393afbcf10 · kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-description&#34;&gt;A command line tool that executes commands using fuzzy finder with preview window for make, npm, pnpm, yarn, just and task. - kyu08/fzf-make&lt;/div&gt;&lt;div class=&#34;blogcard-url&#34;&gt;https://github.com/kyu08/fzf-make/blob/3a627d0a1aa75b1bf1ff87f3443f63393afbcf10/src/misc.rs#L145&lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;動機&#34;&gt;動機&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Rustが書きたかった。(以上)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最近Rustのやっていきが高まっており、&lt;a href=&#34;https://doc.rust-jp.rs/book-ja/&#34; target=&#34;_blank&#34; &gt;The Rust Programming Language&lt;/a&gt; を1周したので何か作ってみるぞーという機運とMakefileのターゲットをfuzzy-finderで絞り込めたら便利そうだなーという気持ちが重なったのでRustでfzf-makeを作ってみた。 (あとはskimの存在を知っていたのも大きい。)&lt;/p&gt;
&lt;p&gt;自分が欲しいCLIツールを手に入れつつRustの経験が積めたのでよかった。&lt;/p&gt;
&lt;p&gt;ちなみにRustに入門した直接的(?)なきっかけとしてはこのスライドを目にして、「Elmっぽい！楽しそう！」と思ったのが発端だった。Rustに興味を持っている人はぜひ読んでみて欲しい。&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://speakerdeck.com/estie/man-wochi-siteshi-merurust&#34; target=&#34;_blank&#34; &gt;満を持して始める Rust&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;rustを触ってみて感じたこと&#34;&gt;Rustを触ってみて感じたこと&lt;/h2&gt;
&lt;p&gt;Rustを触る前に持っていた印象は「コンパイルが通りずらく、安全性が高い」「関数型っぽい」という感じだった。&lt;/p&gt;
&lt;p&gt;実際に学んでみた印象は次のような感じ。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;関数型っぽい書き心地
&lt;ul&gt;
&lt;li&gt;特にenumとパターンマッチング,Option型 ,Result型, 式指向な考え方などの関数型っぽい言語機能や極力データをイミュータブルに扱う思想などが心地よかった。筆者が大好きな言語であるElm(ウェブブラウザベースのGUIを作成するための純粋関数型)の好きな部分をほとんど含んでたのでElmに近い感覚で書くことができた。(もちろん慣れてないこともあってElmよりも全然難しかったけど)&lt;/li&gt;
&lt;li&gt;(Elmが気になる方は&lt;a href=&#34;https://guide.elm-lang.jp/&#34; target=&#34;_blank&#34; &gt;Elm Guide&lt;/a&gt;がおすすめです)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;↑に近いがNull安全なことに加えて所有権などの概念のおかげでコンパイルが通りさえすればちゃんと動いてくれるという安心感がある。
&lt;ul&gt;
&lt;li&gt;リファクタもやりやすそう。(enumにバリアントを追加したとき、パターンマッチの全箇所を修正しないとコンパイルが通らなかったりすると思うので)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;開発体験が良い
&lt;ul&gt;
&lt;li&gt;エラーメッセージがとても丁寧。「ここがこう悪いで〜」とか「ここをこう直すとええで〜」みたいなことまでエラーメッセージに書いてくれてあるホスピタリティに感動した。こういったところもRustが生産性が高いと言われる所以なのかもしれない。&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;コミュニティの初学者をサポートする姿勢がすごい
&lt;ul&gt;
&lt;li&gt;RustのOSSプロジェクトへのcontributionについては &lt;a href=&#34;https://zenn.dev/fraternite/articles/4e11063bf05aac&#34; target=&#34;_blank&#34; &gt;rust-lang/rustへのcode contributionをはじめからていねいに&lt;/a&gt; が詳しいが、Rust製のOSSプロジェクトには&lt;code&gt;E-mentor&lt;/code&gt;というタグがありissueを進めるに当たってメンターが指針を記してくれているらしい。（&lt;a href=&#34;https://github.com/rust-lang/rust/issues/109099&#34; target=&#34;_blank&#34; &gt;https://github.com/rust-lang/rust/issues/109099&lt;/a&gt; これとかすごい。）&lt;/li&gt;
&lt;li&gt;いつかRustのOSSプロジェクトにもcontributionしてみたい&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;他の言語と比べて動くものをつくるまでに必要な学習コストは高いとは思うがRustをちゃんと書けるようになれば生産性高く安全なコードが書けると思うので必ずしも学習コストが高いとは言えないのかもしれない。（他の言語でも安全なコードを書くためには一定の学習や経験が必要だろうし）（※想像で喋っています）&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;総じて開発体験は良かったのでこれからもゆるゆるとRustの学習は続けていきたい。&lt;/p&gt;
&lt;h2 id=&#34;余談&#34;&gt;余談&lt;/h2&gt;
&lt;p&gt;テスト実行に &lt;a href=&#34;nextest-rs/nextest&#34; &gt;https://github.com/nextest-rs/nextest&lt;/a&gt; を使ってみたがテスト結果が見やすくて便利だった。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cargo run&lt;/code&gt;の結果
&lt;img src=&#34;cargo-run.webp&#34; alt=&#34;cargo run&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;cargo nextest run&lt;/code&gt;の結果
&lt;img src=&#34;nextest-run.webp&#34; alt=&#34;cargo nextest run&#34; loading=&#34;lazy&#34; /&gt;&lt;/p&gt;
&lt;p&gt;カラフルで見やすい。&lt;/p&gt;
</content>
    </item>
    
  </channel>
</rss>
