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

(#508) Attempt to resolve relative paths for sources #2943

Merged
merged 4 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 6 additions & 6 deletions src/chocolatey.tests.integration/scenarios/InfoScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace chocolatey.tests.integration.scenarios
using chocolatey.infrastructure.app.configuration;
using chocolatey.infrastructure.app.services;
using chocolatey.infrastructure.commands;
using chocolatey.infrastructure.platforms;
using chocolatey.infrastructure.results;

using NuGet;
Expand Down Expand Up @@ -67,7 +68,6 @@ public override void Because()
}
}

[Broken, Pending("Need to be fixed in either NuGet.Client or before calling code in NuGet.Client")]
public class when_searching_for_exact_package_through_command : CommandScenariosBase
{
public override void Context()
Expand All @@ -94,7 +94,7 @@ public void should_log_package_information()
.ToShortDateString();

MockLogger.Messages.Keys.ShouldContain(LogLevel.Info.to_string());
MockLogger.Messages[LogLevel.Info.to_string()].ShouldContain(" Title: installpackage | Published: 14.12.2022\r\n Number of Downloads: n/a | Downloads for this version: n/a\r\n Package url\r\n Chocolatey Package Source: n/a\r\n Tags: installpackage admin\r\n Software Site: n/a\r\n Software License: n/a\r\n Summary: __REPLACE__\r\n Description: __REPLACE__\r\n".format_with(lastWriteDate));
MockLogger.Messages[LogLevel.Info.to_string()].ShouldContain(" Title: installpackage | Published: {0}\r\n Number of Downloads: n/a | Downloads for this version: n/a\r\n Package url\r\n Chocolatey Package Source: n/a\r\n Tags: installpackage admin\r\n Software Site: n/a\r\n Software License: n/a\r\n Summary: __REPLACE__\r\n Description: __REPLACE__\r\n".format_with(lastWriteDate));
}

[Fact]
Expand All @@ -105,7 +105,6 @@ public void should_log_package_count_as_warning()
}
}

[Broken, Pending("Need to be fixed in either NuGet.Client or before calling code in NuGet.Client")]
public class when_searching_for_exact_package_with_dot_relative_path_source : when_searching_for_exact_package_through_command
{
public override void Context()
Expand Down Expand Up @@ -143,7 +142,7 @@ public override void Because()
.ToShortDateString();

MockLogger.Messages.Keys.ShouldContain(LogLevel.Info.to_string());
MockLogger.Messages[LogLevel.Info.to_string()].ShouldContain(" Title: installpackage | Published: 14.12.2022\r\n Number of Downloads: n/a | Downloads for this version: n/a\r\n Package url\r\n Chocolatey Package Source: n/a\r\n Tags: installpackage admin\r\n Software Site: n/a\r\n Software License: n/a\r\n Summary: __REPLACE__\r\n Description: __REPLACE__\r\n".format_with(lastWriteDate));
MockLogger.Messages[LogLevel.Info.to_string()].ShouldContain(" Title: installpackage | Published: {0}\r\n Number of Downloads: n/a | Downloads for this version: n/a\r\n Package url\r\n Chocolatey Package Source: n/a\r\n Tags: installpackage admin\r\n Software Site: n/a\r\n Software License: n/a\r\n Summary: __REPLACE__\r\n Description: __REPLACE__\r\n".format_with(lastWriteDate));
}

[Fact]
Expand All @@ -154,7 +153,6 @@ public override void Because()
}
}

[Broken, Pending("Need to be fixed in either NuGet.Client or before calling code in NuGet.Client")]
public class when_searching_for_exact_package_with_verbose_output : ScenariosBase
{
public override void Context()
Expand Down Expand Up @@ -193,7 +191,9 @@ public void should_report_expected_name()
[Fact]
public void should_set_source_to_expected_value()
{
Results[0].Source.ShouldEqual("PackageOutput");
Results[0].Source.ShouldEqual(
((Platform.get_platform() == PlatformType.Windows ? "file:///" : "file://") + Path.Combine(Environment.CurrentDirectory, "PackageOutput"))
.Replace("\\","/"));
}

[Fact]
Expand Down
103 changes: 102 additions & 1 deletion src/chocolatey.tests/infrastructure.app/nuget/NugetCommonSpecs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace chocolatey.tests.infrastructure.app.nuget
using System.Linq;
using chocolatey.infrastructure.app.configuration;
using chocolatey.infrastructure.app.nuget;
using chocolatey.infrastructure.filesystem;
using Moq;
using NuGet.Common;
using NuGet.Packaging;
Expand All @@ -35,6 +36,7 @@ private class when_gets_remote_repository : TinySpec
private Action because;
private readonly Mock<ILogger> nugetLogger = new Mock<ILogger>();
private readonly Mock<IPackageDownloader> packageDownloader = new Mock<IPackageDownloader>();
private readonly Mock<IFileSystem> filesystem = new Mock<IFileSystem>();
private ChocolateyConfiguration configuration;
private IEnumerable<SourceRepository> packageRepositories;

Expand All @@ -43,11 +45,17 @@ public override void Context()
configuration = new ChocolateyConfiguration();
nugetLogger.ResetCalls();
packageDownloader.ResetCalls();
filesystem.ResetCalls();

filesystem.Setup(f => f.get_full_path(It.IsAny<string>())).Returns((string a) =>
{
return "C:\\packages\\" + a;
});
}

public override void Because()
{
because = () => packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger.Object);
because = () => packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger.Object, filesystem.Object);
}

[Fact]
Expand All @@ -60,6 +68,99 @@ public void should_create_repository_when_source_is_null()

packageRepositories.Count().ShouldEqual(0);
}

[Fact]
public void should_parse_http_source()
{
Context();
var source = "http://nexus.example.com:8081/repository/choco";
configuration.Sources = source;
configuration.CacheLocation = "C:\\temp";

because();

packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
packageRepositories.First().PackageSource.SourceUri.to_string().ShouldEqual(source);
packageRepositories.First().PackageSource.IsHttp.ShouldBeTrue();
}

[Fact]
public void should_parse_https_source()
{
Context();
var source = "https://nexus.example.com/repository/choco";
configuration.Sources = source;
configuration.CacheLocation = "C:\\temp";

because();

packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
packageRepositories.First().PackageSource.SourceUri.to_string().ShouldEqual(source);
packageRepositories.First().PackageSource.IsHttps.ShouldBeTrue();
}

[Fact]
public void should_parse_absolute_path_source()
{
Context();
var source = "C:\\packages";
configuration.Sources = source;

because();

packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
packageRepositories.First().PackageSource.SourceUri.to_string()
.ShouldEqual(("file:///" + source).Replace("\\","/"));
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
}

[Fact]
public void should_parse_relative_path_source()
{
Context();
var source = "choco";
var fullsource = "C:\\packages\\choco";
configuration.Sources = source;

because();

packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
packageRepositories.First().PackageSource.SourceUri.to_string()
.ShouldEqual(("file:///" + fullsource).Replace("\\", "/"));
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
}

[Fact]
public void should_parse_dot_relative_path_source()
{
Context();
var source = ".";
var fullsource = "C:\\packages";
configuration.Sources = source;

because();

packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
packageRepositories.First().PackageSource.SourceUri.to_string()
.ShouldEqual(("file:///" + fullsource + "/").Replace("\\", "/"));
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
}

[Fact]
public void should_parse_unc_source()
{
Context();
var source = "\\\\samba-server\\choco-share";
configuration.Sources = source;

because();

packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
packageRepositories.First().PackageSource.SourceUri.to_string()
.ShouldEqual(("file:" + source).Replace("\\", "/"));
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
packageRepositories.First().PackageSource.SourceUri.IsUnc.ShouldBeTrue();
}
}
}
}
37 changes: 34 additions & 3 deletions src/chocolatey/infrastructure.app/nuget/NugetCommon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace chocolatey.infrastructure.app.nuget
using System.Net;
using System.Net.Http;
using System.Net.Security;
using System.Runtime.CompilerServices;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
Expand Down Expand Up @@ -92,7 +93,7 @@ public static IPackageRepository GetLocalRepository(IPackagePathResolver pathRes
}
*/

public static IEnumerable<SourceRepository> GetRemoteRepositories(ChocolateyConfiguration configuration, ILogger nugetLogger)
public static IEnumerable<SourceRepository> GetRemoteRepositories(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
{

//TODO, fix
Expand Down Expand Up @@ -185,9 +186,39 @@ public static IEnumerable<SourceRepository> GetRemoteRepositories(ChocolateyConf
}
}

updatedSources.AppendFormat("{0};", source);

var nugetSource = new PackageSource(source);

// If not parsed as a http(s) or local source, let's try resolving the path
// Since NuGet.Client is not able to parse all relative paths
// Conversion to absolute paths is handled by clients, not by the libraries as per
// https://github.com/NuGet/NuGet.Client/pull/3783
if (nugetSource.TrySourceAsUri is null)
{
string fullsource;
try
{
fullsource = filesystem.get_full_path(source);
}
catch
{
// If an invalid source was passed in, we don't care here, pass it along
fullsource = source;
}
nugetSource = new PackageSource(fullsource);

if (!nugetSource.IsLocal)
{
throw new ApplicationException("Source '{0}' is unable to be parsed".format_with(source));
}

"chocolatey".Log().Debug("Updating Source path from {0} to {1}".format_with(source, fullsource));
updatedSources.AppendFormat("{0};", fullsource);
}
else
{
updatedSources.AppendFormat("{0};", source);
}

nugetSource.ClientCertificates = sourceClientCertificates;
var repo = Repository.Factory.GetCoreV3(nugetSource);

Expand Down
13 changes: 7 additions & 6 deletions src/chocolatey/infrastructure.app/nuget/NugetList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ namespace chocolatey.infrastructure.app.nuget
using System.Threading;
using System.Threading.Tasks;
using configuration;
using filesystem;
using NuGet.Common;
using NuGet.Configuration;
using NuGet.PackageManagement;
Expand All @@ -39,19 +40,19 @@ namespace chocolatey.infrastructure.app.nuget

public static class NugetList
{
public static IEnumerable<IPackageSearchMetadata> GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger)
public static IEnumerable<IPackageSearchMetadata> GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
{
return execute_package_search(configuration, nugetLogger).GetAwaiter().GetResult();
return execute_package_search(configuration, nugetLogger, filesystem).GetAwaiter().GetResult();
}

public static int GetCount(ChocolateyConfiguration configuration, ILogger nugetLogger)
public static int GetCount(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
{
return execute_package_search(configuration, nugetLogger).GetAwaiter().GetResult().Count();
return execute_package_search(configuration, nugetLogger, filesystem).GetAwaiter().GetResult().Count();
}

private async static Task<IQueryable<IPackageSearchMetadata>> execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger)
private async static Task<IQueryable<IPackageSearchMetadata>> execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
{
var packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger);
var packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger, filesystem);
var packageRepositoriesResources = NugetCommon.GetRepositoryResources(packageRepositories);
string searchTermLower = configuration.Input.to_lower();
SearchFilter searchFilter = new SearchFilter(configuration.Prerelease);
Expand Down
5 changes: 3 additions & 2 deletions src/chocolatey/infrastructure.app/nuget/NugetPush.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ namespace chocolatey.infrastructure.app.nuget
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using filesystem;
using NuGet.Common;
using NuGet.Configuration;
using NuGet.Protocol;
using NuGet.Protocol.Core.Types;

public class NugetPush
{
public static void push_package(ChocolateyConfiguration config, string nupkgFilePath, ILogger nugetLogger, string nupkgFileName)
public static void push_package(ChocolateyConfiguration config, string nupkgFilePath, ILogger nugetLogger, string nupkgFileName, IFileSystem filesystem)
{
var timeout = TimeSpan.FromSeconds(Math.Abs(config.CommandExecutionTimeoutSeconds));
if (timeout.Seconds <= 0)
Expand All @@ -42,7 +43,7 @@ public static void push_package(ChocolateyConfiguration config, string nupkgFile
const bool noServiceEndpoint = true;

//OK to use FirstOrDefault in this case as the command validates that there is only one source
SourceRepository sourceRepository = NugetCommon.GetRemoteRepositories(config, nugetLogger).FirstOrDefault();
SourceRepository sourceRepository = NugetCommon.GetRemoteRepositories(config, nugetLogger, filesystem).FirstOrDefault();
PackageUpdateResource packageUpdateResource = sourceRepository.GetResource<PackageUpdateResource>();
var nupkgFilePaths = new List<string>() { nupkgFilePath };
UserAgent.SetUserAgentString(new UserAgentStringBuilder("{0}/{1} via NuGet Client".format_with(ApplicationParameters.UserAgent, config.Information.ChocolateyProductVersion)));
Expand Down
Loading