Sono un grande fan dei sotto-moduli Git . Mi piace essere in grado di tenere traccia di una dipendenza insieme alla sua versione, in modo da poter eseguire il rollback a una versione precedente del progetto e avere la versione corrispondente della dipendenza per creare in modo sicuro e pulito. Inoltre, è più facile rilasciare le nostre librerie come progetti open source poiché la cronologia per le librerie è separata da quella delle applicazioni che dipendono da esse (e che non saranno open source).
Sto impostando il flusso di lavoro per più progetti sul lavoro, e mi chiedevo come sarebbe se avessimo adottato questo approccio un po 'estremo invece di avere un singolo progetto monolitico. Ho subito capito che esiste una potenziale lattina di worm in really usando i sub-moduli.
Supponendo una coppia di applicazioni: studio
e player
, e le librerie dipendenti core
, graph
e network
, dove le dipendenze sono le seguenti:
-
core
è indipendente -
graph
dipende dacore
(sottomodulo in./libs/core
) -
network
depdends sucore
(sub-module at./libs/core
) -
studio
dipende dagraph
enetwork
(sotto-moduli a./libs/graph
e./libs/network
) -
player
dipende dagraph
enetwork
(sotto-moduli a./libs/graph
e./libs/network
)
Supponiamo che stiamo usando CMake e che ognuno di questi progetti abbia test unitari e tutte le opere. Ogni progetto (incluso studio
e player
) deve essere compilato autonomamente per eseguire metriche di codice, test di unità, ecc.
Il fatto è un git submodule fetch
ricorsivo, quindi si ottiene la seguente struttura di directory:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/graph/
studio/libs/graph/libs/ (sub-module depth: 2)
studio/libs/graph/libs/core/
studio/libs/network/
studio/libs/network/libs/ (sub-module depth: 2)
studio/libs/network/libs/core/
Tieni presente che core
viene clonato due volte nel progetto studio
. A parte questo spreco di spazio su disco, ho un problema con il sistema di build perché sto creando core
due volte e potenzialmente ho due versioni diverse di core
.
Domanda
Come organizzo i sottomoduli in modo da ottenere la dipendenza dalla versione e la compilazione autonoma senza ottenere più copie di sottomoduli nidificati comuni?
Possibile soluzione
Se la dipendenza della libreria è in qualche modo un suggerimento (cioè in un "noto per lavorare con la versione X" o "solo la versione X è ufficialmente supportata") e le potenziali applicazioni o librerie dipendenti sono responsabili della creazione con qualsiasi versione come, quindi potrei immaginare il seguente scenario:
- Avere il sistema di compilazione per
graph
enetwork
per indicare dove trovarecore
(ad es. tramite un percorso di inclusione del compilatore). Definisci due target di build, "standalone" e "dependency", dove "standalone" è basato su "dependency" e aggiunge il percorso include a puntare al sottomodulocore
locale. - Introduci una dipendenza extra:
studio
sucore
. Quindi,studio
creacore
, imposta il percorso di inclusione sulla propria copia del sottomodulocore
, quindi creagraph
enetwork
in modalità "dipendenza".
La struttura della cartella risultante assomiglia a:
studio/
studio/libs/ (sub-module depth: 1)
studio/libs/core/
studio/libs/graph/
studio/libs/graph/libs/ (empty folder, sub-modules not fetched)
studio/libs/network/
studio/libs/network/libs/ (empty folder, sub-modules not fetched)
Tuttavia, questo richiede un po 'di magia del sistema di build (sono abbastanza sicuro che questo possa essere fatto con CMake) e un po' di lavoro manuale da parte degli aggiornamenti di versione (l'aggiornamento di graph
potrebbe anche richiedere l'aggiornamento di core
e network
per ottenere una versione compatibile di core
in tutti i progetti).
Qualche idea su questo?