Commitizenの導入手順
Commitizenとは
Commitizen commitizen/cz-cli: The commitizen command line utility. #BlackLivesMatter
gitコメントのテンプレを提供してくれるCLIツールです。 導入することでコミットメッセージに盛り込む内容に悩む必要がなくなります。
インストール
Homebrewでインストールすると日本語化プラグインが認識されないので、npmでグローバルインストールする。
$ npm i -g commitizen
日本語化設定
日本語化モジュールをインストールする
$ npm install -g cz-conventional-changelog-ja
設定を追加する
# dotfiles管理下に設定ファイルをつくる touch ~/dotfiles/.czrc
{ "path": "cz-conventional-changelog-ja" }
# dotfiles管理下の設定ファイルを参照させる ln -snfv /Users/HOGE/Documents/github.com/shootacean/dotfiles/.czrc ~/.czrc
日本語化完了
$ git cz cz-cli@4.2.4, cz-conventional-changelog-ja@0.0.2 1行目は100文字で切り取られ、超過分は次行以降に記載されます。 ? コミットする変更タイプを選択: (Use arrow keys) ❯ feat: 新機能 fix: バグ修正 docs: ドキュメントのみの変更 style: フォーマットの変更(コードの動作に影響しないスペース、フォーマット、セミコロンなど) refactor: リファクタリングのための変更(機能追加やバグ修正を含まない) perf: パフォーマンスの改善のための変更 test: 不足テストの追加や既存テストの修正
参考
Google検索を効率化するテクニック
こんにちは、shootaceanです。
プライベートでのちょっとした調べ物や仕事での調査など、Google検索を使う機会はかなり多いと思います。
今回紹介するちょっとしたテクニックを活用することで、調べ物における作業を効率化できます!
さっそく紹介していきます。
- Google検索の設定を変更する方法
- 検索結果1ページ内に表示される件数を増やす
- 検索結果のリンクを別タブで開くようにする
- デフォルトで英語検索にする
- ブックマークレットで英語検索から日本語検索に簡単に変更できるようにする
- まとめ
Google検索の設定を変更する方法
まず、Google検索の設定を変更する方法についてですが、検索結果ページ右上の歯車アイコンから変更できます。
検索結果1ページ内に表示される件数を増やす
ブログやアフィリエイトサイトが増えてきた影響か、内容の薄い記事や海外サイトを日本語に自動翻訳しただけの記事などが増えているので、1ページ目だけでは欲しい情報が見つからないことも多いです。 その際にいちいち2ページ目に移動するのは面倒なので、デフォルトのページ件数の10件から30件に変更します。
検索結果のリンクを別タブで開くようにする
デフォルトの挙動だと、検索結果のリンクをクリックするとページ遷移してしまい、検索結果ページに戻るにはブラウザバックをしないといけないです。 それだと、複数の結果ページを行き来しづらいので、常に別タブでリンクを開くように設定します。 PCだとctrl/command + 左クリックで別タブで開くことができますが操作が手間なので、この設定を行います。
デフォルトで英語検索にする
私の場合だとソフトウェアエンジニアなので、日本語のサイトよりも海外のサイトで調べ物をすることが多いです。 まずは英語圏の情報で収集し、必要に応じて日本語の情報で検索します。
英語圏の情報にアクセスする頻度が高い場合は、この設定をしておくことをおすすめします。
ブックマークレットで英語検索から日本語検索に簡単に変更できるようにする
上記の「デフォルト英語検索」とセットで使えるテクニックです。
英語検索で欲しい情報が見つからなかった場合は、日本語検索に切替えるのですが、普通に切り替えようとすると、再度Google検索の設定を変更する必要があり、かなり面倒くさいです。
そこで、こちらのブックマークレットを使います。
Googleの検索言語をサクッと切り替えるためのブックマークレット - かみのメモ
以下のJavaScriptをブックマークのURL部分に貼り付けて、ブックマークバーに置きます。
javascript:(()=>{if(location.host=='www.google.com'&&location.pathname=='/search'){var params=new URLSearchParams(location.search);params.set('hl', params.get('hl')=='ja'?%27en%27:%27ja%27);location.search=params.toString();}})()
こうすることで、ブラウザのアドレスバーから検索したときは英語検索、英語検索で欲しい情報が見つからなかった場合はブックマークレットを実行して、日本語検索に切り替える、ということが実現できます。
まとめ
かなり小技的なTipsですが、毎日使うものなので、かなりの時間の節約になるのではないかと思います。 Google検索での調べ方にストレスを感じている方は、ぜひ試していただければと思います!
個人利用に最適な翻訳APIを探してみた
500,000 character limit / month
https://shootacean.com/entry/2021/10/10/i-tried-to-find-the-best-translation-api-for-personal-use
こんにちは、shootaceanです。
こちらの記事で紹介したプログラムを書く上で調べた、個人利用で使いやすい無料で利用できる翻訳APIをご紹介します。
DeepL API Freeを使った日本語ブログ記事タイトルをブログURLに変換するPythonスクリプト
用途の前提
- 個人利用
- 月間の翻訳文字数は500,000文字に満たない
- 公開してはいけない文字列を翻訳しない
- APIを利用して自動化などを行う
結論
いきなり結論ですが、
個人利用で無料で済ませたいのであれば、クレジットカードの登録なしで利用できる「DeepL API Free」 一択です。
その他のサービスは無料枠は存在するものの、無料枠に収まらない場合は費用が発生してしまいます。
DeepL API Freeの場合は、無料枠の月間上限に達するとAPI自体が利用できなくなるため、費用の心配をする必要がありません。
ただ、
500,000 character limit / month
の制限があるので、翻訳頻度が高く翻訳文字数も多ければ、すぐに月間の制限に達してしまうのでガッツリ使う場合は、有料プラン前提で他サービスと比較しましょう。
DeepL API
DeepL Translate API | Machine Translation Technology
DeepL Pro | Translate Text, Word Docs & Other Docs Securely
Google Cloud Translation
Cloud Translation | Google Cloud
料金 | Cloud Translation | Google Cloud
Amazon Translate
Amazon Translate(高速で高品質なニューラル機械翻訳サービス)| AWS
Microsoft Azure Translator
Translator - サービスとしてのソフトウェア | Microsoft Azure
価格 - Translator | Microsoft Azure
参考
gRPC + Goのhelloworldを試してみる
こんにちは、shootaceanです。
実務でWEBサービスのリアーキテクチャが進もうとしているので、気になっていたgRPCを学習してみます。
基本的にgrpc.ioのクイックスタートの手順で進めたのですが、エラーなどで手順どおりにならない部分もあったので、その点も含めて書いていきます。
https://grpc.io/docs/languages/go/quickstart/
前提
$ echo $SHELL /bin/zsh $ go version go version go1.16.6 darwin/amd64 $ protoc --version libprotoc 3.17.3
Procol Bufferのコンパイラをインストールする
Protocol Buffersのコンパイラ protoc
をインストールします。
$ brew install protoc
gRPCのGoプラグインをインストールする
$ go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26 $ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
上記のコマンドで以下のエラーが発生する場合があります。
cannot use path@version syntax in gopath mode
私の場合は、go get
でインストールすることで、解決できました。1
$ go get -u google.golang.org/protobuf/cmd/protoc-gen-go $ go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc
サンプルコードを実行してみる
サンプルコードが公開されているので git clone します
$ git clone -b v1.35.0 https://github.com/grpc/grpc-go $ cd grpc-go/examples/helloworld
gRPCサーバープログラムを実行します。
$ go run greeter_server/main.go
別のターミナルでgRPCクライアントプログラムを実行します。
$ go run greeter_client/main.go 2021/08/19 20:30:00 Greeting: Hello world
gRPCクライアントプログラムを実行して上記のような出力が得られれば成功です。
サンプルコードに変更を加えてみる
サンプルコードそのままは動かせたので、新しいエンドポイントを作ってみます。
- 定義ファイルを更新
- 定義ファイルから再生成
- サーバ側プログラムを修正
- クライアント側プログラムを修正
- 実行
という流れです。
Protocol Buffersファイルを修正する
gRPCプログラムを変更する場合は、まず IDLであるProtocol Buffersの .proto
ファイルを修正します。
今回のサンプルコードであれば、helloworld/helloworld.proto
ファイルを修正します。
// The greeting service definition. service Greeter { // Sends a greeting rpc SayHello (HelloRequest) returns (HelloReply) {} // 以下2行を追加する // Sends another greeting rpc SayHelloAgain (HelloRequest) returns (HelloReply) {} }
修正できたらProtocol Buffersからgoプログラムを再生成します。
helloworld/helloworld.pb.go
と helloworld/helloworld_grpc.pb.go
の2ファイルが再生成されます。
$ protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ helloworld/helloworld.proto
上記のコマンド実行時に以下のエラーが発生した場合は、
前手順の protoc-gen-go-grpc
のインストールが漏れているので、インストールしてください。
protoc-gen-go-grpc: program not found or is not executable Please specify a program using absolute path or make sure the program is available in your PATH system variable --go-grpc_out: protoc-gen-go-grpc: Plugin failed with status code 1.
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1 または $ go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc
gRPCサーバープログラムを修正する
helloworld/greeter_server.go
を修正します。
// SayHello implements helloworld.GreeterServer func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { log.Printf("Received: %v", in.GetName()) return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil } // ここを追加する func (s *server) SayHelloAgain(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { return &pb.HelloReply{Message: "Hello again " + in.GetName()}, nil }
gRPCクライアントプログラムを修正する
helloworld/greeter_client.go
を修正します。
main関数の最後に追記します。
func main() { // 省略 r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.GetMessage()) // ここを追加する r, err = c.SayHelloAgain(ctx, &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.GetMessage()) }
実行する
$ go run greeter_client/main.go Alice 2021/08/19 21:17:00 Greeting: Hello Alice 2021/08/19 21:17:00 Greeting: Hello again Alice
無事に変更点が反映されて、問題なくクライアントからサーバー関数を呼び出せています!
まとめ
gRPCはもっととっつきにくい技術かと思っていたのですが、実際に手を動かしてみると思っていたよりも簡単に試すことができました。
マイクロサービスでのサービス間通信で使われていることが多いようですが、gRPC-webでブラウザとサーバー間の通信にも利用できるようになりつつあるので、大部分の通信をgRPCで完結することもできそうです。
何よりもProcol BufferというIDLによるスキーマ駆動開発の恩恵が大きいと感じました。 REST APIでもSwaggerなどでOpen APIに沿ってのコード自動生成は可能ですが、通信方法であるgRPCとIDLであるProtocol Buffersの密接な関係により、開発時のモック用意など、よりスキーマ駆動開発がやりやすい印象です。
Goのシンプルな構文とProtocol BuffersのIDLによって、チームでの開発もやりやすそうですね。 個人的にもかなり興味がある分野なので、gRPC-webも含めて何か個人開発してみようと思います。
参考
- Basics tutorial | Go | gRPC
- Ubuntu 16.04でGOPATHエラー「go:GOPATHモードでpath @version構文を使用できません」を取得-スタックオーバーフロー
- プロトコルバッファ-protoc-gen-go-grpc:プログラムが見つからないか実行可能ではありません-スタックオーバーフロー
- Go Generated Code | Protocol Bufferss | Google Developers
-
この記事を書いている際に
Go 1.16.6
にバージョンアップしたのですが、手順通りgo install
でインストールできました。↩
CloudFormationやCDKからLightsailは操作できない
こんにちは、shootaceanです。
https://web-labs.shootacean.com でバックエンド側の検証環境も用意したく、ホスティングできる環境としてLightsailを検討していました。
現状web-labsは静的ページしか無いので CloudFront + S3 でホスティングしています。 CDKでリソースを管理しているので、同じようにLightsailも管理できればいいなと思い、調べていました。
結論
できません。
CloudFormationがLightsailをサポートしていないので、当然CDKもサポートしていません。
調べた内容
「cdk lightsail」などでGoogle検索すると、すぐに該当するGitHub Issueが出てきました。
Add Lightsail support · Issue #10471 · aws/aws-cdk
Issueの内容の通り、
CloudFormationがサポートしていないので、CDKもサポートしていないです。
まず、CloudFormationでサポートする必要があるので、そっちにIssue作ったよ。
というやり取りがされていました。
AWS::Lightsail::* · Issue #640 · aws-cloudformation/cloudformation-coverage-roadmap
CloudFormationのIssueでも議論が進んでいないので、残念ながらサポートは期待できなさそうです。
まとめ
そもそものLightsailの立ち位置がAWSの主要サービスを少し隠蔽して簡単に使いやすくしたものなので、IaCまで考えるなら通常のEC2を使えばいい、ということで議論が進んでいない・サポートされていないのかもしれないですね。
今回のweb-labsではCDKを学習する面もあるので、Lightsailではなく通常のEC2を利用しようと思います。
Elmでフィボナッチ数列を計算してみた
こんにちは、shootaceanです。
Elmで何かをつくりたくなったので フィボナッチ数列を生成するWEBアプリ をつくってみました。
こちらのサイトにホスティングしているので、ぜひ試してください! https://web-labs.shootacean.com/elm/fibonacci/index.html
ソースコードはGitHubで確認できます! https://github.com/shootacean/shootacean.com/blob/main/web-labs.shootacean.com/src/elm/fibonacci/src/Main.elm
バグってるよ、もっと簡単に書けるよ、などの指摘や意見があればTwitterのDMやメンションなどでお願いします!
フィボナッチ数列を計算する関数
他のプログラミング言語でもよくあるメモ化している実装です。
fibonacci : Int -> List Int -> Int fibonacci n memo = let m = List.getAt n memo in case m of Just memoNum -> memoNum Nothing -> case n of 0 -> 0 1 -> 1 _ -> ( fibonacci (n - 2) memo ) + ( fibonacci (n - 1) memo )
update処理
メモ化とViewに表示するためのリストを更新しています。
update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of Increment -> let n = model.num + 1 fib = fibonacci n model.sequences in ( { model | num = n, sequences = List.append model.sequences [fib] } , Cmd.none )
メモ化なので永続的な状態を保つ必要があるのですが、他のプログラミング言語と違ってElmはTEAに縛られています。
まだElmとTEAの理解ができていなかったので、メモ部分をどうやって持つかで1時間くらい悩んでしまいました…
TEAに従って updateで計算して model を更新する ことしかできないので、 ただいつもどおりTEA様に従うだけでよかったです。
おわりに
個人的にElmを書いていて一番嬉しいのは、HTMLとJavaScriptを行き来しないでよくなることですね。 本当にのんびりとElmを学習しているのでまだまだわからないことばかりですが、ゆったりとElm書いていこうと思います!
aws cliのs3 syncで特定の拡張子ファイルだけをアップロードする方法
こんにちは、shootaceanです。
aws s3 sync
というコマンドで特定の拡張子のファイルだけをアップロードする方法をご紹介します。
Web技術を試す場として、
https://web-labs.shootacean.com
というサイトをつくっていて、そのサイトにデプロイする際に利用しているコマンドです。
HTML、CSS、JavaScriptファイルだけをアップロードしたい場合は、以下のコマンドになります。
$ aws s3 sync src/ s3://bucket-name/ \ --exclude "*" \ --include "*.html" --include "*.css" --include "*.js"
注意点
s3 — AWS CLI 1.20.10 Command Reference
When there are multiple filters, the rule is the filters that appear later in the command take precedence over filters that appear earlier in the command.
複数のフィルターがある場合、コマンドの後半に表示されるフィルターが、コマンドの前半に表示されるフィルターよりも優先されるという規則があります。
とドキュメントに記載されているとおり、
上記コマンドの --exclude
と --include
の指定順序を変えると 全てが exclude されてしまいます。
Reference
ユーザー入力のユーザビリティを高めるためのautocomplete属性
こんにちは、shootaceanです。
HTMLのautocomplete属性使ってますか?僕は全然意識していませんでした…
入力フォームのHTMLを書いていると、Chrome Dev Toolsのコンソールに以下のメッセージが表示されているに気づきました。
そのメッセージ内にあったリンク先1に「autocomplete属性使うといいよ〜」ということが書かれていました。
[DOM] Input elements should have autocomplete attributes (suggested: "username"): (More info: https://goo.gl/9p2vKq)
よく利用しているサービスとかにあったオートフィルはこの属性を使ってやっていたのかと、恥ずかしながら初めて意識しました。
この記事は実際に試してみた感想と気づきをご紹介します。
実際にコードを書く
ひとまず、自分の手元でコードを書いて試してみました。
- Auto Complete | HTML Labs | web-labs.shootacean.com
- shootacean.com/autocomplete.html at main · shootacean/shootacean.com
ログイン情報にあたるユーザー名にしっかりとオートコンプリート候補が出てきました。
パスワード項目に関しては、Dropbox PasswordsのChrome Extentionsもautocomplete属性で制御しているようで、current-password
やnew-password
をつけた項目には、アイコンが適用されました。
特に意識した方がいいのはユーザーの氏名や住所などの部分ですね。 配送先などの入力は面倒ですし、サービス毎に入力する内容が変わることもそんなにありません。
一度入力した内容をそのまま1アクションで埋めて、そのまま登録できる、というのはかなり手間が省けるので、積極的にautocomplete属性を設定したいですね。
オートコンプリートしたくない場合
銀行系などの機密性の高いサイトの場合は、オートコンプリートしないようにすることがあります。
その際は autocomplete=off
と明示的に指定することでオートコンプリートのデータとしてブラウザに保存されなくなります。
HTMLの仕様としては、以下のように記載されているので autocomplete属性が未指定の場合は、ブラウザに保存される可能性があるのかもしれません。2
HTML Standard #autofill When an element's autofill field name is not "off", the user agent may store the control's data, and may offer previously stored values to the user. 要素の自動入力フィールド名が「off」でない場合、ユーザーエージェントはコントロールのデータを保存し、以前に保存された値をユーザーに提供することができます。
MDNの方にはもっと具体的な説明がありました。
フォームのオートコンプリートをオフにする方法-Webセキュリティ| MDN autocomplete="off"フィールドに設定すると、次の2つの効果があります。 ・準拠するためのヒューリスティックはブラウザによって異なりますが、ユーザーが入力したデータを後で同様のフォームでオートコンプリートするために保存しないようにブラウザに指示します。 ・ブラウザがセッション履歴にフォームデータをキャッシュするのを停止します。フォームデータがセッション履歴にキャッシュされている場合、ユーザーがフォームを送信し、[戻る]ボタンをクリックして元のフォームページに戻った場合に、ユーザーが入力した情報が表示されます。 オートコンプリートをオフに設定した後もブラウザが提案を続けている場合は、入力要素の名前属性を変更する必要があります。
ただし、ログインフィールドに関しては、autocomplete=off を無視してブラウザのパスワード管理機能をサジェストされることがあるみたいです。
フォームのオートコンプリートをオフにする方法-Webセキュリティ| MDN ユーザーはブラウザに保存されているパスワードを覚えておく必要がないため、他の方法よりも強力なパスワードを選択できます。
ユーザーが記憶できるレベルのパスワードよりも、難易度の高いパスワードをブラウザのパスワード管理機能で管理したほうが強力なので納得できますね。
まとめ
オートコンプリートの独自実装や機密性の高い入力項目が無い限りは、必須で設定したほうがユーザビリティが上がるのではないかと思います。
氏名や住所が変わる頻度はそう高くないですし、ブラウザ側に保持してオートコンプリートする方が、初期訪問時のユーザーにも恩恵があります。
ブラウザ側の仕様や機能を理解しておくことで、ユーザビリティを上げることもできるので、しっかり情報は追っていかないといけないですねー。
補足
自動入力でユーザーがより速くチェックアウトできるようにする| Web | Google Developers
このサイトに記載されていた「autocomplete=region」「autocomplete=locality」は非推奨になっているおり、情報が古いので注意です。
ちなみに使ってみると、DevToolsのコンソールにワーニングが表示されます。3
autocomplete='region' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW autocomplete='locality' is deprecated and will soon be ignored. See http://goo.gl/YjeSsW
Referrence
- The HTML autocomplete attribute - HTML: HyperText Markup Language | MDN
- Chromiumが理解するパスワードフォームスタイル-Chromiumプロジェクト
- すばらしいパスワードフォームを作成する-Chromiumプロジェクト
- 自動入力でユーザーがより速くチェックアウトできるようにする| Web | Google Developers
- 最適なフォームの作成 | Web | Google Developers
- Help users checkout faster with Autofill | Web | Google Developers
- HTML Standard #autofill
- フォームに自動入力する - パソコン - Google Chrome ヘルプ
【Todoist】タスクの説明を入力できるようになりました!
こんにちは、shootaceanです。
Todoistの7月22日のアップデートで、タスクの説明が入力できるようになりました!
新機能のお知らせ
今まで、タスクの補足やちょっとしたメモはコメントに残すしかなく、 コメントはファーストビューに表示されないので、確認するときには能動的にコメントを見に行く必要がありました。
それだと「このタスクにはコメントに何か補足やメモを残していたはず」というように少し記憶しておかなければならず、完全に忘れ去ることができません。
今回のアップデートで追加された「タスクの説明」項目はファーストビューに表示されるので、上記のようなことを全く気にする必要がなくなりました!
モバイルアプリではこのように表示されます。
複数行の場合は1行目しか表示されません。
地味ですが素晴らしいアップデートですね!
Amazon RDSのバックアップ設定を一覧で取得するPythonスクリプト
こんにちは、shootaceanです。
AWS環境の現状把握作業の一環で、RDSのバックアップ設定を一覧出力するPythonスクリプトを書きました。
同じことはaws cliだけでも実現できるので、そのコマンド例も載せています。 取得した結果を元にさらに処理を行いたい場合は、Pythonスクリプトの方を参考にできると思います。
実行例
$ python3 describe_rds_cluster_backup_window.py rds-cluster-identifier-123456789 7 20:00-20:30 tue:21:00-tue:21:30
Pythonコード
Amazon RDSのバックアップ設定を一覧で取得するPythonスクリプト
AWS CLIコマンド
% aws rds describe-db-clusters \ --query="DBClusters[*].[DBClusterIdentifier,BackupRetentionPeriod,PreferredBackupWindow,PreferredMaintenanceWindow]" \ --output text \ --region ap-northeast-1 \ --profile your-profile rds-cluster-idnetifier-123456789 7 20:00-20:30 tue:21:00-tue:21:30