Eu tenho um projeto que está começando a se tornar mais complexo e quero organizar o sistema de arquivos de forma a reduzir a dor.
Existem bons exemplos do que faz sentido?
Eu tenho um projeto que está começando a se tornar mais complexo e quero organizar o sistema de arquivos de forma a reduzir a dor.
Existem bons exemplos do que faz sentido?
Respostas:
Atualização de maio de 2013: a documentação oficial está na seção " Organização do código "
O código Go deve ser mantido dentro de um espaço de trabalho .
Um espaço de trabalho é uma hierarquia de diretórios com três diretórios em sua raiz:
src
contém arquivos de origem Go organizados em pacotes (um pacote por diretório),pkg
contém objetos de pacote ebin
contém comandos executáveis.O
go tool
cria pacotes de origem e instala os binários resultantes nos diretóriospkg
ebin
.O
src
subdiretório normalmente contém vários repositórios de controle de versão (como para Git ou Mercurial) que rastreiam o desenvolvimento de um ou mais pacotes de origem.
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
Atualização de julho de 2014: consulte " Estruturação de aplicativos em Go " de Ben Johnson
Esse artigo inclui dicas como:
combinar o
main.go
arquivo e a lógica do meu aplicativo no mesmo pacote tem duas consequências:
- Isso torna meu aplicativo inutilizável como biblioteca.
- Só posso ter um binário de aplicativo.
A melhor maneira que encontrei de corrigir isso é simplesmente usar um
cmd
diretório “ ” em meu projeto, onde cada um de seus subdiretórios é um binário de aplicativo.
camlistore/
cmd/
camget/
main.go
cammount/
main.go
camput/
main.go
camtool/
main.go
Mover o
main.go
arquivo para fora de sua raiz permite que você construa seu aplicativo da perspectiva de uma biblioteca. O binário do seu aplicativo é simplesmente um cliente da biblioteca do seu aplicativo.Às vezes, você pode querer que os usuários interajam de várias maneiras, para criar vários binários.
Por exemplo, se você tiver umadder
pacote “ ” que permite aos usuários somar números, pode desejar lançar uma versão de linha de comando, bem como uma versão da web.
Você pode fazer isso facilmente organizando seu projeto desta forma:
adder/
adder.go
cmd/
adder/
main.go
adder-server/
main.go
Os usuários podem instalar os binários do seu aplicativo “adicionador” com “go get” usando reticências:
$ go get github.com/benbjohnson/adder/...
E pronto, seu usuário tem “
adder
” e “adder-server
” instalados!
Normalmente os tipos do meu projeto são todos muito relacionados, então ele se encaixa melhor do ponto de vista de usabilidade e API.
Esses tipos também podem tirar vantagem da chamada não exportada entre eles, o que mantém a API pequena e clara.
- Agrupe tipos e códigos relacionados em cada arquivo. Se seus tipos e funções forem bem organizados, acho que os arquivos tendem a ter entre 200 e 500 SLOC. Pode parecer muito, mas acho fácil navegar. 1000 SLOC geralmente é meu limite superior para um único arquivo.
- Organize o tipo mais importante na parte superior do arquivo e adicione tipos de importância decrescente na parte inferior do arquivo.
- Assim que seu aplicativo começar a ultrapassar 10.000 SLOC, você deve avaliar seriamente se ele pode ser dividido em projetos menores.
Nota: essa última prática nem sempre é boa:
Desculpe, não posso concordar com esta prática.
A separação do tipo em arquivos ajuda no gerenciamento, legibilidade, manutenção e testabilidade do código.
Pode também garantir a responsabilidade única e o seguimento do princípio aberto / fechado…
A regra para não permitir a dependência circular é forçar que tenhamos uma estrutura clara dos pacotes.
(Alternativa de fevereiro de 2013, src
apenas referente )
Você pode encontrar o layout clássico ilustrado em " Layout de código do GitHub ":
O aplicativo e as duas bibliotecas estão no Github, cada um em seu próprio repositório.
$GOPATH
é a raiz do projeto - cada um de seus repositórios Github será verificado em várias pastas abaixo$GOPATH
.O layout do seu código ficaria assim:
$GOPATH/
src/
github.com/
jmcvetta/
useless/
.git/
useless.go
useless_test.go
README.md
uselessd/
.git/
uselessd.go
uselessd_test.go
README.md
Cada pasta abaixo
src/github.com/jmcvetta/
é a raiz de um checkout git separado.
Isso atraiu algumas críticas, porém, nesta página do reddit :
Eu recomendo fortemente não estruturar o repo da maneira que você fez, ele quebrará "
go get
", que é uma das coisas mais úteis sobre Go.
É muito melhor escrever seu código para pessoas que conhecem Go, já que provavelmente serão elas que o compilarão.
E para quem não conhece, pelo menos sentirá o idioma.Coloque o pacote principal na raiz do repo.
Tenha os ativos em um subdiretório (para manter as coisas organizadas).
Mantenha a parte essencial do código em um subpacote (caso alguém queira reutilizá-lo fora do seu binário).
Inclua um script de configuração na raiz do repo para que seja fácil de encontrar.O processo de download, compilação, instalação e configuração ainda é um processo de duas etapas:
- "
go get <your repo path>
": baixa e instala o código go, com um subdiretório para os recursos$GOPATH/<your repo path>/setup.sh
: distribui os ativos no lugar certo e instala o serviço
Presumo que com 'projeto' você não quer dizer um pacote Go, mas um software que você desenvolve. Caso contrário, você pode obter ajuda aqui e aqui . No entanto, não é muito diferente de escrever pacotes para Go: use pacotes, crie uma pasta para cada pacote e combine esses pacotes em seu aplicativo.
Para construir uma opinião, você pode olhar os repositórios de tendências Go no github: https://github.com/trending/go . Exemplos notáveis são cayley e zeus .
O esquema mais popular provavelmente é ter um arquivo Go principal e muitos módulos e submódulos em seus próprios diretórios. No caso de você ter muitos arquivos meta (doc, licença, modelos, ...) você pode querer colocar o código-fonte em um subdiretório. Foi o que fiz até agora.
$GOPATH/src
ou usando seus go get
nomes -table.
doozerd
não é um bom exemplo, mesmo seus testes são fracos.
Há uma abordagem recomendada dos autores de Golang que define como fazer o layout de seu código para funcionar melhor com as ferramentas go e para oferecer suporte aos sistemas de controle de origem
$GOROOT
, não o código dentro do src/<project>
diretório.
Você provavelmente também deve dar uma olhada neste repo. Ele mostra muitas ideias de como estruturar aplicativos Go: https://github.com/golang-standards/project-layout
setup.sh
é que Go é razoavelmente multiplataforma, enquanto os scripts de shell POSIX não são.