天天看點

Gopher項目标準結構

Go 目錄

/cmd

本項目的主幹。

每個應用程式的目錄名應該與你想要的可執行檔案的名稱相比對(例如,

/cmd/myapp

)。

不要在這個目錄中放置太多代碼。如果你認為代碼可以導入并在其他項目中使用,那麼它應該位于 

/pkg

 目錄中。如果代碼不是可重用的,或者你不希望其他人重用它,請将該代碼放到 

/internal

 目錄中。你會驚訝于别人會怎麼做,是以要明确你的意圖!

通常有一個小的 

main

 函數,從 

/internal

 和 

/pkg

 目錄導入和調用代碼,除此之外沒有别的東西。

有關示例,請參閱 /cmd 目錄。

/internal

私有應用程式和庫代碼。這是你不希望其他人在其應用程式或庫中導入代碼。請注意,這個布局模式是由 Go 編譯器本身執行的。有關更多細節,請參閱Go 1.4 release notes 。注意,你并不局限于頂級 

internal

 目錄。在項目樹的任何級别上都可以有多個内部目錄。

你可以選擇向 internal 包中添加一些額外的結構,以分隔共享和非共享的内部代碼。這不是必需的(特别是對于較小的項目),但是最好有有可視化的線索來顯示預期的包的用途。你的實際應用程式代碼可以放在 

/internal/app

 目錄下(例如 

/internal/app/myapp

),這些應用程式共享的代碼可以放在 

/internal/pkg

 目錄下(例如 

/internal/pkg/myprivlib

)。

/pkg

外部應用程式可以使用的庫代碼(例如 

/pkg/mypubliclib

)。其他項目會導入這些庫,希望它們能正常工作,是以在這裡放東西之前要三思:-)注意,

internal

 目錄是確定私有包不可導入的更好方法,因為它是由 Go 強制執行的。

/pkg

 目錄仍然是一種很好的方式,可以顯式地表示該目錄中的代碼對于其他人來說是安全使用的好方法。由 Travis Jeffery  撰寫的 I'll take pkg over internal 部落格文章提供了 

pkg

 和 

internal

 目錄的一個很好的概述,以及什麼時候使用它們是有意義的。

當根目錄包含大量非 Go 元件和目錄時,這也是一種将 Go 代碼分組到一個位置的方法,這使得運作各種 Go 工具變得更加容易(正如在這些演講中提到的那樣: 來自 GopherCon EU 2018 的 Best Practices for Industrial Programming , GopherCon 2018: Kat Zien - How Do You Structure Your Go Apps 和 GoLab 2018 - Massimiliano Pippi - Project layout patterns in Go )。

如果你想檢視哪個流行的 Go 存儲庫使用此項目布局模式,請檢視 /pkg 目錄。這是一種常見的布局模式,但并不是所有人都接受它,一些 Go 社群的人也不推薦它。

如果你的應用程式項目真的很小,并且額外的嵌套并不能增加多少價值(除非你真的想要:-),那就不要使用它。當它變得足夠大時,你的根目錄會變得非常繁瑣時(尤其是當你有很多非 Go 應用元件時),請考慮一下。

/vendor

應用程式依賴項(手動管理或使用你喜歡的依賴項管理工具,如新的内置 Go Modules 功能)。

go mod vendor

 指令将為你建立 

/vendor

 目錄。請注意,如果未使用預設情況下處于啟用狀态的 Go 1.14,則可能需要在 

go build

 指令中添加 

-mod=vendor

 标志。

如果你正在建構一個庫,那麼不要送出你的應用程式依賴項。

注意,自從 1.13 以後,Go 還啟用了子產品代理功能(預設使用 https://proxy.golang.org 作為他們的子產品代理伺服器)。在here 閱讀更多關于它的資訊,看看它是否符合你的所有需求和限制。如果需要,那麼你根本不需要 

vendor

 目錄。

國内子產品代理功能預設是被牆的,七牛雲有維護專門的的子產品代理 。

服務應用程式目錄

/api

OpenAPI/Swagger 規範,JSON 模式檔案,協定定義檔案。

有關示例,請參見 /api 目錄。

Web 應用程式目錄

/web

特定于 Web 應用程式的元件:靜态 Web 資産、伺服器端模闆和 SPAs。

通用應用目錄

/configs

配置檔案模闆或預設配置。

将你的 

confd

 或 

consul-template

 模闆檔案放在這裡。

/init

System init(systemd,upstart,sysv)和 process manager/supervisor(runit,supervisor)配置。

/scripts

執行各種建構、安裝、分析等操作的腳本。

這些腳本保持了根級别的 Makefile 變得小而簡單(例如, https://github.com/hashicorp/terraform/blob/master/Makefile )。

有關示例,請參見  /scripts 目錄。

/build

打包和持續內建。

将你的雲( AMI )、容器( Docker )、作業系統( deb、rpm、pkg )包配置和腳本放在 

/build/package

 目錄下。

将你的 CI (travis、circle、drone)配置和腳本放在 

/build/ci

 目錄中。請注意,有些 CI 工具(例如 Travis CI)對配置檔案的位置非常挑剔。嘗試将配置檔案放在 

/build/ci

 目錄中,将它們連結到 CI 工具期望它們的位置(如果可能的話)。

/deployments

IaaS、PaaS、系統和容器編排部署配置和模闆(docker-compose、kubernetes/helm、mesos、terraform、bosh)。注意,在一些存儲庫中(特别是使用 kubernetes 部署的應用程式),這個目錄被稱為 

/deploy

/test

額外的外部測試應用程式和測試資料。你可以随時根據需求構造 

/test

 目錄。對于較大的項目,有一個資料子目錄是有意義的。例如,你可以使用 

/test/data

 或 

/test/testdata

 (如果你需要忽略目錄中的内容)。請注意,Go 還會忽略以“.”或“_”開頭的目錄或檔案,是以在如何命名測試資料目錄方面有更大的靈活性。

有關示例,請參見  /test 目錄。

其他目錄

/docs

設計和使用者文檔(除了 godoc 生成的文檔之外)。

有關示例,請參閱 /docs 目錄。

/tools

這個項目的支援工具。注意,這些工具可以從 

/pkg

 和 

/internal

 目錄導入代碼。

有關示例,請參見 /tools 目錄。

/examples

你的應用程式和/或公共庫的示例。

有關示例,請參見 /examples 目錄。

/third_party

外部輔助工具,分叉代碼和其他第三方工具(例如 Swagger UI)。

/githooks

Git hooks。

/assets

與存儲庫一起使用的其他資産(圖像、徽标等)。

/website

如果你不使用 Github 頁面,則在這裡放置項目的網站資料。

有關示例,請參見 /website 目錄。

你不應該擁有的目錄

/src

有些 Go 項目确實有一個 

src

 檔案夾,但這通常發生在開發人員有 Java 背景,在那裡它是一種常見的模式。如果可以的話,盡量不要采用這種 Java 模式。你真的不希望你的 Go 代碼或 Go 項目看起來像 Java:-)

不要将項目級别 

src

 目錄與 Go 用于其工作空間的 

src

 目錄(如 How to Write Go Code 中所述)混淆。

$GOPATH

 環境變量指向你的(目前)工作空間(預設情況下,它指向非 windows 系統上的 

$HOME/go

)。這個工作空間包括頂層 

/pkg

/bin

 和 

/src

 目錄。你的實際項目最終是 

/src

 下的一個子目錄,是以,如果你的項目中有 

/src

 目錄,那麼項目路徑将是這樣的: 

/some/path/to/workspace/src/your_project/src/your_code.go

。注意,在 Go 1.11 中,可以将項目放在 

GOPATH

 之外,但這并不意味着使用這種布局模式是一個好主意。

Badges

  • Go Report Card - It will scan your code with 

    gofmt

    go vet

    gocyclo

    golint

    ineffassign

    license

     and 

    misspell

    . Replace 

    github.com/golang-standards/project-layout

     with your project reference.
  • GoDoc - It will provide online version of your GoDoc generated documentation. Change the link to point to your project.
  • Release - It will show the latest release number for your project. Change the github link to point to your project.