はじめに

平素は大変お世話になっております。
クイックガードのパー子です。

以前の記事 (PagerDuty の通知ルールを自社の営業日カレンダーに基づいて制御する) で予告していたとおり、柔軟にカスタマイズ可能なルールに基づいて休業日を判定するコマンドライン・ツール Wholidisuka を公開しましたのでご紹介します。

https://github.com/quickguard-oss/wholidisuka

利用シーンや既存ツールとの違い

元記事 にいろいろ書いてあります。

自分たち独自のカレンダーで柔軟にルールを上書きできるのが最大の特長です。
(= 祝祭日だけど働く。平日だけど休む。など。)

使い方

golang製なので go getReleasesページ から取得できます。

オプションなしで実行した場合、今日が日本の祝祭日かどうかを判定します。

$ wholidisuka

祝祭日なら終了ステータス 0 が、平日なら 1 が返ります。
また、何らかのエラーが発生した場合は 2 が返ります。

$ wholidisuka; echo $?  # 0 => 祝祭日, 1 => 平日, 2 => エラー

引数に日付 (YYYY-MM-DD形式) を指定することで、任意の日の判定ができます。

$ wholidisuka 2020-01-01  # 2020年1月1日は祝祭日か?

-r (--regular)オプションで定休の曜日を指定できます。

曜日は sunmon のように英語3文字表記で、空白なしのカンマ区切りで指定してください。
判定対象日が定休日 or 祝祭日なら終了ステータス 0 を返します。

$ wholidisuka -r 'sat,sun'  # 土曜・日曜が定休日

$ wholidisuka -r 'sat,sun' 2020-09-06; echo $?  # 2020年9月6日は日曜日なので定休 => 終了ステータスは `0`
0

独自のカレンダーに基づいて判定したい場合は -o (--override)オプションを使います。

$ wholidisuka -o my_calendar.yml  # 祝祭日や定休日に優先して、`my_calendar.yml` に基づいて判定を行う

カレンダーは YYYY-MM-DD: '何の日?' のように日付をキーとした単純なマップになっています。
値が NULL (~) の場合、その日が営業日であることを示します。
(= 祝祭日や定休日であっても終了ステータス 1 が返る)

my-calendar.yml
---
2020-01-01: ~                        # 正月だが営業日... ブラック企業のモーレツ社員
2020-09-06: ~                        # 2020年9月6日は日曜日だがイベント出展のため特別に営業
2020-09-19: 'クイック (9.19) ガードの日'  # 毎年9月19日は「クイックガードの日」でお休み (だといいな♪)
$ wholidisuka -o my-calendar.yml 2020-01-01; echo $?  # 正月だが営業日
1

$ wholidisuka -r 'sun' -o my-calendar.yml 2020-09-06; echo $?  # 日曜日だが営業日
1

$ wholidisuka -o my-calendar.yml 2020-09-19; echo $?  # クイックガードの日はお休み
0

$ wholidisuka -o my-calendar.yml 1970-01-01; echo $?  # 独自カレンダーにない日付の判定は通常どおり => 正月は祝祭日なので終了ステータス `0`
0

キャッシュ

Wholidisuka は holiday_jp の yml をローカルにキャッシュします。

キャッシュの格納場所はデフォルトでは ~/.wholidisuka/cache/ ですが、-d (--cache-dir)オプションで変更することもできます。

$ wholidisuka -d /path/to/cache/  # キャッシュを `/path/to/cache/` に格納&参照する

祝祭日はあまり頻繁に変更されるものではないので、キャッシュの有効期限はデフォルトで 180日としました。

変更する場合は -e (--cache-expire)オプションでお好みの期限を指定してください。
(golang の time.ParseDuration() でパース可能な形式で指定する必要があります。)

$ wholidisuka -e '168h'  # 168時間 (= 7日)

$ wholidisuka -e '0s'  # 0秒 (= キャッシュを無効にする)

制約

キャッシュ読み書き時の排他制御を実装していないため、複数のプロセスを同時に走らせるとキャッシュが壊れる可能性があります。

-d (--cache-dir)オプションでキャッシュ格納場所をプロセスごとに分けるなどの工夫をしてください。

まとめ

柔軟なルールに基づき休業日を判定するコマンドライン・ツール Wholidisuka を紹介しました。

https://github.com/quickguard-oss/wholidisuka

キャッシュの排他制御など荒削りな部分はありますが、既存の休業日判定ツールに満足していない方のお役に立てば幸いです。

今後ともよろしくお願い申し上げます。