【git】カウントしたコミットファイルの総文字数を自動でコミットメッセージに追加する

趣味で書いている小説をgitで管理していて、進捗把握のためにコミットメッセージにその日1日書いた総文字数を入れ込んでいます。 こんな感じで。 以前までは、SF作家である藤井太洋先生自身が公開してくださっている拡張機能: novel-writerのステータスバー表示で文字数を把握し、手動でコミットメッセージを書いていました。 ただ、この方法にはいくつかの(個人的には解決したい)問題があり、 日付が回ると文字数がリセットされるので、うっかりしてると差分の文字数がわからなくなる 特定のファイルや変更は含みたくない場合がある(翌日への自分のメモなど) コミットメッセージへの手打ちを辞めたい 上記二つに関しては、私が拡張機能で出来ることを把握しきれていないだけ or 今後改善される可能性はありますが、どうせならコミット時に自動でコミットメッセージ入力できたら楽だよなぁという動機があったので、ちょっと調べてスクリプトを組んでみました。 やったこと 下記のスクリプトを.git/hooks/commit-msgとして設定します。 #!/bin/bash # ステージングエリアに追加されたファイルの差分を取得し、文字数をカウントする関数 # .git/hooksに移動させて、`chmod +x .git/hooks/commit-msg`を実行することでコミット時にhookされる get_character_count() { # ステージングエリアに追加されたファイルの差分を取得 diff_output=$(git diff --cached) # 追加された行の文字数を合計する added_characters=$(echo "$diff_output" | grep '^+' | sed 's/^+//g' | wc -m) # 削除された行の文字数を合計する deleted_characters=$(echo "$diff_output" | grep '^-' | sed 's/^-//g' | wc -m) # 追加された文字数と削除された文字数の合計を計算する total_characters=$((added_characters - deleted_characters)) # 結果を出力 echo "$total_characters" } # コミットメッセージに追加 character_count=$(get_character_count) echo "📝 $character_count 文字" >> "$1" スクリプト内でやっている事はかなりシンプルで、git diffの結果である追加行(+で始まるもの)と削除行(-で始まるもの)の文字数をそれぞれカウントして差し引いて、総文字数を計算しているだけです。...

<span title='2024-05-06 14:51:45 +0900 +0900'>5月 6, 2024</span>

【github】mainではないブランチから派生したブランチでPRを出すとき

ベースブランチってどこ向け? タイトルの通り、main(default)ではないブランチから派生したブランチのPRを出すのに謎の抵抗感があったのですが、githubくんがかなりよしなにしてくれることに気がついたのでその挙動を備忘録として書いておきます。 (知っている人にとってはめちゃくちゃ当たり前体操な内容だと思います) TL;DR main(default)ブランチから切ったブランチAから更に切ったブランチA2のPRを出すときは、難しいこと考えずにブランチA向けにPR出すのが良き。 どういうこと? たとえば、チームメンバーがmainから派生したbranchAで作業していたとします。 branchAに乗っている機能が前提の作業をするために、branchAからbranchA2を切りました。 branchA2の作業が終わりPRを出したいのですが、branchAはまだ細かい部分のPR中でmainにはマージされていません。 さて、このbranchA2のPRの向き先はmainかbranchAか、という話です。 今こうして自分で書いていても「いやbranchA向けだろ……」と思うのですが(main向けにPRを出すと、branchAのコミットもPRに乗ってしまうためかなり見づらいことになるので)、 「branchA向けに出したとして、branchAがmainにマージされたらbranchA向けのPRはどういう扱いになるんだ……? mainでrebase or mergeしてmain向けに直さないといけないのか?」と漠然と面倒臭がっていました。今までは。 この「PRのbaseとなっているブランチがマージされていった後にデフォルトのブランチ向けのPRに直す」作業、githubが勝手にやってくれます。 実例 (ほとんどmainにしかpushしていないprivateリポジトリで実験) test-branch-Aというブランチををmainから切ってPRを出したとします。 その後、test-branch-Aから切ったtest-branch-A2のPRをtest-branch-A向けに出します。 (PR作成時にbaseが選べるし、作成した後もEDITボタンから変更できます) この状態でtest-branch-AのPRがマージされると、 Base automatically changed from test-branch-A to mainというログが残って、test-branch-A2のPRがmain向けに自動修正されます。 めちゃくちゃ便利だ……。もっと早く気が付きたかった。 PR出した後は、ベースとなるブランチ自体に先んじてマージしちゃうか、そっちの作業を待ってからmainにマージするか、どちらにせよベースとなるブランチで作業している方とのコミュニケーションは必要ですが、とりあえず派生元にPR出しておけばあんまり困ることは(今のところの経験上)ないです。 派生PR、もう怖くない!な備忘録でした。

<span title='2024-03-08 18:16:03 +0900 +0900'>3月 8, 2024</span>

日記(~2023/07)

(2023/06/17) We updated our RSA SSH host key - Github 私用のPCで久々にpushしようとして警告出て、ちゃんと公式情報見た上で対応できたけど、3/24以降仕事以外のコードをpushしてなかったことが地味にショックでした。 (2023/06/24) 広くなったベランダで育て始めたペパーミント、苗買ってきた時よりなんか葉っぱ過疎ってないか……?と思って見てみたら馬鹿でかい青虫がついててリアルタイムでもりもり葉っぱ食べられてました。 (2023/06/26) 「AI分析でわかった トップ5%社員の習慣」を読んで、上位5%社員のXX%が〜っていうのに関しては、サンプリング数少ないから95%の人たちと違って一概には言えないんじゃないの?(この本作るために良いところだけピックアップするときにだいぶバイアスかかってそう)とは思ったけど、これ実践してみようかなと思うところはいくつかあったので読んでよかったです。 読んですぐに(内容は本とは全然関係ない)スーパーミニマムな社内LTをしたんですが、「資料作りに時間をかけない」と割り切って最初からNotionにまとめることで割と短い時間で形に出来たのが個人的にいい学びでした。 (2023/06/27) JavaScriptの入れ子の関数とクロージャ、シンプルに知らなかったです。使い過ぎはネストが辛くなりそうなので良くないと思う(というかユースケース自体あんまり思いつかない)けど、外側の関数のスコープを持ってくれる性質を利用して、コード理解の一助のためにロジックの一部を別関数に切り出す時なんかには有効そうだなと思いました。

<span title='2023-06-27 17:14:07 +0900 +0900'>6月 27, 2023</span>

【覚え書き】JavaScriptのプライベートクラス機能

TypeScriptを使っていると、「ちゃんとprivateとかreadonlyとか使って制約かけないとな〜」と認識し直すタイミングが定期的に来るんですが、 そんな折にJavaScript側で実現できるプライベートクラス機能なるものがあることを知りました。 プライベートクラス機能 - JavaScript | MDN クラスのフィールドの先頭にハッシュ(#)をつけることで、プライベートなインスタンスフィールドを生成することができます。 あくまでコンパイル時にエラーの判定を行うTypeScriptと異なり、JavaScript自身の機能なのでランタイム時に判定&エラーを返してくれます。 継承を使う場合は、privateと同じく子クラスからは参照不可になりますが、 子クラス側で同じ名前のプライベートインスタンスフィールドを定義することはできます。 存在を知ってパッと概要を追って、良さそうと思ったけど世の反応(?)はどんな感じなんでしょうか。 (ちなみに、インスタンス生成時に少し遅くなるらしい、と言う旨の去年の記事はお見かけしました: JavaScriptでプライベートを使うと遅くなる話)

<span title='2023-06-20 23:05:31 +0900 +0900'>6月 20, 2023</span>

日記(~2023/06)

(純然たる日記の寄せ集めです) (2023/04/01) ながら聞き用にbocoのPEACE SS-1買いました。 仕事中に音楽とかラジオとか聴きたい派なんですが、ずっとイヤホンをしていると耳が痛いし、中耳炎になって危ないってよく聞くし……と思って数年前にShokz(旧Aftershokz)の骨伝導イヤホンを買ったのが骨伝導との出会いでした。 買った当時は気にならなかったんですが、しばらく経ってちょっといい椅子を導入してヘッドレストにクッションをつけたら首周りの部分が干渉するようになってしまって、ちょっと不便だな〜と思っていたところにPEACE SS-1くんと出会いました。実に快適です。ありがとうboco。 (耳を挟むように押し込むと音量上げたりできるらしいですが、なんか直感的に出来なくてコツが必要&挟み込み部分の寿命縮めそうなので本体操作は諦めてます) (2023/06/16) 最近調べ物によくChatGPTを使っていて、便利だなぁと思う反面このままいくと原神のスメール編で学者たちに起きていたこと(聞けばなんでも出してくれるアーカーシャ端末があるから、誰も一次情報に触れようとしなくなる)が自分の中で起こりそうだなぁと漠然と考えたりしてました。 利便性の恩恵を受けつつ、自分で調べ物をする感覚は忘れないように上手く間をとっていきたいです。 (2023/06/17) 応用情報がCBT方式になるのを密かに待っているんですが(基本情報はそれで去年受けた)、長文読解とか記述方式の回答とかの相性の問題で中々導入されないんじゃないか説が結構濃厚な感じがするので、観念して秋季に受けようかなと考え中です。 予定があれば早起きできることを証明したいと思います。

<span title='2023-06-17 15:11:15 +0900 +0900'>6月 17, 2023</span>

SSOについて調べたことまとめ

SSO、使う側としてはよく見かけますが実装する側としてはあんまりキャッチアップしてこなかったなと思ったので、軽く調べたのをまとめておきます。 SSOとは シングルサインオン(Single Sign-On、SSO)は、ユーザが1回の認証で複数のアプリケーションにアクセスできるようにする仕組み全般のことを指します。 大きく分けるとSAML(Security Assertion Markup Lnaguage)、OIDC(OpenID Connect)の2つの一般的なプロトコルがあります。(※諸説ある) SAML SAMLアサーション(ユーザ情報とアクセスできる内容を含む暗号化署名されたXMLドキュメント)を使用してサービス間でID情報を共有します。 ビジネス系(Slack, Office365, Salesforce)などでよく見られる(らしい)です。 OpenID Connect JWT(JSON Web Token)を使用してサービス間でID情報を共有します。 よくお世話になる「GoogleアカウントでYoutubeにログインしている」系はOpenID Connectで実現されています。 代表的な実現方式 (【図解つき】シングルサインオン(SSO)とは?機能や仕組み、導入メリット、デメリットをわかりやすく解説! | mobiconnect(モビコネクト)を多大に参考にしています、ありがとうございます) 代行認証方式 利用者の代わりにエージェントが認証情報を保持し、ログイン画面を検知したら代行して各システムのID、パスワードを入力する方式です。 (個人的にはこれをSSOと呼んでも良いのか、という気持ちは多少あるけど、パスワード自動生成などで認証情報を意識しないので実質SSO、と言うことなのかもしれない) システム側でSSOに対応していなくても、ID/パスワードでログインする一般的なシステムであれば使用することができ、活用範囲が広いです。 その代わり、利用者側のPC(もしくはWebブラウザ)に常駐するエージェントを必ず入れる必要があります。 リバースプロキシ方式 Web上で実現するSSOの仕組みとして、アクセスを全てリバースプロキシと呼ばれる中継サーバを介して行うようにネットワークを設計する方式です。 リバースプロキシに対して認証を行うと、認証済みのCookieが発行され、各サイトにアクセスできるようになります。 対象としたいシステムに何か導入する必要がないため、既存システムへの影響がほぼない状態で事前検証ができます。が、リバースプロキシがボトルネックになる可能性があります。 実装する場合はざっくり以下のような構成になります: Nginx等を使用して、アプリケーションへのリバースプロキシをセットアップ SSOプロバイダの設定(色々あるので最適なものを選ぶ) アプリケーション側の認証ビュー(API)の実装 エージェント方式 リバースプロキシ方式同様、Web上で実現するSSOの仕組みで、Webサーバやアプリケーションサーバにエージェントソフトウェアを組み込む方式です。 組み込んだモジュールがSSOサーバと連携することでSSOを実現します。 リバースプロキシと異なり、ボトルネックが発生しづらい、既存のネットワーク環境に変更を加えなくて良い点がメリットです。 SAML認証方式 SAML認証方式は、IdP(Identity Provider)とSP(Service Provider)の2つの要素で構成され、SP側(Webサーバやアプリケーション側)をSAMLに対応させることで、IdPが提供する認証情報を利用してSSOを実現できます。 (名前がすごくややこしいけど、別に他の方式がSAMLプロトコルを使わないと言うわけではなくて、この方式の説明の意図は「上二つの方式と異なりWeb上で完結せず、アプリケーション側でSAMLに対応するSSO方式」ってことだと思います) まとめ 認証まわりって難しいですね。 (見ている途中でソーシャル認証やOAuth2あたりの情報も出てきましたがちょっとパンクしてきたのでここで止めておきます) 参考 シングルサインオンとは|「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典 【図解つき】シングルサインオン(SSO)とは?機能や仕組み、導入メリット、デメリットをわかりやすく解説! | mobiconnect(モビコネクト) What Is Single Sign-on (SSO)? How It Works - YouTube 後で見たい Django SSO - YouTube

<span title='2023-06-17 11:06:39 +0900 +0900'>6月 17, 2023</span>

Flutter周りで知ったことまとめ

最近個人でFlutterを触っていて楽しいので色々調べていて、その時知ったことや勉強会で聞かせてもらった話などのまとめ。 (「こんな便利なものあるんだ〜」と思っても一回ブラウザのタブを開いちゃうと忘れがちなので、自分用のリンク集として) Material Design3 https://m3.material.io/ Material 3 is the latest version of Google’s open-source design system. Design and build beautiful, usable products with Material 3. (拙訳) Material 3 は、Google のオープンソース デザイン システムの最新バージョンです。 Material 3 を使用して、美しく使いやすい製品を設計および構築します。 Googleのデザイナーと開発者によって構築・サポートされている、オープンソースなデザインシステム。 Android, Flutter, そしてWeb向けのUXガイダンス・UIコンポーネントの実装が含まれている。 PrimaryColorを選択するだけでいい感じに各色設定してくれたりするので便利。 (絶対それ以外の便利な使い方もある) // ThemeDataで指定する ThemeData( useMaterial3: true, colorSchemeSeed: Colors.XXX, // 好きな色 ) これだけでデフォルトの「テストです!!!」と言わんばかりの真っ青なヘッダが変わるのでちょっと「おぉ……」ってなる。 DartPad https://dartpad.dev/ Dartの構文を気軽に試せる。便利。 ちなみに、新しいバージョンを試したいときは下のstable channelを押して切り替える。 Serverpod https://serverpod.dev/ reverpodならぬServerPod。 Flutterコミュニティ向けに、Dartで書かれたOSSのアプリサーバ。 isar https://isar.dev/ hiveのv2系としてのプロジェクトらしい? Flutterで使うデータベース。詳しくはこれから調べる。

<span title='2023-03-11 20:43:27 +0900 +0900'>3月 11, 2023</span>

Python: requestsのタイムアウトエラーについて

pythonでHTTP通信するときに大体使うrequestsで、timeoutエラーの種類で問題の切り分けがしたくて調べたのでちょっとまとめ。 TL;DR 公式ドキュメントのExceptionsを見るとわかりやすい。 中でもタイムアウト関連のエラーは以下の二つ: connect timeout requests.exceptions.ConnectTimeout例外が投げられる。 相手のサーバと接続を確立する時に時間がかかりすぎたtimeout。 公式ドキュメント read timeout requests.exceptions.ReadTimeout例外が投げられる。 相手のサーバからレスポンスが返ってくるまでに時間がかかりすぎたtimeout。 公式ドキュメント 両方まとめてcatchしたい時は requests.exceptions.Timeout例外が設定されていて、ConnectTimeout, ReadTimeoutどちらも含まれます。 もうちょっと詳しく そもそもRequestsの例外の中には、RequestException(曖昧な例外)やConnectionErrorが設定されていて、明らかに設定がおかしい場合や早期に接続エラーが起きた場合には、レスポンスを待つ前にこの例外が投げられます。 それらが起きずにtimeoutエラーが起きた場合は、接続の確立で相手からレスポンスが返ってこない(ConnectTimeout)か、接続確率はできてるけど接続先がデータの準備などで時間がかかりすぎて設定したtimeout時間内にレスポンスが返ってこない(Readtimeout)かの二択。 なので、ConnectTimeoutが起きた時には安全に再試行できると公式ドキュメントにも書かれてます(少なくともリクエスト時の設定に問題がある訳じゃないから)。 Timeout例外が出た時にする事は下記の感じになると思います: ConnectTimeoutが出た場合は、リクエストを投げてる相手のサーバがダウンしてないか、ネットワーク設定に問題がないかを確認する。 ReadTimeoutが出た場合は、接続の確立には成功していて、向こうのレスポンスに時間がかかっているので、リクエストするサーバ側にも責任がある場合はチューニングする。そうでない場合は一度timeout時間を伸ばして成功するか様子を見る。 デフォルトのtimeout時間は設定されていないので注意する 明示的に設定しない限り、timeoutのデフォルトはNoneです。つまりtimeoutしません。 基本的にはtimeoutを設定して、上記のtimeoutエラーで原因がわかるようにした方が良さそうです。 import requests try: # connect timeout, read timeoutどちらも同じ値で良い場合 res = requests.get('有効なURL', timeout=30) # connect timeout=30, read timeout=60とかで分けたい場合 res = requests.get('有効なURL', timeout=(30, 60)) except requests.exceptions.ConnectTimeout: print("接続確立のエラー") except requests.exceptions.ReadTimeout: print("レスポンスが遅すぎたエラー")

<span title='2023-03-08 16:47:00 +0900 +0900'>3月 8, 2023</span>

Wakatime導入してみた

個人開発でアプリ出したいなぁと思っていて(今はFlutterくんと仲良くなるためにチュートリアルやってるだけですが)、毎日少しずつでもコーディングするモチベーションが欲しい……!と思ってwakatimeを導入しました。 wakatimeは、VSCodeなどのエディタと連携して、実際にコーディングしている時間を計測してくれるサービスです。 ちょうど最近登録したLAPRAS(GithubやTwitterなどからクローリングした情報をまとめてポートフォリオにしてくれるサービス)のbeta版機能として連携できるようになっていて知りました。 個人で使っているPCのVSCodeにだけ導入しておけば、完全に個人でコーディングしている時間を集計できるのが良さげです。 インストール&セットアップ サイトからgithubでサインアップ settingsにあるSecret API Keyをコピーしておく VSCodeの拡張機能でwakatimeをインストール インストールが終わるとAPIKeyの入力を求められるのでペースト これだけです。ダッシュボードは割とリアルタイムに反映されるので、少しコードを触って見に行くと集計されてます。 どのリポジトリを触ったか、どの言語を触ったか、更にはデバッグしていた時間なども記録されてました。 profileに反映されるのは少し時間がかかりますが、少しすると表示され始めます: (githubのProfileにバッジも置いてみた) 結論: 良さそう 最初は「ブログでもzennの記事書くときでも結構だらだらmdファイル触るし、触った言語比率とかそういうのpublicになるとちょっと恥ずかしいな〜」みたいな謎のプライド(?)で導入を悩んでいたんですが、公表するデータは制御できるし、最初から気軽な気持ちで導入しておけばよかったなと思いました。 サイト内でコーディング時間のゴールも設定できる&profileの草形式で自分の頑張りが見られるので、モチベーションアップに繋がりそうです。 (個人で触るコードのみの環境なのでサクッと導入しましたが、仕事上の守秘義務のあるコードを触る環境なんかに入れる時はセキュリティ的にちゃんと色々調べないといけないと思います。)

<span title='2023-02-28 23:40:16 +0900 +0900'>2月 28, 2023</span>

Hugoを使用しているサイトでmermaidを記述できるようにする

最近読んだGoF本を記事としてまとめたくて、このサイト内でmermaidを記述したかったので組み込みました。その時の備忘録です。 ※「エラーを出さずに動くようにする」をメインに進めていったので、「こっちの方がいい」「これやらない方がいい」等もあるかもです。適宜読み替えて実施してください。 手順 mermaidのUNPKGから、mermaild.min.jsとmermaild.min.js.mapをダウンロードする static/jsあたりに取得した2つのファイルを置く 適宜リネームしてください。私はVersion情報を入れてmermaild.min.9.2.jsにしました layouts/shortcodes/mermaid.htmlを作成する。 <script src="{{"js/mermaid.min.9.2.js" | relURL}}" defer></script> <div class="mermaid" align="{{ if .Get "align" }}{{ .Get "align" }}{{ else }}center{{ end }}"> {{ safeHTML .Inner }} </div> (ローカルで確認するときは)ビルド&devサーバ立ち上げ 記事内に{{<mermaid>}} mermaidの記述 {{< /mermaid >}}と記述することで、図として表示されるようになります。 結果 これは試しに入れてみた公式ドキュメントの例: (ダークモードだとちょっと見づらいかも) sequenceDiagram participant Alice participant Bob Alice->>John: Hello John, how are you? loop Healthcheck John->>John: Fight against hypochondria end Note right of John: Rational thoughts prevail! John-->>Alice: Great! John->>Bob: How about you?...

<span title='2022-12-14 19:20:31 +0900 +0900'>12月 14, 2022</span>