Search code examples
json.netnugetnuget-packagepack

How to pack linked files from referenced NuGet packages


I have a build-properties-defining package that is to be used by all the libraries.
Some libraries may provide a json file, that should be retained when they're referenced by some other libraries and then, ultimately, all the configuration files should be transitively provided to a consumer of a top-level library.

There's a convention, that libraries place their configuration files into an appsettings/cfgs directory.

Currently I have the following in my build-defining package's xxx.targets file

...
<ItemGroup>
  <Content Include="$(ProjectDir)\appsettings\cfgs\*.json">
    <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    <Pack>true</Pack>
    <PackagePath>contentFiles\any\any\appsettings\cfgs</PackagePath>
    <PackageCopyToOutput>true</PackageCopyToOutput>
  </Content>
</ItemGroup>
...

What works when using the target file above:

  • when a json file is added to appsettings/cfgs, it is copied to build output by default
  • when a json file is added to library's appsettings/cfgs, it is packed into library's NuGet package via dotnet pack
  • when a library is referenced, its' configuration files are shown in solution explorer as appsettings/cfgs linked directory and linked files are copied to consumer's output.

What doesn't work: I have library1, that provides a configuration file 1.json. I have library2, that consumes library1's NuGet package:

  • 1.json is shown in solution explorer
  • 1.json is copied to library2's output on build
  • 1.json is NOT, despite my best efforts, included into library2's NuGet package, while library2's json files, lying in the same very directory of output, are successfully packed.

How do I ensure that files, linked from referenced NuGet package, are added to consuming library's NuGet package, produced by dotnet pack?

provided by libraries, are packed into a NuGet package


Solution

  • As I couldn't find a complete answer for my case, I'll provide a solution that works for me so far.

    My xxx.targets looks like this now

    <ItemGroup>
      <Content Include="$(ProjectDir)\appsettings\**\*.json">
        <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        <!-- Target below will ensure that the configuration files are correctly packed -->
        <Pack>false</Pack>
      </Content>
    </ItemGroup>
    
    <Target Name="PackConfigurationFiles" AfterTargets="Build">
      <ItemGroup Condition="'$(IsPackable)' == 'true'">
        <Content Include="$(TargetDir)appsettings/cfgs/*.json">
          <Pack>true</Pack>
          <PackagePath>contentFiles\any\any\appsettings\cfgs</PackagePath>
          <PackageCopyToOutput>true</PackageCopyToOutput>
        </Content>
      </ItemGroup>
    </Target>
    

    So, instead of relying on dotnet pack to pick up linked files (which it doesn't so far), we're specifically using appsettings/cfgs directory in build output, where all our linked configuration files are in fact present along with consumner's own json files, if any.