めもちょー

メモ帳代わりに使っています。

dotfilesリポジトリのlinterを書く

dotfilesとは

dotfilesとは各種ソフトウェアの設定ファイルのことです。
.bash_aliasesなどのシェルスクリプトファイルや.alacritty.yamlのようなものを指します。

dotfilesをリポジトリ管理するには

私の場合は、下記のようなdotfilesLink.shを書き、ホームディレクトリにある~/.bash_aliasesに対してリポジトリ内の.bash_aliasesからシンボリックリンクを張っています。

#!/bin/sh
ln -sf ~/src/dotfiles/.bash_aliases ~/.bash_aliases
ln -sf ~/src/dotfiles/.vimrc ~/.vimrc
ln -sf ~/src/dotfiles/.alacritty.yml ~/.alacritty.yml
ln -sf ~/src/dotfiles/.tmux.conf ~/.tmux.conf
ln -sf ~/src/dotfiles/.config/lsd/config.yaml ~/.config/lsd/config.yaml
ln -sf ~/src/dotfiles/.config/lsd/themes.yaml ~/.config/lsd/themes.yaml
ln -sf ~/src/dotfiles/.config/lsd/icons.yaml ~/.config/lsd/icons.yaml
ln -sf ~/src/dotfiles/.gitconfig ~/.gitconfig
ln -sf ~/src/dotfiles/.config/Code/User/settings.json ~/.config/Code/User/settings.json
ln -sf ~/src/dotfiles/.delta/themes.gitconifg ~/.delta/themes.gitconfig
ln -sf ~/src/dotfiles/.config/bat/config ~/.config/bat/config

linterを書く

dotfilesに含まれるファイルとしてよくあるものとして下記が挙げられます。

  • .sh
  • .yaml .yml
  • .json
  • .vimrc

今回はシェルスクリプトファイルとYAMLファイルに対してのリントを行いました。
コードは下記のようになりました。
dotfilesLink.shの3列目に書いてあるファイルをshellcheckやyamllintでリントしています。
.bash_aliasesは拡張子が.shでなく、shebangが無かったり実行権限が無かったりとshellファイルであることの判定が難しいため、予め定義したファイルの配列を作り事前定義配列にあったら、shellcheckを施すという運びにしました。

# /bin/bash

# -e: エラーが出た時点で落とす
# -u: 未設定変数を参照したら落とす
# -o pipefail: pipeの連鎖で1つでもエラーとなったら落とす
set -euo pipefail

# shファイルと判定が難しいshファイル
shell_file_list=(".bash_aliases")

while IFS= read -r line; do
  
  # dotfilesLink.shに書いてあるファイル
  src_file=$(echo "$line" | awk '{print $3}')

  if [ -z "$src_file" ]; then
    continue
  fi

  # ~/src/dotfiles/を空文字に置き換える
  src_path=$(echo "$src_file" | sed 's|~/src/dotfiles/||')
  
  if [[ -e $src_path ]]; then

    echo "check $src_path"

    # 予め定義しておいたshellscriptファイル
    # ~/.bash_aliasesは実行形式でもないしshebangもないためshellファイルであるかの
    # 判定が難しいため手動定義
    if [[ "${shell_file_list[@]}" =~ "$src_path" ]];then
      shellcheck "$src_path"
    fi

    # 拡張子で判定できるものは拡張子をもとにファイルに沿ったリントをかける
    case "${src_path##*/}" in
      *.sh)
        shellcheck "$src_path"
        ;;
      *.yaml | *.yml)
        yamllint "$src_path"
        ;;
    esac
  fi
done < dotfilesLink.sh

GitHub Actionsで動かす

GitHub Actioinsで動かすには下記のような.github/workflows/lint.yamlを書きました。

name: Linter

on:
  push:
    branches:
      - main

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    - name: Set up dependencies
      run: |
        sudo apt-get update
        sudo apt-get install -y shellcheck
        pip install yamllint

    - name: Run linter.sh
      run: |
        bash linter.sh