VimConf 2023 Tiny に行ってきた

vim

昨日(11/18)はVimConfに行ってきました。 前回が2019年だったので実に4年ぶりの開催でした。 vimconf.org 2017年から2019年は3回ともスピーカーでしたが、今回は久しぶりの一聴衆でした。 なので当日は全く緊張する必要がなく、とても穏やかな気持ちで参加す…

gnosticでOpenAPIをProtocol Buffersに変換する

Go

gnosticとgnostic-grpcを使えばOpenAPIの.yaml(.json)を.protoに変換できる。 github.com github.com 1. gnosticをインストールする 2. gnostic-grpcをインストールする 3. 変換する 1. gnosticをインストールする go install github.com/google/gnostic@lat…

github.com/swaggest/openapi-goを使ってOpenAPIを生成する

Go

github.com/swaggest/openapi-goを使うとGoのコードからOpenAPIの定義(json/yaml)を生成できる。 pkg.go.dev 例: package main import ( "encoding/json" "fmt" "log" openapi "github.com/swaggest/openapi-go" "github.com/swaggest/openapi-go/openapi3" …

macvimをビルドする(2023/08)

vim

だいぶ前にも書いていた。 daisuzu.hatenablog.com ここ最近は毎朝UpdateMacVimを実行している。*1 UpdateMacVim() { cd $HOME/go/src/github.com/macvim-dev/macvim git fetch origin master if [ -z "`git diff FETCH_HEAD --shortstat`" ]; then cd - ret…

Goの外部パッケージに独自の変更を加える

Go

外部パッケージを使っていて、ちょっとした修正を試したい時は以下のような方法があります。 1. 外部パッケージをForkしてgo.modで置き換える 2. 外部パッケージのコピーをリポジトリに追加してgo.modで置き換える 3. 変更したファイルをリポジトリに追加し…

Vimの極意

vim

この記事はVim Advent Calendar 2022の1日目の記事です。 今年でVimをメインエディタにして15年になります。 最近どうすれば思考する速度でテキストを編集できるようになる*1のか考えたりすることがあったので、この機会に軽くまとめてみます。 簡単な操作で…

goplsに独自Analyzerを組み込む

Go

internal/lsp/source/options.goのdefaultAnalyzers()が返すmapに自作のAnalyzerを追加してgo installすれば使えるようになる*1。 用途としてはチームのコーディング規約をtextDocument/diagnosticでチェックしたり、チェックに引っかかったコードの修正や一…

QNAPをTS-233に移行した

今までTS-231を使っていたけど、たまに落ちることがあったり去年ついにサポートが切れてしまったのでTS-233に移行した。 手順はTS-231の電源を落として、HDDを入れ替えて、TS-233を起動するだけ。 起動後は固定IPにしていたのがDHCPになっていた*1のでQfinde…

golang.org/x/exp/jsonrpc2を使ってgoplsに接続する

Go

最近golang.org/x/expにjsonrpc2が追加されていることを知ったので試してみた。 pkg.go.dev 基本的な使い方としてはDialでConnectionを作成し、 レスポンスが返ってくるメソッドはCall + Await レスポンスが返ってこないメソッドはNotify を呼べば良い。 Con…

go-cmpでmap内の時間文字列を近似比較する

Go

以下のような関数をテストする際、期待する値もtime.Now()で生成して概ね問題ない。 func f() map[string]interface{} { return map[string]interface{}{ "time": time.Now().Format("2006-01-02 15:04:05"), } } ただし関数内に多くの処理がある場合など、…

Vimのterminalでパイプを使う

vim

この記事はVim Advent Calendar 2021の9日目の記事です。 Vimにterminal機能が追加されてずいぶん経ちましたが、普段はtmux上でVimを使っていたので実際のところ使用頻度はそんなに高くありませんでした。 たまに使った時は出力がVimの中に閉じているため、…

Goのモジュールを個別に更新する

Go

特に問題なければ go get -u ./... で全て更新してしまうのが楽ですが、更新できないモジュールがある場合は個別に更新する必要があります。 go list -m -u all で全モジュールとその更新有無を確認できるため、 -f でgo getコマンドを出力するようにし、必…

aws-sdk-go-v2をモックせずにテストする

Go

テストでaws-sdk-go-v2を使う場合はドキュメントにある通り、Clientのモックを用意するのが一般的な手法かと思います。 ただテストのためだけにinterfaceを書きたくないので、aws-sdk-go-v2が提供するClientをそのまま使える形にしたいです。 幸いaws-sdk-go…

xorm.EngineGroupで複数のDBをまとめる

Go

データベースをWriterとReaderで分けている時、xorm.ioのEngineGroupを使うことでどちらのDBを使うのかを任せられるようになります。 使い方は通常のNewEngineと似ていて、NewEngineGroupの第2引数に接続先をスライスで渡します。 接続先のスライスは1番目が…

goplsと静的解析を活用して変更の影響範囲を調べたい

Go

1000パッケージ弱あるような巨大なリポジトリだと、関数1つの修正でどこまで影響があるのかを調べるのが結構大変*1だったりする。 Vimプラグインを作ったり、goplsを魔改造してみたりしてみたものの、使う人や環境を選ぶし、実行速度もイマイチだったのでも…

goplsのdaemonモードを使う

Go

goplsはgopls -listen=<addr>で実行するとdaemonモードで起動し、指定した<addr>でTCP接続できるようになる。 github.com クライアントはgoplsを使っても良いし、独自に実装することも可能。 その場合、TCP上で以下のような形式のJSON-RPCを送受信すれば良い。 (改行は\r</addr></addr>…

xorm更新用のテストを静的解析で生成した時のメモ

Go

前に書いた↓を使ってxormのバージョンを上げようと思っていたけど、生成されるSQLがおかしくなることがあると聞いたのでさらにテストを拡充することにした。 daisuzu.hatenablog.com といってもまだ完成していないので、ここまでやったことを備忘録*1として…

みんなで書くGoのエンドポイントテスト

Go

Webアプリケーションサーバーに何か大きな変更をしたいけど、既存のテストだと心許なかったので各エンドポイントにHandlerからのテストを追加することにした。 ただ全部のテストを自分1人で作っていくのはボリューム的に現実的ではなかったので、どうしたら…

GoのWebアプリで見かけたツラいコード

Go

構造体のフィールドにContextを持たせる Contextの中に参照を入れておいて任意の場所で更新する 似ている処理を匿名の構造体でまとめる 構造体のフィールドにContextを持たせる ほとんどの場合、各メソッドの引数にいちいちctxを渡すのが面倒だという理由だ…

vim-lspのCallHierarchyをツリーっぽく表示する

vim

リファクタリングしたりコードを調べたりする時、呼び出し元を探すのにLspReferencesやLspCallHierarchyIncomingを使っていた。 ただ、どちらも1階層分しか表示してくれず、呼び出し元が遠いと影響範囲が把握しにくかったのでquickfixに結果をマージして表示…

go/analysisのSuggestedFixでコードを修正する

Goの既存コードを修正するツールを作る時、 既存コードをどう書き換えて 出力して テストするか を考えなければいけないのが少し面倒だと思っていました。 が、golang.org/x/tools/go/analysisのSuggestedFixを使えばすごく簡単にできてしまいます。 golang.…

go-cmpでmap[string]interface{}のJSONを比較する

Go

GoでJSONを扱う際、型を定義せずに map[string]interface{} を使いたくなることがあります。 var ( a = map[string]interface{}{ "data": map[string]interface{}{ "value": int64(1), }, } b = map[string]interface{}{ "data": map[string]interface{}{ "v…

編集を加速するVimのquickfix機能

vim

この記事はVim Advent Calendar 2020の3日目の記事です。 昨日は@mira010さんのvim pluginsをインストールしてみましょうでした。 みなさんquickfixを使っていますか? Vimのquickfix機能はgrepやmakeなどの結果を保持する専用のバッファと、それを扱うため…

GoでDBのテストにgithub.com/cockroachdb/copyistを使う

Go

久しぶりにMySQLを使ったシステムを触ることになったものの、現状のテストが遅すぎたので高速化に取り組むことにした。 遅い原因としては、 テストでDBを使うパッケージが多いので接続時間がそれなりになってしまう テストケースごとにTRUNCATE→INSERTでデー…

ISUCON10に初参戦してみた

ゴリラさんと出てみようと話していたものの、申し込みのタイミングを逃してオワタと思っていたら@inductorさんに拾ってもらい、カンガルーと犬とゴリラとしてなんとかISUCON10に参加することができました。 当日は開始ちょっと前*1にDiscordとGoogleドキュメ…

goplsのSymbolMatcherとSymbolStyleオプション

Go

以下の記事で、workspace/symbolのオプションは補完と同じmatcherと紹介したが、現在のv0.4.4ではsymbolMatcherとsymbolStyleになっている。 daisuzu.hatenablog.com まずはv0.4.1でmatcherがsymbolMatcherに変わり、それまでと同様、 fuzzy caseSensitive c…

Goでprotobufの定義をimportせずにフィールドの値を使う

Go

以下のようなコードでreqにあるフィールドを使いたい場合、 opt := grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { // …

gopls(v0.4.0)の機能

Go

goplsは更新頻度が高く、何ができるのかをちゃんと把握できていなかったので、LSPのメソッドベースで今の時点(v0.4.0)の機能をざっと調べてみることにしました。 補完(textDocument/completion) ジャンプ系 textDocument/definition textDocument/typeDefini…

GoでREST APIを呼ぶテストにhttp.FileServerを使う

Go

例えばGET /users/:idのようなAPIの場合、 testdata └── users └── 1 のように、testdata配下のusersディレクトリにidをファイル名としたJSONファイルを配置しておきます。 そうすると、 http.FileServer(http.Dir("testdata")) で、testdata配下のパスとリ…

packagestestのExported.Expectを使ってGoのソースからマーカーを収集する

Go

golang.org/x/tools/go/packages/packagestestパッケージは静的解析など、Goのソースを読み込んで何かしらの処理を行うようなツールのテスト用にダミープロジェクトを作るためのパッケージです。 そういったツールを作る際、テストで期待する結果を完全に決…