はじめに
タイトル通りです。
Rustの勉強中です。新たなプログラミング言語を学習する際、何を作りながら学習していく方法が効率が良いと考えています。
今回そのテーマとして、コマンドを記録してくれるツール「regcmd」を作りました。
先にGitHubのリンクを張っておきます。
regcmd
何をするものか
そのものずばりです。
指定したコマンドを記録し、管理するものです。
Linuxだと「↑」「↓」やhistoryコマンド、Ctrl+Rでの検索によって過去のコマンドを確認することができます。
しかし、直近入力したコマンドでない場合や、複雑なコマンド、頻繁に使用するコマンドにはあまり効果が発揮できません(個人の感想です)。
このツールではホームディレクトリ直下に管理用のファイルを用意してそこにコマンドを記録していきます。
エイリアスは短いコマンドや頻繁に使用するコマンドでは有利ですが、シェルを作成する必要がある場合、シェルファイルの管理が煩雑になる場合があります。
regcmdに集約することで、管理コストを削減することができます。
機能
現状は最低限の機能である登録、一覧、削除の3つのみ実装しました。
登録
registerサブコマンドで登録できます。
対話的に登録する場合
$ regcmd register
name: ll
command: ls -al
description: show file list
registered ll
ls -alをllという名前で登録しています。
オプションをつけて登録する場合
$ regcmd register -n root_du -c "du -h -d 1 /"
description(option):
registered root_du
/フォルダに対してduコマンドを1階層のみ表示するコマンドをroot_duという名前で登録しています。
同名で登録しようとする場合は上書き確認を行うようにしています。
登録している名前でコマンドを実行できるわけではないので注意です(今後拡張していく予定)。
一覧表示
listサブコマンドで登録しているコマンドの一覧が表示されます。
$ regcmd list
No | name | command | description
0 | ll | ls -al | show file list
1 | root_du | du -h -d 1 / |
削除
deleteサブコマンドで削除できます。
$ regcmd delete ll
delete ll
技術的な話
コマンドラインのIF
CLのIFを作る際に使ったクレートはclapです。
これはコマンドラインの引数解析をしてくれるものです。
シンプルだったので使いやすく、やりたいこともすぐに実現できました。
ファイル書き込み/読み取り
コマンドを管理するファイル(.command)の中身はJSONです。
JSONをシリアライズ/デシリアライズするためにserdeクレートを使いました。
こちらも特にクセはなく簡単に使うことができました。
エラー処理
エラー処理(管理)はanyhowクレートを使いました。
エラー処理はこれがデファクトスタンダードなイメージです。
ファイルロック
今回一番苦労したのはここです。
コマンドを管理するファイルに書き込んでいる間に、別プロセスから読み込みされるとエラーになってしまいました。
処理自体は数十~百数十msecほどで終わるので、書き込みと読み込みが被ることはほぼないと思うのですが、対応したかったです。
これはflockを実現してくれるクレートになります。
ので、ロックを占有されている間は待機する動きが実現できました。
今後の話
まだまだ勉強不足なのと、作っていくうちに拡張したい点が出てきたので引き続き開発していきます。
拡張点としては、以下で、ここまで出来れば実際の仕事でも使えるかなという感覚です。
- コマンドのクリップボードへのコピー機能
- 環境切り替え機能
現在はホームディレクトリ直下にグローバルで管理しているような形なので、ワークスペースで管理できるように - コマンドの実行機能
- コマンド登録+実行時の引数指定
現状の段階でも使ってみて、感想をもらえると嬉しいです。