Listing up all your Git repos in your system using `find`

Listing up all your Git repos in your system using `find`
Photo by Markus Winkler / Unsplash

Introduction

I have been an avid user of tmux for a few years now. I love how I can quickly open terminal sessions and swap between them. As a developer with a lot of projects in my computer, tmux really helps me to manage my workflow.

One workflow that I use all the time is to open one of my projects using tmux windows, so that I can refer to code snippets quickly. No matter where I am in the terminal, a quick tmux shortcut will open up a different project in my system. From there, I can view/copy/edit whatever code I need, and then switch back to where I was with ease.

To run this workflow, I have been using ThePrimeagen's tmux-sessionizer script. This script does the following:

  • find folders in specific directories that you specify
  • Allow you to fuzzy-find the specific folder you want with fzf
  • Create a new tmux session, where you are cd into the folder you picked

Its a very simple yet effective script. However, there is a pain-point in the script that I want to modify. Specifically, the issue I want to fix is step 1.

When using the tmux-sessionizer, you need to add the folders where you store your projects manually. This is fine when you have one folder where you store all your projects:

rolzy ~ $ tree -L 1 ~/projects
/home/rolzy/projects
├── project1
├── project2
└── project3

In this case, all we have to do is search through ~/projects.

However, I like to add an extra level and categorize my projects:

rolzy ~ $ tree -L 1 ~/projects
/home/rolzy/projects
├── automation
│   ├── project1
│   ├── project2
│   └── project3
└── consulting
    ├── project4
    └── project5

In this case, I need to add both ~/projects/automation and ~/projects/consulting to the list of folders to search in the tmux-sessionizer script. This is fine if its a one-off thing, but my folder structure is forever changing. I need a better way to find all projects under my home directory.

But exactly how do we do this?

Well, all my projects are version controlled with git. Maybe we can use that to find my projects.

The find command

find is a command you can use to "search for files and folders in a directory hierarchy". You can run the command by running find <directory to search>. For example, if we run it against the home directory:

(env) rolzy ~ $ find ~
/home/rolzy
/home/rolzy/.rbenv
/home/rolzy/.rbenv/shims
/home/rolzy/.rbenv/versions
/home/rolzy/Documents
/home/rolzy/.bashrc
/home/rolzy/.pyenv
/home/rolzy/.pyenv/CONTRIBUTING.md
/home/rolzy/.pyenv/README.md
.
.
.

It lists all the files you have under the home directory. This is way too much info - remember, we only want to find git repos under our home directory.

Thankfully, find comes with a bunch of flags you can set to customize the search behavior. Lets look at it one by one.

The -type flag

By using the -type flag, you can find files that are a specific type. Using -type f will find files, -type d will find folders, -type l will find symlinks. Here, we want to find projects (which are folders), so lets use the -type d flag.

(env) rolzy ~ $ find ~ -type d
/home/rolzy
/home/rolzy/.rbenv
/home/rolzy/.rbenv/shims
/home/rolzy/.rbenv/versions
/home/rolzy/Documents
/home/rolzy/.pyenv
/home/rolzy/.pyenv/completions
/home/rolzy/.pyenv/plugins
.
.
.

Better! We can see the find command is skipping files like .bashrc and .md files. Lets look at another flag to filter even further.

The -name flag

By using the -name flag, you can search for files and folders with a specific substring.

Remember that we are looking for git repos. All git repos have a hidden .git folder in them, which we can use for our search:

(env) rolzy ~ $ find ~ -type d -name ".git"
/home/rolzy/.pyenv/plugins/pyenv-doctor/.git
/home/rolzy/.pyenv/plugins/pyenv-update/.git
/home/rolzy/.pyenv/plugins/pyenv-virtualenv/.git
/home/rolzy/neovim/.git
/home/rolzy/.zplug/.git
/home/rolzy/.zplug/repos/jeffreytse/zsh-vi-mode/.git
/home/rolzy/.local/share/nvim/lazy/bullets.vim/.git
/home/rolzy/.local/share/nvim/lazy/cmp-nvim-lsp/.git
/home/rolzy/.local/share/nvim/lazy/nvim-dap-virtual-text/.git
/home/rolzy/.local/share/nvim/lazy/nvim-lspconfig/.git
/home/rolzy/.local/share/nvim/lazy/vim-repeat/.git
.
.
.

A lot better!!! We have removed most of the clutter from the first find command. However, we have a lot of .git repos in hidden folders like .pyenv, .zplug and .local... They are plugins of tools that I use in my system, being cloned during installation. Lets try and remove those from the search as well.

The -prune flag

We are currently running the find command on the home directory. This is troublesome because there are a lot of folders in there that the find command have to traverse. As mentioned earlier, hidden folders in my home directory have a lot of git repos that I am not interested in. So, lets tell find to skip searching these folders.

Using the prune flag tells find to not traverse specific paths. Lets tell it to skip all hidden folders. To do this, use the -name flag that we looked at earlier, and put -prune flag after the search pattern to skip the matching files:

(env) rolzy ~ $ find ~ -name ".*" -prune -type d -name ".git"
/home/rolzy/projects/fetch_reddit_wallpapers/.git
/home/rolzy/projects/obsidian_vault/.git
/home/rolzy/projects/mealsteals/.git
/home/rolzy/neovim/.git
/home/rolzy/dotfiles/.git

Great! We now have a small list of projects that are in my home directory. The last step is to remove .git from the file path so it takes me to the project root folder instead.

The -exec flag

The -exec flag allows you to run a command against all the files that were found with the find command. So far, the find command is finding all .git folders - we don't need the .git component, we just want the folder directory. To get rid of .git, we can execute the dirname command on the search results to strip the last component from the file name.

To use the -exec flag, pass in the command with {} as the placeholder for the search result. And then, pass in \; as the terminal character. For example:

(env) rolzy ~ $ find ~ -name ".*" -prune -name ".git" -type d -exec dirname {} \;
/home/rolzy/projects/fetch_reddit_wallpapers
/home/rolzy/projects/obsidian_vault
/home/rolzy/projects/mealsteals
/home/rolzy/neovim
/home/rolzy/dotfiles

Perfect! We now have the list of project folders under the home directory.

Putting it together

Now all we have to do is replace the newly made find command to the tmux-sessionizer script:

find ~ -name ".*" -prune -name ".git" -type d -exec dirname {} ; | fzf

dotfiles/scripts/tmux-sessionizer at main · rolzy/dotfiles
Contribute to rolzy/dotfiles development by creating an account on GitHub.

Here, we are piping the find results into the fzf command so that we can fuzzy-find search our projects in the home directory. The rest of the script will create a new tmux session on the project folder that you choose.

Read more

Terraformを使って"AWS Lambdaとその取り巻き"を召喚しよう

Terraformを使って"AWS Lambdaとその取り巻き"を召喚しよう

はじめに 人生、いろんな「派閥」ってありますよね。私が属するITインフラ業界にも色々あります。どのクラウドを使うか、どのIDEを使うか、どのOSを使うか…枚挙に暇がありません。 インフラ(IaC)言語もその一つ。私はこの業界に足を踏み入れてから、ずっとCloudFormation派閥です。私はAWS専門だったので、AWS公式のCloudFormationで仕事が成り立ってました。 しかし最近、AzureやDatabricks関連の仕事も私に降ってくるようになりました。そうなると、AWS限定のCloudFormationでは対応できません。 そんなとき、複数のクラウドプラットフォームに対応できるTerraformという存在を耳にしました。 Terraformの練習として、AWS Lambdaとその取り巻き(ECR, IAM, Secrets Manager, CloudWatch, SQS) を召喚してみたので、この記事にまとめます。 環境構築 まずは公式マニュアルを参考にTerraformをインストールしましょう。 ターミナルからTerraformが動けば、インストー

By Roland Thompson