2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dialoguerライブラリを使ってGitコマンドのCLIツールを作成する方法

Last updated at Posted at 2024-12-21

TL;DR

この記事では、dialoguerというRustのライブラリを使って、Gitコマンドを実行するためのCLIツールを作成する方法を紹介します。

dialoguerは、Rustでインタラクティブなコマンドラインツールを作成するためのライブラリです。このライブラリを使うことで、非常に簡単な実装ではあるものの比較的にUXの良いCLIツールを作成することができると感じました。

作ったもの

git-wizard」は、Gitコマンドを実行するためのインタラクティブなCLIツールです。ユーザーはツールのメニューから実行したいGitコマンドを選択し、簡単な操作でGitの基本的なコマンドを実行できます。例えば、git addgit commitgit pushgit statusgit branch などの操作を手軽に行うことができます。

Vim風の操作感

dialoguerを使うと自動的にVimの使用感を持つCLIツールを作成することができます。例えば、jを押すと下に移動し、kを押すと上に移動するなど、Vimのキーバインドに似た操作が可能です。

このあたりの実装がcrateの中で行われているのが、とても使い勝手がよく素晴らしいと感じました。

作ったもののコード

メイン部分

main 関数では、ユーザーに対してコマンドの選択肢を表示し、その選択に応じて適切なGitコマンドを実行します。

fn main() {
    let options = vec![
        "ステージング (git add)", 
        "コミット (git commit)", 
    ];

    let term = Term::stderr();
    println!("Git Wizardへようこそ!\n");

    loop {
        // メニューの選択
        let selection = Select::with_theme(&ColorfulTheme::default())
            .with_prompt("実行したいGitコマンドを選んでください (:q で終了)")
            .items(&options)
            .default(0)
            .interact_on_opt(&term)
            .unwrap();

        match selection {
            Some(index) => match index {
                0 => {
                    // git add
                    let files = user_input_with_exit(&term, "ステージングしたいファイル/ディレクトリを指定してください (例: .)");
                    execute_command("git", &["add", &files]);
                }
                1 => {
                    // git commit
                    let message = user_input_with_exit(&term, "コミットメッセージを入力してください");
                    execute_command("git", &["commit", "-m", &message]);
                }
                _ => {
                    println!("不明な選択肢です。");
                }
            },
            None => {
                // 選択をキャンセル(Ctrl+CやESCが押された場合)
                println!("終了します。");
                break;
            }
        }
    }
}

ユーザーが選択したコマンドに応じて、対応するGitコマンドを実行を行います。

ユーザー入力の取得

user_input_with_exit 関数では、:q と入力された場合に終了する機能を備えつつ、ユーザーからの入力を受け付けます。

fn user_input_with_exit(term: &Term, prompt: &str) -> String {
    loop {
        let input: String = Input::new()
            .with_prompt(prompt)
            .allow_empty(true)
            .interact_text()
            .unwrap();

        if input.trim() == ":q" {
            println!("終了します。");
            term.clear_last_lines(1).unwrap();
            std::process::exit(0);
        }

        if !input.trim().is_empty() {
            return input;
        }
    }
}

コマンドの実行

execute_command 関数は、指定されたコマンドを実行し、その結果を標準出力や標準エラーに表示します。

fn execute_command(command: &str, args: &[&str]) {
    println!("\n実行中: {} {}\n", command, args.join(" "));
    let output = Command::new(command)
        .args(args)
        .output();

    match output {
        Ok(output) => {
            if !output.stdout.is_empty() {
                println!("{}", String::from_utf8_lossy(&output.stdout));
            }
            if !output.stderr.is_empty() {
                eprintln!("{}", String::from_utf8_lossy(&output.stderr));
            }
        }
        Err(e) => {
            eprintln!("コマンドの実行に失敗しました: {}", e);
        }
    }
}

最後に

RustのCLIツールを初めて作成したのですが、dialoguerを使うことで非常に簡単にインタラクティブなCLIツールを作成することができました。また、Vim風の操作感を持つことで、より使いやすいツールを作成することができたと感じました。

今までPythonやGoでCLIツールを作成していましたが、RustにもCLIツールを作成するための優れたライブラリがあることを知り、今後もRustを使ってCLIツールを作成していきたいと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?