.tool-versions徹底活用:asdfで実現するプロジェクト固有のバージョン管理とチーム開発

なぜ開発環境はいつも「カオス」なのか?

「あれ?このプロジェクト、Node.jsのバージョンが違うぞ…」「Rubyのバージョンアップしたら、別のプロジェクトが動かなくなった!」

複数のプロジェクトを掛け持ちする開発者なら、誰もが一度は経験する環境構築の課題。新しいメンバーがジョインするたびに、環境構築の手順書とにらめっこし、結局動かなくて半日潰れる…なんてことも珍しくありません。

この「環境依存の問題」は、開発効率を低下させ、チームの生産性に影響を与えています。

しかし、もしプロジェクトごとに最適なツールバージョンを自動で切り替え、チーム全員が同じ環境で開発できる効率的な仕組みがあったとしたらどうでしょう?

asdfの.tool-versionsファイルは、その解決策となります。

この記事では、asdfの.tool-versionsファイルを徹底的に活用し、プロジェクト固有のバージョン管理を確立する方法、そしてそれがチーム開発にどのような変革をもたらすのかを、具体的なシナリオを交えて解説します。

もう、環境構築で悩む日々とはお別れです!


対象読者

  • asdfを導入しているが、.tool-versionsファイルの活用方法について深く理解したい開発者
  • 複数のプロジェクトで異なるツールバージョンを管理する必要がある開発者
  • チーム開発において、開発環境の統一と再現性を高めたいと考えている開発者
  • CI/CDパイプラインでツールバージョンの管理を効率化したいと考えている開発者

目次


1. .tool-versionsファイルとは?asdfにおける役割と重要性

asdfは、Node.js、Python、Rubyなど、様々なプログラミング言語やツールを統一的に管理できるバージョンマネージャーです。
そのasdfの中核をなすのが、.tool-versionsファイルです。


1.1. asdfにおける役割と重要性

.tool-versionsファイルは、プロジェクトのルートディレクトリに配置されるシンプルなテキストファイルで、そのプロジェクトで使用するツールとそのバージョンを定義します。

asdfは、このファイルが存在するディレクトリ、またはその親ディレクトリを探索し、定義されたバージョンを自動的に適用します。

これにより、開発者はプロジェクトディレクトリに移動するだけで、そのプロジェクトに必要なツールバージョンが自動的に設定されるため、手動でのバージョン切り替えや、誤ったバージョンでの開発を防ぐことができます。


プロジェクトと.tool-versionsファイルの関係

asdfは、カレントディレクトリから親ディレクトリへと.tool-versionsファイルを探索し、最初に見つかったファイルを適用します。
この仕組みにより、プロジェクト全体で統一されたバージョン管理が可能になります。

例えば、以下のようなフォルダ構造を持つモノレポプロジェクトを考えてみましょう。
my-project/直下の.tool-versionsで共通のツールバージョンを定義し、各サブプロジェクトで必要に応じて上書きします。

my-project/
├── .tool-versions  (Node.js 18.x, Python 3.9.x)  <- プロジェクト共通のツールを定義
├── frontend/
   ├── .tool-versions (Node.js 20.x)  <- Node.jsバージョンを上書き
   └── package.json
├── backend/
   ├── .tool-versions (Python 3.10.x) <- Pythonバージョンを上書き
   └── requirements.txt
└── utils/
    ├── common_script.py  <- Pythonスクリプト
    └── cli_tool.js       <- Node.js CLIツール

この場合、asdfは以下のようにバージョンを適用します。

  • my-project/ ディレクトリにいる場合:
    • my-project/.tool-versions の設定 (Node.js 18.x, Python 3.9.x) が適用されます。
  • my-project/frontend/ ディレクトリにいる場合:
    • my-project/frontend/.tool-versions の設定 (Node.js 20.x) が適用されます。Pythonのバージョンはmy-project/.tool-versionsから継承されます。
  • my-project/backend/ ディレクトリにいる場合:
    • my-project/backend/.tool-versions の設定 (Python 3.10.x) が適用されます。Node.jsのバージョンはmy-project/.tool-versionsから継承されます。
  • my-project/utils/ ディレクトリにいる場合:
    • my-project/.tool-versions の設定 (Node.js 18.x, Python 3.9.x) がそのまま適用されます。これにより、utils/内のスクリプトはプロジェクト共通のツールバージョンで実行されることが保証されます。

このように、asdfの.tool-versionsファイルは、プロジェクト全体でのツールバージョンの一貫性を保ちつつ、特定のサブプロジェクトでは柔軟にバージョンを上書きできるという大きなメリットを提供します。

この関係を図で表現すると以下のようになります。

asdfの.tool-versionsファイルは、プロジェクト全体でのツールバージョンの一貫性を保ちつつ、特定のサブプロジェクトでは柔軟にバージョンを上書きできる

1.2. ファイルの構造と記述方法

.tool-versionsファイルの記述は非常にシンプルです。
各行に「ツール名 バージョン」の形式で記述します。

nodejs 18.17.1
python 3.10.12
ruby 3.2.2

この例では、Node.jsは18.17.1、Pythonは3.10.12、Rubyは3.2.2を使用することをasdfに指示しています。

バージョンは以下の形式で指定できます。

  • 10.15.0: 特定のバージョン。asdfがバイナリをダウンロードして使用します。
  • ref:v1.0.2-a または ref:39cb398vb39: GitHubのタグ、コミット、ブランチを指定してソースからコンパイルします。
  • path:~/src/elixir: カスタムコンパイルされたツールのパスを指定します。言語開発者などが利用します。
  • system: asdfが管理しない、システムにインストールされているツールバージョンを使用します。

また、複数のバージョンをスペースで区切って指定することも可能です。
例えば、Python 3.7.2を優先し、それが利用できない場合に2.7.15、さらにそれが利用できない場合にsystemのPythonを使用したい場合は、以下のように記述します。

python 3.7.2 2.7.15 system

.tool-versionsファイルにはコメントを含めることもできます。

# This is a comment
nodejs 18.17.1 # Node.js version for this project

プロジェクト構造における.tool-versionsファイルの例

前述の「プロジェクトと.tool-versionsファイルの関係」で示したモノレポプロジェクトの例を元に、各.tool-versionsファイルの内容を見てみましょう。

my-project/.tool-versions:
プロジェクト全体で共通して使用するNode.jsとPythonのバージョンを定義します。

nodejs 22.x
python 3.13.x

my-project/frontend/.tool-versions:
frontendプロジェクトで必要となるNode.jsのバージョンを、プロジェクトルートの設定を上書きして定義します。

nodejs 22.x

my-project/backend/.tool-versions:
backendプロジェクトで必要となるPythonのバージョンを、プロジェクトルートの設定を上書きして定義します。

python 3.13.x

my-project/utils/.tool-versions:
utilsディレクトリでは、プロジェクトルートの.tool-versionsで定義されたバージョンをそのまま継承するため、このファイルは不要です。asdfは親ディレクトリを探索し、my-project/.tool-versionsのバージョンを適用します。


2. プロジェクトローカルでのバージョン設定

asdfの大きな利点は、プロジェクトローカルでのバージョン管理にあります。


2.1. asdf set コマンドの使い方

特定のプロジェクトでツールバージョンを設定するには、プロジェクトのルートディレクトリでasdf setコマンドを使用します。

例えば、Node.jsの22.21.0をこのプロジェクトで使いたい場合:

cd your-project/
asdf set nodejs 22.21.0

このコマンドを実行すると、自動的に.tool-versionsファイルが作成(または更新)され、nodejs 22.21.0という行が追加されます。


2.2. .tool-versionsファイルの自動生成

asdf setコマンドは、.tool-versionsファイルが存在しない場合は新規作成し、既に存在する場合は指定されたツールとバージョンを追記または更新します。
これにより、手動でファイルを作成する手間が省け、常に正しい形式でバージョンが管理されます。


3. チーム開発における.tool-versionsの活用

.tool-versionsファイルは、個人開発だけでなく、チーム開発において大きな効果をもたらします。


3.1. Gitでの管理と共有

.tool-versionsファイルは、プロジェクトのコードベースの一部としてGitで管理し、チームメンバー間で共有することを推奨します。

リポジトリをクローンした開発者は、asdf installコマンドを実行するだけで、プロジェクトに必要なすべてのツールバージョンを一度にインストールできます。

# プロジェクトをクローン
git clone https://github.com/your-org/your-project.git
cd your-project/

# .tool-versionsに定義されたすべてのツールをインストール
asdf install

3.2. 開発環境の統一と再現性

.tool-versionsファイルを共有することで、チーム全員が常に同じツールバージョンで開発を行うことができます。

これは「私の環境では動くのに…といった環境依存のバグを減らし、開発の再現性を高めます。新しいメンバーのオンボーディングも、asdf installの一言で完了するため、スムーズになります。


3.3. Mermaid.jsによるワークフロー図の提案

チーム開発におけるasdfと.tool-versionsのワークフローを図解すると、以下のようになります。

チーム開発におけるasdfと.tool-versionsのワークフロー

4. .tool-versionsとグローバル設定の優先順位

asdfは、ツールバージョンの解決において明確な優先順位を持っています。
この優先順位を理解することで、意図しないバージョンが適用されるのを防ぎ、より堅牢な環境管理が可能になります。

優先度設定方法/場所説明
1 (最高).tool-versionsファイル (カレントディレクトリ)現在のディレクトリに存在する.tool-versionsファイルの設定が適用されます。
2.tool-versionsファイル (親ディレクトリ)カレントディレクトリにファイルがない場合、asdfは親ディレクトリを遡って.tool-versionsファイルを探索し、最初に見つかったファイルの設定を適用します。
3ASDF_TOOL_VERSIONS環境変数環境変数ASDF_TOOL_VERSIONSで直接指定されたバージョンが適用されます。
4 (最低)グローバル設定 (asdf global)asdf globalコマンドで設定されたバージョンが適用されます。

4.1. .asdfrcファイルによるユーザー固有の設定

.asdfrcファイルは、ユーザー固有のasdf設定を定義するためのファイルで、通常は${HOME}/.asdfrcに配置されます。
このファイルを使用することで、asdfの挙動をより細かく制御できます。

主な設定項目には以下のようなものがあります。

  • legacy_version_file:
    • yesに設定すると、asdfが.ruby-versionのような他のバージョンマネージャーのレガシーバージョンファイルを読み込むようになります。
  • always_keep_download:
    • yesに設定すると、asdf install時にダウンロードしたソースコードやバイナリをインストール後も保持します。
  • plugin_repository_last_check_duration:
    • asdfプラグインリポジトリの同期間隔を分単位で設定します。0で毎回同期、neverで同期を無効にできます。
  • disable_plugin_short_name_repository:
    • プラグインのショートネームリポジトリの同期を無効にします。
  • concurrency:
    • ソースコードのコンパイル時に使用するコア数を指定します。autoに設定すると自動的に最適なコア数を計算します。

4.2. 環境変数によるasdfの挙動制御

asdfは、いくつかの環境変数によってもその挙動を制御できます。これらの環境変数は、通常、asdf.shなどのasdfスクリプトを読み込む前に設定する必要があります。

主要な環境変数は以下の通りです。

  • ASDF_CONFIG_FILE:
    • .asdfrcファイルのパスを指定します。
  • ASDF_TOOL_VERSIONS_FILENAME:
    • .tool-versionsファイルのファイル名を変更したい場合に指定します。
  • ASDF_DIR:
    • asdfのコアスクリプトの場所を指定します。
  • ASDF_DATA_DIR:
    • asdfがプラグイン、シム、ツールバージョンをインストールする場所を指定します。
  • ASDF_CONCURRENCY:
    • コンパイル時に使用するコア数を指定します。.asdfrcconcurrency設定よりも優先されます。

これらの設定を適切に利用することで、個人の開発環境や特定のプロジェクトの要件に合わせてasdfを柔軟にカスタマイズすることが可能になります。


5. .tool-versionsを使ったCI/CD連携の基礎

.tool-versionsファイルは、CI/CDパイプラインにおいても非常に強力なツールとなります。

CI/CD環境でasdf installを実行するだけで、開発環境と全く同じツールバージョンを自動的にセットアップできます。

これにより、CI/CD環境と開発環境の間にバージョン差異による問題が発生するリスクを最小限に抑え、安定したビルドとテストを実現します。

例えば、GitHub Actionsでasdfを使用する場合、以下のように設定できます。

name: CI

on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Install asdf and tools
      uses: asdf-vm/actions/install@v4
    - name: Install tools
      run: asdf install
    - name: Build and Test
      run: |
        # ここにビルドやテストのコマンドを記述
        npm install
        # npm test

まとめ:asdfと.tool-versionsで開発をより効率的にする

asdfの.tool-versionsファイルは、単なるバージョン管理ツール以上のものです。それは、開発者の環境構築の負担を軽減し、チームの生産性向上に貢献する強力なツールです。

この記事を通じて、あなたは.tool-versionsファイルの基本的な使い方から、チーム開発やCI/CD連携におけるその効果を理解できたでしょう。

今日からあなたのプロジェクトに.tool-versionsファイルを導入し、環境依存の悩みを解消しましょう。そして、より創造的で効率的な開発体験をチームにもたらします。

asdfと.tool-versionsを使いこなすことで、開発ワークフローは次のレベルへと進化するでしょう。ぜひ、今日から実践してみてください!


免責事項

本記事の情報は、公開時点での内容に基づいて作成されています。asdfや関連ツールのバージョンアップにより、手順や設定が変更される可能性があります。本記事の内容を参考に作業を行う際は、ご自身の責任において実施してください。いかなる損害が発生した場合でも、筆者は一切の責任を負いません。


SNSでもご購読できます。

コメントを残す

*