web-dev-qa-db-ja.com

チーム用のGoサブパッケージの構造化

現在、コードベースの一部をGoに移行しており、チーム内の複数の開発者向けの柔軟なディレクトリ構造に少し苦労しています。これが初心者の質問である場合はお詫びしますが、私は他のすべての場所を検索し、答えを思いつきませんでした。

次の構造のパッケージがあるとします。

package main

import "username/myproject/subpackage"

func main() {

}

およびサブパッケージ:

package subpackage

func main() {

}

これは正常に機能し、Githubで他の人々のコードを読むことから、これがサブパッケージを定義するための受け入れられた方法であるように思われます。

例としてCoreOSソースを参照してください: https://github.com/coreos/etcd/blob/master/main.go

私の問題は、Goのディレクトリ構造が原因で、これらのパッケージが特定のgitリポジトリ内に保存され、チームの他の誰かがこのコードをチェックアウトして作業する場合、フォークによってディレクトリ構造が異なることです。パスとインポートステートメントのユーザー名が変更されます。これは、一元化されたリポジトリを使用するのではなく、相互に多くをプルおよびプッシュするという事実によって助けられません。

package main

import "otherusername/myproject/subpackage" (This line will have to be changed)

func main() {

}

Goについて読んだことはすべて、チーム環境での使いやすさを示しているので、パッケージシステムを正しく理解しているかどうか疑問に思っています。

理想的には、相対パスを使用してサブパッケージを呼び出せるようにする必要があります。私たちは名前空間の操作に慣れていますが、Goには名前空間がないことを私は知っています。すなわち:

package main

import "myproject/subpackage"

func main() {

}

しかし、Goはファイルを見つけることができず、オンラインで相対パスを使用する例がないため、これは正しい方法ではないと確信しています。

だからいくつかの質問:

1)パッケージには定義済みの所有者があり、インポートパスの一部として常にそのユーザー名を保持する必要がありますか?

2)この「所有者」レポは、すべてのコードがプッシュ/プルされる集中リポジトリ(たとえば、会社または組織)である必要がありますか?

3)コードの一部に取り組んでいる他のチームメンバーは、自分のコードではなく、作成者のフォルダー/名前空間内でそれを使用する必要がありますか?

4)インポートステートメントで相対パスを定義する方法はありますか?もしそうなら、なぜ誰もそれをしないのですか?それは悪い習慣と見なされますか?

5)Goサブパッケージでレポフォークはどのように処理されますか?

ありがとう。

20
Tom Jowitt

短縮版:

  1. パッケージは常に取得可能である必要があります(go get packageで動作します)。したがって、99%の場合、パッケージはgithub.com/user/reponameになり、プロジェクト全体で常にそれを維持します。

  2. はい、これは中央リポジトリである必要があり、寄稿者(内部の従業員またはコミュニティ)はそのリポジトリへのプルリクエストを作成する必要があり、実際に作業することはありません。

  3. はい、gitリモートフォークを使用して元のフォルダー内で使用する必要があります(以下を参照)

  4. いいえ、はい。 go-gettable以外のパッケージの相対インポートを定義できます。つまりあなたがあなたのgopathにいないとき、あなたはimport "./subpackage"することができます。ただし、GOPATHに移動すると、Goはローカルインポートとリモートインポートが混在していると文句を言います。一般的なケースでは、相対インポートを使用しないでください。

  5. サブパッケージのフォークは、メインパッケージのフォークによって処理されます。

ロングバージョン:

例として、複数のチームメンバーがいるGithubリポジトリを取り上げます。

中央リポジトリは http://github.com/central/repo

このリポジトリには、github.com/central/repo/pkg、github.com/central/repo/whateverのようなサブリポジトリがあります。

最も簡単な方法と私見の最良の方法は、gitremoteを使用することです。

サブレポ(またはそれに関しては何でも)に貢献したいとしましょう。プロセスは単純です。他の言語と同じように、レポをフォークします。

さて、あなたが言ったように、あなたは中央のものをターゲットとするインポートを備えたリポジトリのコピーを持っています。実際に作業するのはあまり実用的ではありません。これが理由です(単純な小さなプロジェクトを期待してください)、私は決してgo getフォーク、私はgo get中央リポジトリ、$GOPATH/src/github.com/central/repoに移動し、git remote add creack https://github.com/creack/repoでリモートを追加します

これで、プロジェクトに取り組むことができ、それを中心的なものであるかのように使用できます。完了したら、ブランチをフォークにプッシュしてから、プルリクエストを作成します。

この場合、フォークはgithub上のソースのプレースホルダーにすぎず、使用されません。

9
creack