Best Practice della gestione delle dipendenze di Golang

In Golang, possiamo specificare le librerie open source su GitHub come dipendenze. Per esempio:

import "github.com/RichardKnop/somelibrary" 

Questo proverà a cercare un ramo basato sulla tua versione di Go e di default a master se ho capito bene.

Quindi non c’è modo di importare una versione specifica di una dipendenza, ad esempio:

 import "github.com/RichardKnop/somelibrary#v1.4.8" 

Qual è la migliore pratica per gestire le dipendenze in Go allora?

Posso vedere due approcci.

I. Moduli di versione

È per creare nuovi moduli per le versioni principali con modifiche di rottura?

Ad esempio, la mia libreria Go può definire i moduli v1 e v2, quindi è ansible:

 import "github.com/RichardKnop/somelibrary/v1" 

O:

 import "github.com/RichardKnop/somelibrary/v2" 

In base a ciò di cui hai bisogno. Eventuali modifiche apportate a v1 o v2 sarebbero necessarie per non interrompere alcuna API o funzionalità di lavoro.

II. biforcazione

Questo ti darebbe un controllo completo su una versione di dipendenza esterna richiesta dal tuo codice Go.

Ad esempio, puoi inserire github.com/RichardKnop/somelibrary nel tuo account GitHub e poi nel tuo codice:

 import "github.com/ForkingUser/somelibrary" 

Quindi dovresti sborsare tutte le dipendenze esterne che sembra un po ‘eccessivo. Tuttavia ti darebbe il controllo totale sulle versioni. Puoi mantenere le tue forchette in una versione che sai funzionare con il tuo codice e aggiornare le forche solo dopo aver verificato che le nuove versioni delle dipendenze non infrangono nulla.

Pensieri?

Nota: giugno 2015, il primo supporto per i fornitori appare in Go 1.5!

Vedi c / 10923 / :

Quando GO15VENDOREXPERIMENT=1 è nell’ambiente, questo CL modifica la risoluzione dei percorsi di importazione in base alla proposta del fornitore Go 1.5:

  • Se esiste una directory di origine d/vendor , quindi, quando si compila un file sorgente all’interno della sottostruttura con radice a d , l’ import "p" viene interpretata come import "d/vendor/p" se esiste.
  • Quando ci sono più risoluzioni possibili, vince il percorso più specifico (il più lungo).
  • Il modulo breve deve essere sempre utilizzato: nessun percorso di importazione può contenere ” /vendor/ ” esplicitamente.
  • I commenti di importazione vengono ignorati nei pacchetti venduti.

Aggiornamento gennaio 2016: Go 1.6 renderà la vendita predefinita l’impostazione predefinita.
E come dettagliato nell’articolo “PIÙ GO TOOLS ORA LAVORA CON GO15VENDOREXPERIMENT” :

1.6 porta il supporto /vendor/ alla maggior parte degli strumenti (come l’oracle) fuori dalla scatola; usa la Beta per ricostruirli.

  • il numero 12278 è stato risolto.
  • c’è ancora un problema con i goimports , e c’è un CL che può essere selezionato .

Febbraio 2018: l’approccio alla vendita presentato di seguito (nel 2015/2016) potrebbe finire per scomparire se vgo è integrato nella toolchain.
Vedi la mia risposta qui sotto .


Edizione di agosto 2015: Go 1.5 viene fornito con un supporto di vendita integrato (ma ancora sperimentale). Impostando la variabile di ambiente GO15VENDOREXPERIMENT , i GO15VENDOREXPERIMENT go build e di amici potranno cercare i pacchetti nella directory ./vendor e in GOPATH . Vedi la risposta di VonC e il documento di progettazione per maggiori dettagli.


III. Vendoring

AFAIK, questo è il modo più diffuso per garantire che le tue build siano riproducibili e prevedibili. Lo stesso team di Go utilizza i distributori nel loro repo. Il team di Go sta ora discutendo il formato del file manifest di dipendenza unificato. Dalla mailing list degli sviluppatori di toolchain Go :

Nell’albero dei sorgenti interno di Google, vendiamo (copia) tutte le nostre dipendenze nell’albero dei sorgenti e disponiamo al massimo una copia di una determinata libreria esterna. Abbiamo l’equivalente di un solo GOPATH e riscriviamo le nostre importazioni per fare riferimento alla nostra copia venduta. Ad esempio, il codice Go all’interno di Google che desidera utilizzare “golang.org/x/crypto/openpgp” lo importerebbe invece come qualcosa come “google / third_party / golang.org / x / crypto / openpgp”.

(…)

La nostra proposta è che il progetto Go,

  • raccomanda ufficialmente la vendita in una directory “interna” con riscrittura delle importazioni (non le modifiche GOPATH) come metodo canonico per bloccare le dipendenze.

  • definisce un comune formato di file di configurazione per dipendenze e distribuzione

  • non effettua modifiche al codice in cmd / go in Go 1.5. Strumenti esterni come ” godep ” o ” nut ” implementeranno 1) e 2). Possiamo rivalutare anche questo strumento in Go 1.6+.

Aggiornamento agosto 2018: questo (vgo presentato di seguito) è ora implementato con Go 1.11 e moduli .

Aggiornamento febbraio 2018, 3 anni dopo.

C’è un nuovo approccio sviluppato da Russ Cox , dal core team di sviluppo di Golang.

Il progetto vgo .

 go get -u golang.org/x/vgo 

Questa proposta:

  • mantiene le parti migliori di go get ,
  • aggiunge build riproducibili ,
  • adotta il controllo delle versioni semantiche,
  • elimina la vendita ,
  • depreca GOPATH a favore di un stream di lavoro basato su progetto e
  • fornisce un percorso di migrazione senza problemi dal dep e dai suoi predecessori.

vgo semver

Si basa su un nuovo algoritmo MVS (“Minimal Version Selection”) :

https://research.swtch.com/version-select-2.png

Puoi vedere:

  • i primi articoli in Go & Versioning
  • la discussione in questa discussione
  • l’ analisi di quel thread di Jon Calhoun
  • il contro-punto di Sam Boyer in ” Pensieri su vgo e dep “:
    Stava guidando l’iniziativa privata di go dep
  • il primo dibattito (YouTube) tra Russ, Sam e Jesse Frazelle !

Maggio 2018: Artifactory propone un proxy vgo

La recente versione di Artifactory 5.11 ha aggiunto il supporto per i registri Go compatibili vgo (e go proxy) dando alla community una varietà di funzionalità durante lo sviluppo con Go.
Eccone alcuni:

  • I repository locali in Artifactory consentono di configurare registri Go privati ​​e protetti con controllo di accesso a grana fine per i pacchetti in base a progetti o team di sviluppo.
  • Un repository remoto in Artifactory è un proxy di caching per risorse Go remote come un progetto GitHub. L’accesso a un proxy go tramite Artifactory rimuove la dipendenza dalla rete o su GitHub poiché tutte le dipendenze necessarie per le build Go sono memorizzate nella cache in Artifactory e sono quindi disponibili localmente. Ciò rimuove anche il rischio che qualcuno muti o rimuova una dipendenza dal controllo di versione, o peggio, spinga forzatamente le modifiche a un tag Git remoto, cambiando quindi quella che dovrebbe essere una versione immutabile che può creare molta confusione e instabilità per i progetti dipendenti.
  • Un repository virtuale aggrega i registri Go sia locali che remoti, consentendo l’accesso a tutte le risorse Go necessarie per le build da un singolo URL, nascondendo la complessità dell’utilizzo di una combinazione di risorse locali e remote.

inoltre è ansible solo descrivere le dipendenze in maven, se si usa mvn-golang-wrapper , nel caso in cui assomigli a maven come sotto il testo

  com.igormaznitsa mvn-golang-wrapper 1.1.0   golang-get  get    github.com/gizak/termui   -u  1.6