TFS 2010 Object Model - Utilizzo dei Workspaces
Scritto da
Massimo Bonanni
il
mercoledì 23 marzo 2011
Linguaggio:
•
Framework:
•
Livello: 200
Download pdf
Nel precedente articolo abbiamo esaminato come poter gestire
alcuni aspetti del versioning utilizzando il servizio
VersionControlServer. In questo articolo vedremo come utilizzare i
servizi esposti dai workspaces di Team Foundation Server.
La classe WorkSpace
La classe WorkSpace modella il workspace con cui siamo
abituati a lavorare se utilizziamo Team Explorer:

Un workspace è identificato da una project collection a cui è
connesso, un nome ed un proprietario ed è recuperabile tramite il
servizio VersionControlServer tramite il metodo GetWorkspace.
Il seguente metodo fornisce un esempio di utilizzo di tale
metodo:
Public Function GetWorkSpace(ByVal collectionUrl As String,
ByVal workspaceName As String,
ByVal workspaceOwner As String) As Workspace
Dim retVal As Workspace = Nothing
If Not String.IsNullOrWhiteSpace(collectionUrl) Then
Try
Dim tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(New Uri(collectionUrl),
New UICredentialsProvider())
Dim versionControlServer = CType(tpc.GetService(Of VersionControlServer)(), VersionControlServer)
retVal = versionControlServer.GetWorkspace(workspaceName, workspaceOwner)
Catch ex As Exception
Throw
End Try
Else
Throw New ArgumentNullException("collectionUrl must be not null")
End If
Return retVal
End Function
Il metodo GetWorkspace prevede 3
differenti overload che consentono di recuperare il workspace
mappato in una specifica directory del disco, a partire dal nome
del workspace e del proprietario (l'overload utilizzato nel
precedente esempio) oppure utilizzando la classe WorkSpaceInfo:

Gestire un workspace
La classe VersionControlServer ci permette di creare un
nuovo workspace come mostrato nel seguente esempio:
Public Function CreateWorkSpace(ByVal collectionUrl As String,
ByVal workspaceName As String,
ByVal workspaceOwner As String) As Workspace
Dim retVal As Workspace = Nothing
If Not String.IsNullOrWhiteSpace(collectionUrl) Then
Try
Dim tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(New Uri(collectionUrl),
New UICredentialsProvider())
Dim versionControlServer = CType(tpc.GetService(Of VersionControlServer)(), VersionControlServer)
retVal = versionControlServer.CreateWorkspace(workspaceName, workspaceOwner)
Catch ex As Exception
Throw
End Try
Else
Throw New ArgumentNullException("collectionUrl must be not null")
End If
Return retVal
End Function
Il metodo CreateWorkspace della VersionControlServer prevede
anche la possibilità di creare anche il mapping tra gli items
presenti nel controllo del codice sorgente e le cartelle su disco.
E' possibile creare un workspace anche su una workstation che non è
quella in cui gira il codice.
In maniera del tutto analoga, possiamo eliminare un workspace
utilizzando il metodo DeleteWorkspace a partire dal nome e
dall'owner:
Public Function DeleteWorkSpace(ByVal collectionUrl As String,
ByVal workspaceName As String,
ByVal workspaceOwner As String) As Boolean
Dim retVal As Boolean = False
If Not String.IsNullOrWhiteSpace(collectionUrl) Then
Try
Dim tpc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(New Uri(collectionUrl),
New UICredentialsProvider())
Dim versionControlServer = CType(tpc.GetService(Of VersionControlServer)(), VersionControlServer)
retVal = versionControlServer.DeleteWorkspace(workspaceName, workspaceOwner)
Catch ex As Exception
Throw
End Try
Else
Throw New ArgumentNullException("collectionUrl must be not null")
End If
Return retVal
End Function
Funzionalità di un workspace
Una volta recuperato il workspace, possiamo eseguire le
stesse operazioni che eseguiamo tipicamente con il Team
Explorer.
Prima operazione che possiamo eseguire è il recupero di una
versione specifica dei sorgenti (che può anche essere l'ultima
versione).
Per fare ciò, la classe Workspace ci mette a disposizione il
metodo Get (con ben 8 overloads). L'utilizzo più semplice di questo
metodo è quello che prevede la chiamata senza parametri e che
provoca un "Get Latest Version":
Dim ws = GetWorkSpace("http://MyServer:8080/tfs/MyCollection", "MioWorkspace", "utente")
If ws IsNot Nothing Then
Dim result = ws.Get()
If Not result.NoActionNeeded Then
' gestione degli errori
End If
End If
La chiamata al metodo Get restituisce un oggetto di classe
GetStatus:

L'oggetto GetStatus consente di avere tutte le informazioni
riguardo il risultato dell'operazione di Get ed in particolare:
- NoActionNeeded : se true tutto è andato a buon
fine senza problemi, se false ci sono stati degli errori (o
warning) e debbono essere intraprese delle azioni;
- HaveResolvableWarnings : se true significa che
almeno un warning può essere risolto;
- NumConflicts : numero di conflitti verificati
durante l'operazione;
- NumFailures : numero di errori verificati
durante l'operazione;
- NumOperations : numero totale di operazioni
eseguite;
- NumUpdated : numero di aggiornamenti eseguiti
nel workspace su disco;
- NumWarnings: numero di warning che si sono
verificati nell'operazione.
Se l'operazione genera degli errori (NoActionNeed = false),
possiamo sapere cosa è accaduto utilizzando il metodo GetFailures
della classe GetStatus.
Questo metodo restituisce un array di oggetti di tipo Failure
(vedere figura precedente) ognuno dei quali contiene tutte le
informazioni relative all'errore verificatosi.
Il metodo Get della classe Workspace può essere utilizzato anche
per recuperare una specifica versione del codice sorgente (ad
esempio ad un determinato changeset o ad una determinata data).
Nel seguente esempio, recuperiamo tutti i file della versione
presente sul server il giorno 31/12/2010:
Dim ws = GetWorkSpace("http://MyServer:8080/tfs/MyCollection", "MioWorkspace", "utente")
If ws IsNot Nothing Then
Dim dateVersionSpec = New DateVersionSpec(New DateTime(2010, 12, 31))
Dim result = ws.Get(dateVersionSpec, GetOptions.GetAll)
If Not result.NoActionNeeded Then
' gestione degli errori
End If
End If
Il metodo Get mette a disposizione anche la possibilità di
eseguire delle query per recuperare il codice sorgente in maniera
articolata permettendo di gestire in maniera semplice anche il
filtraggio dei dati di ritorno. In particolare, uno degli overload
mette a disposizione la possibilità di passare una callback (un
delegate) che viene richiamata dall'OM dopo aver eseguito la
request sul server ma prima che i dati vengano processati
localmente.
Nell'esempio seguente recuperiamo tutti i file sotto controllo
di codice sorgente alla data odierna andando ad ignorare tutti quei
file la cui operazione è l'aggiunta:
Dim ws = GetWorkSpace("http://MyServer:8080/tfs/MyCollection", "MioWorkspace", "utente")
If ws IsNot Nothing Then
Dim dateVersionSpec = New DateVersionSpec(DateTime.Now)
Dim request = New GetRequest("*.*", RecursionType.Full, dateVersionSpec)
Dim result = ws.Get(request, GetOptions.GetAll, AddressOf FilterGet, Nothing)
If Not result.NoActionNeeded Then
' gestione degli errori
End If
End If
.
.
.
Private Sub FilterGet(ByVal workspace As Workspace,
ByVal operations As ILocalUpdateOperation(),
ByVal userData As Object)
For Each operation In operations
' eseguiamo il filtro in base a ciò che è contenuto in operation
If operation.ChangeType = ChangeType.Add Then
' se il tipo di operazione è Add
Else
operation.Ignore = True ' ignoro l'operazione
End If
Next
End Sub
Un'altra operazione consuenta nella gestione quotidiana del
codice sorgente è il CheckIn. La classe WorkSpace mette a
disposizione un metodo omonimo (con 5 overload) per eseguire questa
operazione.
La firma più completa prevede il passaggio di un oggetto di
classe WorkspaceCheckInParameters:

La classe WorkspaceCheckinParameters espone una serie di
proprietà che ci consentono di definire data di checkin, commento,
elenco degli item da confermare sul server, workitem associati con
relativa azione (resolve, associate, etc., etc.) e tutto ciò a cui
siamo abituati se utilizziamo il Team Explorer.
Il risultato del metodo CheckIn è un intero che, in caso di
successo, contiene il numero di changset.
Nell'ottica di eseguire un check-in, la classe Workspace mette a
disposizione anche la possibilità di controllare preventivamente se
i file locali sono pronti per un check-in.
Il metodo EvaluateCheckin "simula", infatti, un checkin
(anche se non lo esegue effettivamente) e restituisce un oggetto di
classe CheckinEvaluationResult che contiene eventuali conflitti ed
eccezioni che si possono verificare durante il check-in vero e
proprio.
La classe Workspace permette, ovviamente, di gestire anche
l'aggiunta, la rimozione, il rename, l'edit, l'undelete ed il
branch degli elementi presenti nel repository del codice sorgente.
Esistono, infatti, una serie di metodi (con molteplici overload)
per la gestioned i queste casistiche:
- PendAdd : aggiunge un file o una cartella alla
coda per l'inserimento all'interno del repository del codice
sorgente;
- PendBranch : aggiunge un file o una cartella
come pianificato per una branch;
- PendDelete : aggiunge un file o una cartella
alla coda per l'eliminazione dal repository del codice
sorgente;
- PendEdit : aggiunge un file o una cartella
alla coda degli items modificati;
- PendRename : aggiunge un file o una cartella
alla coda degli items rinominati (vale anche per i file
spostati);
- PendUndelete : aggiunge un file o una cartella
alla coda degli items recuperati da una cancellazione.
Per esempio, il seguente codice aggiunge il file MiaClasse.vb
tra i file sotto controllo di codice sorgente:
Dim ws = GetWorkSpace("http://MyServer:8080/tfs/MyCollection", "MioWorkspace", "utente")
If ws IsNot Nothing Then
Dim numFiles = ws.PendAdd("C:\MioProgetto\MiaClasse.vb")
End If
Una volta eseguite le operazioni di gestione dei file sotto
controllo di codice sorgente (aggiunta, rimozione, spostamento,
etc., etc.) possiamo recuperare l'elenco degli items in pending
changes utilizzando il metodo GetPendingChanges (ben 11
overload).
Nel seguente esempio vediamo come recuperare tutti i pending
changes di un certo workspace:
Dim ws = GetWorkSpace("http://MyServer:8080/tfs/MyCollection", "MioWorkspace", "utente")
If ws IsNot Nothing Then
Dim items = ws.GetPendingChanges()
For Each item In items
Console.WriteLine("{0} - {1}", item.FileName, item.ChangeType)
Next
End If
Il metodo GetPendingChanges restituisce un array di
oggetti PendingChange ognuno dei quali contiene tutte le
informazioni per identificare l'item:

Abbiamo a disposizione anche il metodo
GetPendingChangesEnumerable che restituisce un oggetto IEnumerable
anzichè un array e ci consente di eseguire anche query linq
sull'insieme dei pending changes.
La classe Workspace mette a disposizione, quindi, una quantità
enorme di funzionalità che ci consentono di eseguire tutte quelle
operazioni a cui siamo abituati (e che diamo per scontate) quando
usiamo il Team Explorer e che ci consentono di realizzare, più o
meno facilmente, un nostro client per la gestione del codice
sorgente.
Il consiglio è di studiarsi le proprietà e i metodi esposti (che
abbiamo in minima parte analizzato in questo articolo) andando
direttamente su MSDN all'indirizzo http://msdn.microsoft.com/en-us/library/bb171783.aspx.
Riferimenti
[1] Team Foundation Server Architecture: http://msdn.microsoft.com/en-us/library/ms252473.aspx
[2] Extending Team Foundation: http://msdn.microsoft.com/en-us/library/bb130146.aspx
[3] Team Foundation Server 2010 SDK: http://code.msdn.microsoft.com/TfsSdk
[4] Team Foundation Server Team Blog: http://blogs.msdn.com/b/team_foundation/
Tags: TFS,Team Foundation,Team Foundation Server