Skip to content

Commit ca14cff

Browse files
authored
Add PackageRepository.Package overload that accept .nupkg file (#276)
1 parent d94ac75 commit ca14cff

File tree

9 files changed

+116
-7
lines changed

9 files changed

+116
-7
lines changed

src/Microsoft.Build.Utilities.ProjectCreation.UnitTests/PackageFeedTests/PackageFeedTestBase.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@ protected string GetNuspec(Package package)
6666
return GetFileContents(package.FullPath, filePath => filePath.EndsWith($"{package.Id}.nuspec", StringComparison.OrdinalIgnoreCase));
6767
}
6868

69-
protected NuspecReader GetNuspecReader(Package package)
70-
{
71-
return new NuspecReader(GetNuspec(package));
72-
}
73-
7469
protected Assembly? LoadAssembly(string packageFullPath, string filePath)
7570
{
7671
byte[]? bytes = GetFileBytes(packageFullPath, filePath);
@@ -85,6 +80,11 @@ protected void ShouldThrowExceptionIfNoPackageAdded(Action action)
8580
exception.Message.ShouldBe(Strings.ErrorWhenAddingAnythingBeforePackage);
8681
}
8782

83+
private protected NuspecReader GetNuspecReader(Package package)
84+
{
85+
return new NuspecReader(GetNuspec(package));
86+
}
87+
8888
private T? ReadFile<T>(ZipArchive nupkg, string filePath, Func<Stream, ZipArchiveEntry, T> streamFunc)
8989
{
9090
ZipArchiveEntry? archiveEntry = nupkg.GetEntry(filePath);

src/Microsoft.Build.Utilities.ProjectCreation.UnitTests/PackageRepositoryTests/RepositoryTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,44 @@ public void CanUseNuGetSdkResolver()
227227
}
228228
}
229229
}
230+
231+
[Fact]
232+
public void CanCreatePackageFromNupkg()
233+
{
234+
string feedRootPath = Path.Combine(TestRootPath, "Feed");
235+
string targetFramework = "netstandard2.0";
236+
string contentFileText = "b7e41f28-0e3e-4824-90d3-025da699630e";
237+
238+
// Create a .nupkg to use as a source
239+
using (PackageFeed.Create(feedRootPath)
240+
.Package("PackageA", "1.2.3", out Package originalPackage, "John Smith", "Custom Description", developmentDependency: true)
241+
.Library(targetFramework)
242+
.ContentFileText("file.txt", contentFileText, targetFramework)
243+
.Save())
244+
{
245+
originalPackage.FullPath.ShouldNotBeNull();
246+
247+
using (PackageRepository.Create(TestRootPath)
248+
.Package(new FileInfo(originalPackage.FullPath), out Package newPackage))
249+
{
250+
newPackage.Author.ShouldBe("John Smith");
251+
newPackage.Description.ShouldBe("Custom Description");
252+
newPackage.DevelopmentDependency.ShouldBeTrue();
253+
newPackage.Id.ShouldBe("PackageA");
254+
newPackage.Version.ShouldBe("1.2.3");
255+
256+
newPackage.FullPath.ShouldNotBeNullOrEmpty();
257+
DirectoryInfo? baseDir = new FileInfo(newPackage.FullPath).Directory;
258+
baseDir.ShouldNotBeNull().ShouldExist();
259+
260+
new FileInfo(Path.Combine(baseDir.FullName, "lib", targetFramework, $"{newPackage.Id}.dll"))
261+
.ShouldExist();
262+
263+
new FileInfo(Path.Combine(baseDir.FullName, "contentFiles", "any", targetFramework, "file.txt"))
264+
.ShouldExist()
265+
.ReadAsText().ShouldBe(contentFileText);
266+
}
267+
}
268+
}
230269
}
231270
}

src/Microsoft.Build.Utilities.ProjectCreation/ExtensionMethods.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,5 +141,11 @@ internal static void WriteElementStringIfNotNull(this XmlWriter writer, string l
141141
writer.WriteElementString(localName, value.Value ? "true" : "false");
142142
}
143143
}
144+
145+
internal static string ReadAsText(this FileInfo file)
146+
{
147+
using StreamReader reader = file.OpenText();
148+
return reader.ReadToEnd();
149+
}
144150
}
145151
}

src/Microsoft.Build.Utilities.ProjectCreation.UnitTests/NuspecReader.cs renamed to src/Microsoft.Build.Utilities.ProjectCreation/NuspecReader.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
using System.Xml.Linq;
1010
using System.Xml.XPath;
1111

12-
namespace Microsoft.Build.Utilities.ProjectCreation.UnitTests
12+
namespace Microsoft.Build.Utilities.ProjectCreation
1313
{
14-
public class NuspecReader
14+
internal class NuspecReader
1515
{
1616
private static readonly XNamespace NuspecNamespace = "http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd";
1717

src/Microsoft.Build.Utilities.ProjectCreation/PackageRepository.Package.cs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
using System;
66
using System.Collections.Generic;
77
using System.IO;
8+
using System.IO.Compression;
9+
using System.Linq;
810

911
namespace Microsoft.Build.Utilities.ProjectCreation
1012
{
@@ -44,6 +46,64 @@ public string GetManifestFilePath(string packageId, string version)
4446
return Path.Combine(GetInstallPath(packageId, version), $"{packageId.ToLowerInvariant()}.nuspec");
4547
}
4648

49+
/// <summary>
50+
/// Creates a new package.
51+
/// </summary>
52+
/// <param name="nupkg">A <see cref="FileInfo"/> object that corresponds to the .nupkg file.</param>
53+
/// <param name="package">Receives a <see cref="ProjectCreation.Package" /> object representing the package.</param>
54+
/// <returns>The current <see cref="PackageRepository" />.</returns>
55+
/// <exception cref="FileNotFoundException">The <paramref name="nupkg"/> does not exist.</exception>
56+
/// <exception cref="InvalidOperationException">The package's ID or version is <c>null</c>.</exception>
57+
public PackageRepository Package(FileInfo nupkg, out Package package)
58+
{
59+
if (!nupkg.Exists)
60+
{
61+
throw new FileNotFoundException("The specified .nupkg file does not exist", nupkg.FullName);
62+
}
63+
64+
using ZipArchive zip = new ZipArchive(System.IO.File.OpenRead(nupkg.FullName), ZipArchiveMode.Read, leaveOpen: false);
65+
66+
ZipArchiveEntry? nuspecEntry = zip.Entries.SingleOrDefault(entry => entry.Name.EndsWith(".nuspec", StringComparison.OrdinalIgnoreCase)) ?? throw new InvalidOperationException($"The .nupkg file '{nupkg.FullName}' does not contain a .nuspec file");
67+
using StreamReader nuspecStream = new StreamReader(nuspecEntry.Open());
68+
69+
NuspecReader reader = new NuspecReader(nuspecStream.ReadToEnd());
70+
71+
Package(
72+
id: reader.Id ?? throw new InvalidOperationException($"The .nupkg file '{nupkg.FullName}' does not contain an ID"),
73+
version: reader.Version ?? throw new InvalidOperationException($"The .nupkg file '{nupkg.FullName}' does not contain a version"),
74+
package: out package,
75+
authors: reader.Authors,
76+
description: reader.Description,
77+
copyright: reader.Copyright,
78+
developmentDependency: reader.DevelopmentDependency,
79+
icon: reader.Icon,
80+
iconUrl: reader.IconUrl,
81+
language: reader.Language,
82+
licenseUrl: reader.LicenseUrl,
83+
licenseExpression: reader.LicenseExpression,
84+
licenseVersion: reader.LicenseVersion,
85+
owners: reader.Owners,
86+
packageTypes: reader.PackageTypes,
87+
projectUrl: reader.ProjectUrl,
88+
releaseNotes: reader.ReleaseNotes,
89+
repositoryType: reader.RepositoryType,
90+
repositoryUrl: reader.RepositoryUrl,
91+
repositoryBranch: reader.RepositoryBranch,
92+
repositoryCommit: reader.RepositoryCommit,
93+
requireLicenseAcceptance: reader.RequireLicenseAcceptance,
94+
serviceable: reader.Serviceable,
95+
summary: reader.Summary,
96+
tags: reader.Tags,
97+
title: reader.Title);
98+
99+
foreach (ZipArchiveEntry entry in zip.Entries.Where(entry => entry != nuspecEntry))
100+
{
101+
File(entry.FullName, fi => entry.ExtractToFile(fi.FullName));
102+
}
103+
104+
return this;
105+
}
106+
47107
/// <summary>
48108
/// Creates a new package.
49109
/// </summary>

src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net472/PublicAPI.Shipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Library(string! targ
168168
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.NuGetConfigPath.get -> string!
169169
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, out Microsoft.Build.Utilities.ProjectCreation.Package! package, string? authors = "UserA", string? description = "Description", string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
170170
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, string? authors = null, string? description = null, string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171+
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(System.IO.FileInfo! nupkg, out Microsoft.Build.Utilities.ProjectCreation.Package! package) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171172
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Packages.get -> System.Collections.Generic.IReadOnlyCollection<Microsoft.Build.Utilities.ProjectCreation.Package!>!
172173
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator
173174
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Choose(string? label = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!

src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net6.0/PublicAPI.Shipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Library(string! targ
168168
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.NuGetConfigPath.get -> string!
169169
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, out Microsoft.Build.Utilities.ProjectCreation.Package! package, string? authors = "UserA", string? description = "Description", string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
170170
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, string? authors = null, string? description = null, string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171+
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(System.IO.FileInfo! nupkg, out Microsoft.Build.Utilities.ProjectCreation.Package! package) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171172
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Packages.get -> System.Collections.Generic.IReadOnlyCollection<Microsoft.Build.Utilities.ProjectCreation.Package!>!
172173
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator
173174
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Choose(string? label = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!

src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net7.0/PublicAPI.Shipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Library(string! targ
168168
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.NuGetConfigPath.get -> string!
169169
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, out Microsoft.Build.Utilities.ProjectCreation.Package! package, string? authors = "UserA", string? description = "Description", string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
170170
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, string? authors = null, string? description = null, string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171+
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(System.IO.FileInfo! nupkg, out Microsoft.Build.Utilities.ProjectCreation.Package! package) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171172
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Packages.get -> System.Collections.Generic.IReadOnlyCollection<Microsoft.Build.Utilities.ProjectCreation.Package!>!
172173
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator
173174
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Choose(string? label = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!

src/Microsoft.Build.Utilities.ProjectCreation/PublicAPI/net8.0/PublicAPI.Shipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Library(string! targ
168168
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.NuGetConfigPath.get -> string!
169169
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, out Microsoft.Build.Utilities.ProjectCreation.Package! package, string? authors = "UserA", string? description = "Description", string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
170170
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(string! id, string! version, string? authors = null, string? description = null, string? copyright = null, bool developmentDependency = false, string? icon = null, string? iconUrl = null, string? language = null, string? licenseUrl = null, string? licenseExpression = null, string? licenseVersion = null, string? owners = null, System.Collections.Generic.IEnumerable<string!>? packageTypes = null, string? projectUrl = null, string? releaseNotes = null, string? repositoryType = null, string? repositoryUrl = null, string? repositoryBranch = null, string? repositoryCommit = null, bool requireLicenseAcceptance = false, bool serviceable = false, string? summary = null, string? tags = null, string? title = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171+
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Package(System.IO.FileInfo! nupkg, out Microsoft.Build.Utilities.ProjectCreation.Package! package) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
171172
Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Packages.get -> System.Collections.Generic.IReadOnlyCollection<Microsoft.Build.Utilities.ProjectCreation.Package!>!
172173
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator
173174
Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Choose(string? label = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!

0 commit comments

Comments
 (0)