TFS2010 Object Model: Scaricare tutti i file sorgente di tutte le project collection in un colpo solo e senza workspace
In questo post vorrei mostrarvi come sia possibile scaricare tutti i files presenti nel controllo di codice sorgente di TFS senza utilizzare un workspace.
Per fare questo utilizzeremo un istanza della classe VersionControlService (namespace Microsoft.TeamFoundation.VersionControl.Client).
Prima di tutto abbiamo la necessità di referenziare gli assembly:
- Microsoft.TeamFoundation.Client.dll;
- Microsoft.TeamFoundation.VersionControl.Client.dll;
- Microsoft.TeamFoundation.Common.dll
Le dll sono già presenti nelle macchine che hanno installato Team Explorer.
L’algoritmo che utilizzeremo sarà:
- recuperare l’elenco delle project collection presenti sul server TFS (e a cui abbiamo accesso);
- iterare su ogni collection e recuperare l’elenco di tutti i file sotto controllo di codice sorgente ad una certa data
- salvare i file in una cartella definita dall’utente mantenendo la struttura gerarchica delle cartelle sul server.
Abbiamo già visto in un precedente post come recuperare l’elenco delle collection e, riportiamo, quindi solo il codice necessario:
- Private Sub CreateTFSServer(ByVal serverUrl As String)
- Contracts.Contract.Requires(Not String.IsNullOrWhiteSpace(serverUrl), "Url Server non pu? essere vuoto")
- If TFSServer IsNot Nothing Then TFSServer.Dispose()
- Try
- TFSServer = TfsConfigurationServerFactory.GetConfigurationServer(New Uri(serverUrl), New UICredentialsProvider())
- Catch ex As Exception
- Throw
- End Try
- End Sub
- Public Function GetCollectionUris() As IEnumerable(Of String)
- Contracts.Contract.Requires(Me.TFSServer IsNot Nothing, "Server non connesso")
- Dim retList As IEnumerable(Of String) = Nothing
- Try
- Dim collections = Me.TFSServer.CatalogNode().QueryChildren({CatalogResourceTypes.ProjectCollection},
- False,
- CatalogQueryOptions.None)
- retList = From o In collections
- Select String.Format("{0}/{1}", Me.TFSServer.Uri.AbsoluteUri, o.Resource.DisplayName)
- Catch ex As Exception
- Throw
- End Try
- Return retList
- End Function
Il metodo CreateTFSServer istanzia un oggetto di classe TfsConfigurationServer utile per accedere ai dati delle collection che sono, invece, recuperati dal metodo GetCollectionUris. Questo metodo restituisce una collezione di stringhe che rappresentano gli uri delle singole collezioni nella forma:
http://mioserver:8080/tfs/miacollezione
Il seguente metodo permette di recuperare l’elenco dei file sotto controllo di codice sorgente per una collezione:
- Public Function GetVersionedItems(ByVal collectionUri As String,
- ByVal projectName As String,
- ByVal filter As String,
- ByVal versionDate As DateTime) As IEnumerable(Of Item)
- Contracts.Contract.Requires(Not String.IsNullOrWhiteSpace(collectionUri), "CollectionUri non pu? essere nullo")
- Dim retList As IEnumerable(Of Item) = Nothing
- Try
- Dim tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(New Uri(collectionUri))
- Dim versionControlServer = CType(tpc.GetService(Of VersionControlServer)(), VersionControlServer)
- Dim pathStr = String.Format("$/{0}/{1}", projectName, filter)
- Dim dateVerSpec = New DateVersionSpec(versionDate)
- retList = versionControlServer.GetItems(pathStr, dateVerSpec, RecursionType.Full).Items
- Catch ex As Exception
- Throw
- End Try
- Return retList
- End Function
Per prima cosa otteniamo l’istanza della classe TfsTeamProjectCollection necessaria per ricavare l’oggetto VersionControlServer il quale ci permette, tramite il metodo GetItems, di recuperare l’elenco degli Items sotto controllo di codice sorgente. Da notare che l’argomento stringa filter può servire per recuperare tutti e soli gli item di un certo tipo (ad esempio “*.vb”).
Ultimo step dell’algoritmo è quello di salvare gli items di tipo file nella cartella decisa dall’utente e per fare ciò ci viene in aiuto il seguente codice:
- Private Function SaveItems(ByVal items As IEnumerable(Of Microsoft.TeamFoundation.VersionControl.Client.Item),
- ByVal destinationPath As String) As IEnumerable(Of String)
- Dim retval = New List(Of String)
- For Each Item In items
- If Item.ItemType = ItemType.File Then
- Dim origFileName = Item.ServerItem.Replace("$/", "")
- origFileName = origFileName.Replace("/", "\")
- Dim fileName = IO.Path.Combine(destinationPath, origFileName)
- Try
- Item.DownloadFile(fileName)
- retval.Add(fileName)
- Catch ex As Exception
- Throw
- End Try
- End If
- Next
- Return retval
- End Function
In questo caso iteriamo sugli items di tipo ItemType.File, per ognuno di questi creiamo il percorso in cui salvarlo a partire dal percorso originale all’interno della cartella di destinazione e salviamo il file.
Il metodo che esegue i tre passi precedenti è il seguente:
- Private Function DownloadAllItems(ByVal destinationPath As String, _
- ByVal versionDate As DateTime) As IEnumerable(Of String)
- Contracts.Contract.Requires(Not String.IsNullOrWhiteSpace(destinationPath), "destinationPath non pu? essere vuota")
- Dim retval = New List(Of String)
- Dim colls As IEnumerable(Of String) = Nothing
- Try
- colls = Me.GetCollectionUris()
- Catch ex As Exception
- Throw
- End Try
- If colls IsNot Nothing Then
- For Each coll In colls
- Dim items As IEnumerable(Of Item) = Nothing
- Try
- items = GetVersionedItems(coll, Nothing, "*.*", versionDate)
- Catch ex As Exception
- Throw
- End Try
- If items IsNot Nothing Then
- Dim collName = coll.Substring(coll.LastIndexOf("/") + 1)
- Dim destPath = IO.Path.Combine(destinationPath, collName)
- Try
- retval.AddRange(SaveItems(items, destPath))
- Catch ex As Exception
- Throw
- End Try
- End If
- Next
- End If
- Return retval
- End Function
Nella soluzione che trovate allegata al post, è presente anche una versione asincrona (l’operazione di autenticazione e recupero degli items da TFS può durare anche qualche secondo) che utilizza un algoritmo del tutto analogo.
La form dell’applicazione è la seguente:
Commenti