Reputation: 115
I have a C# library which has a complex way of generating its output on build and I can not get the correct output to be copied to projects referencing it.
MySolution
├─ MyConsoleApp (c# console)
│ └─ Program.cs
└─ MyNodeServices (c# library)
├─ node_modules**
├─ NodeProgram
│ ├─ build**
│ │ ├─ tsCode.js**
│ │ └─ tsCode.map**
│ └─ src
│ └─ tsCode.ts (TypeScriptCompile)
├─ package.json
├─ tsconfig.json
└─ CodeThatReferencesNodeProgram.cs
** indicates files are not included in project
On build, I want MyNodeServices to copy the NodeProgram folder entirely to the output directory (src as well as build) and then copy node_modules into the NodeProgram. This is going to be my execution context when using NodeServices.
MyConsoleApp references MyNodeServices and I want the NodeProgram directory from MyNodeServices to be copied to the output directory of MyConsoleApp on build.
Include NodeProgram as content
<TypeScriptCompile Include="NodeProgram\src\tsCode.ts">
<Content Include="$(ProjectDir)NodeProgram\**" />
This works for including the code in the output of MyConsoleApp but the .ts files are displayed twice in solution explorer. This also does not address node_modules.
After build copy
<Target Name="AfterBuild">
<ItemGroup>
<ProgramCode Include="$(ProjectDir)NodeProgram\**" />
<NodeModules Include="$(ProjectDir)node_modules\**" />
</ItemGroup>
<MakeDir Directories="$(TargetDir)\NodeProgram" Condition=" !Exists('$(TargetDir\NodeProgram') " />
<MakeDir Directories="$(TargetDir)\NodeProgram\node_modules" Condition=" !Exists('$(TargetDir\NodeProgram\node_modules') " />
<Copy SourceFiles="@(ProgramCode)" DestinationFiles="@(ProgramCode->'$(TargetDir)\NodeProgram\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
<Copy SourceFiles="@(NodeModules)" DestinationFiles="@(NodeModules->'$(TargetDir)\NodeProgram\node_modules\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true" />
</Target>
This keeps my solution clean and copies the correct files to the output directory but the files seem to be ignored after that. If I clean the solution the copied folder remains in the output directory and the contents are not copied to referencing projects.
Upvotes: 3
Views: 1447
Reputation: 115
I came up with a solution that seems to solve my problems. I have added the following to the project file of MyNodeServices
<!-- Specify the files to be included in the output directory -->
<ItemGroup>
<NodeFile Include="NodePrograms\**">
<InProject>false</InProject>
</NodeFile>
<NodeModule Include="node_modules\**">
<InProject>false</InProject>
</NodeModule>
</ItemGroup>
<!-- Copy files from the project directory into the output directory -->
<Target Name="BeforeBuild"
Inputs="@(NodeFile);@(NodeModules)"
Outputs="@(NodeFile->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)');@(NodeModule->'$(OutputPath)NodePrograms\%(RelativeDir)%(Filename)%(Extension)')">
<Copy SourceFiles="@(NodeFile)"
DestinationFiles="$(OutputPath)%(NodeFile.RelativeDir)%(NodeFile.Filename)%(NodeFile.Extension)" />
<Copy SourceFiles="@(NodeModule)"
DestinationFiles="$(OutputPath)NodePrograms\%(NodeModule.RelativeDir)%(NodeModule.Filename)%(NodeModule.Extension)" />
<ItemGroup>
<!-- Specify files that were written to the output directory so the clean task knows to remove them -->
<FileWrites Include="@(NodeFile->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')"/>
<FileWrites Include="@(NodeModule->'$(OutputPath)NodePrograms\%(RelativeDir)%(Filename)%(Extension)')"/>
</ItemGroup>
</Target>
<!-- Include the files from the output directory when other projects reference this -->
<Target Name="IncludeNodeFiles"
BeforeTargets="GetCopyToOutputDirectoryItems">
<ItemGroup>
<OutputNodeFiles Include="@(NodeFile->'$(OutputPath)%(RelativeDir)%(Filename)%(Extension)')">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>%(RelativeDir)%(FileName)%(Extension)</TargetPath>
</OutputNodeFiles>
<OutputNodeModules Include="@(NodeModule->'$(OutputPath)NodePrograms\%(RelativeDir)%(Filename)%(Extension)')">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<TargetPath>NodePrograms\%(RelativeDir)%(FileName)%(Extension)</TargetPath>
</OutputNodeModules>
<AllItemsFullPathWithTargetPath Include="@(OutputNodeFiles->'%(FullPath)')" />
<AllItemsFullPathWithTargetPath Include="@(OutputNodeModules->'%(FullPath)')" />
</ItemGroup>
</Target>
Upvotes: 3