I have a target like below. It needs to replace content of a file with new content. I have multiple files I am matching with ItemGroup. I couldn't figure out a way to get this working.
Here is my target definition.
<ItemGroup>
<PRSetting Include="$(settings_root)\**\settings_config_*.xml">
<NewContent>$([System.IO.File]::ReadAllText('%(Identity)')).Replace('[config.version]', '$(PR_Version)'))</NewContent>
</PRSetting>
</ItemGroup>
<Target Name="PrepSettings" Inputs="@(PRSetting)"
Outputs="@(PRSetting->'$out\$Filename.xml')" >
<Message Text="%(PRSetting.Identity) new contents:" />
<Message Text="%(PRSetting.NewContent)"/>
</Target>
I hope I explained it right what I am trying to do. When the target is built, I am getting an error that the path to File::ReadFile() can't be empty string. I am using VS 2019. This is work in progress. I am yet to figure out how to save the new content in destination file.
Update
I have the Itemgroup outside. I updated the question. The reason it is outside is because the target inputs parameter needs it.
Try the following and see if it works:
There are two changes:
Include
that doesn't use an existingItemGroup
and metadata that is self-referencing. So, setting upPRSetting
is split in two.PRSetting
with theInclude
.NewContent
metadata item.Condition="%(Identity) != ''"
on theNewContent
metadata.I'm not able to fully test your exact scenario at present but I tested an analogue.
Here is my test analogue:
The output is
Regarding your code change to move the
ItemGroup
outside the target:ItemGroup
as written won't work, but if you are using VS2017 or later and working with .NET Core/.NET 5+ you can useUpdate
.Outputs
attribute has syntax errors. I assumeOutputs="@(PRSetting->'$(OutputPath)\%(Filename).xml')"
(or something close) is intended.Outputs
attribute will never be satisfied becausePrepSettings
doesn't create the files. I assumePrepSettings
as shown is not complete.