私は、より複雑になり始めているgoプロジェクトを持っており、苦痛を軽減するような方法でファイルシステムをレイアウトしたいと考えています。
何が理にかなっているのか、いくつかの良い例がありますか?
2013年5月の更新:公式ドキュメントは「コード編成」のセクションにあります
Goコードはワークスペース内に保持する必要があります。
ワークスペースは、ルートに3つのディレクトリがあるディレクトリ階層です。
src
パッケージに編成されたGoソースファイル(ディレクトリごとに1つのパッケージ)が含まれ、pkg
パッケージオブジェクトを含み、bin
実行可能コマンドが含まれています。
go tool
ソースパッケージをビルドし、結果のバイナリをおよびディレクトリにインストールしpkg
ますbin
。サブディレクトリには通常、
src
1つ以上のソースパッケージの開発を追跡する複数のバージョン管理リポジトリ(GitやMercurialなど)が含まれています。
bin/
streak # command executable
todo # command executable
pkg/
linux_amd64/
code.google.com/p/goauth2/
oauth.a # package object
github.com/nf/todo/
task.a # package object
src/
code.google.com/p/goauth2/
.hg/ # mercurial repository metadata
oauth/
oauth.go # package source
oauth_test.go # test source
2014年7月の更新:BenJohnsonの「StructuringApplicationsinGo」を参照してください。
その記事には、次のようなヒントが含まれています。
main.go
同じパッケージでファイルとアプリケーションロジックを組み合わせると、次の2つの結果になります。
- それは私のアプリケーションをライブラリとして使用できなくします。
- アプリケーションバイナリは1つしか持てません。
これを修正するために私が見つけた最善の方法は、プロジェクトで「<code>cmd」ディレクトリを使用することです。このディレクトリの各サブディレクトリはアプリケーションバイナリです。
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
ファイルをルートから移動する
main.go
と、ライブラリの観点からアプリケーションを構築できます。アプリケーションバイナリは、単にアプリケーションのライブラリのクライアントです。複数のバイナリを作成するために、ユーザーが複数の方法で対話するようにしたい場合があります。
たとえば、ユーザーが数字を一緒に追加できる「<code> adder」パッケージがある場合は、コマンドラインバージョンとWebバージョンをリリースすることをお勧めします。
プロジェクトを次のように整理することで、これを簡単に行うことができます。
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
ユーザーは、省略記号を使用して、「goget」を使用して「adder」アプリケーションバイナリをインストールできます。
$ go get github.com/benbjohnson/adder/...
そして出来上がり、あなたのユーザーは「<code>adder」と「<code>adder-server」をインストールしています!
通常、私のプロジェクトのタイプはすべて非常に関連しているため、使いやすさとAPIの観点からより適切です。
これらのタイプは、APIを小さく明確に保つために、それらの間でunexportedを呼び出すことも利用できます。
- 関連するタイプとコードを各ファイルにグループ化します。タイプと機能が適切に整理されている場合、ファイルは200〜500SLOCになる傾向があることがわかります。これは多くのように聞こえるかもしれませんが、ナビゲートするのは簡単だと思います。1000 SLOCは通常、単一ファイルの上限です。
- 最も重要なタイプをファイルの上部に整理し、ファイルの下部に向かって重要度を下げてタイプを追加します。
- アプリケーションが10,000SLOCを超え始めたら、それをより小さなプロジェクトに分割できるかどうかを真剣に評価する必要があります。
注:最後の練習が常に良いとは限りません:
申し訳ありませんが、私はこの慣行に同意できません。
タイプをファイルに分離すると、コード管理、可読性、保守性、テスト性が向上します。
また、単一責任とオープン/クローズド原則の遵守を保証する場合もあります…<br>循環依存を許可しないためのルールは、パッケージの明確な構造を強制することです。
(2013年2月の代替案src
のみ) 「 GitHubコードレイアウト」
に示されているクラシックレイアウトを見つけることができます。
アプリと両方のライブラリはGithubにあり、それぞれが独自のリポジトリにあります。
$GOPATH
はプロジェクトのルートです-各Githubリポジトリは、以下のいくつかのフォルダーからチェックアウトされます$GOPATH
。コードレイアウトは次のようになります。
$GOPATH/
src/
github.com/
jmcvetta/
useless/
.git/
useless.go
useless_test.go
README.md
uselessd/
.git/
uselessd.go
uselessd_test.go
README.md
下の各フォルダー
src/github.com/jmcvetta/
は、個別のgitチェックアウトのルートです。
しかし、このredditページでは、いくつかの批判が寄せられました。
リポジトリを現在のように構成しないことを強くお勧めします。
go get
これは、Goの最も便利な機能の1つである「」を壊します。
Goを知っている人のためにコードを書く方がはるかに良いでしょう。なぜなら、彼らがそれをコンパイルする人である可能性が最も高いからです。
そして、そうでない人にとっては、少なくともその言語の感触をつかむでしょう。メインパッケージをリポジトリのルートに配置します。
サブディレクトリにアセットを配置します(物事を整理するため)。
コードの要点をサブパッケージに保存します(誰かがバイナリの外部でコードを再利用したい場合に備えて)。
簡単に見つけられるように、リポジトリのルートにセットアップスクリプトを含めます。ダウンロード、ビルド、インストール、セットアップはまだ2ステップのプロセスです。:
- "
go get <your repo path>
":アセットのサブディレクトリを含むgoコードをダウンロードしてインストールします$GOPATH/<your repo path>/setup.sh
:アセットを適切な場所に配布し、サービスをインストールします
「プロジェクト」では、Goパッケージではなく、開発するソフトウェアを意味すると思います。それ以外の場合は、こことここでヘルプを得ることができます。ただし、Go用のパッケージを作成する場合とそれほど違いはありません。パッケージを使用し、パッケージごとにフォルダーを作成して、アプリケーションでそれらのパッケージを結合します。
自分の意見を構築するために、githubでトレンドのGoリポジトリを見ることができます:https ://github.com/trending/go 。注目すべき例は、ケイリー とゼウスです。
最も一般的なスキームは、おそらくメインのGoファイルと多くのモジュールとサブモジュールを独自のディレクトリに置くことです。多くのメタファイル(ドキュメント、ライセンス、テンプレートなど)がある場合は、ソースコードをサブディレクトリに配置することをお勧めします。それは私がこれまでにしたことです。
Golangの作成者から推奨されるアプローチがあり、goツールで最適に動作し、ソース管理システムをサポートするようにコードをレイアウトする方法を定義しています。
おそらく、このリポジトリも調べる必要があります。Goアプリケーションを構造化する方法について多くのアイデアを示しています:https ://github.com/golang-standards/project-layout