【问题标题】:Don't include dependencies from packages.config file when creating NuGet package创建 NuGet 包时不要包含 packages.config 文件中的依赖项
【发布时间】:2013-02-07 09:48:39
【问题描述】:

我正在使用 Nuget 创建包。我想创建一个不包含任何其他 NuGet 包的依赖项(在.nuspec 中)文件的包。我的项目确实在其packages.config 文件中定义了 NuGet 包依赖项。

首先我创建.nuspec 文件...

C:\code\MySolution>.nuget\nuget.exe spec MyProject\MyProject.csproj

我将生成的.nuspec 文件编辑为最小,没有依赖关系。

<?xml version="1.0"?>
<package >
  <metadata>
    <id>MyProject</id>
    <version>1.2.3</version>
    <title>MyProject</title>
    <authors>Example</authors>
    <owners>Example</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Example</description>
    <copyright>Copyright 2013 Example</copyright>
    <tags>example</tags>
    <dependencies />
  </metadata>
</package>

然后我构建解决方案并创建一个 NuGet 包...

C:\code\MySolution>.nuget\nuget.exe pack MyProject\MyProject.csproj -Verbosity detailed

这是该命令的输出...

Attempting to build package from 'MyProject.csproj'.
Packing files from 'C:\code\MySolution\MyProject\bin\Debug'.
Using 'MyProject.nuspec' for metadata.
Found packages.config. Using packages listed as dependencies

Id: MyProject
Version: 1.2.3
Authors: Example
Description: Example
Tags: example
Dependencies: Google.ProtocolBuffers (= 2.4.1.473)

Added file 'lib\net40\MyProject.dll'.

Successfully created package 'C:\code\MySolution\MyProject.1.2.3.nupkg'.

创建的.nupkg 包中包含一个.nuspec 文件,但它包含一个我在原始.nuspec 文件中没有的依赖项部分...

<dependencies>
  <dependency id="Google.ProtocolBuffers" version="2.4.1.473" />
</dependencies>

我相信这是因为这个......(来自上面的输出)

Found packages.config. Using packages listed as dependencies

如何让 NuGet 自动解析依赖关系并将它们插入到由pack 命令生成的.nuspec 文件中?

我目前使用的是 NuGet 2.2。另外,我不认为这种行为发生在旧版本的 NuGet 中。这是一个新的“功能”吗?我找不到任何描述此“功能”或何时实施的文档。

【问题讨论】:

  • 删除 packages.config 文件或重命名。然后打包操作将忽略依赖项。这是我在 2.7 发布之前的临时解决方法。
  • 有没有人用有效的答案回答这个问题。没有这种能力可能是我遇到过的最愚蠢的事情。
  • 对我来说,我无法让它包含我的依赖项:(
  • 我也无法包含我的依赖项。多年。我开始认为这是一个大谎言。
  • 在你的 pack 命令中使用 -IncludeReferencedProjects 标志来自动包含依赖项,但删除它们并没有多大帮助。

标签: dependencies package nuget nuget-package nuspec


【解决方案1】:

在 2.7 版本中,有一个名为 developmentDependency 的选项可以设置到 package.config 中以避免包含依赖项。

<?xml version="1.0" encoding="utf-8"?>
<packages>
    <package id="jQuery" version="1.5.2" />
    <package id="netfx-Guard" version="1.3.3.2" developmentDependency="true" />
    <package id="microsoft-web-helpers" version="1.15" />
</packages>

【讨论】:

  • 此功能的开箱即用实现要求包的每个用户都将此属性添加到他们包含它的每个项目的 packages.config 文件中。许多用户甚至不知道这个属性。我在博客上写了关于包作者如何在安装包期间自动执行此步骤,从而将责任从用户身上移开,blog.danskingdom.com/…
  • @deadlydog 在 Nuget 2.8 中,您现在可以通过 在 nuspec 中将 developmentDependency 设置为 true 来声明您的包为“仅开发依赖项”。见docs.nuget.org/docs/reference/nuspec-reference#Metadata_Section
  • @theDmi 是的,我更新了我的博客文章,并在不久前发布了我自己的答案,其中包含所有更新的信息。请随意对我的答案进行投票,因为它提供了清晰的示例和比这个更多的信息。
【解决方案2】:

防止你的包依赖于其他包

截至NuGet 2.7 there is a new developmentDependency attribute 可以是added to a package node in your project's packages.config file。因此,如果您的项目包含一个您不希望 NuGet 包作为依赖项包含的 NuGet 包,则可以像这样使用此属性:

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="CreateNewNuGetPackageFromProjectAfterEachBuild" version="1.8.1-Prerelease1" targetFramework="net45" developmentDependency="true" />
</packages>

您需要在此处添加的重要一点是developmentDependency="true"

防止你的开发包被其他包依赖

如果您正在创建一个开发 NuGet 包供其他人使用,并且您知道他们不希望在他们的包中具有依赖项,那么您可以避免用户必须手动将该属性添加到他们的 packages.config 文件中使用NuGet 2.8 developmentDependency attribute in the metadata section of your .nuspec file。当您的包被其他人安装时,这将自动将 developmentDependency 属性添加到 packages.config 文件中。这里的问题是它要求用户至少安装 NuGet 2.8。幸运的是,我们可以使用NuGet 2.5 minClientVersion attribute 来确保用户至少安装了 v2.8;否则将通知他们需要更新 NuGet 客户端才能安装包。

我有一个非常适合的开发 NuGet 包。这是我的 .nuspec 文件的样子,展示了如何使用 minClientVersion 和 developmentDependency 属性(分别为第 3 行和第 20 行):

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
  <metadata minClientVersion="2.8">
    <id>CreateNewNuGetPackageFromProjectAfterEachBuild</id>
    <version>1.8.1-Prerelease1</version>
    <title>Create New NuGet Package From Project After Each Build</title>
    <authors>Daniel Schroeder,iQmetrix</authors>
    <owners>Daniel Schroeder,iQmetrix</owners>
    <licenseUrl>https://newnugetpackage.codeplex.com/license</licenseUrl>
    <projectUrl>https://newnugetpackage.codeplex.com/wikipage?title=NuGet%20Package%20To%20Create%20A%20NuGet%20Package%20From%20Your%20Project%20After%20Every%20Build</projectUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Automatically creates a NuGet package from your project each time it builds. The NuGet package is placed in the project's output directory.
    If you want to use a .nuspec file, place it in the same directory as the project's project file (e.g. .csproj, .vbproj, .fsproj).
    This adds a PostBuildScripts folder to your project to house the PowerShell script that is called from the project's Post-Build event to create the NuGet package.
    If it does not seem to be working, check the Output window for any errors that may have occurred.</description>
    <summary>Automatically creates a NuGet package from your project each time it builds.</summary>
    <releaseNotes>- Changed to use new NuGet built-in method of marking this package as a developmentDependency (now requires NuGet client 2.8 or higher to download this package).</releaseNotes>
    <copyright>Daniel Schroeder 2013</copyright>
    <tags>Auto Automatic Automatically Build Pack Create New NuGet Package From Project After Each Build On PowerShell Power Shell .nupkg new nuget package NewNuGetPackage New-NuGetPackage</tags>
    <developmentDependency>true</developmentDependency>
  </metadata>
  <files>
    <file src="..\New-NuGetPackage.ps1" target="content\PostBuildScripts\New-NuGetPackage.ps1" />
    <file src="Content\NuGet.exe" target="content\PostBuildScripts\NuGet.exe" />
    <file src="Content\BuildNewPackage-RanAutomatically.ps1" target="content\PostBuildScripts\BuildNewPackage-RanAutomatically.ps1" />
    <file src="Content\UploadPackage-RunManually.ps1" target="content\PostBuildScripts\UploadPackage-RunManually.ps1" />
    <file src="Content\UploadPackage-RunManually.bat" target="content\PostBuildScripts\UploadPackage-RunManually.bat" />
    <file src="tools\Install.ps1" target="tools\Install.ps1" />
    <file src="tools\Uninstall.ps1" target="tools\Uninstall.ps1" />
  </files>
</package>

如果您不想强制用户至少安装 NuGet v2.8 才能使用您的包,那么您可以在 NuGet 2.8 developmentDependency 属性存在之前use the solution I came up with and blogged about

【讨论】:

  • 对我不起作用。这里的 Nuget 2.8 和 developmentDependency="true" 没有区别。当我通过 Nuget 管理器查看包时,它“仍然”报告所有这些外部依赖项,并且仍然将它们拉入我的项目中。
  • @DiggyJohn 嗯,我在发布之前对其进行了测试,它对我来说效果很好。我也在使用v2.8。您是否也在使用 .nuspec 文件?也许您在 .nuspec 文件中将这些额外文件列为依赖项?
  • @DiggyJohn,如果您已经拥有对您的包的引用,那么它将不会更新它。我不得不删除我的包配置中的引用,然后重新安装包,它按预期显示
  • 使用 nuget 4.7,这两个选项都无法阻止下载依赖项。
【解决方案3】:

如果您使用的是PackageReference 元素而不是package.config 文件,则解决方法如下:

<PackageReference Include="Nerdbank.GitVersioning" Version="1.5.28-rc" PrivateAssets="All" />

<PackageReference Include="Nerdbank.GitVersioning" Version="1.5.28-rc">
   <PrivateAssets>all</PrivateAssets>
</PackageReference>

Related GitHub discussion

【讨论】:

  • 如果这不起作用,请尝试删除 binobj 文件夹。
【解决方案4】:

您可以明确指定要包含的文件,然后对 nuspec 文件本身运行 pack 命令。

<?xml version="1.0"?>
<package >
  <metadata>
    <id>MyProject</id>
    <version>1.2.3</version>
    <title>MyProject</title>
    <authors>Example</authors>
    <owners>Example</owners>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Example</description>
    <copyright>Copyright 2013 Example</copyright>
    <tags>example</tags>
    <dependencies />
  </metadata>

  <files>
    <file src="bin\Release\MyProject.dll" target="lib" />
  </files>

</package>

您应该在此处使用相对于 nuspec 文件的路径设置 src 属性。然后就可以运行打包命令了。

nuget.exe pack MyProject\MyProject.nuspec

【讨论】:

  • 这是一种我没有考虑过的有趣方法;我稍后会在有时间的时候尝试这个解决方案。我的印象是使用.nuspec 文件来生成包不是一个好主意;首选使用.csproj 文件。以这种方式构建软件包有什么后果吗?
  • @JesseWebb 我猜你不能使用变量填充一些字段,比如版本,但除此之外应该没问题。我认为使用 nuspec 文件没有任何问题。你有没有其他说法的消息来源?
  • 我想不建议特别反对; NuGet 文档只是说在 pack 命令中使用 csproj 文件,并且“nuspec 实际上会被拾取”。 docs.nuget.org/docs/creating-packages/… 不过,这个解决方案看起来很有希望,我会尽快尝试一下......过去几周我真的被淹没了。
  • @DiggyJohn 规范在以后的版本中可能已经改变。 docs.nuget.org/docs/reference/nuspec-reference
  • 引用 .nuspec 而不是 .csproj 将起作用(即不包括您未明确指定的依赖项)。缺点是标准替换令牌不会得到解决,例如$version$ 不会设置为项目的 AssemblyInfo.cs 中的值。参考docs.microsoft.com/en-us/nuget/schema/nuspec#replacement-tokens
【解决方案5】:

根据问题 #1956 (https://nuget.codeplex.com/workitem/1956) 和拉取请求 3998 (https://nuget.codeplex.com/SourceControl/network/forks/adamralph/nuget/contribution/3998),此功能已包含在 2.4 版本 2.7 版本中。

但是我找不到有关该功能的文档,而且我还没有弄清楚如何使用它。如果有人知道,请更新此答案。

更新:问题 #1956 已由开发人员更新。该功能未包含在 2.4 版本中,但延迟到即将发布的 2.7 版本中。这就是它尚未记录在案的原因。

【讨论】:

【解决方案6】:

我不确定您为什么要忽略运行 NuGet 包所需的依赖项,但您是否考虑过使用 NuGet Package Explorer 工具来创建您的包?

【讨论】:

  • 我们的构建过程由我们的 CI 服务器 TeamCity 自动化,因此我们没有考虑在此过程中使用 GUI 工具。我认为这个工具不会帮助我们实现自动化。
  • 我们不需要.nuspec中包含的依赖是因为我们只是使用GoogleProtocolBuffers来生成合适的C#源文件;它不是运行时依赖。
  • 您可以使用该工具创建和维护 .nuspec 文件,然后直接在构建服务器上从 .nuspec 文件生成包,而不是从 .csproj 生成包
  • 我明白了...您建议使用该工具来维护.nuspec 文件,类似于@UfukHacıoğulları 在他的回答中建议的内容。我会在尝试他的解决方案时尝试一下。
  • 在我们的例子中,这是因为我们在许多程序集上使用了 ILMerge。我们不需要 Nuget 拉入所有依赖程序集,因为它们已经是主程序集的一部分,它实际上不再“依赖”它们。
猜你喜欢
  • 2016-09-13
  • 1970-01-01
  • 2011-01-16
  • 1970-01-01
  • 1970-01-01
  • 2018-01-09
  • 1970-01-01
  • 2020-05-15
  • 2019-08-05
相关资源
最近更新 更多