Numero di versione principale come parte del nome del pacchetto / spazio dei nomi?

1

Sfondo

In un ecosistema software in cui diversi pacchetti dipendono da versioni diverse di altri pacchetti, a volte la risoluzione delle dipendenze termina con un conflitto di versione.

Esempio:

  • Il pacchetto root A dipende da B 1. * e C 1. *.
  • Il pacchetto B dipende da E 1. *.
  • Il pacchetto C dipende da E 2. *. - > conflitto.

Forse gli sviluppatori della libreria C hanno discusso sul fatto che sia giusto dipendere da E 2. * anziché E 1. *, e quante persone potrebbero arrabbiarsi.

Forse gli sviluppatori della libreria E hanno anche discusso se qualcuno passerebbe al loro nuovo ramo E 2. , che potrebbe rompere la compatibilità con pacchetti più vecchi che usano ancora E 1. .

Ho visto discussioni su questo tipo di problema nella comunità PHP, per l'ecosistema Composer / Packagist. Ma presumo che discussioni simili accadano altrove.

Domanda

Mi sono chiesto, perché non rilasciare una nuova versione con il proprio nome e spazio dei nomi? Ciò consentirebbe a diverse versioni di coesistere senza conflitto.

es. invece di E 1. * e E 2. , ci sarebbe E1 1. ed E2 1. *. Il nome del pacchetto non sarebbe "E" ma "E1" / "E2". Lo spazio dei nomi per le classi sarebbe ACME::E1::* o ACME::E::v1::* , invece di solo ACME::E::* .

O nell'ecosistema PHP / Composer / Packagist:

Invece di solo symfony / symfony , ci sarebbero symfony / symfony1, symfony / symfony2 ecc. E lo spazio dei nomi sarebbe essere Symfony2\Component\Asset ecc.

O forse il numero di versione si applicherebbe a un livello inferiore, ad es. Symfony\Component2\Asset .

Quindi la mia domanda è: esiste un ecosistema di pacchetti in cui questa è una pratica comune? C'è una buona ragione per non farlo?

    
posta donquixote 27.08.2017 - 23:40
fonte

2 risposte

2

Questo dipende molto dall'ecosistema, in particolare:

  • Gli sviluppatori di librerie accettano seriamente la compatibilità con le versioni precedenti?
  • Posso installare versioni diverse dello stesso pacchetto affiancate?

Se la risposta a entrambe le domande è "sì", non ci sono problemi.

Quando viene garantita la retrocompatibilità, non esiste alcun conflitto tra la dipendenza da E v1.X e E v2.X. Poiché E v2.X è retrocompatibile con E v1.X, è possibile risolvere la dipendenza su E v2.X e tutto dovrebbe funzionare. Ciò significa che i pacchetti non devono specificare versioni di dipendenze esatte o intervalli di versioni consentite, ma solo versioni minime richieste. Questa strategia è sufficiente in ecosistemi stabili e ben collaudati come Debian / APT o CPAN.

Quando posso installare e caricare più versioni dello stesso pacchetto, due versioni diverse non entrano in conflitto. Il vantaggio è che tutte le dipendenze sono isolate e che le versioni precise possono essere bloccate. Lo svantaggio è che le dipendenze non possono essere condivise tra le librerie che portano alla duplicazione e al rigonfiamento. Le lingue che presuppongono uno spazio dei nomi globale dei pacchetti generalmente hanno difficoltà con questa strategia. Questa strategia può anche far fronte a ecosistemi instabili in cui i cambiamenti di rottura sono comuni (ad es. Ruby o JavaScript). Utenti notevoli di questa strategia sono NPM e Java / OSGi.

Quindi cosa succede se ci sono cambiamenti di rottura, ma non posso installare due versioni per lo stesso pacchetto?

Lo schema di denominazione che hai suggerito non è raro. Supponendo che ogni progetto utilizzi un numero di versione compatibile con SemVer come "Foo v1.X.0" e "Foo v2.Y.0", il numero di versione principale che indica le modifiche di interruzione diventerebbe parte del nome del pacchetto, portando a pacchetti come foo X.0 e foo2 Y.0 . (Se la versione principale è 1 che è essenzialmente priva di significato ai fini del nome di un pacchetto, quindi può essere omessa.) All'interno di ognuno di foo e foo2 ci sarebbero solo modifiche compatibili con i precedenti, quindi il minimo -version strategia può essere utilizzata.

Nei repository di Ubuntu, ci sono più pacchetti APT con tali nomi, ad esempio python vs python3 , o openjdk-8 rispetto a openjdk-9 , o libgtk2.0-0 rispetto a libgtk-3-0 . La maggior parte dei progetti non vede le modifiche su una scala che renderebbe necessari i nomi dei pacchetti con versione.

    
risposta data 28.08.2017 - 10:17
fonte
1

Una domanda importante è se i pacchetti B e C esportano oggetti con tipi da E. Quindi potrebbe esserci un conflitto reale. Se usano E solo internamente, il problema è solo che hanno bisogno di spazi dei nomi diversi in fase di compilazione, quindi il sistema di compilazione deve essere in grado di gestirli.

Nel mondo Java, OSGi può farcela. Al rovescio della medaglia, la specifica per OSGi Core da sola è lunga 80 pagine, più del doppio della definizione di LISP (McCarthy, 1960). Spetta a te decidere se un gestore delle dipendenze è più complesso di un linguaggio di programmazione.

    
risposta data 28.08.2017 - 17:16
fonte