DenoでGitリポジトリ管理とワークディレクトリ管理ができるCLIツールを作った

#Deno#advent_calendar

ryoo14

これはDeno Advent Calendar 2022 8日目の記事です。

x-motemen/ghqをご存知でしょうか。コマンドライン上でリポジトリを管理できるとても便利なCLIツールです。

私も長らくお世話になっていまして、junegunn/fzfjunegunn/fzf.vimと組み合わせて快適なCLIライフを満喫していました。

ghqになんの不満もない私ですが、ちょうどDenoで何か簡単なCLIツールを作りたいと思っていて、基本的な機能をそなえたghqクローンであるryoo14/pattyを作ってみたので簡単にご紹介したいと思います。

インストールと初期設定

pattyをインストールして、PATHを通します。

$ deno install --allow-read --allow-write --allow-env --allow-run https://deno.land/x/patty@0.4.1/patty.ts
✅ Successfully installed patty
/home/user/.deno/bin/patty
ℹ️  Add /home/user/.deno/bin to PATH
    export PATH="/home/user/.deno/bin:$PATH"

$ export PATH="/home/user/.deno/bin:$PATH"  

PATHを通せたらpattyを実行してみます。引数なしでhelpが表示されます。

$ patty

  Usage:   patty
  Version: 0.4.1

  Description:

    a CLI tool for managing git and working directories written in Deno.

  Options:

    -h, --help     - Show this help.                            
    -V, --version  - Show the version number for this program.  

  Commands:

    create  <dir>      - Create a working but non-git managed directory.      
    get     <url>      - Get a git repository from remote repository services.
    list               - Print git and working directories.                   
    root               - Print root path on patty's configuration.            
    help    [command]  - Show this help or the help of a sub-command.         

pattyはデフォルトで$HOME/pattyが管理用のルートディレクトリとなります。
デフォルトから変更したい場合、$PATTY_ROOT変数をセットすると、そちらが優先されます。

管理用のルートディレクトリがどう設定されているかは、patty rootで確認できます。

$ patty root
/home/user/patty

リモートリポジトリからcloneしてみる

patty listで管理対象を一覧表示でき、patty getでリモートのリポジトリサービスからcloneできます。

$ mkdir patty # ルートディレクトリ作成
$ patty list  # この時点では空
$ patty get -q github.com/ryoo14/patty
$ patty list
github.com/ryoo14/patty

Denoでgitを操作する際、モジュールがないか探したのですが開発が続いていそうなモジュールがなく、仕方なくDeno.rungit cloneを実行しています。

いいモジュールや実装方法があれば教えていただきたいです。

ワークディレクトリを作成する

ghqと全く同じだと面白くないので、Gitで管理するほどではないけどpatty listでリストには表示できるワークディレクトリを作成するpatty createがあります。
逆にpatty createではGitリポジトリを現状作成できないので、今後の課題とします。

$ patty create work/memo
$ patty list
work/memo
github.com/ryoo14/patty

patty createは指定されたPATHの直下に.pattyディレクトリを作成します。patty list.git.pattyがあるディレクトリを管理対象として表示するようになっています。

$ ls -a patty/work/memo
.  ..  .patty

fzfと組み合わせて快適コマンドライン生活

fzfと組み合わせれば便利です。
C-]で管理下のリストが出るので、選択するだけでcdできます。

fzf_patty() {
  local project_name=$(patty list | sort | $(__fzfcmd))
  if [[ -n "$project_name" ]]; then
    local project_full_path=$(patty root)/$project_name
    local project_relative_path="~/$(realpath --relative-to=$HOME $project_full_path)"
    READLINE_LINE="cd $project_relative_path"
    READLINE_POINT=${#READLINE_LINE}
  fi
}

bind -x '"\C-]": fzf_patty'

fzf.vimと組み合わせて、vim内でもすぐにcdできます。

command! -nargs=0 Fq call fzf#run({
\ 'source': 'patty list --full-path',
\ 'down': 20,
\ 'sink': 'cd'
\ })

nnoremap <Space>fq :Fq<CR>

終わりに

DenoでCLIツールを作るときはdeno-cliffyがめちゃくちゃ便利です。
また何かCLIツールと、Freshを使ってWebアプリも書いてみたいなと思います。