How do I resolve the root and relative paths of TFS folders on the server?
Asked Answered
S

1

7

I have created a CodeActivity for use in (custom) build definitions. This activity needs to copy files located on the server to/from places like the 'source directory', 'custom folders' to the 'drop directory' (etc.) before executing its primary purpose.

Some of the variables I have are valid paths, but others are obviously placeholders for 'relative paths'. However, I need the physical server path so I can copy useful items to-and-fro.

I NEED THINGS LIKE:

  • The physical path for the projects root (see image below)
  • To be able to resolve the physical path to custom folders (see image below)
  • It would be nice to be able to resolve physical paths from 'relative paths'

Of course, I could pass the project-name into the activity (for parsing purposes)...because that would just be 'cheesy'.

MY QUESTION(S) ARE:

  • How do I resolve the physical path to the TFS project root?
  • Once I resolve the root, can I rely on it to 'build' paths to custom folders?
  • How do I get the server paths from relative paths like '$/Test/Drops'?

SOME EXAMPLES OF THINGS I KNOW HOW TO GET:
These items are somewhat useful, while others...not so much. Unless, I can use them to get the physical server paths.

BuildDirectory:
'F:\bld\Builds\41\Test\Test_CustomActivity_CreateNuGetPackages'

BuildDetail.DropLocationRoot:
'$/Test/Drops'
...wish I had the physical path

BuildDetail.BuildController.CustomAssemblyPath:
'$/Test/BuildProcessTemplates'
...wish I had the physical path

SourcesDirectory:
'F:\bld\Builds\41\Test\Test_CustomActivity_CreateNuGetPackages\src'

Workspace.Folders:
'F:\bld\Builds\41\Test\Test_CustomActivity_CreateNuGetPackages\src\Test\NuGet.Research\net35'

SOME EXAMPLES OF THINGS I WANT:
enter image description here

UPDATE: 2/2/2015
@Edward - per your request. Below is a more detailed explanation of what I am trying to accomplish.

enter image description here enter image description here

Slosh answered 26/1, 2015 at 19:43 Comment(2)
are you expecting there to be physical folder paths on the server corresponding to your source code?Diecious
@Diecious Yes...why wouldn't there be? I would think there would have to be?Slosh
C
14

Let me preface this answer by saying that there's a lot of terminology overload going on, so I want to define a few things:

  • Server path: the path to the file or folder in the version control system. For example, $/Test/BuildResources is a server path. This is an absolute server path, it is not relative.
  • Local path: the path that you have mapped the server path to on your machine. For example, D:\Test\BuildResources or /home/me/test/buildresources is a local path.
  • Mapping: the correspondence between the server paths and local paths - so that TFVC knows where to put files on your local machine when you do a "get".

I define this not to be pedantic, but because having the terminology correct will be helpful when using the TFS SDK, which will let you query the local path for a given server path (and vice versa) easily. (You should not simply concatenate path components together, since TFVC allows for very complex workspace mappings.)

To get started with the TFS SDK, you first need to find the server connection information. If you have a given local path (in this case, your SourcesDirectory) you can use that to read the workspace cache and get the information you need for the server connection that the build server has created:

// Get the workspace information for the build server's workspace
var workspaceInfo = Workstation.Current.GetLocalWorkspaceInfo(sourcesDirectory);

// Get the TFS Team Project Collection information from the workspace cache
// information then load the TFS workspace itself.
var server = new TfsTeamProjectCollection(workspaceInfo.serverUri);
var workspace = workspaceInfo.GetWorkspace(server);

Once you have a workspace, you can query it for the path mappings. It will do the necessary translation from server to local path based on your workspace mappings. For example:

workspace.GetServerItemForLocalItem("D:\My\Local\Path");

and

workspace.GetLocalItemForServerItem("$/My/Server/Path");

This mechanism will only work, however, if your build definition actually sets up the workspace to include these files. If you need some directory $/Foo/Bar, you will need to make sure that it is included in the Source Settings details tab of the Build Definition.

Caddish answered 26/1, 2015 at 20:7 Comment(8)
Thanks...I really do I appreciate you correcting my wording :) I will play with this.Slosh
You could also pass in the Mapped value to your activity from the build definition template. In the template use ConvertWorkspaceItem or ConvertWorkspaceItems prior to calling your activity to get the local file values from the server location. Since you have the workspace variable in there you just pass it to the activity to get the mapped value. Good answer Ed.Liebig
I am testing-out this recommendation on things like '$/Test/SomeFolder' However, I am getting an exception saying, "There is no working folder mapping for {some folder I know is there}". Does the Build Definition setup (e.g. depth) affect the kind of paths I am able to resolve?Slosh
Yes; if you want to be able to map a local file to a server file, then you must set that in the workspace mappings tab on the build definition.Caddish
You say, "...file." How about a local DIRECTORY? It fails on directories.Slosh
Is it actually mapped? Can you provide a screenshot of the mapping dialog and an example of the paths (files or folders) you are trying to map?Caddish
It's the build definition that controls what gets mapped and downloaded. Can you post a screenshot of the build definition's mappings? Available by going to "Edit Build Definition".Caddish
It looks like your build definition only sets up two source control folders to get from the server: net35 and net45. If you need the contents of another folder, add it to the Source Settings tab.Caddish

© 2022 - 2024 — McMap. All rights reserved.