Skip to content

Commit

Permalink
Add support for local feeds in PackageRepository (#211)
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffkl committed Apr 11, 2023
1 parent 3a242ca commit e29dea3
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 19 deletions.
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ NuGet and MSBuild are very tightly coupled and a lot of times you need packages
## Package Repository
Create a package repository if you want to generate packages as if they've already been installed. If you want to create actual `.nupkg` packages, see [Package Feed]

### Example
### Examples

Create a package repository with a package that supports two target frameworks:

Expand Down Expand Up @@ -246,23 +246,39 @@ By default, all package sources are disabled so that when running unit tests pac

You can add feeds if needed with the following examples:

#### Add nuget.org as a feed
```C#
using(PackageRepository.Create(
rootPath,
feeds: new[] { new Uri("https://api.nuget.org/v3/index.json") })
using(PackageRepository.Create(rootPath, feeds: new Uri("https://api.nuget.org/v3/index.json"))
{
}

```

#### Add a local directory as a feed
```C#
using(PackageRepository.Create(rootPath)
.Feed("https://api.nuget.org/v3/index.json")
DirectoryInfo localFeed = new DirectoryInfo("<path to local feed>");

using(PackageRepository.Create(rootPath, feeds: new Uri(localFeed.FullName))
{
}

```

#### Create a local feed on-the-fly
```C#
// Create a local feed with one package
string TestRootPath = "<path to folder used for testing>";
string FeedRootPath = Path.Combine(TestRootPath, "Feed");

using PackageFeed packageFeed = PackageFeed.Create(FeedRootPath)
.Package("PackageA", "1.0.0", out Package packageA)
.Library(TargetFramework)
.Save();

// Create a package repository that points to the local feed
using PackageRepository packageRepository = PackageRepository.Create(TestRootPath, feeds: packageFeed);
```

## Package Feed
Create a package feed if you want to generate `.nupkg` packages that can be installed by NuGet. If you want to create a repository of packages as if they've already been installed, see [Package Repository].

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
// Licensed under the MIT license.

using Shouldly;
using System;
using System.IO;
using System.Linq;
using Xunit;

Expand All @@ -14,7 +16,7 @@ public class PackageFeedTests : PackageFeedTestBase
public void BasicPackage()
{
using PackageFeed packageFeed = PackageFeed.Create(FeedRootPath)
.Package("PackageA", "1.0.0", out _, "John Smith", "Custom Description", true)
.Package("PackageA", "1.0.0", out _, "John Smith", "Custom Description", developmentDependency: true)
.Library("net45")
.Save();

Expand Down Expand Up @@ -44,7 +46,7 @@ public void BasicPackage()
public void BasicPackageWithDependency()
{
using PackageFeed packageFeed = PackageFeed.Create(FeedRootPath)
.Package("PackageA", "1.0.0", out _, "John Smith", "Custom Description", true)
.Package("PackageA", "1.0.0", out _, "John Smith", "Custom Description", developmentDependency: true)
.Library("net45")
.Dependency("net45", "PackageB", "2.0.0")
.Save();
Expand Down Expand Up @@ -74,5 +76,24 @@ public void BasicPackageWithDependency()
dependency.Version.ShouldBe("2.0.0");
dependency.ExcludeAssets.ShouldBe("Build, Analyzers");
}

[Fact]
public void RestoreCanConsumePackage()
{
using PackageFeed packageFeed = PackageFeed.Create(FeedRootPath)
.Package("PackageA", "1.0.0", out Package packageA)
.Library(TargetFramework)
.Save();

using PackageRepository packageRepository = PackageRepository.Create(TestRootPath, feeds: packageFeed);

ProjectCreator.Templates.SdkCsproj(
path: Path.Combine(TestRootPath, "ClassLibraryA", "ClassLibraryA.csproj"),
targetFramework: TargetFramework)
.ItemPackageReference(packageA)
.TryRestore(out bool result, out BuildOutput buildOutput);

result.ShouldBeTrue(buildOutput.GetConsoleLog());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Linq;
using Xunit;

namespace Microsoft.Build.Utilities.ProjectCreation.UnitTests.PackageRepositoryTests
Expand Down Expand Up @@ -57,6 +58,48 @@ public void BuildCanConsumePackage()
}
}

[Fact]
public void LocalFeedsAreAddedCorrectly()
{
DirectoryInfo feed1 = Directory.CreateDirectory(Path.Combine(TestRootPath, "Feed1"));
DirectoryInfo feed2 = Directory.CreateDirectory(Path.Combine(TestRootPath, "Feed2"));

using (PackageRepository.Create(TestRootPath, new Uri(feed1.FullName), new Uri(feed2.FullName)))
{
FileInfo nuGetConfig = new FileInfo(Path.Combine(TestRootPath, "NuGet.config"));

nuGetConfig.ShouldExist();

XDocument xmlDocument = XDocument.Load(nuGetConfig.FullName);

XElement packageSourcesElement = xmlDocument
.Element("configuration")
.Element("packageSources");

packageSourcesElement.ShouldNotBeNull();

IEnumerator<XElement> enumerator = packageSourcesElement.Elements().GetEnumerator();

for (int i = 0; i < 3; i++)
{
enumerator.MoveNext().ShouldBeTrue();

XElement element = enumerator.Current;

if (i == 0)
{
element.Name.ShouldBe("clear");
continue;
}

element.Name.ShouldBe("add");
element.Attribute("key").Value.ShouldBe($"Local{i}");

element.Attribute("value").Value.ShouldBe(i == 1 ? feed1.FullName : feed2.FullName);
}
}
}

[Fact]
public void CanSetAllPackageProperties()
{
Expand Down
6 changes: 6 additions & 0 deletions src/Microsoft.Build.Utilities.ProjectCreation/PackageFeed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ private PackageFeed(DirectoryInfo rootPath)
_rootPath.Create();
}

/// <summary>
/// Converts the current <see cref="PackageFeed" /> to a <see cref="Uri" />.
/// </summary>
/// <param name="packageFeed">The <see cref="PackageFeed" /> to convert.</param>
public static implicit operator Uri(PackageFeed packageFeed) => new Uri(packageFeed._rootPath.FullName);

/// <summary>
/// Creates a new <see cref="PackageFeed" /> instance at the specified path.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,15 @@ private PackageRepository(string rootPath, IEnumerable<Uri>? feeds = null)

if (feeds != null)
{
int i = 1;

foreach (Uri? feed in feeds.Where(i => i != null))
{
string feedName = feed.IsFile ? $"Local{i++}" : feed.Host;

writer.WriteStartElement("add");
writer.WriteAttributeString("key", feed.Host);
writer.WriteAttributeString("value", feed.ToString());
writer.WriteAttributeString("key", feedName);
writer.WriteAttributeString("value", feed.IsFile ? feed.LocalPath : feed.ToString());
writer.WriteEndElement();
}
}
Expand All @@ -80,10 +84,7 @@ private PackageRepository(string rootPath, IEnumerable<Uri>? feeds = null)
/// <param name="rootPath">The root directory to create a package repository directory in.</param>
/// <param name="feeds">Optional feeds to include in the configuration.</param>
/// <returns>A <see cref="PackageRepository" /> object that is used to construct an NuGet package repository.</returns>
public static PackageRepository Create(string rootPath, IEnumerable<Uri>? feeds = null)
{
return new PackageRepository(rootPath, feeds);
}
public static PackageRepository Create(string rootPath, params Uri[] feeds) => new PackageRepository(rootPath, feeds);

/// <inheritdoc cref="IDisposable.Dispose" />
public void Dispose()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ static Microsoft.Build.Utilities.ProjectCreation.MSBuildAssemblyResolver.SearchP
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(string! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(System.IO.DirectoryInfo! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Templates.get -> Microsoft.Build.Utilities.ProjectCreation.PackageFeedTemplates!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, System.Collections.Generic.IEnumerable<System.Uri!>? feeds = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Create(string? path = null, string? defaultTargets = null, string? initialTargets = null, string? sdk = null, string? toolsVersion = null, string? treatAsLocalProperty = null, Microsoft.Build.Evaluation.ProjectCollection? projectCollection = null, Microsoft.Build.Evaluation.NewProjectFileOptions? projectFileOptions = null, System.Collections.Generic.IDictionary<string!, string!>? globalProperties = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Construction.ProjectRootElement!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Construction.ProjectRootElement!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Evaluation.Project!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Evaluation.Project!
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.implicit operator System.Uri!(Microsoft.Build.Utilities.ProjectCreation.PackageFeed! packageFeed) -> System.Uri!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, params System.Uri![]! feeds) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ static Microsoft.Build.Utilities.ProjectCreation.MSBuildAssemblyResolver.SearchP
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(string! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(System.IO.DirectoryInfo! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Templates.get -> Microsoft.Build.Utilities.ProjectCreation.PackageFeedTemplates!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, System.Collections.Generic.IEnumerable<System.Uri!>? feeds = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Create(string? path = null, string? defaultTargets = null, string? initialTargets = null, string? sdk = null, string? toolsVersion = null, string? treatAsLocalProperty = null, Microsoft.Build.Evaluation.ProjectCollection? projectCollection = null, Microsoft.Build.Evaluation.NewProjectFileOptions? projectFileOptions = null, System.Collections.Generic.IDictionary<string!, string!>? globalProperties = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Construction.ProjectRootElement!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Construction.ProjectRootElement!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Evaluation.Project!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Evaluation.Project!
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.implicit operator System.Uri!(Microsoft.Build.Utilities.ProjectCreation.PackageFeed! packageFeed) -> System.Uri!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, params System.Uri![]! feeds) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ static Microsoft.Build.Utilities.ProjectCreation.MSBuildAssemblyResolver.SearchP
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(string! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(System.IO.DirectoryInfo! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Templates.get -> Microsoft.Build.Utilities.ProjectCreation.PackageFeedTemplates!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, System.Collections.Generic.IEnumerable<System.Uri!>? feeds = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Create(string? path = null, string? defaultTargets = null, string? initialTargets = null, string? sdk = null, string? toolsVersion = null, string? treatAsLocalProperty = null, Microsoft.Build.Evaluation.ProjectCollection? projectCollection = null, Microsoft.Build.Evaluation.NewProjectFileOptions? projectFileOptions = null, System.Collections.Generic.IDictionary<string!, string!>? globalProperties = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Construction.ProjectRootElement!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Construction.ProjectRootElement!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Evaluation.Project!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Evaluation.Project!
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.implicit operator System.Uri!(Microsoft.Build.Utilities.ProjectCreation.PackageFeed! packageFeed) -> System.Uri!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, params System.Uri![]! feeds) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ static Microsoft.Build.Utilities.ProjectCreation.MSBuildAssemblyResolver.SearchP
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(string! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Create(System.IO.DirectoryInfo! rootPath) -> Microsoft.Build.Utilities.ProjectCreation.PackageFeed!
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.Templates.get -> Microsoft.Build.Utilities.ProjectCreation.PackageFeedTemplates!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, System.Collections.Generic.IEnumerable<System.Uri!>? feeds = null) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.Create(string? path = null, string? defaultTargets = null, string? initialTargets = null, string? sdk = null, string? toolsVersion = null, string? treatAsLocalProperty = null, Microsoft.Build.Evaluation.ProjectCollection? projectCollection = null, Microsoft.Build.Evaluation.NewProjectFileOptions? projectFileOptions = null, System.Collections.Generic.IDictionary<string!, string!>? globalProperties = null) -> Microsoft.Build.Utilities.ProjectCreation.ProjectCreator!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Construction.ProjectRootElement!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Construction.ProjectRootElement!
static Microsoft.Build.Utilities.ProjectCreation.ProjectCreator.implicit operator Microsoft.Build.Evaluation.Project!(Microsoft.Build.Utilities.ProjectCreation.ProjectCreator! creator) -> Microsoft.Build.Evaluation.Project!
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
#nullable enable
static Microsoft.Build.Utilities.ProjectCreation.PackageFeed.implicit operator System.Uri!(Microsoft.Build.Utilities.ProjectCreation.PackageFeed! packageFeed) -> System.Uri!
static Microsoft.Build.Utilities.ProjectCreation.PackageRepository.Create(string! rootPath, params System.Uri![]! feeds) -> Microsoft.Build.Utilities.ProjectCreation.PackageRepository!
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "9.0",
"version": "10.0",
"assemblyVersion": "1.0",
"buildNumberOffset": -1,
"nugetPackageVersion": {
Expand Down

0 comments on commit e29dea3

Please sign in to comment.