Domanda

Per prima cosa, lo so: Come organizzeresti un repository Subversion per progetti software interni? Quindi, la vera domanda: Il mio team sta ristrutturando il nostro repository e sto cercando suggerimenti su come organizzarlo. (SVN in questo caso). Ecco cosa ci è venuto in mente. Abbiamo un repository, più progetti e più svn: riferimenti incrociati esterni

\commonTools /*tools used in all projects. Referenced in each project with svn:externals*/
   \NUnit.v2.4.8
   \NCover.v.1.5.8
   \<other similar tools>
\commonFiles /*settings strong name keys etc.*/
   \ReSharper.settings
   \VisualStudio.settings
\trash /*each member of the team has trash for samples, experiments etc*/
   \user1
   \user2
\projects
   \Solution1 /*Single actual project (Visual Studio Solution)*/
      \trunk
         \src
             \Project1 /*Each sub-project resulting in single .dll or .exe*/
             \Project2
         \lib
         \tools
         \tests
         \Solution1.sln
      \tags
      \branches
   \Solution2
      \trunk
         \src
             \Project3 /*Each sub-project resulting in single .dll or .exe*/
             \Project1 /*Project1 from Solution1 references with svn:externals*/
         \lib
         \tools
         \tests
         \Solution2.sln
      \tags
      \branches

Per cancellare il vocabolario: soluzione significa singolo prodotto, Project è un progetto Visual Studio (che si traduce in una singola DLL o singolo .exe)

È così che intendiamo strutturare il repository. Il problema principale è che abbiamo più soluzioni, ma vogliamo condividere i progetti tra le soluzioni. Abbiamo pensato che non avrebbe davvero senso spostare quei progetti condivisi nelle proprie soluzioni, e invece abbiamo deciso di usare svn: externals per condividere i progetti tra le soluzioni. Vogliamo anche mantenere un set comune di strumenti e librerie di terze parti in un unico posto nel repository e fare riferimento a loro in ciascuna soluzione con svn: externals.

Cosa ne pensi di questo layout? Soprattutto sull'uso di svn: externals. Non è una soluzione ideale, ma considerando tutti i pro e i contro, è la migliore che ci viene in mente. Come lo faresti?

È stato utile?

Soluzione

Se segui i miei consigli di seguito (lo faccio da anni), sarai in grado di:

- metti ogni progetto ovunque nel controllo del codice sorgente, purché conservi la struttura dalla directory radice del progetto in giù

- costruisci ogni progetto ovunque su qualsiasi macchina, con rischio minimo e preparazione minima

- crea ogni progetto completamente autonomo, a patto che tu abbia accesso alle sue dipendenze binarie (directory "biblioteca" locale e "uscita" e locale)

- crea e lavora con qualsiasi combinazione di progetti, poiché sono indipendenti

- crea e lavora con più copie / versioni di un singolo progetto, poiché sono indipendenti

- evita di ingombrare il repository di controllo del codice sorgente con file o librerie generati

Consiglio (ecco il manzo):

  1. Definisci ciascun progetto per produrre un unico deliverable primario, come un .DLL, .EXE o .JAR (predefinito con Visual Studio).

  2. Strutturare ogni progetto come un albero di directory con una singola radice.

  3. Crea uno script di compilazione automatizzato per ogni progetto nella sua directory principale che lo costruirà da zero, senza dipendenze su un IDE (ma non impedirne la creazione nell'IDE, se possibile).

  4. Prendi in considerazione nAnt per progetti .NET su Windows o qualcosa di simile in base al tuo sistema operativo, piattaforma di destinazione, ecc.

  5. Fai in modo che ogni script di compilazione di progetti faccia riferimento alle sue dipendenze esterne (di terze parti) da una singola libreria " locale " condivisa " directory, con ogni binario COMPLETAMENTE identificato dalla versione: % DirLibraryRoot% \ ComponentA-1.2.3.4.dll , % DirLibraryRoot% \ ComponentB-5.6.7.8.dll .

  6. Rendi ogni script di compilazione del progetto pubblica il deliverable primario in un singolo "output" quotato locale condiviso directory: % DirOutputRoot% \ ProjectA-9.10.11.12.dll , %DirOutputRoot%\ProjectB-13.14.15.16.exe.

  7. Fai in modo che ogni script di compilazione di progetti faccia riferimento alle sue dipendenze tramite percorsi assoluti configurabili e con versione completa (vedi sopra) nella " libreria " e "output" directory, E NESSUN ALTRO.

  8. MAI lasciare che un progetto faccia direttamente riferimento a un altro progetto o ad uno dei suoi contenuti - consenti solo riferimenti ai risultati principali nel "output" directory (vedi sopra).

  9. Fa in modo che ogni script di compilazione del progetto faccia riferimento ai suoi strumenti di compilazione richiesti mediante un percorso assoluto configurabile e con versione completa: % DirToolRoot% \ ToolA \ 1.2.3.4 , % DirToolRoot% \ toolb \ 5.6.7.8 .

  10. Rendi ogni progetto compilare il contenuto di origine dello script di riferimento mediante un percorso assoluto relativo alla directory principale del progetto: $ {project.base.dir} / src , $ {project. base.dir} / tst (la sintassi varia in base allo strumento di compilazione).

  11. SEMPRE richiedono uno script di compilazione del progetto per fare riferimento a OGNI file o directory tramite un percorso assoluto e configurabile (radicato in una directory specificata da una variabile configurabile): $ {project.base.dir} / some / dirs o ${env.Variable}/other/dir.

  12. MAI consentire a uno script di compilazione di progetti di fare riferimento a NULLA con un percorso relativo come . \ some \ dirs \ here o .. \ some \ more \ dirs , SEMPRE utilizzano percorsi assoluti.

  13. Non consentire MAI a uno script di compilazione di progetti di fare riferimento a NULLA usando un percorso assoluto che non ha una directory root configurabile, come C: \ some \ dirs \ here o \\ server \ share \ più \ roba \ vi .

  14. Per ciascuna directory root configurabile a cui fa riferimento uno script di compilazione del progetto, definire una variabile di ambiente che verrà utilizzata per tali riferimenti.

  15. Tenta di ridurre al minimo il numero di variabili d'ambiente che devi creare per configurare ogni macchina.

  16. Su ogni macchina, creare uno script shell che definisca le variabili di ambiente necessarie, che è specifica per quella macchina (e possibilmente specifica per quell'utente, se pertinente).

  17. NON mettere lo script della shell di configurazione specifico della macchina nel controllo del codice sorgente; invece, per ogni progetto, esegui il commit di una copia dello script nella directory principale del progetto come modello.

  18. RICHIEDE ogni script di compilazione del progetto per controllare ciascuna delle sue variabili di ambiente e interrompere con un messaggio significativo se non sono definiti.

  19. RICHIEDE ogni script di compilazione del progetto per controllare ciascuno dei suoi eseguibili di strumenti di compilazione dipendenti, file di librerie esterne e file di erogazione di progetti dipendenti e interrompere con un messaggio significativo se tali file non esistono.

  20. RESISTENZA alla tentazione di impegnare QUALSIASI file generato nel controllo del codice sorgente - nessun risultato del progetto, nessuna fonte generata, nessun documento generato, ecc.

  21. Se si utilizza un IDE, generare tutti i file di controllo del progetto che è possibile e non impegnarli nel controllo del codice sorgente (inclusi i file di progetto di Visual Studio).

  22. Stabilisci un server con una copia ufficiale di tutte le librerie e strumenti esterni, da copiare / installare sulle stazioni di lavoro degli sviluppatori e costruire macchine. Esegui il backup, insieme al tuo repository di controllo del codice sorgente.

  23. Stabilisci un server di integrazione continua (build machine) senza strumenti di sviluppo.

  24. Prendi in considerazione uno strumento per la gestione delle tue librerie esterne e dei risultati finali, come Ivy (usato con Ant).

  25. NON usare Maven: inizialmente ti renderà felice e alla fine ti farà piangere.

Notare che nulla di tutto ciò è specifico di Subversion e la maggior parte di essi è generica per progetti destinati a qualsiasi sistema operativo, hardware, piattaforma, linguaggio, ecc. Ho usato un po 'di sintassi specifica del sistema operativo e dello strumento, ma solo per esempio - confido che traducerai nel tuo sistema operativo o strumento preferito.

Nota aggiuntiva sulle soluzioni di Visual Studio: non metterle nel controllo del codice sorgente! Con questo approccio, non ne hai affatto bisogno o puoi generarli (proprio come i file di progetto di Visual Studio). Tuttavia, trovo che sia meglio lasciare i file della soluzione ai singoli sviluppatori per crearli / utilizzarli come meglio credono (ma non sono registrati per il controllo del codice sorgente). Conservo un file Rob.sln sulla mia workstation da cui faccio riferimento ai miei progetti attuali. Poiché i miei progetti sono tutti autonomi, posso aggiungere / rimuovere progetti a piacimento (ciò significa che non ci sono riferimenti di dipendenza basati su progetti).

Per favore, non usare gli esterni di Subversion (o simili in altri strumenti), sono un anti-schema e, quindi, non necessari.

Quando si implementa l'integrazione continua o anche quando si desidera solo automatizzare il processo di rilascio, creare uno script per questo. Crea un singolo script shell che: prende i parametri del nome del progetto (come elencato nel repository) e del nome della tag, crea una directory temporanea all'interno di una directory root configurabile, controlla l'origine per il nome del progetto e il nome della tag (costruendo il URL appropriato nel caso di Subversion) a quella directory temporanea, esegue una build pulita che esegue test e pacchetti il ??deliverable. Questo script della shell dovrebbe funzionare su qualsiasi progetto e dovrebbe essere verificato nel controllo del codice sorgente come parte dei tuoi "strumenti di costruzione" progetto. Il tuo server di integrazione continua può utilizzare questo script come base per la costruzione di progetti, oppure potrebbe anche fornirlo (ma potresti comunque volerne uno tuo).

@VonC: NON vuoi lavorare in qualsiasi momento con " ant.jar " anziché " ant-a.b.c.d.jar " dopo che ti sei bruciato quando lo script di compilazione si interrompe perché inconsapevolmente lo hai eseguito con una versione incompatibile di Ant. Questo è particolarmente comune tra Ant 1.6.5 e 1.7.0. Generalizzando, SEMPRE vuoi sapere quale versione specifica di OGNI componente viene utilizzato, compresa la tua piattaforma (Java A.B.C.D) e il tuo strumento di compilazione (Ant E.F.G.H). Altrimenti, alla fine incontrerai un bug e il tuo primo GRANDE problema sarà quello di rintracciare le versioni dei vari componenti coinvolti. È semplicemente meglio risolvere questo problema in anticipo.

Altri suggerimenti

Credo che Controllo pragmatico della versione utilizzando Subversion ha tutto il necessario per organizzare il tuo repository.

Abbiamo impostato il nostro in modo che corrisponda quasi esattamente a quello che hai pubblicato. Usiamo il modulo generale:

\Project1
   \Development (for active dev - what you've called "Trunk", containing everything about a project)
   \Branches (For older, still-evolving supported branches of the code)
       \Version1
       \Version1.1
       \Version2
   \Documentation (For any accompanying documents that aren't version-specific

Anche se suppongo che non sia completo come il tuo esempio, ha funzionato bene per noi e ci consente di tenere le cose separate. Mi piace l'idea che ogni utente abbia un " Thrash " anche cartella - attualmente, questi tipi di progetti non finiscono nel controllo del codice sorgente e ho sempre pensato che dovrebbero.

Perché avere tutto in un repository? Perché non avere un repository separato per ciascun progetto (intendo "soluzione")?

Beh, almeno mi sono abituato all'approccio a un progetto per repository. La struttura del tuo repository mi sembra eccessivamente complicata.

E quanti progetti hai intenzione di mettere in questo grande repository? 2? 3? 10? 100?

E cosa fai quando annulli lo sviluppo di un progetto? Basta eliminarlo dall'albero del repository in modo che in futuro diventi difficile da trovare. O lasciarlo in giro per sempre? O quando vuoi spostare completamente un progetto su un altro server?

E che dire del pasticcio di tutti quei numeri di versione? I numeri di versione di un progetto vanno come 2, 10, 11, mentre l'altro va come 1, 3, 4, 5, 6, 7, 8, 9, 12 ...

Forse sono sciocco, ma mi piace un progetto per repository.

Penso che il principale svantaggio della struttura proposta sia che i progetti condivisi verranno modificati solo con la prima soluzione a cui sono stati aggiunti (a meno che svn: externals sia più elaborato di quanto immagino). Ad esempio, quando si crea un ramo per la prima versione di Solution2, Project1 non verrà ramificato poiché risiede in Solution1. Se è necessario compilare da quel ramo in un secondo momento (versione QFE), utilizzerà l'ultima versione di Project1 anziché la versione di Project1 al momento del branch.

Per questo motivo, può essere vantaggioso inserire i progetti condivisi in una o più soluzioni condivise (e quindi directory di livello superiore nella struttura) e quindi ramificarli con ogni versione di qualsiasi .

Per aggiungere al problema relativo al percorso:

Non sono sicuro che sia un problema:
Basta estrarre Solution1 / trunk nella directory denominata " Soluzione1 " ;, idem per Solution2: l'obiettivo di "directory" che rappresentano effettivamente i rami è non essere visibile una volta importato in un'area di lavoro. Quindi sono possibili percorsi relativi tra 'Soluzione1' (in realtà 'Soluzione1 / trunk') e 'Soluzione2' (Soluzione2 / trunk).

RE: il percorso relativo e il problema del file condiviso -

Sembra che questo sia specifico per svn, ma non è un problema. Un'altra persona ha già menzionato repository separati e questa è probabilmente la soluzione migliore che mi viene in mente nel caso in cui tu abbia diversi progetti che si riferiscono ad altri progetti arbitrari. Nel caso in cui non si disponga di file condivisi, la soluzione OP (così come molte altre) funzionerà correttamente.

Stiamo ancora cercando di risolverlo e ho 3 diversi sforzi (client diversi) che devo risolvere in questo momento da quando ho assunto la configurazione del controllo della versione inesistente o scadente.

Ho un layout simile, ma il mio tronco, i rami, i tag completamente in alto. Quindi: / trunk / main, / trunk / utils, / filiali / release /, ecc.

Questo è risultato molto utile quando volevamo provare altri sistemi di controllo della versione perché molti degli strumenti di traduzione funzionavano meglio con il layout SVN del manuale di base.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top