feature image

2025年8月24日 | ブログ記事

Don't Repeat Your Metadata | Nix+Cargoの統一的なメタデータ管理

もしあなたがこのような素晴らしいCargo.tomlを書いたとしよう。

[package]
name = "your-brilliant-app"
edition = "2024"
version = "1.0.0-alpha"
description = "A brilliant app that does something amazing."
authors = ["John Doe <john.doe@example.com>"]
license = "MIT OR Apache-2.0"
homepage = "https://example.com/your-brilliant-app"

しかし、これを配布する段になって、もう一度バージョンに説明、ライセンスにパッケージ名と入力するのは退屈だ。そこで、Nixを使ってCargo.tomlのような言語固有の設定ファイルとより一般的な形式のパッケージのメタデータを接続する。

本題

動機

Nixでは、(正確には、Nixpkgsは、) パッケージングの際に、パッケージを表現する辞書型のmetaキーにメタデータを含めるような仕組みになっている。例えば、slのメタデータは、

# Copyright (c) 2003-2025 Eelco Dolstra and the Nixpkgs/NixOS contributors
# Full license: https://github.com/NixOS/nixpkgs/blob/master/COPYING

# https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/sl/sl/package.nix

stdenv.mkDerivation rec {
  pname = "sl";
  version = "5.05";

# 中略

  meta = with lib; {
    description = "Steam Locomotive runs across your terminal when you type 'sl'";
    homepage = "http://www.tkl.iis.u-tokyo.ac.jp/~toyoda/index_e.html";
    license = rec {
      shortName = "Toyoda Masashi's free software license";
      fullName = shortName;
      url = "https://github.com/eyJhb/sl/blob/master/LICENSE";
    };
    maintainers = with maintainers; [ eyjhb ];
    platforms = platforms.unix;
    mainProgram = "sl";
  };
}

というように記述されている。Nixpkgsのようなソースコードを直接管理しないプロジェクトではメタデータをNix式にハードコードすることは自然かもしれないが、ソースコードの隣にあるflake.nixでパッケージをNix経由で配布する際には、フレームワーク側の設定ファイルとNix式の両方に同じメタデータを置くのは美しくない。

実装

完全な実装は https://github.com/comavius/dont-repeat-your-version-tag を参照のこと。

まず、Cargo.tomlの内容をNix式の世界に持ち込む必要がある。

# type: string
  cargo-toml-text = builtins.readFile ./Cargo.toml;
# type: attrset
  cargo-toml-parsed = builtins.fromTOML cargo-toml-text;
# あるいは、
# type: attrset
  cargo-toml = builtins.fromTOML (builtins.readFile ./Cargo.toml);

次に、stdenv.mkDerivationのメタデータをcargo-tomlから設定する。

rustPlatform.buildRustPackage {
  # `pname` and `version` are read from Cargo.toml.
  pname = cargo-toml.package.name;
  version = cargo-toml.package.version;

  src = ./.;
  cargoLock = {
    lockFile = ./Cargo.lock;
  };

  # Also, metadata is read from Cargo.toml.
  meta = with cargo-toml.package; {
    inherit description homepage;
    license.spdxId = license;
  };
};

実装が終わったので、実際にメタデータが正しく設定されているか確認する。

まずはstore pathから。

$ nix eval
«derivation /nix/store/bnjp5y0bdrrrg56w93nhlayrl3x1yq13-dry_metadata-1.0.0-alpha.drv»

Cargo.tomlに書かれたとおり、パッケージ名はdry_metadata、バージョンは1.0.0-alphaとなっている。

次はmetaを確認する。

$ nix eval ".#default.meta" --json | jq '.license'
{
  "spdxId": "CC-BY-SA-4.0"
}

こちらも確かに、Cargo.tomlと同じ値が設定されている。

課題

本稿ではSPDX License Identifierを挟むことでCargo.tomlのライセンス表記をNixの習慣に沿った形で渡すことができたが、Cargo.tomlにはフィールドがないもののNixでは習慣的に使われているライセンスへのリンクを設定することができなかった。SPDX Licence Listにあるライセンスの場合何らかの方法でIDからその他の情報への変換ができると思うので、機会があれば挑戦したい。

終わりに

このように、Nixを使うことで開発者体験を高めることができる。そんなNixのインストールはこちらから:

comavius icon
この記事を書いた人
comavius

この記事をシェア

このエントリーをはてなブックマークに追加
共有

関連する記事

2024年9月17日
1か月でゲームを作った #BlueLINE
Komichi icon Komichi
2024年8月21日
【最新版 / 入門】JUCEを使ってVSTプラグインを作ろう!!!!【WebView UI】
kashiwade icon kashiwade
2021年8月12日
CPCTFを支えたWebshell
mazrean icon mazrean
2022年9月26日
競プロしかシラン人間が web アプリ QK Judge を作った話
tqk icon tqk
2022年9月16日
5日でゲームを作った #tararira
Komichi icon Komichi
2024年12月11日
Nixで実行環境のライセンス違反を予防する話
comavius icon comavius
記事一覧 タグ一覧 Google アナリティクスについて 特定商取引法に基づく表記