🚀

クソ雑にgemini-cli使ってRustの開発環境作ってもらったりしてみた

に公開

めちゃくちゃ時代に取り残されてるので、とりあえず試し始めました。無料で試せるの助かります、ありがとうGoogle.

1. 開発環境の準備

gemini-cliで以下の点を伝えて作ってみてもらいました

  1. Macbookを使っている
  2. homebrewはインストールされている
  3. vscodeを使いたい
  4. プログラミング言語としてRustを使いたい

こんな感じで動いてくれました

gemini-cliさんが書いてくれた文章による動き

まず、Homebrewを使ってRustのコンパイラ (rustc) とパッケージマネージャ (cargo) をインストールしました。

brew install rust

VS Code拡張機能のインストール

Rust開発を快適にするため、VS Codeに以下の拡張機能をインストールしました。

  • rust-analyzer: 公式の言語サーバー。コード補完、定義へ移動、エラー表示など。
  • CodeLLDB: デバッグ機能。
  • Even Better TOML: Cargo.toml ファイルのシンタックスハイライトや文法チェック。
code --install-extension rust-lang.rust-analyzer
code --install-extension vadimcn.vscode-lldb
code --install-extension tamasfe.even-better-toml

トラブルシューティング: code コマンドが見つからない

code コマンドがパスに通っていないため、VS Codeのコマンドラインランチャーを有効にする必要がありました。

  1. VS Codeを開く。
  2. Cmd + Shift + P でコマンドパレットを開く。
  3. Shell Command: Install 'code' command in PATH を実行。

rustup によるRustツールチェーンの管理

Homebrewで直接Rustをインストールしたため、rustup コマンドが見つからず、rust-analyzer が正しく動作しない問題が発生しました。rustup はRustの公式ツールチェーンインストーラであり、バージョン管理やコンポーネントの追加に優れています。

解決策: HomebrewでインストールしたRustをアンインストールし、rustup をHomebrew経由でインストールし直しました。

  1. HomebrewのRustをアンインストール:
    brew uninstall rust
    
  2. rustup をインストール:
    brew install rustup
    
  3. rustup を初期化し、デフォルトのツールチェーンをインストール:
    rustup-init -y
    
  4. Cargoの環境変数を現在のシェルに読み込む:
    source "$HOME/.cargo/env"
    
  5. rust-analyzer が必要とする rust-src コンポーネントを追加:
    rustup component add rust-src
    

この後、VS Codeを再起動することで rust-analyzer のエラーが解消されました。

まず素直に動いてみて、エラーが出て自分で解消できなければ人にやって欲しいことを手順で提示してくれるのがとても助かる 😸
最終的に拡張機能の関連でRust自体のインストール方法を変えていい感じにしてくれたのは凄いなぁと

2. Rustプロジェクトの作成と管理

とりあえずHello world出力させたかったのでその依頼と、プロジェクト自体はこれから勉強にも使いたかったのでいい感じの名付けを依頼しました

gemini-cliさんが書いてくれた文章による動き

「Hello, World!」プロジェクトの作成

cargo new コマンドを使って、新しいRustプロジェクト hello_world を作成しました。

cargo new hello_world

作成後、cargo run で実行し、「Hello, world!」が正しく出力されることを確認しました。

cd hello_world
cargo run

プロジェクト名の変更

hello_world というディレクトリ名が一般的すぎるため、より学習用であることがわかる rust-learning-project に変更しました。

mv hello_world rust-learning-project

ディレクトリ名の変更に伴い、Cargo.toml 内の namerust-learning-project に修正しました。

# Cargo.toml
[package]
name = "rust-learning-project" # 変更後
version = "0.1.0"
edition = "2024"

[dependencies]

3. Gitによるバージョン管理

外部サービスとの接続も試したくてgithubへの保存を依頼
この辺りは流石に必要情報だけ渡せばぬるっとやってくれますね 👍

gemini-cliさんが書いてくれた文章による動き

プロジェクトをGitHubで管理するため、Gitリポジトリを初期化し、コミットを行いました。

.gitignore の作成

RustプロジェクトでGit管理から除外すべきファイル(ビルド成果物など)を指定する .gitignore を作成しました。

# Generated by cargo
# See more here: https://github.com/github/gitignore/blob/main/Rust.gitignore

# General
/target/
.DS_Store

# Editor-specific
.vscode/

Gitリポジトリの初期化と初回コミット

プロジェクトディレクトリでGitリポジトリを初期化し、すべてのファイルをステージングして初回コミットを行いました。

cd rust-learning-project
git init
git add .
git commit -m "Initial commit: Create Rust project"

GitHubへの接続とプッシュ

GitHub上に新しいリポジトリを作成し、ローカルリポジトリと接続してコードをプッシュしました。

git remote add origin git@github.com:ryutarn/rust-learning-project.git
git branch -M main # ブランチ名をmasterからmainに変更
git push -u origin main

4. テストの追加と管理

ここはもはや人間が迷走しました 😢
Rustのこと理解してなくてあれこれやった結果、一番最初に提案してくれたパターンが一番良かったという。geminiさんを信じよう 🙏

gemini-cliさんが書いてくれた文章による動き

Rustのベストプラクティスに従い、単体テストを追加しました。

単体テストの追加 (src/main.rs内)

main() 関数を直接テストするのではなく、テストしたいロジックを get_hello_message 関数として抽出し、その関数をテストするようにしました。テストコードは src/main.rs 内の #[cfg(test)] モジュールに記述しました。

// src/main.rs
fn main() {
    println!("{}", get_hello_message());
}

fn get_hello_message() -> String {
    String::from("Hello, world!")
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_get_hello_message() {
        assert_eq!(get_hello_message(), "Hello, world!");
    }
}

cargo test コマンドでテストを実行し、パスすることを確認しました。

~/.cargo/bin/cargo test # 環境変数PATHが未設定の場合

テストケースの別ファイル管理 (統合テストへの移行と修正)

テストケースを tests/ ディレクトリに移動して管理したいという要望がありました。これはRustの統合テストの慣習に沿ったものです。

  1. tests ディレクトリを作成。
  2. src/main.rs を元のシンプルな「Hello, World!」に戻す。
  3. tests/common_tests.rs を作成し、get_hello_message 関数とテストを移動。

問題発生: tests/common_tests.rs から rust_learning_project クレートの get_hello_message をインポートしようとすると unresolved import エラーが発生しました。

原因と解決策: バイナリクレート (main.rs を持つクレート) の関数は、デフォルトでは外部から参照できません。統合テストから参照できるようにするには、src/lib.rs を作成し、そこに公開したい関数を移動する必要があります。

  1. src/lib.rs を作成し、get_hello_message 関数を移動:
    // src/lib.rs
    pub fn get_hello_message() -> String {
        String::from("Hello, world!")
    }
    
  2. src/main.rs から get_hello_message 関数を削除し、lib.rs からインポートするように変更:
    // src/main.rs
    use rust_learning_project::get_hello_message;
    
    fn main() {
        println!("{}", get_hello_message());
    }
    
  3. tests/common_tests.rsuse rust_learning_project::get_hello_message; のままでOK。

この修正により、統合テストが正しく実行されるようになりました。

5. AIアシスタントへの指示

最後はGEMINI.mdに書いておくと、いい感じになっていくっていう話を見たので試してみました

gemini-cliさんが書いてくれた文章による動き

AIアシスタント(Gemini)がGit操作を行う際のポリシーについて指示を行いました。

指示内容: 自動的にGitHubへプッシュせず、ローカルでのコミットまでに留めること。プッシュが必要な場合は、明確に指示を仰ぐこと。

この指示はAIアシスタントの記憶に保存され、さらにプロジェクトの GEMINI.md ファイルにも記録されました。

# GEMINI.md の内容例
This is a sample project to learn Rust.

## Gemini Agent Instructions

- **Git Push Policy**: Do not automatically push changes to GitHub. Only commit changes locally. Prompt the user for explicit permission before pushing to a remote repository.

この記録は、AIアシスタントとの協調作業を通じてRustプロジェクトを構築・管理するプロセスを示しています。今後もこのプロジェクトはAIの助けを借りながら進化していく予定です。

Discussion