MSBuild Task: Detokenise File


This task can be used to find and replace tokens in a file or set of files.

[25 May 07: – Download the update with samples from here.]

There are two distinct ways of using this task.
  1. The first way is to pass in a ReplacementValues collection. Easy, the task simply matches on the collection and substitutes the token with the Replacement value.
  2. The second way is to pass in no ReplacementValues. If this is done, then the task will use the evaluated properties of the calling project. This is handy if you have a bunch of imports and don’t want to maintain a specific ReplacementValues collection. This is how I mostly use the task, but there are two things that should be noted when using the task in this way.
    • The properties that are evaluated are the ‘FinalValues’ of properties as if the project file were instantiated with no parameters. This means that if you have made any changes to a property before calling the task or overridden the property from the command line, the changes will not be seen, the original ‘FinalValue’ is what is substituted. This is a limit of MSBuild, not the task.
    • Because the task must load the calling project, there will be a minor performance hit. This should be insignificant, but I’m guessing that if you have a project file loading several meg’s of imports or you call the task many (thousands) of times, then you may have problems.
Required Input Parameters

TargetFiles: an ItemGroup of files to be detokenised. An optional encoding may be specified for each file, e.g.

<ItemGroup>
<FileCollection Include=”C:\web.config”>
<Encoding>UTF8</Encoding>
</FileCollection>
<FileCollection Include=”C:\web1.config”/>
</ItemGroup>

— or —

TargetPath: detokenise any files in the given path. A * can be used to search all sub directories.

Optional Input Parameters

DisplayFiles: the task will log the processing of each file to the console. The default is true.

Encoding: the file encoding to use when re-writing the file. If no encoding is passed, then the task will attempt to maintain the current file encoding. This encoding will be overridden by any individual encodings passed in the TargetFiles collection.

ForceWrite: the task will re-write any file it processes, even if no tokens have been replaced. This may be handy if you want to ensure all processed files have the same encoding. The default is false.

ReplacementValues: an ItemGroup of values to use for de-tokenising files (the default is to use the calling projects evaluated properties), e.g.

<ItemGroup>
<Parameters Include=”Token1″>
<Replacement>value1</Replacement>
</Parameters>
<Parameters Include=”Token2″>
<Replacement>value2</Replacement>
</Parameters>
</ItemGroup>

TokenPattern: this is the regular expression to use to identify a token. The default token format to replace is $(token)

Output Parameters

FilesProcessed: the count of files the task has processed.

FilesDetokenised: the count of files which have had tokens replaced.For performance reasons, it is best that these two output parameters are equal; otherwise the task is processing unnecessary files.

Using the Task

  1. Download it from here
  2. Add an Import in your .proj file
    <Import Project=”FreeToDev.MSBuildTasks.tasks”/>
  3. The imported file (FreeToDev.MSBuildTasks.tasks) should have
    <?xml version=”1.0″ encoding=”utf-8″?>
    <Project xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″>
    <UsingTask AssemblyFile=”FreeToDev.MSBuild.SystemTasks.dll” TaskName=”FreeToDev.MSBuild.SystemTasks.DetokeniseFile” />
    </Project>

Samples

TestFile.txt contains the following text:

Hello my name is $(MyName) and my blog can be found at $(MyBlog).

Let’s use the .proj file below

<Project DefaultTargets=”Execute” xmlns=”http://schemas.microsoft.com/developer/msbuild/2003″>
<Import Project=”FreeToDev.MSBuildTasks.tasks”/>
<PropertyGroup>
<MyName>FreeToDev!!!</MyName>
<MyBlog>http://freetodev.spaces.live.com</MyBlog>
<PathToDetokenise>C:\Atest\*</PathToDetokenise>
</PropertyGroup>
<ItemGroup>
<FileCollection Include=”C:\TestFile.txt”> <!–This file will be written with UTF8 encoding –>
<Encoding>UTF8</Encoding>
</FileCollection>
<FileCollection Include=”C:\TestFile2.txt”/> <!—This file will be written with its current encoding or the encoding specified in the Encoding parameter –>
</ItemGroup>
<ItemGroup>
<TokenValues Include=”MyName”>
<Replacement>FreeToDev</Replacement>
</TokenValues >
<TokenValues Include=”MyBlog”>
<Replacement>www.freetodev.com</Replacement>
</TokenValues >
</ItemGroup>
<Target Name=”Execute”>
<!– 1 –>
<DetokeniseFile TargetFiles=”@(FileCollection)” ReplacementValues=”@(TokenValues)”/>
<!– 2 –>
<DetokeniseFile Encoding=”ASCII” TargetFiles=”@(FileCollection)”/>
<!– 3 –>
<DetokeniseFile TargetPath=”$(PathToDetokenise)”/>
<!– 4 –>
<DetokeniseFile TargetPath=”$(PathToDetokenise)” DisplayFiles=”false” ForceWrite=”true”/>
<!– 5 –>
<DetokeniseFile TargetPath=”$(PathToDetokenise)” DisplayFiles=”false”>
<Output TaskParameter=”FilesProcessed” ItemName=”FilesProcessed”/>
<Output TaskParameter=”FilesDetokenised” ItemName=”FilesDetokenised”/>
</DetokeniseFile>
<Message Text=”FilesDetokenised = @(FilesDetokenised), FilesProcessed = @(FilesProcessed)”/>
</Target>
</Project>

  1. Detokenise the files defined in FileCollection and use the TokenValues collection for substitution. TestFile.txt will read
  2. Detokenise the files defined in FileCollection and use the tokens defined by the .proj properties. TestFile.txt will read
  3. Detokenise the files at the given TargetPath and perform a recursive search. Assuming TestFile.txt is in the path, it will read
  4. This will produce the same result as #3, but no file processing will be logged to the console. Because ForceWrite has been specified, all files will be re-written.
  5. This will produce the same result as 4, though ForceWrite is false by default so the difference can be displayed using the output parameters.

Hope it’s of use….

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s