IT박스

Go 프로젝트를 레이아웃하는 현명한 방법은 무엇입니까?

itboxs 2020. 8. 10. 07:50
반응형

Go 프로젝트를 레이아웃하는 현명한 방법은 무엇입니까?


더 복잡해지기 시작하는 go 프로젝트가 있으며 고통을 줄이기 위해 파일 시스템을 배치하고 싶습니다.

이치에 맞는 좋은 예가 있습니까?


2013 년 5 월 업데이트 : 공식 문서는 " 코드 구성 " 섹션에 있습니다 .

Go 코드는 작업 공간 내에 보관되어야합니다 .
작업 공간은 루트에 세 개의 디렉토리가있는 디렉토리 계층 구조입니다.

  • src 패키지로 구성된 Go 소스 파일을 포함합니다 (디렉토리 당 하나의 패키지).
  • pkg 패키지 객체를 포함하고
  • bin 실행 가능한 명령이 포함되어 있습니다.

go tool소스 패키지를 구축하고에 결과 바이너리를 설치 pkg하고 bin디렉토리.

src하위 디렉토리는 일반적으로 하나 개 이상의 소스 패키지의 개발을 추적 (예 : 힘내이나 의욕 만) 여러 버전 관리 저장소가 포함되어 있습니다.

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 월 업데이트 : Ben Johnson의 " Go 에서 애플리케이션 구조화 "참조

이 기사에는 다음과 같은 팁이 포함되어 있습니다.

바이너리를 애플리케이션에서 분리하세요.

main.go동일한 패키지에서 파일과 애플리케이션 로직을 결합하면 두 가지 결과가 발생합니다.

  • 내 응용 프로그램을 라이브러리로 사용할 수 없게 만듭니다.
  • 애플리케이션 바이너리는 하나만 가질 수 있습니다.

이 문제를 해결하는 가장 좋은 방법은 cmd각 하위 디렉터리가 응용 프로그램 바이너리 인 프로젝트에서 " "디렉터리를 사용하는 것 입니다.

camlistore/
  cmd/
    camget/
      main.go
    cammount/
      main.go
    camput/
      main.go
    camtool/
      main.go

도서관 주도 개발

main.go루트 에서 파일을 이동하면 라이브러리 관점에서 애플리케이션을 빌드 할 수 있습니다. 애플리케이션 바이너리는 단순히 애플리케이션 라이브러리의 클라이언트입니다.

때로는 사용자가 여러 방식으로 상호 작용하도록하여 여러 바이너리를 만들 수 있습니다.
예를 들어 adder사용자가 숫자를 함께 추가 할 수 있는 " "패키지가있는 경우 웹 버전뿐 아니라 명령 줄 버전도 릴리스 할 수 있습니다.
다음과 같이 프로젝트를 구성하여 쉽게 수행 할 수 있습니다.

adder/
  adder.go
  cmd/
    adder/
      main.go
    adder-server/
      main.go

사용자는 줄임표를 사용하여 "go get"으로 "adder"응용 프로그램 바이너리를 설치할 수 있습니다.

$ go get github.com/benbjohnson/adder/...

그리고 짜잔, 당신의 사용자는 " adder"와 " adder-server"이 설치되어 있습니다!

서브 패키지에 미쳐 가지 마세요

Usually my project’s types are all very related so it fits better from a usability and API standpoint.
These types can also take advantage of calling unexported between them which keeps the API small and clear.

  1. Group related types and code together in each file. If your types and functions are well organized then I find that files tend to be between 200 and 500 SLOC. This might sound like a lot but I find it easy to navigate. 1000 SLOC is usually my upper limit for a single file.
  2. Organize the most important type at the top of the file and add types in decreasing importance towards the bottom of the file.
  3. Once your application starts getting above 10,000 SLOC you should seriously evaluate whether it can be broken into smaller projects.

Note: that last practice isn't always good:

Sorry I just cant agree with this practice.
Separating type to files helps code management, readability, maintenancability, testability.
It may also ensure single responsibility and the follow of open/closed principle…
The rule for not allowing circular dependency is to force we have a clear structure of the packages.


(Alternative February 2013, regarding src only)
You can find the classic layout illustrated in "GitHub Code Layout":

The app and both libraries live on Github, each in its own repository.
$GOPATH is the root of the project - each of your Github repos will be checked out several folders below $GOPATH.

Your code layout would look like this:

$GOPATH/
    src/
        github.com/
            jmcvetta/
                useless/
                    .git/
                    useless.go
                    useless_test.go
                    README.md
                uselessd/
                    .git/
                    uselessd.go
                    uselessd_test.go
                    README.md

Each folder under src/github.com/jmcvetta/ is the root of a separate git checkout.

That attracted some criticisms though, in this reddit page:

I highly recommend not structuring the repo the way you have, it'll break "go get", which is one of the most useful things about Go.
It's far better to write your code for people who do know Go, since they're most likely to be the ones compiling it.
And for people who don't, they'll at least get a feel for the language.

Put the main package in the root of the repo.
Have the assets in a subdirectory (to keep things neat).
Keep the meat of the code in a subpackage (in case anyone wants to reuse it outside your binary).
Include a setup script in the root of the repo so it's easy to find.

It's still only a two step process to download, build, install, and setup.:

  • "go get <your repo path>": downloads and installs the go code, with a subdir for the assets
  • $GOPATH/<your repo path>/setup.sh: distributes the assets to the right place and installs the service

I assume that with 'project' you don't mean a Go package but a software you develop. Otherwise you can get help here and here. However it's not so much different to writing packages for Go: Use packages, create a folder for each package and combine those packages in your application.

To build yourself an opinion, you can look at trending Go repositories on github: https://github.com/trending/go. Notable examples are cayley and zeus.

The most popular scheme is probably to have a main Go file and many modules and submodules in their own directories. In case you have many meta files (doc, license, templates, ...) you may want to put the source code into a subdirectory. That's what I did so far.


There is a recommended approach from the authors of Golang that defines how to layout your code to work best with the go tools and to support source control systems


You should probably also have a look into this repo. It shows a lot of ideas how to structure go applications: https://github.com/golang-standards/project-layout

참고URL : https://stackoverflow.com/questions/14867452/what-is-a-sensible-way-to-layout-a-go-project

반응형