I have a project A (.NET Core) that is referenced by a project B. In project A, I have a JSON file that needs to be updated at compile time (to replace some values) and I would like the JSON file in the build output of project B to be replaced as well.
Sln :
Project A
file.json (build action : none, copy always)
Project B
References
Project A
Content of file A before build is something like :
{
key : {{this will be replaced during build}}
}
After build it is something like :
{
key : "VALUE"
}
So far, I tried with post build events in Project A and this works well for the bin folder of project A, but in the bin folder of project B, I have the file.json before string replacement.
I tried disabling the accelerated build as I thought this might be the issue but it does not seem to change the output.
I also tried with a msbuild task :
<UsingTask TaskName="TestReplace" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
<ParameterGroup />
<Task>
<Reference Include="System.Xml" />
<Using Namespace="System" />
<Using Namespace="System.IO" />
<Code Type="Fragment" Language="cs">
<![CDATA[
var path = "file.json";
var fileContent = File.ReadAllText(path);
fileContent = fileContent.Replace("{{this will be replaced during build}}", "VALUE");
File.WriteAllText(path, fileContent);
]]>
</Code>
</Task>
</UsingTask>
<Target Name="TestReplace" AfterTargets="CopyFilesToOutputDirectory">
<TestReplace />
</Target>
But with the same result (JSON is OK in output folder for project A, but not for project B)
Is this the intended behavior or did I misconfigure anything? And if this is indeed the intended behavior, what would be the recommended way to achieve the string replacement both in project A and in all the projects that depend on it?
I looked into Single File Generators but it sounds like a complicated solution, and I would prefer to avoid installing a custom extension on all devs machines.
Thanks !
edit : for anyone wondering, I ended up doing something like this :
<None Update="file.json">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
<None Update="tmp\file.json" Link="file.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
<Exec Command="do something that write from file.json to tmp/file.json" />
</Target>
and I added tmp/ to the .gitignore
The problem is that Project B doesn't actually copy files from Project A's output folder.
During the execution project B's GetCopyToOutputDirectoryItems
target, the json is being picked up directly from A and added to B's _TransitiveItemsToCopyToOutputDirectory
list (which is later dumped in B's output).
What you can do instead is ensure that the file added to A's <None>
list is already transformed, not the original file. So, hook your target earlier into the build process, perform the transformation, then add the transformed file into None
.