Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【ITニュース解説】Building a CLI Tool That Made My Life Easier

2025年09月19日に「Dev.to」が公開したITニュース「Building a CLI Tool That Made My Life Easier」について初心者にもわかりやすく解説しています。

作成日: 更新日:

ITニュース概要

AIでプログラミング課題解決の手間を減らすため、開発者はCLIツールを作った。これは、プロジェクトのファイル構造やGit情報などを自動でまとめ、AIに正確に伝える。開発を通じてC++知識や開発ツールの使い方を深く学んだ。

出典: Building a CLI Tool That Made My Life Easier | Dev.to公開日:

ITニュース解説

このニュース記事は、システムエンジニアが日々の作業を効率化するために開発したコマンドラインインターフェース(CLI)ツールの体験と、その機能について解説している。特に、ChatGPTのような大規模言語モデル(LLM)と連携してプログラミングの問題を解決する際、手作業によるファイル情報のコピー&ペーストの手間を省き、より正確なAIサポートを得ることを目的としたツールの開発経緯が説明されている。

筆者は、コーディングに関する疑問をLLMに投げかける際、プロジェクトのソースコードや構造、依存関係といった多くの情報を一つずつ手作業でコピー&ペーストすることに煩わしさを感じていた。また、LLMに漠然とした情報だけを与えても、的確な回答が得られにくいという課題もあった。LLMがプロジェクト全体の文脈を理解できていなければ、表面的なアドバイスしか得られず、開発者は依然として多くの時間を使って必要な情報を整理しなければならない。この課題を解決するため、筆者はプロジェクトの全体像をLLMに適切に伝えるための自動化ツールが必要だと考えた。関連性の高いデータのみを抽出してLLMに提供できれば、より質の高い、プロジェクト固有の知見や解決策を引き出せると期待したのだ。

筆者が開発したのは、C++言語で書かれたCLIツールである。このツールは、単一のコマンドでプロジェクト全体を分析し、包括的なコンテキストドキュメントを自動で生成する。生成されるドキュメントには、プロジェクト内のファイルのローカルパス、Gitのリポジトリ履歴、ディレクトリ構造のツリー表示、すべてのソースファイルの内容とその拡張子、そしてプロジェクト全体の統計情報が含まれる。さらに、開発者の要望に応じて、特定のファイルやフォルダをドキュメントから除外したり、含めたりする柔軟な設定が可能だ。これにより、LLMに質問する際に手作業でファイルを選んだり、プロジェクトの文脈を見失ったりする心配がなくなる。

このツールを開発する過程で、筆者は予想以上に多くの技術的な知識と経験を得た。まず、ファイルシステムにおけるファイルの読み書きのスキルが向上し、C++17で導入された新しいライブラリや機能に深く触れる機会となった。例えば、プロジェクトのディレクトリツリー(フォルダの階層構造)を表現する際には、フォルダの中にさらにフォルダがあるという構造をたどるために「再帰」というプログラミング手法が必要だと気づいた。この再帰的なファイルとフォルダの探索には、std::filesystemというC++の標準ライブラリが非常に役立ったという。また、プロジェクトのビルドを管理するCMakeというツールを初めて設定し、他のオープンソースプロジェクトを自身のコードに統合する方法も習得した。この開発経験を通じて、筆者はプログラムの予期せぬ挙動(エッジケース)やエラーへの対処(エラーハンドリング)について深く考えるようになり、コードを書き始める前に全体の設計を熟考する重要性を学んだと述べている。

開発中に直面した具体的な課題も共有されている。最初の大きな課題は、Gitリポジトリの情報を取得する方法だった。当初は、システムのコマンドラインでgitコマンドを実行し、その出力結果を解析することを考えたが、これはユーザーのシステムにGitがインストールされていなかったり、パスが正しく設定されていなかったりする場合に問題となる可能性があった。この問題を回避するため、筆者はlibgit2というGitの機能をプログラムから利用するためのライブラリを導入した。このライブラリをvcpkgというパッケージ管理ツールを使って導入・統合したのは初めての経験であり、慣れないツールを使うことで新たなスキルを得たという。libgit2を使ってGit情報を取得する中で、筆者はC言語スタイルのコードやポインターに関する知識を再確認する機会も得た。さらに、GitがコミットID(変更履歴を識別する文字列)をどのように保存しているかについても深く理解した。Gitはコミット時に、その時点のファイル内容、コミット者、日付などの情報すべてをSHA-1というハッシュ関数に通すことで、一意のバイナリデータを生成している。私たちが目にする文字列は、そのバイナリデータを人間が読める形式に変換したものだという新たな発見があった。

二つ目の課題は、プログラムの出力先に関するものだった。開発を始めた当初、筆者は出力のほとんどを画面(コンソール)に表示するためにstd::coutという標準出力ストリームに依存しすぎていた。しかし、ある時点で、その出力データをファイルに書き込む必要が生じた。全てを書き直すのではなく、既存の出力ロジックを再利用する方法として、出力ストリームをリダイレクトするテクニックを学んだ。これは、std::streambufというC++の標準ライブラリの機能を使うもので、一時的にstd::coutの出力先を、画面ではなくstd::ostringstreamというメモリ上の文字列バッファに切り替える。これにより、既存の関数を呼び出すだけで、その出力が画面ではなく文字列バッファに蓄積され、後からその内容をファイルに書き出すことが可能になる。この方法は、コードの再利用性を高める上で重要なテクニックである。

C++の言語仕様に関する深い学びも紹介されている。プロジェクト内で、コンパイル時(プログラムが実行される前)にデータの内容が確定しているような特定のデータに対して、std::arrayconstexprを組み合わせて使おうとした際に問題が発生した。constexprは、コンパイラに対して「このデータはコンパイル時に確定している」と伝えるためのキーワードであり、std::arrayはメモリ効率に優れている。しかし、constexpr std::array<std::string, 8> ignoredDirsのような記述はエラーとなる。その理由は、std::stringが内部で動的なメモリ割り当てを行うため、コンパイル時にすべてが確定しているconstexprの要件と矛盾するからだ。この問題を解決するためには、std::string_viewというC++17で導入された新しい型を使用するのが適切だと筆者は学んだ。std::string_viewは、既存の文字列データを「参照」するだけで、自身ではメモリを所有しないため、動的なメモリ割り当てを伴わず、コンパイル時に作成することが可能となる。

この開発プロジェクトを通じて、筆者はstd::filesystemstreambufといったC++の重要なライブラリや機能について深く理解し、これらの知識が自身のエンジニアリングスキルを大きく向上させたと結論付けている。