Gustavo
Gustavo

Reputation: 735

TextTransform on MSBuild only when file modified? (or an alternate route of doing this)

I have a project that integrates TextTransform with MSBuild, but I am now at the point that the files are too many and it is slowing down development time.

The process that I have is, I have a POCO.cs; I use Roslyn to Parse the .cs file to gather some metadata; hand the metadata to a .tt file that will then generate a [Implementation].cs

Here is part of the .csproj file that pertains to my question:

<PropertyGroup>
  <_CommonProgramFiles>$([System.Environment]::GetEnvironmentVariable('CommonProgramFiles(x86)'))</_CommonProgramFiles>
  <_CommonProgramFiles Condition=" '$(_CommonProgramFiles)' == '' ">$(CommonProgramFiles)</_CommonProgramFiles>
  <TextTransformPath Condition="'$(TextTransformPath)' == ''">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating\$(VisualStudioVersion)\TextTransform.exe</TextTransformPath>
  <!-- Initial default value -->
  <_TransformExe>$(TextTransformPath)</_TransformExe>
  <_RoslynDllPath>$(ProjectDir)Lib\RoslynWrapper.dll</_RoslynDllPath>
  <!-- Cascading probing if file not found -->
  <_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating\10.0\TextTransform.exe"</_TransformExe>
  <_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating\11.0\TextTransform.exe"</_TransformExe>
  <_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating\12.0\TextTransform.exe"</_TransformExe>
  <!-- Future proof 'til VS2013+2 -->
  <_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating\13.0\TextTransform.exe"</_TransformExe>
  <_TransformExe Condition="!Exists('$(_TransformExe)')">$(_CommonProgramFiles)\Microsoft Shared\TextTemplating\14.0\TextTransform.exe"</_TransformExe>
</PropertyGroup>

<ItemGroup>
  <Compile Include="SomePoco.cs" />
  <Compile Include="Properties\AssemblyInfo.cs" />
  <Compile Include="SomePocoMetadata.cs">
    <AutoGen>True</AutoGen>
    <DesignTime>True</DesignTime>
    <DependentUpon>SomePocoMetadata.tt</DependentUpon>
  </Compile>
</ItemGroup>
<ItemGroup>
  <None Include="SomePocoMetadata.tt">
    <Generator>TextTemplatingFileGenerator</Generator>
    <LastGenOutput>SomePocoMetadata.cs</LastGenOutput>
  </None>
</ItemGroup>

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="TransformOnBuild" AfterTargets="BeforeBuild">
  <Error Text="Failed to find TextTransform.exe tool at '$(_TransformExe)." Condition="!Exists('$(_TransformExe)')" />
  <ItemGroup>
    <_TextTransform Include="@(None)" Condition="'%(None.Generator)' == 'TextTemplatingFileGenerator'" />
  </ItemGroup>
  <!-- Perform task batching for each file -->
  <Exec Command="&quot;$(_TransformExe)&quot; &quot;%(_TextTransform.FullPath)&quot; -r &quot;$(_RoslynDllPath)&quot;" Condition="'%(_TextTransform.Identity)' != ''" />
</Target>

With the above, the .tt files are always transforming and it takes a couple of minutes to compile the DLL. Is there a way to do this in MSBuild to only transform when the SomePoco.cs file is modified only?

Is there maybe another approach that I should look into to get what i want accomplished?

Upvotes: 2

Views: 962

Answers (2)

Gustavo
Gustavo

Reputation: 735

what i ended up doing was using with ITaskItem[] as one of the input parameters and in there i used C# to figure out the last modified of the files and determined if i needed to generate that way.

Upvotes: 0

seva titov
seva titov

Reputation: 11920

Make sure you specify Inputs and Outputs attributes for your target.

In your specific case you seem to obtain name of one of the inputs inside the target, so you cannot use it in the enclosing Target's Input attribute. A workaround for you is to move the definition of _TextTransform item group outside of the target.

Upvotes: 2

Related Questions