简体   繁体   English

如何在生成的 .nuspec 的 MSBuild NuGet 包中注入自定义依赖项

[英]How to inject a custom dependency in an MSBuild NuGet pack generated .nuspec

I'm attempting to migrate to using MSBuild Pack support for using .csproj to generate a projects NuGet package where during development local .dll's are used to build the project but they need to be replaced/swapped to reference an external NuGet package in the generated .nuspec when Using MSBuild to "pack" the project.我正在尝试迁移到使用 MSBuild Pack支持使用 .csproj 生成项目 NuGet 包,其中在开发过程中使用本地 .dll 来构建项目,但需要替换/交换它们以引用生成的外部 NuGet 包.nu​​spec 使用 MSBuild 来“打包”项目时。

The closest documented example of this use-case I could find is Replacing one library from a restore graph where it suggests you can replace an external NuGet reference:我能找到的最接近此用例的文档示例是从还原图替换一个库,它建议您可以替换外部 NuGet 引用:

<PackageReference Include="Newtonsoft.Json" Version="9.0.1">
  <ExcludeAssets>All</ExcludeAssets>
</PackageReference>

Which overrides the package to reference to a local .dll instead:它覆盖了包以引用本地.dll

<Reference Include="Newtonsoft.Json.dll" />

I'm trying to do something similar where the project should build against local .dll's that were injected as an artifact from a dependent TeamCity/CI build:我正在尝试做一些类似的事情,项目应该针对本地.dll's构建,这些.dll's从依赖的 TeamCity/CI 构建中作为工件注入的:

<Reference Include="..\..\lib\net45\ServiceStack.Interfaces.dll" />
<Reference Include="..\..\lib\net45\ServiceStack.Text.dll" />
<Reference Include="..\..\lib\net45\ServiceStack.Common.dll" />

But when using ExcludeAssets=All as per the documentation:但是当按照文档使用ExcludeAssets=All时:

<PackageReference Include="ServiceStack.Common" Version="5.0.0">
  <ExcludeAssets>All</ExcludeAssets>
</PackageReference>

The PackageReference doesn't get exported in the generated dependency list, eg: PackageReference 不会在生成的依赖项列表中导出,例如:

<group targetFramework=".NETFramework4.5" />

The closest I've come to getting the preferred behavior is to use ExcludeAssets="compile" so my local project doesn't build against it, except this behavior also gets exported in the .nuspec:我最接近获得首选行为的是使用ExcludeAssets="compile"以便我的本地项目不会针对它进行构建,除了此行为也会在 .nuspec 中导出:

<group targetFramework=".NETFramework4.5">
  <dependency id="ServiceStack.Common" version="5.4.0" exclude="Compile,Build,Analyzers" />
</group>

I only want to avoid building against it locally but have it exported as a normal dependency.我只想避免在本地针对它进行构建,而是将其作为正常依赖项导出。 The other issue with this approach is that I need it to reference a package that hasn't been published to NuGet yet (as all packages are published in lock-step), eg:这种方法的另一个问题是我需要它引用一个尚未发布到 NuGet 的包(因为所有包都是在锁定步骤中发布的),例如:

<!-- v5.5.0 is the new version to publish -->
<PackageReference Include="ServiceStack.Common" Version="5.5.0" ExcludeAssets="compile"/>

The build fails that it can't find the unpublished package:构建失败,因为它找不到未发布的包:

[NU1102] Unable to find package ServiceStack.Common with version (>= 5.5.0)

Effectively I need someway to "inject" the exact dependencies and version I need in the generated .nuspec so it's included in the generated .nuspec dependency list, eg:实际上,我需要某种方式在生成的 .nuspec 中“注入”我需要的确切依赖项和版本,以便将其包含在生成的 .nuspec 依赖项列表中,例如:

<group targetFramework="net45">
  <dependency id="ServiceStack.Common" version="5.5.0" />
</group>
<group targetFramework=".netstandard2.0">
  <dependency id="ServiceStack.Common" version="5.5.0" />
</group>

How can we inject a custom dependency in MSBuild generated .nuspec?我们如何在 MSBuild 生成的 .nuspec 中注入自定义依赖项?

Is there some way I can manually declare <dependency/> as above so it's only used when MSBuild/NuGet packs the project?有什么方法可以像上面那样手动声明<dependency/>以便它仅在 MSBuild/NuGet 打包项目时使用? Otherwise is there a way to apply some XML transform to the generated .nuspec so I can manipulate the XML in the .nuspec before it's packed/compressed?否则有没有办法对生成的 .nuspec 应用一些 XML 转换,这样我就可以在 .nuspec 中的 XML 被打包/压缩之前操作它?

Basically I'm only interested in injecting dependencies when the "pack" target is run so it's ignored/inert in all other targets.基本上我只对在运行“pack”目标时注入依赖项感兴趣,因此它在所有其他目标中被忽略/惰性。

Interesting question, and when I looked around for answers I found Another discussion in Stackoverflow有趣的问题,当我四处寻找答案时,我发现了Stackoverflow 中的另一个讨论

Where in one of the comments - there was an indication that the pack command only works with framework projects with 4.6 and above - not 4.5.在其中一条评论中 - 有迹象表明 pack 命令仅适用于 4.6 及更高版本的框架项目 - 而不是 4.5。

The .Net Standard 2.0 has to match 4.6.1 based on this blog entry from Microsoft根据微软的这篇博客文章,.Net Standard 2.0 必须匹配 4.6.1

You've probably found another solution for this by now, but I "succeeded" in doing this, by adding some custom targets to the csproj.您现在可能已经找到了另一个解决方案,但我通过向 csproj 添加了一些自定义目标来“成功”做到了这一点。 The solution did leave me with the feeling that maybe I shouldn't have done it.解决方案确实让我觉得也许我不应该这样做。

The steps were步骤是

  • Inject a step before the package generation target, that disables the nupkg generation在包生成目标之前注入一个步骤,禁用 nupkg 生成
  • Inject a step after the package generation target that modifies the generated nuspec file, and call the package generation target again.在包生成目标后注入修改生成的nuspec文件的step,再次调用包生成目标。

I've modified my fix below so it injects the dependencies mentioned in the post.我在下面修改了我的修复程序,因此它注入了帖子中提到的依赖项。 I've disabled validation here (NoPackageAnalysis=true).我在这里禁用了验证(NoPackageAnalysis=true)。 You can put it in a .target file and import it from the csproj.您可以将其放在 .target 文件中并从 csproj 导入。

<Project>

  <!-- Disable nupkg generation before running pack -->
  <Target Name="__DisablePacking" BeforeTargets="GenerateNuspec" Condition="$(NuspecFile) == ''">
    <PropertyGroup>
      <ContinuePackingAfterGeneratingNuspec>false</ContinuePackingAfterGeneratingNuspec>
    </PropertyGroup>
  </Target>

  <!-- Modify the generated nuspec file and rerun the pack target -->
  <Target Name="__EnablePackingAndInjectDependencies" AfterTargets="Pack" Condition="$(NuspecFile) == ''">
    <!-- Get the nuspec file name -->
    <PropertyGroup>
      <_NugetPackOutputAsProperty>@(NuGetPackOutput)</_NugetPackOutputAsProperty>
    </PropertyGroup>
    <ItemGroup>
      <_NugetPackOutputAsItem Remove="@(_NugetPackOutputAsItem)"/>
      <_NugetPackOutputAsItem Include="$(_NugetPackOutputAsProperty.Split(';'))" />
    </ItemGroup>
    <PropertyGroup>
      <__NuspecFileName>%(_NugetPackOutputAsItem.Identity)</__NuspecFileName>
    </PropertyGroup>

    <!-- Create an updated dependencies, with the net46 dependencies copied to a native group -->
    <PropertyGroup>
      <__NuSpecUpdatedDependencies>
        <group targetFramework="net45">
          <dependency id="ServiceStack.Common" version="5.5.0" />
        </group>
        <group targetFramework=".netstandard2.0">
          <dependency id="ServiceStack.Common" version="5.5.0" />
        </group>
      </__NuSpecUpdatedDependencies>
    </PropertyGroup>

    <!-- Poke them back in -->
    <XmlPoke XmlInputPath="$(__NuspecFileName)"
             Value="$(__NuSpecUpdatedDependencies)"
             Query="/n:package/n:metadata/n:dependencies"
             Namespaces="&lt;Namespace Prefix='n' Uri='http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd' /&gt;">
    </XmlPoke>

    <!-- call the pack operation again -->
    <PropertyGroup>
      <ContinuePackingAfterGeneratingNuspec>true</ContinuePackingAfterGeneratingNuspec>
    </PropertyGroup>

    <Msbuild
      Projects="$(MSBuildProjectFullPath)"
      Targets="Pack"
      Properties="NuspecFile=$(__NuspecFileName);NoPackageAnalysis=true">
    </Msbuild>
  </Target>
</Project>

(I was looking to inject a native0.0 framework dependency so my packages could be consumed by c++/cli projects, in case someone should know of an easier way to do it). (我希望注入一个 native0.0 框架依赖项,以便我的包可以被 c++/cli 项目使用,以防有人知道更简单的方法来做到这一点)。

<?xml version="1.0"?>
<package >
<metadata>
<id>FIK.DAL</id>
<version>$version$</version>
<title>FIK.DAL .NET</title>
<authors>$author$</authors>
<owners>Imamul Karim</owners>
<license type="expression">MIT</license>
<projectUrl>https://github.com/imamulkarim/FIK.DAL</projectUrl>

<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>A Simple SQL Query Generator Using ADO.NET Provider with SqlClient</description>
<releaseNotes>SQLite Library Bug</releaseNotes>
<copyright>$copyright$</copyright>
<tags>ADO.NET SQL QUERY Generator</tags>
</metadata>
<files>
<file src="bin\Debug\System.Data.SQLite.DLL" target="lib\net40"></file>
</files>
</package>

https://docs.microsoft.com/en-us/nuget/reference/nuspec https://docs.microsoft.com/en-us/nuget/reference/nuspec

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带有自定义 .nuspec 元数据的 nuget 包 .csproj - nuget pack .csproj with custom .nuspec metadata 如何使用msbuild 15从生成的nuget包中的nuspec文件中删除依赖项部分 - How to remove the dependencies section from nuspec file in the generated nuget package using msbuild 15 使用 Nuget 包创建 Nuget Package 说要将 net6.0 的依赖组添加到 nuspec 和需要的点? - Creating a Nuget Package with Nuget Pack Says to Add a dependency group for net6.0 to the nuspec and Dots Required? 如何在没有任何nuspec文件的情况下将多个项目中的产品打包到一个nuget中? - How to pack the products from multiple projects into one nuget without any nuspec file? 如何强制 msbuild 和 nuget 将引用的 Lib 打包为 dll? - How to force msbuild and nuget to pack the referenced Lib as dll? NuGet Pack-针对nuspec或csproj打包的不同问题 - NuGet Pack - Different Problems Packing Against nuspec or csproj 无法使用 dotnet CLI 和 nuspec 文件打包 NuGet 包 - Unable to pack a NuGet package using dotnet CLI and nuspec file 如何在创建 Nuget package 时在 nuspec 文件中正确指定依赖信息? - How to correctly specify dependency information in nuspec file while creating Nuget package? 如何将依赖项注入到自定义控件中 - how to inject dependency into a custom control NuGet Msbuild 打包带非SDK项目 - NuGet Msbuild Pack with non-SDK project
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM