I have the following lines in my MSBuild project file:
<PropertyGroup>
<TestResultsFileName Condition=" '$(TestResultsFileName)' == '' ">
TestResults.trx
</TestResultsFileName>
<TestResultsFilePath>$(OutDir)\$(TestResultsFileName)</TestResultsFilePath>
</PropertyGroup>
I need to create another file, having the same name as TestResultsFilePath only with the .xml extension. So I want to have a property to hold the file path of the other file.
At first, I thought that something like this would work:
<PropertyGroup>
<NUnitResultsFilePath>
$(OutDir)\$(TestResultsFileName->'%(Filename).xml')
</NUnitResultsFilePath>
</PropertyGroup>
And, of course, it did not, because TestResultsFileName is not an item collection. Unfortunately, it cannot be such, because it is a parameter to some task that expects a simple value, not a collection.
So, my question is how can I replace the extension of the TestResultsFileName property value with .xml?
Thanks.
Never mind. I have written a custom task to do the job:
public class ReplaceExtension : Task
{
[Required]
public string FilePath { get; set; }
public string NewExtension { get; set; }
[Output]
public string Result { get; set; }
public override bool Execute()
{
if (string.IsNullOrEmpty(FilePath))
{
Log.LogError("FilePath cannot be empty!");
return false;
}
try
{
int length = FilePath.Length;
int startIndex = length;
int oldExtensionLength = 0;
while (--startIndex >= 0)
{
char ch = FilePath[startIndex];
if (ch == '.')
{
oldExtensionLength = length - startIndex;
break;
}
if (ch == Path.DirectorySeparatorChar ||
ch == Path.AltDirectorySeparatorChar ||
ch == Path.VolumeSeparatorChar)
{
break;
}
}
bool isNewExtensionEmpty = string.IsNullOrEmpty(NewExtension) ||
(NewExtension.Length == 1 && NewExtension[0] == '.');
if (isNewExtensionEmpty)
{
// The new extension is empty - remove the old extension.
if (oldExtensionLength > 0)
{
Result = FilePath.Remove(startIndex, oldExtensionLength);
}
else
{
Result = FilePath;
}
}
else
{
// Replace the old extension with the new one.
StringBuilder sb = new StringBuilder(FilePath.Length - oldExtensionLength +
NewExtension.Length + (NewExtension[0] == '.' ? 0 : 1));
sb.Append(FilePath, 0, FilePath.Length - oldExtensionLength);
if (NewExtension[0] != '.')
{
sb.Append('.');
}
sb.Append(NewExtension);
Result = sb.ToString();
}
}
catch (Exception ex)
{
Log.LogErrorFromException(ex);
}
return !Log.HasLoggedErrors;
}
}
I am using it like this:
<Target Name="CreateProperties">
<ReplaceExtension FilePath="$(TestResultsFilePath)" NewExtension="xml">
<Output TaskParameter="Result" PropertyName="NUnitResultsFilePath"/>
</ReplaceExtension>
</Target>