Organizar un proyecto Go de múltiples archivos

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 único mypack , así que supongo que puse todos los archivos mypack en un directorio mypack .

Pero luego, me gustaría probarlo durante el desarrollo, así que necesito al menos un archivo que declare el paquete main , para poder go run trypack.go

¿Cómo debería organizar esto? ¿Debo go install mypack cada vez que quiero probarlo?

Recomiendo revisar esta página sobre cómo escribir el código Go

Documenta cómo estructurar su proyecto de una manera amigable, y también cómo escribir pruebas. Las pruebas no necesitan ser un cmd usando el paquete main . Simplemente pueden ser funciones nombradas en TestX como parte de cada paquete, y luego go test los descubrirá.

La estructura sugerida en ese enlace en su pregunta está un poco desactualizada, ahora con el lanzamiento de Go 1. Ya no necesitaría 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, puedes simplemente colocar tu proyecto mypack , y debajo de eso están todos tus archivos .go incluyendo mypack_test.go

go build se comstackrá 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 . Yo agregaría que si pretendes tener un binario también, quizás quieras agregar un nivel adicional a los directorios.

 ~/projects/src/ myproj/ mypack/ lib.go lib_test.go ... myapp/ main.go 

ejecutando go build myproj/mypack construirá el paquete mypack junto con sus dependencias ejecutando go build myproj/myapp construirá el binario myapp junto con sus dependencias que probablemente incluyen la biblioteca mypack .

He estudiado varios proyectos de Go y hay bastante variación. Puede decirnos quién viene de C y quién viene de Java, ya que el anterior volcó casi todo en el directorio raíz de los proyectos en un paquete main , y los últimos tienden 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 reutilizarlas.

Para obtener los mejores resultados, he elaborado 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. O mantenlos todos en el directorio raíz o coloca 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 privados . 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 construir el proyecto, utilice main/mypack , por ejemplo, go build main/mypack . Si tiene más de un ejecutable, también puede separar los que están debajo del main sin tener que crear proyectos separados. ej. main/myfoo/myfoo.go y main/mybar/mybar.go .

Me parece muy útil para entender cómo organizar código en Golang este capítulo http://www.golang-book.com/11 del libro escrito por Caleb Doxsey

No parece haber 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 repository separado para mylib que se puede usar para otros proyectos y se puede recuperar con “go get”. 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/

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 

$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 repository bajo

$ GOPATH / src / repository_remote / user_name / project_name


$ GOPATH / src / github.com/gohugoio/hugo

Esta es una buena forma de crear su ruta de proyecto inicial . 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 pueden clasificarse en

  • Libraries (no binarios ejecutables)
  • Single Project (contiene solo 1 binario ejecutable)
  • Tooling Projects (contiene varios binarios ejecutables)

Generalmente, los archivos del proyecto golang se pueden empaquetar bajo cualquier principio de diseño como DDD , POD

La mayoría de los proyectos de go disponibles siguen este diseño orientado a paquetes

El diseño orientado al paquete alienta al desarrollador a mantener la implementación solo dentro de sus propios paquetes, que no sean el paquete /internal que esos paquetes no pueden comunicarse entre sí.


Bibliotecas

  • Proyectos como controladores de bases de datos , qt pueden incluir esta categoría.
  • Algunas bibliotecas, como el color , ahora siguen una estructura plana sin ningún otro paquete.
  • La mayoría de estos proyectos de biblioteca manejan un paquete llamado interno .
  • /internal paquete /internal se usa para mantener archivos go que usan otros paquetes múltiples dentro del proyecto.
  • No tiene binarios ejecutables, por lo que no contiene archivos que contengan la función principal .

  ~/$GOPATH/ bin/ pkg/ src/ repository_remote/ user_name/ project_name/ internal/ other_pkg/ 

Proyecto individual

  • Proyectos como hugo , etcd tienen un único func principal en el nivel raíz y.
  • El objective es generar un solo binario

Proyectos de herramientas

  • Proyectos como kubernetes , go-ethereum tienen múltiples funciones principales organizadas bajo un paquete llamado cmd
  • cmd/ package gestiona la cantidad 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/