Organización de un proyecto Go de varios archivos


Nota: esta pregunta está relacionada con esta, pero dos años es un tiempo muy largo en la historia de Go.

¿Cuál es la forma estándar de organizar un proyecto Go durante el desarrollo ?

Mi proyecto es un solo paquete mypack, así que supongo que pongo todos los .ir archivos en un directorio mypack.

Pero entonces, me gustaría probarlo durante el desarrollo, por lo que necesito al menos un archivo que declare el paquete main, para que pueda hacer go run trypack.go

¿Cómo debo organizar esto ? Tengo que hacer go install mypack cada vez que quiero probarlo ?

 212
go
Author: Gauranga, 2012-04-03

7 answers

Recomendaría revisar esta página en Cómo Escribir Código Go

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

La estructura sugerida en ese enlace en su pregunta está un poco desactualizada, ahora con el lanzamiento de Go 1. Ya no necesitarías coloque un directorio pkg bajo src. Los únicos 3 directorios relacionados con especificaciones son los 3 en la raíz de tu GOPATH: bin, pkg, src . Debajo de src, simplemente puede colocar su proyecto mypack, y debajo de eso está todo su .ir archivos incluyendo el mypack_test.go

go build luego se construirá en el nivel raíz pkg y bin.

Así que tu GOPATH podría verse así: {[13]]}

~/projects/
    bin/
    pkg/
    src/
      mypack/
        foo.go
        bar.go
        mypack_test.go

export GOPATH=$HOME/projects

$ go build mypack
$ go test mypack
 157
Author: jdi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-02 20:07:13

Jdi tiene la información correcta sobre el uso de GOPATH. Yo añadiría que si usted tiene la intención de tener un binario, así que es posible que desee añadir 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 ejecutar go build myproj/myapp construirá el binario myapp junto con sus dependencias que probablemente incluyen la biblioteca mypack.

 59
Author: Jeremy Wall,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-03-24 19:29:27

He estudiado una serie de proyectos Go y hay un poco de variación. Puede decir quién viene de C y quién viene de Java, ya que el primero volcó casi todo en el directorio raíz de proyectos en un paquete main, y el segundo 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 reutilizarlas.

Para obtener los mejores resultados he elaborado lo siguiente enfoque.

myproj/
  main/
    mypack.go
  mypack.go

Donde mypack.go es package mypack y main/mypack.go es (obviamente) package main.

Si necesita archivos de soporte adicionales, tiene dos opciones. Manténgalos todos en el directorio raíz, o ponga archivos de soporte privados en un subdirectorio lib. Por ejemplo,

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 teniendo lib separate para separar las interfaces públicas de las privadas.

Hacer las cosas de esta manera le dará una ruta de importación agradable, myproj.org/mypack para reutilizar el código en otros proyectos. Si usa lib entonces los archivos de soporte internos tendrán una ruta de importación que es indicativa de eso, myproj.org/lib/mysupport.

Al construir el proyecto, use main/mypack, por ejemplo go build main/mypack. Si tiene más de un ejecutable, también puede separarlos bajo main sin tener que crear proyectos separados. por ejemplo, main/myfoo/myfoo.go y main/mybar/mybar.go.

 47
Author: trans,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-26 11:02:54

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

 21
Author: edap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-02 06:42:33

No parece haber una forma estándar de organizar proyectos Go pero https://golang.org/doc/code.html especifica una buena práctica para la mayoría de los proyectos. la respuesta de jdi es buena, pero si usas github o bitbucket y también tienes bibliotecas adicionales, deberías 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 puede ser utilizado para otros proyectos y puede ser recuperado por "go get". Tu 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 /

 11
Author: alexdotc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-09 04:33:06

Mantenga los archivos en el mismo directorio y use package main en todos los archivos.

myproj/
   your-program/
      main.go
      lib.go

Luego ejecute:

~/myproj/your-program$ go build && ./your-program
 4
Author: Gustav,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-24 16:13:08

Vamos a explorar cómo el comando go get repository_remote_url administra la estructura del proyecto bajo $GOPATH. Si hacemos un go get github.com/gohugoio/hugo clonará el repositorio bajo

GOP GOPATH/src/repository_remote / user_name / project_name


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

Esta es una buena manera de crear su ruta inicial del proyecto. Ahora vamos a explorar cuáles son los tipos de proyectos por ahí y cómo sus estructuras internas son organizado. Todos los proyectos de golang en la comunidad se pueden clasificar en

  • Libraries (sin 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 go disponibles siguen este Orientado a paquetes Diseño

Diseño orientado a paquetes anime al desarrollador a mantener la implementación solo dentro de sus propios paquetes, aparte del paquete /internal esos paquetes no pueden comunicarse entre sí


Bibliotecas

  • Proyectos como controladores de base de datos, qt puede poner en esta categoría.
  • Algunas bibliotecas como color, ahora sigue una estructura plana sin ningún otro paquete.
  • La mayoría de estos proyectos de bibliotecas gestionan un paquete llamado internal.
  • /internal package se usa para mantener archivos go que usan otros paquetes múltiples dentro del proyecto.
  • no tiene ningún binarios ejecutables, así que no hay archivos que contiene el principal func.

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

Proyecto único

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

Proyectos de herramientas

  • Proyectos como kubernetes, go-ethereum tiene múltiples func principal organizado bajo un paquete llamado cmd
  • cmd/ el paquete gestiona el número de binarios (herramientas) que queremos compilar

 ~/$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/
 0
Author: noelyahan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-21 06:54:29