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

Fix dotnet add package doesn't work with relative path source or when version is not specified #3783

Merged
merged 31 commits into from
Jan 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
f1a52d0
Fix 'dotnet add package' with user supplied source feed works if no v…
erdembayar Dec 1, 2020
b1994d9
Prevent from user enter duplicate source from cli.
erdembayar Dec 1, 2020
5ebec22
Add unit tests for 'dotnet pack Package' command with user supplied s…
erdembayar Dec 3, 2020
f2e4d5d
Fix test breaking on Linux.
erdembayar Dec 3, 2020
29632d9
2nd attempt to fix unit test failing on Linux.
erdembayar Dec 3, 2020
d810d92
Fix failing Linux unit test3.
erdembayar Dec 3, 2020
35c2426
Remove unneeded utility method.
erdembayar Dec 3, 2020
528f0cd
Address PR review by Nikolche.
erdembayar Dec 5, 2020
c2c9692
Implemented V2 unget source feed instead of V3 source feed for unit t…
erdembayar Dec 5, 2020
b5ab7ca
Correct conflicting FindLocalPackagesResourceV2Provider, FindLocalPac…
erdembayar Dec 8, 2020
cbd7a36
Fix relative path is not discovered when resolving package from local.
erdembayar Dec 9, 2020
1a9398e
Add more unit test covering all possible scenarios.
erdembayar Dec 9, 2020
586e3ab
Fix Linux unit tests.
erdembayar Dec 10, 2020
a87d7f2
Remove unneeded changes.
erdembayar Dec 18, 2020
7a8f91c
Add passed sources into dgSpec sources.
erdembayar Dec 21, 2020
6deb739
Refactor code: Instead of add source we replace source in dgSpec file.
erdembayar Dec 21, 2020
3a1b6f1
Revert other feed provider problem fix which need to go in seperate PR.
erdembayar Dec 21, 2020
86a56b8
Address code review comments by Nikolche.
erdembayar Dec 22, 2020
f4224c2
Address latest code review comment
erdembayar Dec 22, 2020
eabc100
Instead of relative to project directory, now resolve sources relativ…
erdembayar Jan 1, 2021
aabcaf5
Start moving dotnet relative source tests to dotnet integration tests.
erdembayar Jan 5, 2021
a901f57
Move another dotnet relative source test into dotnet.integration.test
erdembayar Jan 6, 2021
73a3141
Fix empty source passed situation for dotnet add package.
erdembayar Jan 6, 2021
f46d327
Test additional frameworks
erdembayar Jan 6, 2021
3646937
Finish moving dotnet relative source unit tests to dotnet.integration…
erdembayar Jan 6, 2021
f4598c1
Fix new unit test names.
erdembayar Jan 6, 2021
4943245
Address PR review by Nkolche.
erdembayar Jan 7, 2021
ec6c73f
Remove unused `sources` parameter passed down.
erdembayar Jan 7, 2021
8f797e1
Remove V2 sourcefeed unit tests
erdembayar Jan 8, 2021
c9e4a0f
Revert unused file change.
erdembayar Jan 8, 2021
514e29b
Merge branch 'dev' into dev-eryondon-package-incompatible-allframworks
erdembayar Jan 12, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ public async Task<int> ExecuteCommand(PackageReferenceArgs packageReferenceArgs,
// Setup the Credential Service before making any potential http calls.
DefaultCredentialServiceUtility.SetupDefaultCredentialService(packageReferenceArgs.Logger, !packageReferenceArgs.Interactive);

if (packageReferenceArgs.Sources?.Any() == true)
{
// Convert relative path to absolute path if there is any
List<string> sources = new List<string>();

foreach (string source in packageReferenceArgs.Sources)
{
sources.Add(UriUtility.GetAbsolutePath(Environment.CurrentDirectory, source));
}

originalPackageSpec.RestoreMetadata.Sources =
sources.Where(ns => !string.IsNullOrEmpty(ns))
.Select(ns => new PackageSource(ns))
.ToList();
}

PackageDependency packageDependency = default;
if (packageReferenceArgs.NoVersion)
{
Expand Down Expand Up @@ -338,8 +354,8 @@ private static async Task<RestoreResultPair> PreviewAddPackageReferenceAsync(Pac
Log = packageReferenceArgs.Logger,
MachineWideSettings = new XPlatMachineWideSetting(),
GlobalPackagesFolder = packageReferenceArgs.PackageDirectory,
PreLoadedRequestProviders = providers,
Sources = packageReferenceArgs.Sources?.ToList()
PreLoadedRequestProviders = providers
// Sources : No need to pass it, because SourceRepositories contains the already built SourceRepository objects
};

// Generate Restore Requests. There will always be 1 request here since we are restoring for 1 project.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FluentAssertions;
using NuGet.Packaging;
using NuGet.Packaging.Core;
using NuGet.ProjectModel;
using NuGet.Test.Utility;
using NuGet.Versioning;
using NuGet.XPlat.FuncTest;
using Xunit;

namespace Dotnet.Integration.Test
{
[Collection("Dotnet Integration Tests")]
public class DotnetAddPackageTests
{
private readonly MsbuildIntegrationTestFixture _fixture;

public DotnetAddPackageTests(MsbuildIntegrationTestFixture fixture)
{
_fixture = fixture;
}

[Fact]
public async Task AddPkg_V3LocalSourceFeed_WithRelativePath_NoVersionSpecified_Success()
{
using (var pathContext = new SimpleTestPathContext())
{
var projectName = "projectA";
var targetFrameworks = "net5.0";
SimpleTestProjectContext projectA = XPlatTestUtils.CreateProject(projectName, pathContext, targetFrameworks);
var packageX = "packageX";
var packageX_V1 = new PackageIdentity(packageX, new NuGetVersion("1.0.0"));
var packageX_V2 = new PackageIdentity(packageX, new NuGetVersion("2.0.0"));
var packageFrameworks = "net472; netcoreapp2.0";
var packageX_V1_Context = XPlatTestUtils.CreatePackage(packageX_V1.Id, packageX_V1.Version.Version.ToString(), frameworkString: packageFrameworks);
var packageX_V2_Context = XPlatTestUtils.CreatePackage(packageX_V2.Id, packageX_V2.Version.Version.ToString(), frameworkString: packageFrameworks);
var customSourcePath = Path.Combine(pathContext.WorkingDirectory, "Custompackages");
var sourceRelativePath = Path.Combine("..", "..", "Custompackages");

// Generate Package
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
customSourcePath,
PackageSaveMode.Defaultv3,
new SimpleTestPackageContext[] { packageX_V1_Context, packageX_V2_Context });

var projectDirectory = Path.Combine(pathContext.SolutionRoot, projectName);
var projectFilePath = Path.Combine(projectDirectory, $"{projectName}.csproj");

// Act
CommandRunnerResult result = _fixture.RunDotnet(projectDirectory, $"add {projectFilePath} package {packageX} -s {sourceRelativePath}", ignoreExitCode: true);

// Assert
result.Success.Should().BeTrue(because: result.AllOutput);

// Make sure source is replaced in generated dgSpec file.
PackageSpec packageSpec = projectA.AssetsFile.PackageSpec;
string[] sources = packageSpec.RestoreMetadata.Sources.Select(s => s.Name).ToArray();
Assert.Equal(sources.Count(), 1);
Assert.Equal(sources[0], customSourcePath);

var ridlessTarget = projectA.AssetsFile.Targets.Where(e => string.IsNullOrEmpty(e.RuntimeIdentifier)).Single();
ridlessTarget.Libraries.Should().Contain(e => e.Type == "package" && e.Name == packageX);
// Should resolve to specified package.
ridlessTarget.Libraries.Should().Contain(e => e.Version.Equals(packageX_V2.Version));
}
}

[Fact]
public async Task AddPkg_V3LocalSourceFeed_WithRelativePath_NoVersionSpecified_Fail()
{
using (var pathContext = new SimpleTestPathContext())
{
var projectName = "projectA";
var targetFrameworks = "net5.0";
XPlatTestUtils.CreateProject(projectName, pathContext, targetFrameworks);
var packageX = "packageX";
var packageY = "packageY";
var packageY_V1 = new PackageIdentity(packageY, new NuGetVersion("1.0.0"));
var packageFrameworks = "net472; netcoreapp2.0";
var packageY_V1_Context = XPlatTestUtils.CreatePackage(packageY_V1.Id, packageY_V1.Version.Version.ToString(), frameworkString: packageFrameworks);
var customSourcePath = Path.Combine(pathContext.WorkingDirectory, "Custompackages");
var sourceRelativePath = Path.Combine("..", "..", "Custompackages");

// Generate Package
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
customSourcePath,
PackageSaveMode.Defaultv3,
new SimpleTestPackageContext[] { packageY_V1_Context });

var projectDirectory = Path.Combine(pathContext.SolutionRoot, projectName);
var projectFilePath = Path.Combine(projectDirectory, $"{projectName}.csproj");

// Act
CommandRunnerResult result = _fixture.RunDotnet(projectDirectory, $"add {projectFilePath} package {packageX} -s {sourceRelativePath}", ignoreExitCode: true);

// Assert
result.Success.Should().BeFalse(because: result.AllOutput);
}
}

[Fact]
public async Task AddPkg_V3LocalSourceFeed_WithRelativePath_VersionSpecified_Success()
{
using (var pathContext = new SimpleTestPathContext())
{
var projectName = "projectA";
var targetFrameworks = "net5.0";
SimpleTestProjectContext projectA = XPlatTestUtils.CreateProject(projectName, pathContext, targetFrameworks);
var packageX = "packageX";
var packageX_V1 = new PackageIdentity(packageX, new NuGetVersion("1.0.0"));
var packageX_V2 = new PackageIdentity(packageX, new NuGetVersion("2.0.0"));
var packageFrameworks = "net472; netcoreapp2.0";
var packageX_V1_Context = XPlatTestUtils.CreatePackage(packageX_V1.Id, packageX_V1.Version.Version.ToString(), frameworkString: packageFrameworks);
var packageX_V2_Context = XPlatTestUtils.CreatePackage(packageX_V2.Id, packageX_V2.Version.Version.ToString(), frameworkString: packageFrameworks);
var customSourcePath = Path.Combine(pathContext.WorkingDirectory, "Custompackages");
var sourceRelativePath = Path.Combine("..", "..", "Custompackages");

// Generate Package
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
customSourcePath,
PackageSaveMode.Defaultv3,
new SimpleTestPackageContext[] { packageX_V1_Context, packageX_V2_Context });

var projectDirectory = Path.Combine(pathContext.SolutionRoot, projectName);
var projectFilePath = Path.Combine(projectDirectory, $"{projectName}.csproj");

// Act
CommandRunnerResult result = _fixture.RunDotnet(projectDirectory, $"add {projectFilePath} package {packageX} -s {sourceRelativePath} -v {packageX_V1.Version}", ignoreExitCode: true);

// Assert
result.Success.Should().BeTrue(because: result.AllOutput);

// Make sure source is replaced in generated dgSpec file.
PackageSpec packageSpec = projectA.AssetsFile.PackageSpec;
string[] sources = packageSpec.RestoreMetadata.Sources.Select(s => s.Name).ToArray();
Assert.Equal(sources.Count(), 1);
Assert.Equal(sources[0], customSourcePath);

var ridlessTarget = projectA.AssetsFile.Targets.Where(e => string.IsNullOrEmpty(e.RuntimeIdentifier)).Single();
ridlessTarget.Libraries.Should().Contain(e => e.Type == "package" && e.Name == packageX);
// Should resolve to specified package.
ridlessTarget.Libraries.Should().Contain(e => e.Version.Equals(packageX_V1.Version));
}
}

[Fact]
public async Task AddPkg_V3LocalSourceFeed_WithRelativePath_VersionSpecified_Fail()
{
using (var pathContext = new SimpleTestPathContext())
{
var projectName = "projectA";
var targetFrameworks = "net5.0";
SimpleTestProjectContext projectA = XPlatTestUtils.CreateProject(projectName, pathContext, targetFrameworks);
var packageX = "packageX";
var packageX_V1 = new PackageIdentity(packageX, new NuGetVersion("1.0.0"));
var packageX_V2 = new PackageIdentity(packageX, new NuGetVersion("2.0.0"));
var packageFrameworks = "net472; netcoreapp2.0";
var packageX_V1_Context = XPlatTestUtils.CreatePackage(packageX_V1.Id, packageX_V1.Version.Version.ToString(), frameworkString: packageFrameworks);
var customSourcePath = Path.Combine(pathContext.WorkingDirectory, "Custompackages");
var sourceRelativePath = Path.Combine("..", "..", "Custompackages");

// Generate Package
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
customSourcePath,
PackageSaveMode.Defaultv3,
new SimpleTestPackageContext[] { packageX_V1_Context });

var projectDirectory = Path.Combine(pathContext.SolutionRoot, projectName);
var projectFilePath = Path.Combine(projectDirectory, $"{projectName}.csproj");

// Act
CommandRunnerResult result = _fixture.RunDotnet(projectDirectory, $"add {projectFilePath} package {packageX} -s {sourceRelativePath} -v {packageX_V2.Version}", ignoreExitCode: true);

// Assert
result.Success.Should().BeFalse(because: result.AllOutput);
}
}

[Fact]
public async Task AddPkg_V3LocalSourceFeed_WithDefaultSolutiuonSource_NoVersionSpecified_Success()
{
using (var pathContext = new SimpleTestPathContext())
{
var projectName = "projectA";
var targetFrameworks = "net5.0";
SimpleTestProjectContext projectA = XPlatTestUtils.CreateProject(projectName, pathContext, targetFrameworks);
var packageY = "packageY";
var packageY_V1 = new PackageIdentity(packageY, new NuGetVersion("1.0.0"));
var packageY_V2 = new PackageIdentity(packageY, new NuGetVersion("2.0.0"));
var packageFrameworks = "net472; netcoreapp2.0";
var packageY_V1_Context = XPlatTestUtils.CreatePackage(packageY_V1.Id, packageY_V1.Version.Version.ToString(), frameworkString: packageFrameworks);
var packageY_V2_Context = XPlatTestUtils.CreatePackage(packageY_V2.Id, packageY_V2.Version.Version.ToString(), frameworkString: packageFrameworks);

// Generate V3 Package
await SimpleTestPackageUtility.CreateFolderFeedV3Async(
pathContext.PackageSource, // using default solution source folder, not passing source as parameter.
PackageSaveMode.Defaultv3,
new SimpleTestPackageContext[] { packageY_V1_Context, packageY_V2_Context });

var projectDirectory = Path.Combine(pathContext.SolutionRoot, projectName);
var projectFilePath = Path.Combine(projectDirectory, $"{projectName}.csproj");

// Act
CommandRunnerResult result = _fixture.RunDotnet(projectDirectory, $"add {projectFilePath} package {packageY}", ignoreExitCode: true);

// Assert
result.Success.Should().BeTrue(because: result.AllOutput);

// Make sure source is replaced in generated dgSpec file.
PackageSpec packageSpec = projectA.AssetsFile.PackageSpec;
string[] sources = packageSpec.RestoreMetadata.Sources.Select(s => s.Name).ToArray();
Assert.Equal(sources.Count(), 1);
Assert.Equal(sources[0], pathContext.PackageSource);

var ridlessTarget = projectA.AssetsFile.Targets.Where(e => string.IsNullOrEmpty(e.RuntimeIdentifier)).Single();
// Should resolve to specified package.
ridlessTarget.Libraries.Should().Contain(e => e.Type == "package" && e.Name == packageY);
// Should resolve to highest available version.
ridlessTarget.Libraries.Should().Contain(e => e.Version.Equals(packageY_V2.Version));
}
}
}
}
Loading