<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Perforce</title>
        <link>http://geekswithblogs.net/EltonStoneman/category/7943.aspx</link>
        <description>Perforce SCM - P4 command line and P4V GUI, used in Windows</description>
        <language>en-GB</language>
        <copyright>EltonStoneman</copyright>
        <managingEditor>elton.stoneman@gmail.com</managingEditor>
        <generator>Subtext Version 0.0.0.0</generator>
        <item>
            <title>Sample CruiseControl build using Perforce</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2008/05/29/sample-cruisecontrol-build-using-perforce.aspx</link>
            <description>&lt;p&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;Tim asked for some more detail on using Perforce as your SCM for CruiseControl from &lt;a href="http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/using-perforce-with-cruisecontrol.net.aspx"&gt;this post&lt;/a&gt;, so here are some sample config files. This post may be too detailed for a general audience… &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;&lt;em&gt;Perforce Setup –  Build Server Workspace &lt;/em&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-size: 10pt;"&gt;&lt;span style="font-family: Arial;"&gt;You'll need a dedicated workspace for the build server to use – this will be used by CC.Net to check for changes and to resync. You don't need a separate user account, so it can be created with the build manager as the owner. You'll define the location to monitor in the CC.Net config, so the workspace only needs a view over the root project. So you may create a workspace called &lt;strong&gt;build.server&lt;/strong&gt; with a view of &lt;/span&gt;&lt;span style="font-family: Courier New;"&gt;//depot/… //build.server/…&lt;/span&gt;&lt;span style="font-family: Arial;"&gt; (while you're setting this up you can use it from your dev machine with a different root from your normal workspace, then change the host to be the build server when your scripts are finished). &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;&lt;em&gt;CruiseControl setup - CCNet.config&lt;/em&gt;&lt;/span&gt; 		&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 10pt;"&gt; &lt;/span&gt; 		&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 10pt;"&gt;This sample config uses the build server's workspace to monitor //depot/ProjectX/MAIN/source (assumes the workspace depot is c:\depot): &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;span style="font-family: Courier New; font-size: 9pt;"&gt;&amp;lt;cruisecontrol&amp;gt; &lt;br /&gt;
  &amp;lt;project name="ProjectX"&amp;gt; &lt;br /&gt;
    &amp;lt;sourcecontrol type="p4"&amp;gt; &lt;br /&gt;
      &amp;lt;view&amp;gt;//depot/ProjectX/MAIN/source...&amp;lt;/view&amp;gt; &lt;br /&gt;
      &amp;lt;client&amp;gt;build.server&amp;lt;/client&amp;gt; &lt;br /&gt;
      &amp;lt;applyLabel&amp;gt;true&amp;lt;/applyLabel&amp;gt; &lt;br /&gt;
      &amp;lt;autoGetSource&amp;gt;true&amp;lt;/autoGetSource&amp;gt; &lt;br /&gt;
    &amp;lt;/sourcecontrol&amp;gt; &lt;br /&gt;
    &amp;lt;workingDirectory&amp;gt;C:\depot\ProjectX\MAIN\source&amp;lt;/workingDirectory&amp;gt; &lt;br /&gt;
    &amp;lt;webURL&amp;gt;&lt;a href="http://localhost/ccnet"&gt;http://localhost/ccnet&lt;/a&gt; &amp;lt;/webURL&amp;gt; &lt;br /&gt;
    &amp;lt;artifactDirectory&amp;gt;C:\buildOutput\ProjectX\artifacts&amp;lt;/artifactDirectory&amp;gt; &lt;br /&gt;
    &amp;lt;modificationDelaySeconds&amp;gt;5&amp;lt;/modificationDelaySeconds&amp;gt; &lt;br /&gt;
    &amp;lt;triggers&amp;gt; &lt;br /&gt;
      &amp;lt;intervalTrigger name="continuous" seconds="10"/&amp;gt; &lt;br /&gt;
    &amp;lt;/triggers&amp;gt; &lt;br /&gt;
    &amp;lt;state type="state" directory="C:\buildOutput\ProjectX\artifacts" /&amp;gt; &lt;br /&gt;
    &amp;lt;labeller type="iterationlabeller"&amp;gt; &lt;br /&gt;
      &amp;lt;prefix&amp;gt;1.1&amp;lt;/prefix&amp;gt; &lt;br /&gt;
      &amp;lt;duration&amp;gt;4&amp;lt;/duration&amp;gt; &lt;br /&gt;
      &amp;lt;releaseStartDate&amp;gt;2008/5/29&amp;lt;/releaseStartDate&amp;gt; &lt;br /&gt;
      &amp;lt;separator&amp;gt;.&amp;lt;/separator&amp;gt; &lt;br /&gt;
    &amp;lt;/labeller&amp;gt; &lt;br /&gt;
    &amp;lt;tasks&amp;gt; &lt;br /&gt;
      &amp;lt;msbuild&amp;gt; &lt;br /&gt;
        &amp;lt;executable&amp;gt;C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe&amp;lt;/executable&amp;gt; &lt;br /&gt;
        &amp;lt;projectFile&amp;gt;build\ProjectX.build&amp;lt;/projectFile&amp;gt; &lt;br /&gt;
        &amp;lt;targets&amp;gt;FullBuild&amp;lt;/targets&amp;gt; &lt;br /&gt;
        &amp;lt;buildArgs&amp;gt;/noconsolelogger /p:Configuration=Debug /verbosity:minimal&amp;lt;/buildArgs&amp;gt; &lt;br /&gt;
        &amp;lt;logger&amp;gt;C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll&amp;lt;/logger&amp;gt; &lt;br /&gt;
      &amp;lt;/msbuild&amp;gt; &lt;br /&gt;
    &amp;lt;/tasks&amp;gt; &lt;br /&gt;
  &amp;lt;/project&amp;gt; &lt;br /&gt;
&amp;lt;/cruiseControl&amp;gt; &lt;br /&gt;
&lt;/span&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt; &lt;/span&gt; 		&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 10pt;"&gt;This tells CC to connect to Perforce in the build.server workspace, and monitor all files under //depot/ProjectX/MAIN/source. When it finds a change, it will resynchronise (bringing the build server's copy of the source up to date), determine a label for the build, and start the FullBuild target in the MSBuild file. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;If the build is successful, the label is applied to all files in the view, so Perforce is stamped with a label for every successful build (this means at any time we can create a branch for a specific build which we know will work). There's no publishing here, but you typically configure CCNet to issue build failure mails to people/lists named in the project. &lt;/span&gt; 	&lt;/p&gt;
&lt;p&gt;For multiple projects in the same &lt;span style="font-family: Arial; font-size: 10pt;"&gt;CCNet config, you can use the same workspace but specify a different view. &lt;/span&gt; 		&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 10pt;"&gt; &lt;/span&gt; 		&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 10pt;"&gt;&lt;em&gt;MSBuild setup – projectX.build&lt;/em&gt;&lt;/span&gt; 	&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;The build file specifies targets as entry points. Targets can contain other targets, so typically the build process will be split into component parts which are brought together by composite targets. A sample build file split like this is:&lt;/span&gt; 	&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: 9pt;"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt; &lt;br /&gt;
&amp;lt;Project xmlns="&lt;a href="http://schemas.microsoft.com/developer/msbuild/2003"&gt;http://schemas.microsoft.com/developer/msbuild/2003&lt;/a&gt;" DefaultTargets="FullBuild"&amp;gt; &lt;br /&gt;
  &amp;lt;!-- MSBuild extensions required; use installer from Prerequisites--&amp;gt; &lt;br /&gt;
  &amp;lt;Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/&amp;gt; &lt;br /&gt;
  &amp;lt;!-- Properties--&amp;gt; &lt;br /&gt;
  &amp;lt;PropertyGroup&amp;gt; &lt;br /&gt;
    &amp;lt;Configuration Condition=" '$(Configuration)' == '' "&amp;gt;Debug&amp;lt;/Configuration&amp;gt; &lt;br /&gt;
    &amp;lt;OutputDir&amp;gt;bin\$(Configuration)&amp;lt;/OutputDir&amp;gt; &lt;br /&gt;
    &amp;lt;ObjOutputDir&amp;gt;obj\$(Configuration)&amp;lt;/ObjOutputDir&amp;gt; &lt;br /&gt;
    &amp;lt;ProjectDir&amp;gt;..\ProjectX&amp;lt;/ProjectDir &amp;gt; &lt;br /&gt;
    &amp;lt;ProjectTestDir&amp;gt;..\ProjectX.Test&amp;lt;/ProjectTestDir &amp;gt; &lt;br /&gt;
    &amp;lt;ProjectFile&amp;gt;$(ProjectDir)\ProjectX.csproj&amp;lt;/ProjectFile &amp;gt; &lt;br /&gt;
    &amp;lt;TestProjectFile&amp;gt;$(ProjectTestDir)\ProjectX.Test.csproj&amp;lt;/TestProjectFile &amp;gt; &lt;br /&gt;
    &amp;lt;ExcludeTestCategories&amp;gt;InProgress,LongRunning&amp;lt;/ExcludeTestCategories&amp;gt; &lt;br /&gt;
    &amp;lt;Version Condition=" '$(CCNetLabel)' == '' "&amp;gt;1.0.0.0&amp;lt;/Version&amp;gt; &lt;br /&gt;
    &amp;lt;NUnitOutputXmlFile&amp;gt;C:\buildOutput\ProjectX\artifacts\testResults_$(Version).xml&amp;lt;/NUnitOutputXmlFile&amp;gt; &lt;br /&gt;
  &amp;lt;/PropertyGroup&amp;gt; &lt;br /&gt;
  &amp;lt;!-- Default entry point, builds &amp;amp; runs all Continuous tests--&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="FullBuild"&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="BuildNoTests"/&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="UnitTestContinuous"/&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="Package" /&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="BuildNoTests"&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="Build"/&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="PostBuild"/&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;ItemGroup&amp;gt; &lt;br /&gt;
    &amp;lt;OutputDirectory Include="d1"&amp;gt; &lt;br /&gt;
      &amp;lt;DirectoryName&amp;gt; &lt;br /&gt;
        $(ProjectDir)\$(OutputDir) &lt;br /&gt;
      &amp;lt;/DirectoryName&amp;gt; &lt;br /&gt;
    &amp;lt;/OutputDirectory&amp;gt; &lt;br /&gt;
    &amp;lt;OutputDirectory Include="d2"&amp;gt; &lt;br /&gt;
      &amp;lt;DirectoryName&amp;gt; &lt;br /&gt;
        $(ProjectDir)\$(ObjOutputDir)&amp;lt;/DirectoryName&amp;gt; &lt;br /&gt;
    &amp;lt;/OutputDirectory&amp;gt; &lt;br /&gt;
    &amp;lt;OutputDirectory Include="d3"&amp;gt; &lt;br /&gt;
      &amp;lt;DirectoryName&amp;gt;$(ProjectTestDir)\$(OutputDir)&amp;lt;/DirectoryName&amp;gt; &lt;br /&gt;
    &amp;lt;/OutputDirectory&amp;gt; &lt;br /&gt;
    &amp;lt;OutputDirectory Include="d4"&amp;gt; &lt;br /&gt;
      &amp;lt;DirectoryName&amp;gt;$(ProjectTestDir)\$(ObjOutputDir)&amp;lt;/DirectoryName&amp;gt; &lt;br /&gt;
    &amp;lt;/OutputDirectory&amp;gt; &lt;br /&gt;
  &amp;lt;/ItemGroup&amp;gt; &lt;br /&gt;
  &amp;lt;ItemGroup&amp;gt; &lt;br /&gt;
    &amp;lt;ProjectDirectory Include="p1"&amp;gt; &lt;br /&gt;
      &amp;lt;DirectoryName&amp;gt;$(ProjectDir)&amp;lt;/DirectoryName&amp;gt; &lt;br /&gt;
    &amp;lt;/ProjectDirectory&amp;gt; &lt;br /&gt;
    &amp;lt;ProjectDirectory Include="p2"&amp;gt; &lt;br /&gt;
      &amp;lt;DirectoryName&amp;gt;$(ProjectTestDir)&amp;lt;/DirectoryName&amp;gt; &lt;br /&gt;
  &amp;lt;/ProjectDirectory&amp;gt; &lt;br /&gt;
  &amp;lt;/ItemGroup&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="CleanDirectories"&amp;gt; &lt;br /&gt;
    &amp;lt;Attrib Directories="%(OutputDirectory.DirectoryName)" ReadOnly="false" ContinueOnError="true"/&amp;gt; &lt;br /&gt;
    &amp;lt;RemoveDir Directories="%(OutputDirectory.DirectoryName)" ContinueOnError="true"/&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="SetAssemblyVersions"&amp;gt; &lt;br /&gt;
    &amp;lt;Attrib Files="%(ProjectDirectory.DirectoryName)\Properties\AssemblyInfo.cs" ReadOnly="false"/&amp;gt; &lt;br /&gt;
    &amp;lt;AssemblyInfo CodeLanguage="CS" OutputFile="%(ProjectDirectory.DirectoryName)\Properties\AssemblyInfo.cs" AssemblyVersion="$(Version)" AssemblyFileVersion="$(Versiom)" /&amp;gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: 9pt;"&gt;  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;!--Setup tasks prior to build--&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="PreBuild"&amp;gt; &lt;br /&gt;
    &amp;lt;Message Importance="high" Text="In target PreBuild"/&amp;gt; &lt;br /&gt;
    &amp;lt;!-- Clean the output directories--&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="CleanDirectories"/&amp;gt; &lt;br /&gt;
    &amp;lt;!--Set assembly versions equal to CCNet version--&amp;gt; &lt;br /&gt;
    &amp;lt;CallTarget Targets="SetAssemblyVersions"/&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;!-- Build projects --&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="Build" DependsOnTargets="PreBuild"&amp;gt; &lt;br /&gt;
    &amp;lt;Message Importance="high" Text="In target Build"/&amp;gt; &lt;br /&gt;
    &amp;lt;MSBuild Projects="$(ProjectFile)"&amp;gt; &lt;br /&gt;
    &amp;lt;/MSBuild&amp;gt; &lt;br /&gt;
    &amp;lt;MSBuild Projects="$(TestProjectFile)"&amp;gt; &lt;br /&gt;
    &amp;lt;/MSBuild&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;ItemGroup&amp;gt; &lt;br /&gt;
    &amp;lt;ProjectOutput Include="$(ProjectDir)\$(OutputDir)\*.*"/&amp;gt; &lt;br /&gt;
  &amp;lt;/ItemGroup&amp;gt; &lt;br /&gt;
  &amp;lt;ItemGroup&amp;gt; &lt;br /&gt;
    &amp;lt;ProjectTestOutput Include="$(ProjectTestDir)\$(OutputDir)\*.*"/&amp;gt; &lt;br /&gt;
  &amp;lt;/ItemGroup&amp;gt; &lt;br /&gt;
  &amp;lt;!--Cleanup tasks after build--&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="PostBuild" DependsOnTargets="Build"&amp;gt; &lt;br /&gt;
    &amp;lt;Message Importance="high" Text="In target PostBuild"/&amp;gt; &lt;br /&gt;
    &amp;lt;Copy SourceFiles="@(ProjectOutput)" DestinationFolder="C:\buildOutput\ProjectX\$(Version)"/&amp;gt; &lt;br /&gt;
    &amp;lt;Copy SourceFiles="@(ProjectTestOutput)" DestinationFolder="C:\buildOutput\ProjectX\Test\$(Version)"/&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;!-- Run all tests with the Continuous category--&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="UnitTestContinuous"&amp;gt; &lt;br /&gt;
    &amp;lt;Message Importance="high" Text="In target UnitTestContinuous"/&amp;gt; &lt;br /&gt;
    &amp;lt;CreateItem Include="SmartRename.Test.Dummy.dll"&amp;gt; &lt;br /&gt;
      &amp;lt;Output TaskParameter="Include" ItemName="TestAssembly" /&amp;gt; &lt;br /&gt;
    &amp;lt;/CreateItem&amp;gt; &lt;br /&gt;
    &amp;lt;Message Importance="high" Text="Assemblies: @(TestAssembly)"/&amp;gt; &lt;br /&gt;
    &amp;lt;NUnit ToolPath="C:\Program Files\NUnit 2.4.6\bin" WorkingDirectory="$(ProjectTestDir)\$(OutputDir)" Assemblies="@(TestAssembly)" ExcludeCategory="$(ExcludeTestCategories)" OutputXmlFile="$(NUnitOutputXmlFile)"/&amp;gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family: Courier New; font-size: 9pt;"&gt;  &amp;lt;/Target&amp;gt; &lt;br /&gt;
  &amp;lt;!-- Package a&amp;amp; deployment tasks--&amp;gt; &lt;br /&gt;
  &amp;lt;Target Name="Package" DependsOnTargets="Build"&amp;gt; &lt;br /&gt;
    &amp;lt;Message Importance="high" Text="In target Package"/&amp;gt; &lt;br /&gt;
  &amp;lt;/Target&amp;gt; &lt;br /&gt;
&amp;lt;/Project&amp;gt;  &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;  &lt;/p&gt;
&lt;p&gt;(note some of the targets are placeholders). &lt;/p&gt;
&lt;p&gt;&lt;br /&gt;
&lt;span style="font-family: Arial; font-size: 10pt;"&gt;This is more involved and MSBuild is well documented, but the key things to note are:&lt;/span&gt; 		&lt;span style="font-family: Arial; font-size: 10pt;"&gt; 		&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;Properties defined in the initial PropertyGroup can be overridden by values passed to the MSBuild exe (with /p:name=value;name2=value2); they are referenced in the script with $(name); &lt;/span&gt; 		&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;ItemGroup allows you to define an array of items that can be operated on (e.g. in CleanDirectories target); the loop is started and entries accessed with %(GroupName.ElementName); &lt;/span&gt; 		&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;Individual items in an ItemGroup can be accessed with @(ItemName); &lt;/span&gt;&lt;br /&gt;
    &lt;span style="font-family: Arial; font-size: 10pt;"&gt;DependsOnTargets flag will ensure the necessary targets are run before the executing target, but will not invoke the target if it has already been called; &lt;/span&gt; 		&lt;/li&gt;
    &lt;li&gt;&lt;span style="font-family: Arial; font-size: 10pt;"&gt;The SetAssemblyVersions target uses a MSBuild Community Task (&lt;a href="http://msbuildtasks.tigris.org/"&gt;http://msbuildtasks.tigris.org/&lt;/a&gt;) to update the build number in the projects' AssemblyInfo files - this ensures the built assemblies have the same build number as the Perforce source label (available in $(CCNetLabel) property.&lt;/span&gt; 		&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122473"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=122473" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/122473.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>EltonStoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2008/05/29/sample-cruisecontrol-build-using-perforce.aspx</guid>
            <pubDate>Thu, 29 May 2008 19:34:17 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/122473.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2008/05/29/sample-cruisecontrol-build-using-perforce.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/122473.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Scripting Branch Creation in Perforce</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/scripting-branch-creation-in-perforce.aspx</link>
            <description>&lt;br /&gt;
To simplify the branching process, allow automation and remove the errors likely from manually branching, I'd like the whole process to be scripted. The P4 command allows us to do this, but there are complications as it requires user input via the specification forms for most of its commands. You can direct it to read the input from a file, but that's not much help when you want to use variables to specify branch names etc.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Generating Specification Forms on the Fly&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
My solution was to create a simple console app to generate spefication forms based on input parameters. The variables in the script go into the generator which stores them as files, which P4 can use as input. It's not terribly elegant, but it's efficient and I haven't found any other solutions out there. The code is on CodePlex here: &lt;a href="http://www.codeplex.com/GenerateP4SpecForm"&gt;Generate Perforce Specification Form&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Using the console app, it's easy to take the manual steps from &lt;a href="../../../../EltonStoneman/archive/2008/04/04/branching-with-perforce.aspx"&gt;Branching with Perforce&lt;/a&gt; and script them for automation. In this case, I'm expecting branching to be an occassional job so the purpose of scripting it is to reduce the possibility of error and simplify the branching process for anyone who needs to do it and doesn't want to trawl through these blogs.&lt;br /&gt;
&lt;br /&gt;
With this in mind, the script is a Windows batch file (the full script is &lt;span style="font-weight: bold;"&gt;BranchWorkspace.bat&lt;/span&gt; in the Samples directory of the CodePlex source) rather than a build task. It should be straightforward to read, but I'll dissect it here to show how the commands fit in with the manual process.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Walkthrough&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;Firstly the batch file sets up parameters for all the variables we'll use - branch name, branch master workspace name, views etc. Then it follows the same order as the manual process, generating the specification forms where needed, then invoking the P4 command and telling it to read from the spec form.&lt;br /&gt;
&lt;br /&gt;
1. Create the branch view&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;::generate spec form for the branch:&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;set branchSpecPath=C:\%branchName%.p4&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;GenerateP4SpecForm "WRITE" "%branchSpecPath%" "|" "Branch: %branchName%|Owner:    elton.stoneman|Description: Created by elton.stoneman.|Options:    unlocked|View: %mainView% %branchView%"&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;The console app takes parameters telling it where to create the spec form, how the form options are separated (I use a pipe as there are colons in the options), and then the pipe-separated option list.  &lt;br /&gt;
&lt;br /&gt;
What goes into the list depends on the type of spec form P4 wants; there are samples in the CodePlex source, or you can copy and paste from a real spec form, or many of the commands take a -o parameter so you can output an existing spec form and use that as the basis.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;::create the branch view:&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;p4 branch -i &amp;lt;%branchSpecPath%&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;&lt;/span&gt;- the branch view is created and we pass the spec form path to P4 so there's no user intervention.&lt;br /&gt;
&lt;br /&gt;
2. Create the master workspace&lt;br /&gt;
&lt;br /&gt;
As before, generate the relevant spec form and pass it into P4:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;::generate spec form for the branch master workspace:&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;set branchClientSpecPath=C:\%branchClient%.p4&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;GenerateP4SpecForm "WRITE" "%branchClientSpecPath%" "|" "Client: %branchClient%|Owner: elton.stoneman|Host: myHost|Description: Created by elton.stoneman.|Root: %branchClientRoot%|Options: noallwrite noclobber nocompress unlocked nomodtime normdir|SubmitOptions: submitunchanged|LineEnd: local|View: %branchView% %branchClientView%"&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;::create branch workspace:&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;p4 client -i &amp;lt;%branchClientSpecPath%&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
3. Flag files to be branched&lt;br /&gt;
&lt;br /&gt;
No spec form needed here, but the batch file allows you to branch from the current revisions or from a specified label:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;::integrate the branch back to main - branch to label if provided:&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;IF "%label%"==" " p4 -c%branchClient% integrate -b %branchName%&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;IF NOT "%label%"==" " p4 -c%branchClient% integrate -b %branchName% @%label%&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
4. Submit the change list&lt;br /&gt;
&lt;br /&gt;
This is a bit different as the submit command launches a spec form listing the files to be submitted, and requires you to add a description. We can't generate the spec form here, as we'll lose the file list, so instead we output the file list first:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;::get a list of the changes (required for Submit):&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;set changePath=c:\%branchClient%.chg&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;p4 -c%branchClient% change -o &amp;gt;%changePath%&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
- and then use the UPDATE mode of the console app to set the description (P4 always uses the same text for the default description):&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;IF "%label%"==" " GenerateP4SpecForm "UPDATE" "%changePath%" "&amp;lt;enter description here&amp;gt;" "MASTER created from branch: %branchName%"&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;IF NOT "%label%"==" " GenerateP4SpecForm "UPDATE" "%changePath%" "&amp;lt;enter description here&amp;gt;" "MASTER created from branch: %branchName%, label: %label%"&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This way we get the full change list from Perforce and add in our description (in this case, specifying the branch view and label used to get the files). Now we submit using the updated change list:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;::submit to create branch in depot:&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;p4 -c%branchClient% submit -i &amp;lt;%changePath%&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
And the branch is complete and populated.&lt;br /&gt;
&lt;br /&gt;
Note, the sample batch file leaves the generated spec forms in place, in case of any issues. It's a simple change to make the script delete them at the end.&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121042"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121042" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/121042.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>EltonStoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/scripting-branch-creation-in-perforce.aspx</guid>
            <pubDate>Fri, 04 Apr 2008 16:17:40 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/121042.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/scripting-branch-creation-in-perforce.aspx#feedback</comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/121042.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Branching with Perforce</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/branching-with-perforce.aspx</link>
            <description>&lt;br /&gt;
My preferred structure is for each project to have a root in the depot, then each branch to have a root within the project. So as the codebase matures you end up with:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;\\depot&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;    \ProjectX&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;        \MAIN&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;            \source&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;        \R1&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;            \source&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;        \R2&lt;br /&gt;
           \source&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;    \ProjectY&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;        \MAIN&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;            \source&lt;/span&gt;&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;etc.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Nothing revolutionary there, but it gives some context for the examples. &lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Branching the Codeline&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;There are  four steps to creating and populating a branch from the main codeline:&lt;br /&gt;
&lt;ol&gt;
    &lt;li&gt;Create a branch view&lt;/li&gt;
    &lt;li&gt;Create a master workspace (&lt;span style="font-weight: bold;"&gt;client view&lt;/span&gt;) for the branch&lt;/li&gt;
    &lt;li&gt;Flag files to be branched (&lt;span style="font-weight: bold;"&gt;integrated &lt;/span&gt;in Perforce terminology)&lt;/li&gt;
    &lt;li&gt;Submit the change list from 3) to the depot&lt;/li&gt;
&lt;/ol&gt;
(there are other approaches but this is straightforward and recommended. See &lt;a href="http://books.google.co.uk/books?id=mlm61wb2v3MC&amp;amp;pg=PA244&amp;amp;lpg=PA244&amp;amp;dq=synchronize+workspace+to+branch+perforce&amp;amp;source=web&amp;amp;ots=IWq3yNOwPB&amp;amp;sig=Z5nqg6VC7DuSqebd5b4NFYtu1P4&amp;amp;hl=en#PPA240,M1"&gt;Practical Perforce - Google Book Search&lt;/a&gt;&lt;br /&gt;
 and &lt;a href="http://www.perforce.com/perforce/doc.002/manuals/p4guide/09_branching.html"&gt;Perforce Branching&lt;/a&gt; for more details).&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Walkthrough&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
I'll follow this through with the example that ProjectX has just been released to version 3.0. The build applied a label of 3.0.4.86 to the code which has gone into release, and work has been checked into the main branch since, so we want to create a new R3 branch and populate it from the MAIN branch at label 3.0.4.86.&lt;br /&gt;
&lt;br /&gt;
The example will use the command line tool p4.exe, so when we look at automating this in a script the commands will be familiar. Note that in Perforce most command lines take a small number of arguments, then launch a text editor with a pre-populated &lt;span style="font-weight: bold;"&gt;specification form&lt;/span&gt;. After editing and saving the form, the command will complete. &lt;br /&gt;
&lt;br /&gt;
1. Create the branch view&lt;br /&gt;
    &lt;br /&gt;
We start by creating a branch with a view that links it back to the main codeline. Following best practice guidelines, the branch name reflects the project and the views it links: ProjectX_MAIN-R3. Creating it is as simple as issuing:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;    p4 branch ProjectX_MAIN-R3&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
- and setting the view in the specification form to map the existing MAIN branch to the new R3 branch:&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;&lt;br /&gt;
//depot/ProjectX/MAIN/... //depot/ProjectX/R3/... &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
This creates the branch view which you will see listed in the Branches tab of P4V, but the new branch is not yet in the depot.&lt;br /&gt;
&lt;br /&gt;
2. Create the master workspace&lt;br /&gt;
&lt;br /&gt;
We'll create a workspace for the branch which will be the master - by integrating the R3 master workspace with the main branch, we'll populate the depot with the desired source. Using the p4 client command, we'll create the workspace ProjectX_R3-MASTER:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;    p4 client ProjectX_R3-MASTER&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
- and in the specifcation form, set the view to map the R3 master to the R3 branch: &lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;&lt;br /&gt;
//depot/ProjectX/R3/... //ProjectX_R3-MASTER/...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You should now see the new master in the P4V Workspaces view, but the depot won't have an R3 branch populated yet.&lt;br /&gt;
&lt;br /&gt;
3. Flag files to be branched&lt;br /&gt;
&lt;br /&gt;
Using p4 integrate, we create a changelist which will populate the R3 master from MAIN, via the R3 branch:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New;"&gt;p4 -cProjectX_R3-MASTER integrate -b ProjectX_MAIN-R3 @3.0.4.86&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
There is no specification form for this command. Note that we tell P4 to use the R3 master workspace with the -c global option before issuing integrate. This will flag all the files from the R3 branch with the 3.0.4.86 label in the R3 master's default changelist as new additions. To populate the branch in the depot we just need to submit the changelist.&lt;br /&gt;
&lt;br /&gt;
4. Submit the change list&lt;br /&gt;
&lt;br style="font-family: Courier New;" /&gt;
&lt;span style="font-family: Courier New;"&gt;p4 -cProjectX_R3-MASTER submit&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The specification form here shows you all the files that will be added and requires you to give the changelist a description - you must change it from the default &lt;span style="font-family: Courier New;"&gt;&amp;lt;enter description here&amp;gt;&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Assuming there were no errors, we'll now have the populated R3 branch under ProjectX, without the changes made in MAIN after the 3.0.4.86 build. You may well have errors as the views you enter in the spec forms are not validated against what's in the depot. This is a brittle operation which is likely to be needed repeatedly, so in the next post we look at scripting the whole branch creation.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Developing Against Branches&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
You can create your dev workspaces with a view over the whole project (e.g. &lt;span style="font-family: Courier New;"&gt;\\depot\\ProjectX\... \\a.developer\ProjectX\...&lt;/span&gt;), so when the new branch is added it will be automatically brought into the developers' workspaces when they Get Latest. &lt;br /&gt;
&lt;br /&gt;
I'd prefer to set workspaces up to a specific branch (&lt;span style="font-family: Courier New;"&gt;\\depot\\ProjectX\MAIN\... \\a.developer\ProjectX\MAIN\...&lt;/span&gt;). This means you only have people working in the branch they need. When a new branch is made the people who need to work on it can edit their workspace to add the new view (&lt;span style="font-family: Courier New;"&gt;\\depot\\ProjectX\R3\... \\a.developer\ProjectX\R3\...&lt;/span&gt;). The main dev team continue as they are and don't end up having to synchronize to branches they never use. &lt;br /&gt;
&lt;br /&gt;
Alternatively, you can set up a workspace for each branch you work on, so developers would have a main workspace and a Release 1 workspace. The new dev workspace can be created using the branch master as a template. I'm disinclined to use this as there's a greater admin/maintenance/licensing overheead, with no benefits above the single-workspace-multiple-views approach.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;&lt;/span&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121038"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121038" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/121038.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>EltonStoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/branching-with-perforce.aspx</guid>
            <pubDate>Fri, 04 Apr 2008 14:27:59 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/121038.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/branching-with-perforce.aspx#feedback</comments>
            <slash:comments>7</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/121038.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Using Perforce with CruiseControl.Net</title>
            <link>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/using-perforce-with-cruisecontrol.net.aspx</link>
            <description>&lt;br /&gt;
On my latest project we're using Perforce for source control and my first tasks have been to set up CruiseControl.Net for continuous integration, and define the branching strategy to use. I'm new to P4 and wanted to document the learning curve - the next few posts will cover what I've put in place.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;Perforce Concepts&lt;br /&gt;
&lt;br /&gt;
&lt;/span&gt;Being an SCM with all the usual features, Perforce naturally has a different set of terminology for all the usual concepts. The repository on the server is the &lt;span style="font-weight: bold;"&gt;depot &lt;/span&gt;and the local dev repository is a &lt;span style="font-weight: bold;"&gt;workspace&lt;/span&gt;. The workspace is also known as a &lt;span style="font-weight: bold;"&gt;client view&lt;/span&gt;, which has a mapping to the depot that looks like: &lt;br /&gt;
&lt;br /&gt;
    &lt;span style="font-family: Courier New;"&gt;//depot/ProjectX/... //a.developer/ProjectX/...&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
- meaning all files within the ProjectX node of the depot are mapped to the ProjectX node of a.developer's workspace.&lt;br /&gt;
&lt;br /&gt;
Views are also used in branching and labelling, which I'll cover more in the branch strategy post.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-style: italic;"&gt;CruiseControl Config&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Perforce with CC is a well trodden path, but for reference the sourceControl project node is:
&lt;p style="font-family: Courier New;"&gt;    &amp;lt;sourcecontrol type="p4"&amp;gt;&lt;br /&gt;
        &amp;lt;view&amp;gt;//depot/ProjectX/MAIN/source/...&amp;lt;/view&amp;gt;&lt;br /&gt;
        &amp;lt;client&amp;gt;BuildServer&amp;lt;/client&amp;gt;&lt;br /&gt;
        &amp;lt;applyLabel&amp;gt;true&amp;lt;/applyLabel&amp;gt;&lt;br /&gt;
        &amp;lt;autoGetSource&amp;gt;true&amp;lt;/autoGetSource&amp;gt;&lt;br /&gt;
    &amp;lt;/sourcecontrol&amp;gt;&lt;/p&gt;
The client node specifies the workspace to connect to, and the view specifies the exact mapping for the project. That view is used to monitor the folder for changes, and if you specify autoGetSource and applyLabel, they'll run over all the files in the view. This allows you to set up one workspace for the build server which has a view over the entire depot, and then specify different views for each build project. &lt;br /&gt;
&lt;br /&gt;
There are various warnings saying that Perforce doesn't work with purely numeric labels, but in version 2007.3 that seems fine. With the standard iteration labeller for every successful build CC will create a label in Perforce and label every file in the specified view.&lt;br /&gt;
&lt;br /&gt;
Perforce seems like a nice SCM, with excellent cross-platform support. The licensing model allows you to download and use it for free with up to 2 users and 5 workspaces: &lt;a href="http://www.perforce.com/perforce/loadprog.html"&gt;http://www.perforce.com/perforce/loadprog.html&lt;/a&gt;&lt;p&gt;&lt;a href="http://www.pheedo.com/click.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121035"&gt;&lt;img src="http://www.pheedo.com/img.phdo?x=6cda6ad746d942b9a1110d0715a4fa12&amp;u=121035" border="0"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;PageID=31016&amp;amp;SiteID=1" width=1 height=1 Marginwidth=0 Marginheight=0 Hspace=0 Vspace=0 Frameborder=0 Scrolling=No&gt;
&lt;script language='javascript1.1' src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Browser=NETSCAPE4&amp;amp;NoCache=True&amp;PageID=31016&amp;amp;SiteID=1"&gt;&lt;/script&gt;
&lt;noscript&gt;&lt;a href="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Click&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" target="_blank"&gt;
&lt;img src="http://ads.geekswithblogs.net/a.aspx?ZoneID=5&amp;amp;Task=Get&amp;amp;Mode=HTML&amp;amp;SiteID=1&amp;amp;PageID=31016" width="1" height="1" border="0"  alt=""&gt;&lt;/a&gt;
&lt;/noscript&gt;
&lt;/iframe&gt;
&lt;img src="http://geekswithblogs.net/EltonStoneman/aggbug/121035.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>EltonStoneman</dc:creator>
            <guid>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/using-perforce-with-cruisecontrol.net.aspx</guid>
            <pubDate>Fri, 04 Apr 2008 13:31:44 GMT</pubDate>
            <wfw:comment>http://geekswithblogs.net/EltonStoneman/comments/121035.aspx</wfw:comment>
            <comments>http://geekswithblogs.net/EltonStoneman/archive/2008/04/04/using-perforce-with-cruisecontrol.net.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://geekswithblogs.net/EltonStoneman/comments/commentRss/121035.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>