Organizando un proyecto Go de mĂșltiples archivos
(7)
He estudiado varios proyectos de Go y hay un poco de variación. Usted puede decir quién viene de C y quién de Java, ya que el volcado anterior casi todo en el directorio raíz de proyectos en un paquete main
, y el último tiende a poner todo en un directorio src
. Sin embargo, ninguno es óptimo. Cada uno tiene consecuencias porque afectan las rutas de importación y cómo otros pueden reutilizarlos.
Para obtener los mejores resultados he desarrollado el siguiente enfoque.
myproj/
main/
mypack.go
mypack.go
Donde mypack.go
es el package mypack
y main/mypack.go
es (obviamente) el package main
.
Si necesita archivos de soporte adicionales, tiene dos opciones. Manténgalos a todos en el directorio raíz o coloque los archivos de soporte privados en un subdirectorio lib
. P.ej
myproj/
main/
mypack.go
myextras/
someextra.go
mypack.go
mysupport.go
O
myproj.org/
lib/
mysupport.go
myextras/
someextra.go
main/
mypack.go
mypage.go
Solo coloque los archivos en un directorio lib
si no están destinados a ser importados por otro proyecto. En otras palabras, si son archivos de soporte privado . Esa es la idea detrás de tener lib
--para separar las interfaces públicas de las privadas.
Hacer las cosas de esta manera le dará una buena ruta de importación, myproj.org/mypack
para reutilizar el código en otros proyectos. Si usa lib
entonces los archivos de soporte interno tendrán una ruta de importación que es indicativa de eso, myproj.org/lib/mysupport
.
Al main/mypack
el proyecto, use main/mypack
, por ejemplo, go build main/mypack
. Si tiene más de un ejecutable, también puede separarlos en main
sin tener que crear proyectos separados. p.ej. main/myfoo/myfoo.go
y main/mybar/mybar.go
.
Nota: esta pregunta está relacionada con esta , pero dos años es mucho tiempo en la historia de Go.
¿Cuál es la forma estándar de organizar un proyecto Go durante el desarrollo?
Mi proyecto es un paquete mypack
único, así que supongo que coloco todos los archivos mypack
en un directorio mypack
.
Pero luego, me gustaría probarlo durante el desarrollo, por lo que necesito al menos un archivo que declare el paquete main
, para poder go run trypack.go
¿Cómo debo organizar esto? ¿Tengo que hacer go install mypack
cada vez que quiera probarlo?
Mantenga los archivos en el mismo directorio y use el package main
en todos los archivos.
myproj/
your-program/
main.go
lib.go
Entonces corre:
~/myproj/your-program$ go build && ./your-program
Me parece muy útil entender cómo organizar el código en Golang en este capítulo http://www.golang-book.com/11 del libro escrito por Caleb Doxsey
Parece que no hay una forma estándar de organizar los proyectos de Go, pero https://golang.org/doc/code.html especifica una mejor práctica para la mayoría de los proyectos. La respuesta de jdi es buena, pero si usa github o bitbucket y también tiene bibliotecas adicionales, debe crear la siguiente estructura:
~/projects/
bin/
pkg/
src/
github.com/
username/
mypack/
foo.go
bar.go
mypack_test.go
mylib/
utillib.go
utillib_test.go
Al hacerlo de esta manera, puede tener un repositorio separado para mylib que se puede usar para otros proyectos y se puede recuperar con "ir a buscar". Su proyecto mypack puede importar su biblioteca usando "github.com/username/mylib". Para más información:
http://www.alexvictorchan.com/2014/11/06/go-project-structure/
Recomendaría revisar esta página en Cómo escribir Go Code
Documenta cómo estructurar su proyecto de una manera fácil de go build
, y también cómo escribir pruebas. Las pruebas no necesitan ser un cmd usando el paquete main
. Simplemente pueden ser funciones nombradas de TestX como parte de cada paquete, y luego go test
descubrirá.
La estructura sugerida en ese enlace en su pregunta está un poco desactualizada, ahora con el lanzamiento de Go 1. Ya no tendrá que colocar un directorio pkg
bajo src
. Los únicos 3 directorios relacionados con las especificaciones son los 3 en la raíz de su GOPATH: bin, pkg, src. Debajo de src, simplemente puede colocar su proyecto mypack
, y debajo de eso están todos sus archivos .go, incluido mypack_test.go
go build
se construirá en el nivel raíz pkg y bin.
Entonces tu GOPATH podría verse así:
~/projects/
bin/
pkg/
src/
mypack/
foo.go
bar.go
mypack_test.go
export GOPATH=$HOME/projects
$ go build mypack
$ go test mypack
jdi tiene la información correcta sobre el uso de GOPATH
. Me gustaría agregar que si pretende tener un binario también puede agregar un nivel adicional a los directorios.
~/projects/src/
myproj/
mypack/
lib.go
lib_test.go
...
myapp/
main.go
ejecutando go build myproj/mypack
compilará el paquete mypack
junto con sus dependencias ejecutando go build myproj/myapp
compilará el binario myapp
junto con sus dependencias que probablemente incluyen la biblioteca mypack
.
$GOPATH
cómo el comando go get repository_remote_url
administra la estructura del proyecto en $GOPATH
. Si hacemos un go get github.com/gohugoio/hugo
el repositorio bajo
$ GOPATH / src / repository_remote / user_name / project_name
$ GOPATH / src / github.com/gohugoio/hugo
Esta es una buena manera de crear su ruta inicial de proyecto . Ahora exploremos cuáles son los tipos de proyectos y cómo se organizan sus estructuras internas. Todos los proyectos de golang en la comunidad se pueden clasificar en
-
Libraries
(no binarios ejecutables) -
Single Project
(contiene solo 1 binario ejecutable) -
Tooling Projects
(contiene múltiples binarios ejecutables)
Generalmente, los archivos de proyectos de Golang se pueden empaquetar bajo cualquier principio de diseño como DDD , POD
La mayoría de los proyectos de Go disponibles siguen este POD
POD anima al desarrollador a mantener la implementación solo dentro de sus propios paquetes, además del paquete /internal
que esos paquetes no pueden comunicarse entre sí
Bibliotecas
- Los proyectos como los controladores de base de datos , qt pueden poner en esta categoría.
- Algunas bibliotecas como el color , now siguen una estructura plana sin ningún otro paquete.
- La mayoría de estos proyectos de biblioteca gestiona un paquete llamado interno .
-
/internal
paquete/internal
se utiliza para mantener los archivos go que usan otros paquetes múltiples dentro del proyecto. - No tiene archivos binarios ejecutables, por lo que no hay archivos que contengan la función principal .
~/$GOPATH/
bin/
pkg/
src/
repository_remote/
user_name/
project_name/
internal/
other_pkg/
Proyecto único
- Proyectos como hugo , etcd tienen una única función principal en el nivel raíz y.
- El objetivo es generar un solo binario.
Proyectos de herramientas
- Proyectos como kubernetes , go-ethereum tiene múltiples go-ethereum principales organizadas en un paquete llamado cmd
-
cmd/
package gestiona el número de binarios (herramientas) que queremos construir
~/$GOPATH/
bin/
pkg/
src/
repository_remote/
user_name/
project_name/
cmd/
binary_one/
main.go
binary_two/
main.go
binary_three/
main.go
other_pkg/