7.0 KiB
Embedded Readmes Technical Spec
- Status: Implementing
- Author(s): Advay Tandon
- Issue: 6873 README.md (markdown description) support for NuGet packages
Problem Background
Users of NuGet want to be able to include Readme files as part of the package when they pack
and push
their project through the commandline. The design document outlines the work needed for this feature and the intended results.
Who are the customers
NuGet customers that use the commandline to publish their packages, and want to be able to include Readme files through the pack
process, rather than having to do it manually after the package has been published.
Goals
- Implement the Client side functionality for Embedded Readmes:
nuget pack
supportdotnet pack
supportmsbuild /t:pack
support- Validation of readme files
Non-Goals
- Server side functionality
- Parsing the readme as a valid markdown file on the Client side
- Enabling readme selection through the VS Project Properties UI (Project System)
Solution
NOTE: To see the code described in this section, you can look at the edited files here.
First, we need to add a readme
string element to the nuspec schema to ensure that the readme property is recognized and parsed from the nuspec file. We also need to ensure that the PackageReadmeFile
property is parsed from a csproj file by editing NuGet.Build.Tasks.Pack.targets to include this line:
Readme="$(PackageReadmeFile)"
Further, a GetReadme
method must be added to the NuspecReader.cs file to facilitate the reading of the Readme element from a nuspec file.
Next, we need to add Readme
member variables to multiple relevant classes and interfaces, and ensure that the Readme property is transmitted from one class to another when pack
is called. These are:
In order to transmit the Readme
value from the source file (nuspec or csproj) to the final output nuspec file, the appropriate assignment statements are needed at the relevant locations.
After this, a ManifestMetadata
object is used to create the output nuspec file that is included in the nupkg. For this step, we need to edit the ToXElement method in PackageMetadataXmlExtensions.cs to include this line:
AddElementIfNotNull(elem, ns, "readme", metadata.Readme);
Validation and Errors
To validate the Readme property and the corresponding file when pack
is called, the ValidateReadmeFile method in PackageBuilder.cs checks that:
- The file extension matches a Markdown file
- The file specified in the Readme property exists in the package's files
- The file is not empty
Each of these errors has a corresponding log code and error message defined in NuGetLogCode.cs and NuGetResources.resx respectively, and the appropriate support must be added in NuGetResources.Designer.cs.
NOTE: The Server team will parse and validate the markdown contents of the Readme file when it is uploaded.
Future Work
- Adding readme support through the VS Project Properties UI (Project System) - dotnet/project-system#6457
- Adding a
View README
link in the PM UI that points to the package's readme file - NuGet/Home#9890
Open Questions
- Are there any other validation checks to do when packing a Readme?
Considerations
1. Should we warn users if the Readme property is empty?
Based on feedback from both the NuGet team and customers, we should not do this. The goal of encouraging user adoption of Embedded Readmes can be pursued as part of a separate Package Quality endeavor.
2. Automatically packing a Readme file from the base directory
Similar to the above point, this functionality is not something that we will look to add right now. Relying on explicit user input for the metadata is more desirable, and avoids springing any surprises on customers.
3. Enforcing a size limit on Readme files on pack
Originally, we intended to enforce a 1 MB size limit on Embedded Readme files both while running pack
on the Client-side and while using push
to upload to NuGet.org. However, since we do not want to impose such size restrictions on users looking to upload packages to private or local feeds, we decided against throwing an error for this on pack
. Now, the user can run pack
to create packages with Readme files over 1 MB, but will receive an error if they try to upload such a package to NuGet.org, which enforces a strict 1 MB limit.