msbuildmetadataitemgroup

how to get extension name (without dot) in MSBuild


I have an ItemGroup, and I use its metadata as identifiers in my MSBuild project for batch processing. For example:

        <BuildStep
          TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
          BuildUri="$(BuildUri)"
          Name="RunUnitTestsStep-%(TestSuite.Filename)-%(TestSuite.Extension)"
          Message=" - Unit Tests: %(TestSuite.Filename): %(TestSuite.Extension)">

          <Output
            TaskParameter="Id"
            PropertyName="RunUnitTestsStepId-%(TestSuite.Filename)-%(TestSuite.Extension)" />
        </BuildStep>

However, this will not work, because there is a dot in the Extension, which is invalid character for an Id (in the BuildStep task). Thus, the MSBuild always fails on the BuildStep task.

I've been trying to remove the dot, but with no luck. Maybe there is a way to add some metadata to en existing ItemGroup? Ideally, I would like to have something like %(TestSuite.ExtensionWithoutDot). How can I achieve that?


Solution

  • I think you are slightly confused about what the <Output> element is doing here - it will create a property named with the value in the PropertyName attribute, and will set the value of that property to be value of the Id output from the BuildStep task. You have no influence on the value of Id - you just store it in a property for later reference in order to set the status of the build step

    With that in mind, I can't see why you are concerned that the Property created would have a name that would include the concatenation of the extension. As long as the property name is unique, you can reference it later in a subsequent BuildStep task, and I presume your testsuite filename is enough to indicate uniqueness.

    In fact, you could avoid having to create unique properties that track each testsuite/buildstep pair if you did Target batching:

    <Target Name="Build"
            Inputs="@(TestSuite)"
            Outputs="%(Identity).Dummy">
        <!--
        Note that even though it looks like we have the entire TestSuite itemgroup here,
        We will only have ONE - ie we will execute this target *foreach* item in the group
        See http://beaucrawford.net/post/MSBuild-Batching.aspx
        -->
    
    
        <BuildStep
              TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
              BuildUri="$(BuildUri)"
              Name="RunUnitTestsStep-%(TestSuite.Filename)-%(TestSuite.Extension)"
              Message=" - Unit Tests: %(TestSuite.Filename): %(TestSuite.Extension)">
    
              <Output
                TaskParameter="Id"
                PropertyName="TestStepId" />
            </BuildStep>
    
        <!--
        ..Do some stuff here..
        -->
    
        <BuildStep Condition=" Evaluate Success Condition Here "
               TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
               BuildUri="$(BuildUri)"
               Id="$(TestStepId)"
               Status="Succeeded" />
        <BuildStep Condition=" Evaluate Failed Condition Here "
               TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
               BuildUri="$(BuildUri)"
               Id="$(TestStepId)"
               Status="Failed" />
    </Target>