Gopls: 貢献

貢献は歓迎します!ただし、開発は急速に進んでおり、貢献をレビューする能力には限りがあります。したがって、CLを送信する前に、どうかどうかどうか

  • バグまたは機能リクエストのイシューを提出してください(まだ存在しない場合)。これにより、重複するリクエストを特定したり、特定の問題をより一般的な問題に統合したり、問題の重要性を評価したりすることができます。

  • イシューにコメントするか、可能であればイシューを自分に割り当てることで、自分でイシューを主張してください。これにより、2人が同じ問題に取り組むことを避けることができます。

  • どのような複雑さのCLでも、イシュー・トラッカーで実装計画を提案してください。コードレビューの詳細に陥る前に、高レベルで計画を議論する方がはるかに効率的です。

CLを送信する際は、以下を含める必要があります

  • 変更点を要約し、その必要性を説明し、高レベルで説明し、より明白または単純なアプローチとの違いを対比させ、関連するイシューにリンクするCL説明
  • テスト(統合テストまたはマーカーテスト)。
  • 新規または変更された機能のドキュメント。および
  • 新規機能または重要な変更のリリースノート

コードレビュー中は、すべてのレビュアーのコメントに対応してください。コメントによっては、直接的なコード変更が必要なものもあれば、より複雑な対応が求められるものもあります。レビュアーが質問した場合、最善の回答は直接回答するのではなく、コードを自己説明的にするなどして、質問が生じないようにコードを変更することです。コメントに異議を唱えたり、レビュアーの間違いを指摘したり、フォローアップの変更でコメントに対応することを提案したり、現在のCLにTODOコメントを残したりすることは問題ありません。ただし、行動せずにコメントを無視したり、ひっそりと見過ごしたりしないでください。これにより、レビュアーが繰り返しコメントしたり、深刻な問題が見過ごされたりする可能性があります。

詳細については、Goプロジェクトの貢献ガイドラインを参照してください。

イシューを見つける

すべてのgoplsイシューにはそのようにラベルが付けられています(goplsラベルを参照)。コントリビューターに適したイシューには、さらにhelp-wantedラベルが付与されています。

イシューに取り組み始める前に、それを担当することをコメントに残してください。

入門

goplsロジックのほとんどはgolang.org/x/tools/gopls/internalディレクトリにあります。コードの構成の概要については、design/implementation.mdを参照してください。

ビルド

変更が適用されたgoplsバージョンをビルドするには

cd /path/to/tools/gopls
go install

正しいgoplsバージョンでテストしていることを確認するには、goplsバージョンが次のように見えることを確認してください。

$ gopls version
golang.org/x/tools/gopls master
    golang.org/x/tools/gopls@(devel)

ヘルプを得る

goplsチームに直接連絡する最善の方法は、gophers slackの#gopls-devチャネルです。貢献について、または一般的な貢献について、ご質問があればお気軽にお尋ねください。

エラー処理

ユーザーエクスペリエンスにとって重要なのは、可能な限り、特定の機能における軽微なロジックエラーがサーバーをクラッシュさせないことです。

Goプログラムの表現は複雑です。パッケージメタデータのインポートグラフ、パースされたファイルの構文木、およびそれらに関連付けられた型情報は、すべて膨大なAPIサーフェスを形成します。入力が有効な場合でも、考慮すべきエッジケースは多く、インポートの欠落、パースエラー、型エラーを考慮すると、その数は桁違いに増加します。

「起こりえない」と考えるエラーをロジックで処理しなければならない場合、どうすべきでしょうか?

  • エラーを返せる場合は、bug.Errorf関数を使用してユーザーにエラーを返しますが、そのバグをgoplsのキャッシュにも記録することで、無視される可能性を低くします。

  • 安全に進められる場合は、bug.Reportfを呼び出してエラーを記録し、通常どおり続行できます。

  • 進行する手段がない場合は、bug.Fatalfを呼び出してエラーを記録し、log.Fatalfでプログラムを停止します。回復ハンドラーが状況を救う可能性がある場合は、bug.Panicfを使用することもできます。

  • ローカルでエラーが起こりえないことを証明できる場合にのみ、log.Fatalを呼び出すべきです。ただし、たとえ可能性が低いとしても、何らかの入力でエラーが発生する可能性がある場合は、上記のアプローチのいずれかを使用する必要があります。また、安全性の証明がコードベース全体に広く分散された不変条件に依存する場合は、代わりにbug.Panicfを使用する必要があります。

また、パニックはVS Codeのクラッシュレポートがスタックを認識し、キャプチャすることを可能にするため、log.Fatalよりも好ましいことに注意してください。

bug.Errorfなどを通じて報告されたバグは、gopls bugコマンドを使用して取得されます。このコマンドはGitHub Issueテンプレートを開き、各バグの概要とその頻度でテンプレートを埋めます。バグのテキストは、ユーザー名やエラーメッセージ文字列(プロジェクト識別子を含む可能性がある)をGitHubと共有しないように、かなり丁寧に標準出力に出力されます。ユーザーは、希望する場合に共有するよう促されます。

テスト

変更後にテストを実行するために使用すべき通常のコマンドは次のとおりです。

gopls$ go test -short ./...

-shortフラグは一部の実行時間の長いものをスキップします。トライボットビルダは、幅広いプラットフォームで完全なセットを実行します。)

Goplsのテストには2種類の組み合わせがあります。

  • マーカーテストは、各テストシナリオを、ターゲットとなる.go、go.mod、go.workファイルを含む独立したテキストファイルで表現し、コメントに埋め込まれた特殊なアノテーションがテストを駆動します。これらのテストは一般的に記述が簡単でイテレーションも速いですが、表現できる内容に制限があります。

  • 統合テストは、偽のLSP対応クライアントエディタのAPIに対する一連の呼び出しを行う通常のGo func Test(*testing.T)関数です。このAPIを使用すると、ファイルを開いて編集したり、定義に移動したり、他のLSP操作を呼び出したり、状態に関するプロパティをアサートしたりできます。

    LSPの非同期な性質上、統合テストはエディターが最終的に達成すべき状態をアサートします。プログラムがすぐに問題を起こしても、エラーが数分以内に目的の状態を達成できないという失敗として報告されるまでには時間がかかることがあります。デバッグ時に統合テストのタイムアウトを短縮するために、GOPLS_INTEGRATION_TEST_TIMEOUT=10sを設定することをお勧めします。

    失敗した場合、統合テストはクライアントとサーバー間のLSPセッションのログを出力します。冗長ではありますが、読み方を知っていればデバッグに非常に役立ちます。

ヘルプが必要な場合は、遠慮なくgoplsチームに連絡してください

CI

CLをメールで送信し、あなたまたは協力者がGerritでRun-TryBot=1ラベルを割り当てると、TryBotsは上記のとおりgolang.org/x/toolsgolang.org/x/tools/goplsモジュールの両方でテストを実行します。

さらに、Docker化されたテストを実行するためのJenkinsのようなGoogleインフラであるKokoroによって、追加の「gopls-CI」パスが実行されます。これにより、TryBotsに追加するのが難しいさまざまな環境でgoplsテストを実行できます。特に、KokoroはTryBotsではサポートされなくなった古いGoバージョンでテストを実行します。そのポリシーに従い、これらの古いGoバージョンのサポートは努力目標であり、テストの失敗は修正されるのではなくスキップされる場合があります。

Kokoroの実行は、TryBotsと同様にRun-TryBot=1ラベルによってトリガーされますが、TryBotsとは異なり、Gerritで「gopls-CI」の結果が削除されても自動的に再実行されません。Run-TryBot=1ラベルを含むCLでKokoro CIの再実行を強制するには、Gerritで「kokoro rerun」とコメントして返信できます。

デバッグ

変更をデバッグする最も簡単な方法は、デバッガを使用して単一のgoplsテストを実行することです。

また、トラブルシューティングも参照してください。

ドキュメント

機能を追加または変更する各CLには、新しい動作を検証するテストに加えて、以下を含める必要があります。

  • 変更点を簡潔に説明するリリースノート、および
  • 機能のインデックスにおける包括的なドキュメント

リリースノートは、今後のリリース用のファイルに記述してください。例えば、release/v0.16.0.mdです。(機能がリリース後に最初に追加される場合は、ファイルを作成してください。)

設計ドキュメント


このドキュメントのソースファイルは、golang.org/x/tools/gopls/doc の下にあります。