Search code examples
msbuildmsbuild-task

How concatenate files in MSBuild and preserve tabs and spaces


I'm trying to concatenate a few files during my build but the way I tried strips out the tabs and spaces leaving the output unformatted.

<CreateItem Include="Scripts\ApplicationModule.d.ts; Scripts\AccountModule.d.ts; Scripts\FeedModule.d.ts;">
  <Output TaskParameter="Include" ItemName="ApplicationDefinitionFiles" />
</CreateItem>

<ReadLinesFromFile File="%(ApplicationDefinitionFiles.FullPath)">
  <Output TaskParameter="Lines" ItemName="ApplicationDefinitionLines" />
</ReadLinesFromFile>

<WriteLinesToFile File="Scripts\ApplicationDefinition.d.ts" Lines="@(ApplicationDefinitionLines)" Overwrite="true" />

What's the way to preserve formatting?


Solution

  • This is what I ended up with when faced with the same problem:

    <Target Name="ConcatenateScripts">
      <!-- List all the files you want to concatenate. -->
      <ItemGroup>
        <ConcatFiles Include="
            Scripts\ApplicationModule.d.ts; 
            Scripts\AccountModule.d.ts;
            Scripts\FeedModule.d.ts;"/>
      </ItemGroup>
    
      <!-- Read the contents of the files (preserving tabs/spaces). -->
      <ItemGroup>
        <FileContents Include="$([System.IO.File]::ReadAllText(%(ConcatFiles.Identity)))"/>
      </ItemGroup>
    
      <!-- Write the result to a single file. -->
      <WriteLinesToFile File="Scripts\ApplicationDefinition.d.ts" Lines="@(FileContents)" Overwrite="true" />
    </Target>
    
    <!-- Concatenate scripts on AfterBuild. -->
    <Target Name="AfterBuild">
      <CallTarget Targets="ConcatenateScripts"/>
    </Target>
    

    This is a modified version of this blog post but using $([System.IO.File]::ReadAllText(...) instead of the ReadLinesFromFile task, as suggested in this answer.