Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch from .nuspec files to project properties #958

Merged
merged 6 commits into from
Sep 11, 2024

Conversation

MattKotsenas
Copy link
Contributor

@MattKotsenas MattKotsenas commented Aug 22, 2024

Both the main YamlDotNet and the StaticGenerator projects had NuGet package information split between project properties and metadata in the .nuspec file. More confusingly, the projects weren't linked to the nuspec (using <NuspecFile>), so the packages were totally different if build via dotnet pack or nuget pack.

To avoid confusion and simplify future changes, I migrated all the properties from each package into project properties and deleted the nuspec files. I verified via a diff tool that the package contents and manifests are the same except for fixing bugs.

Known diffs:

  • requireLicenseAcceptance=false is now the default so dotnet pack omits it
  • <iconUrl> is removed (because it is deprecated) and <icon> with a path inside the package is used instead
  • LICENSE.txt is no longer included as we use the <license> expression instead
  • <language> is automatically excluded because there are no localized resources
  • <summary> is dropped (because it is deprecated); the VS UI shows the package description in its place

Here's a diff of each:

YamlDotNet

--- YamlDotNet.nuspec
+++ YamlDotNet.nuspec
@@ -1,27 +1,24 @@
 <?xml version="1.0" encoding="utf-8"?>
-<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
+<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
-  <metadata minClientVersion="2.8">
+  <metadata>
     <id>YamlDotNet</id>
     <version>16.1.0-refactor-dotnet-pack-</version>
     <authors>Antoine Aubry</authors>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
     <license type="expression">MIT</license>
     <licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
     <icon>images/yamldotnet.png</icon>
     <readme>README.md</readme>
     <projectUrl>https://github.com/aaubry/YamlDotNet</projectUrl>
-    <iconUrl>http://aaubry.net/images/yamldotnet.png</iconUrl>
-    <description>A .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument.</description>
+    <description>YamlDotNet is a .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument. A serialization library is also included that allows to read and write objects from and to YAML streams.</description>
-    <summary>This package contains the YAML parser and serializer.</summary>
-    <language>en-US</language>
+    <copyright>Copyright (c) Antoine Aubry and contributors</copyright>
     <tags>yaml parser development library serialization</tags>
-    <repository type="git" url="https://github.com/aaubry/YamlDotNet.git" />
+    <repository type="git" url="https://github.com/aaubry/YamlDotNet" commit="126f2eadd933329214d8f4d0d461f892d57fe172" />
     <dependencies>
       <group targetFramework=".NETFramework4.7" />
       <group targetFramework=".NETStandard2.0" />
       <group targetFramework=".NETStandard2.1" />
      <group targetFramework="net6.0" />
      <group targetFramework="net8.0" />
     </dependencies>
   </metadata>
 </package>

YamlDotNet.Analyzers.StaticGenerator

--- YamlDotNet.Analyzers.StaticGenerator.nuspec
+++ YamlDotNet.Analyzers.StaticGenerator.nuspec
@@ -1,19 +1,16 @@
 <?xml version="1.0" encoding="utf-8"?>
-<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
+<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
-  <metadata minClientVersion="2.8">
+  <metadata>
-    <id>Vecc.YamlDotNet.Analyzers.StaticGenerator</id>
+    <id>YamlDotNet.Analyzers.StaticGenerator</id>
     <version>16.1.0-refactor-dotnet-pack-</version>
     <authors>YamlDotNet Contributors</authors>
-    <requireLicenseAcceptance>false</requireLicenseAcceptance>
-    <license type="file">LICENSE.txt</license>
+    <license type="expression">MIT</license>
-    <licenseUrl>https://aka.ms/deprecateLicenseUrl</licenseUrl>
+    <licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
     <icon>images/yamldotnet.png</icon>
     <projectUrl>https://github.com/aaubry/YamlDotNet/wiki</projectUrl>
-    <iconUrl>http://aaubry.net/images/yamldotnet.png</iconUrl>
     <description>Roslyn Code Generator that will generate a static context for use with YamlDotNet to support ahead-of-time and library trimming.</description>
-    <summary>Static context generator for YamlDotNet.</summary>
-    <language>en-US</language>
+    <copyright>Copyright (c) Antoine Aubry and contributors</copyright>
     <tags>yaml parser development library serialization</tags>
-    <repository type="git" url="https://github.com/aaubry/YamlDotNet.git" />
+    <repository type="git" url="https://github.com/aaubry/YamlDotNet" commit="4ca55db6d3f5f337df3bb53a3387a1728987759f" />
   </metadata>
 </package>

Here the analyzer was incorrectly being put into //analyzers/dotnet/cs/netstandard2.0, when it should instead be either in the parent folder or should have a roslyn version folder. Thus the analyzer was moved to //analyzers/dotnet/cs

--- YamlDotNet.Analyzers.StaticGenerator#contents
+++ YamlDotNet.Analyzers.StaticGenerator#contents
@@ -1,11 +1,8 @@
 /
-|-- LICENSE.txt
-|-- Vecc.YamlDotNet.Analyzers.StaticGenerator.nuspec
+|-- YamlDotNet.Analyzers.StaticGenerator.nuspec
 |-- analyzers
 |   |-- dotnet
 |   |   |-- cs
-|   |   |   |-- netstandard2.0
-|   |   |   |   |-- YamlDotNet.Analyzers.StaticGenerator.dll
+|   |   |   |-- YamlDotNet.Analyzers.StaticGenerator.dll
 |-- images
 |   |-- yamldotnet.png

@MattKotsenas
Copy link
Contributor Author

@EdwardCooke, I have at least one upcoming change to propose that leverages System.Span, which requires a package for old .NET Framework versions. Rather than try to edit the .nuspec directly, I'll base that change off of this one which makes keeping dependencies in sync much easier.

If you have any questions, please let me know. Thanks!

@EdwardCooke
Copy link
Collaborator

I’d rather not bring in a dependency on another package. Things get messy for the consumer when they already reference a different version.

@MattKotsenas
Copy link
Contributor Author

I’d rather not bring in a dependency on another package. Things get messy for the consumer when they already reference a different version.

Ok no problem. I think this change is still goodness, even without new dependencies. Otherwise I was confused for a while because there's diverging values between the project and the nuspec.

Additionally, today the YAMLDotNet project is taking references that aren't declared. Luckily they also aren't used, but without this change you could get into a state where you ship a broken package.

Let me know if you disagree or have questions. Thanks!

@lahma
Copy link
Contributor

lahma commented Aug 23, 2024

There's also #931 , but my proposals seem go unnoticed.

@EdwardCooke
Copy link
Collaborator

They’re not going unnoticed. I promise. I’m hoping to start knocking some prs out in the next few weeks.

@EdwardCooke
Copy link
Collaborator

@lahma I just merged in your PR, so this PR has become obsolete so I'm going to close this one.

@MattKotsenas
Copy link
Contributor Author

@EdwardCooke, I believe this PR is still relevant. If you take a look at your tools build:

Run("nuget", $"pack YamlDotNet.nuspec -Version {version.NuGetVersion} -OutputDirectory bin -Symbols -SymbolPackageFormat snupkg", buildDir);

You're still packing via a nuspec. If you open a built package in a tool like NuGet Package Explorer you'll see that none of the package properties in the .csproj are being applied.

I believe this PR still solves a few problems, namely:

  1. Fixing the issue of getting different results if you do dotnet pack vs building with the tool
  2. Needing to keep the .csproj files and .nuspec files in-sync (which they currently are not)

Would you mind taking another look? If I'm misunderstanding something or you have additional questions, please let me know. Thanks!

@EdwardCooke
Copy link
Collaborator

I'll double check this then, I may have missed something.

@EdwardCooke EdwardCooke reopened this Sep 1, 2024
@EdwardCooke
Copy link
Collaborator

I just compared the package output from both the nuget pack and the dotnet pack version, theres a couple of differences in the output between the 2 (nuget vs dotnet). Don't be wrong, I want to use dotnet because that works natively on Linux. The differences I noticed right off the bat are the missing readme and icon elements and the addition of all of those references for the .net core frameworks. Not sure where those are coming from, but we'll those things resolved before we can switch to using dotnet instead of nuget.

New with dotnet

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
  <metadata>
    <id>YamlDotNet</id>
    <version>16.1.0-ec-makeconcurrent-</version>
    <authors>YamlDotNet</authors>
    <license type="expression">MIT</license>
    <licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
    <projectUrl>https://github.com/aaubry/YamlDotNet</projectUrl>
    <description>YamlDotNet is a .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument. A serialization library is also included that allows to read and write objects from and to YAML streams.</description>
    <copyright>Copyright (c) Antoine Aubry and contributors</copyright>
    <repository type="git" url="https://github.com/aaubry/YamlDotNet" commit="5737a3c56b871b49b0856a81f00157f760872d55" />
    <dependencies>
      <group targetFramework=".NETFramework4.7" />
      <group targetFramework="net6.0">
        <dependency id="System.ComponentModel.TypeConverter" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Diagnostics.Debug" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Runtime.Serialization.Formatters" version="4.3.0" exclude="Build,Analyzers" />
      </group>
      <group targetFramework="net8.0">
        <dependency id="System.ComponentModel.TypeConverter" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Diagnostics.Debug" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Runtime.Serialization.Formatters" version="4.3.0" exclude="Build,Analyzers" />
      </group>
      <group targetFramework=".NETStandard2.0">
        <dependency id="System.ComponentModel.TypeConverter" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Diagnostics.Debug" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Runtime.Serialization.Formatters" version="4.3.0" exclude="Build,Analyzers" />
      </group>
      <group targetFramework=".NETStandard2.1">
        <dependency id="System.ComponentModel.TypeConverter" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Diagnostics.Debug" version="4.3.0" exclude="Build,Analyzers" />
        <dependency id="System.Runtime.Serialization.Formatters" version="4.3.0" exclude="Build,Analyzers" />
      </group>
    </dependencies>
    <frameworkAssemblies>
      <frameworkAssembly assemblyName="System.Core" targetFramework=".NETFramework4.7" />
      <frameworkAssembly assemblyName="System" targetFramework=".NETFramework4.7" />
    </frameworkAssemblies>
  </metadata>
</package>

Original with nuget

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
  <metadata minClientVersion="2.8">
    <id>YamlDotNet</id>
    <version>16.1.0-ec-makeconcurrent-</version>
    <authors>Antoine Aubry</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <license type="expression">MIT</license>
    <licenseUrl>https://licenses.nuget.org/MIT</licenseUrl>
    <icon>images/yamldotnet.png</icon>
    <readme>README.md</readme>
    <projectUrl>https://github.com/aaubry/YamlDotNet/wiki</projectUrl>
    <iconUrl>http://aaubry.net/images/yamldotnet.png</iconUrl>
    <description>A .NET library for YAML. YamlDotNet provides low level parsing and emitting of YAML as well as a high level object model similar to XmlDocument.</description>
    <summary>This package contains the YAML parser and serializer.</summary>
    <language>en-US</language>
    <tags>yaml parser development library serialization</tags>
    <repository type="git" url="https://github.com/aaubry/YamlDotNet.git" />
    <dependencies>
      <group targetFramework=".NETFramework4.7" />
      <group targetFramework=".NETStandard2.0" />
      <group targetFramework=".NETStandard2.1" />
      <group targetFramework="net6.0" />
      <group targetFramework="net8.0" />
    </dependencies>
  </metadata>
</package>

@EdwardCooke
Copy link
Collaborator

Found a difference that isn't supported by using the project properties instead of the .nuspec. The summary. It's whats shown in Visual Studio when you search for a nuget package. So I think we should stick to the nuspec, however, we should switch it to using dotnet pack with the nuspec instead of using nuget pack so it's cross platform.

@EdwardCooke
Copy link
Collaborator

Also, the references in the csproj for dotnet core can safely be removed. They aren't used. Not sure when or why they were added.

@MattKotsenas
Copy link
Contributor Author

Found a difference that isn't supported by using the project properties instead of the .nuspec. The summary. It's whats shown in Visual Studio when you search for a nuget package. So I think we should stick to the nuspec, however, we should switch it to using dotnet pack with the nuspec instead of using nuget pack so it's cross platform.

Summary is deprecated in favor of description, see https://learn.microsoft.com/en-us/nuget/reference/nuspec#summary. I'll double-check that the description shows up in VS UI; assuming is does, is switching OK with you?

Also, the references in the csproj for dotnet core can safely be removed. They aren't used. Not sure when or why they were added.

I did a git blame, but the commit comment doesn't elaborate on the rationale for adding them. However, it highlights why I think switching away from a .nuspec is so important. It's very easy to make changes that require .nuspec updates but forget to update the .nuspec itself. By driving the packaging process from the project itself, this whole class of errors can be eliminated.

I'm unfortunately tied up with other stuff at the moment, but I should be able to update this PR for you to take another look later this week, or on the weekend at the latest.

If you have any questions / concerns, please let me know. Thanks for taking a look!

@EdwardCooke
Copy link
Collaborator

I'm fine with the change. It was just something I noticed. No rush on it, I'm not planning on pushing a new version for about a week and a half. I try to keep releases no more frequent than every 2 weeks.

@MattKotsenas
Copy link
Contributor Author

@EdwardCooke, this should be ready for another look. I also validated I was able to consume the package in a project that builds both net472 and net6.0.

@EdwardCooke
Copy link
Collaborator

At first glance it looks good. I'll take a look at it tomorrow in depth.

@EdwardCooke EdwardCooke merged commit 00026fb into aaubry:master Sep 11, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants