Skip to content

Commit 1d33db8

Browse files
authored
Merge pull request #2943 from TheCakeIsNaOH/relative-path-source
(#508) Attempt to resolve relative paths for sources
2 parents d700d5c + 0e7b369 commit 1d33db8

File tree

7 files changed

+165
-31
lines changed

7 files changed

+165
-31
lines changed

Diff for: src/chocolatey.tests.integration/scenarios/InfoScenarios.cs

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ namespace chocolatey.tests.integration.scenarios
1010
using chocolatey.infrastructure.app.configuration;
1111
using chocolatey.infrastructure.app.services;
1212
using chocolatey.infrastructure.commands;
13+
using chocolatey.infrastructure.platforms;
1314
using chocolatey.infrastructure.results;
1415

1516
using NuGet;
@@ -67,7 +68,6 @@ public override void Because()
6768
}
6869
}
6970

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

9696
MockLogger.Messages.Keys.ShouldContain(LogLevel.Info.to_string());
97-
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));
97+
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));
9898
}
9999

100100
[Fact]
@@ -105,7 +105,6 @@ public void should_log_package_count_as_warning()
105105
}
106106
}
107107

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

145144
MockLogger.Messages.Keys.ShouldContain(LogLevel.Info.to_string());
146-
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));
145+
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));
147146
}
148147

149148
[Fact]
@@ -154,7 +153,6 @@ public override void Because()
154153
}
155154
}
156155

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

199199
[Fact]

Diff for: src/chocolatey.tests/infrastructure.app/nuget/NugetCommonSpecs.cs

+102-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ namespace chocolatey.tests.infrastructure.app.nuget
2121
using System.Linq;
2222
using chocolatey.infrastructure.app.configuration;
2323
using chocolatey.infrastructure.app.nuget;
24+
using chocolatey.infrastructure.filesystem;
2425
using Moq;
2526
using NuGet.Common;
2627
using NuGet.Packaging;
@@ -35,6 +36,7 @@ private class when_gets_remote_repository : TinySpec
3536
private Action because;
3637
private readonly Mock<ILogger> nugetLogger = new Mock<ILogger>();
3738
private readonly Mock<IPackageDownloader> packageDownloader = new Mock<IPackageDownloader>();
39+
private readonly Mock<IFileSystem> filesystem = new Mock<IFileSystem>();
3840
private ChocolateyConfiguration configuration;
3941
private IEnumerable<SourceRepository> packageRepositories;
4042

@@ -43,11 +45,17 @@ public override void Context()
4345
configuration = new ChocolateyConfiguration();
4446
nugetLogger.ResetCalls();
4547
packageDownloader.ResetCalls();
48+
filesystem.ResetCalls();
49+
50+
filesystem.Setup(f => f.get_full_path(It.IsAny<string>())).Returns((string a) =>
51+
{
52+
return "C:\\packages\\" + a;
53+
});
4654
}
4755

4856
public override void Because()
4957
{
50-
because = () => packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger.Object);
58+
because = () => packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger.Object, filesystem.Object);
5159
}
5260

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

6169
packageRepositories.Count().ShouldEqual(0);
6270
}
71+
72+
[Fact]
73+
public void should_parse_http_source()
74+
{
75+
Context();
76+
var source = "http://nexus.example.com:8081/repository/choco";
77+
configuration.Sources = source;
78+
configuration.CacheLocation = "C:\\temp";
79+
80+
because();
81+
82+
packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
83+
packageRepositories.First().PackageSource.SourceUri.to_string().ShouldEqual(source);
84+
packageRepositories.First().PackageSource.IsHttp.ShouldBeTrue();
85+
}
86+
87+
[Fact]
88+
public void should_parse_https_source()
89+
{
90+
Context();
91+
var source = "https://nexus.example.com/repository/choco";
92+
configuration.Sources = source;
93+
configuration.CacheLocation = "C:\\temp";
94+
95+
because();
96+
97+
packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
98+
packageRepositories.First().PackageSource.SourceUri.to_string().ShouldEqual(source);
99+
packageRepositories.First().PackageSource.IsHttps.ShouldBeTrue();
100+
}
101+
102+
[Fact]
103+
public void should_parse_absolute_path_source()
104+
{
105+
Context();
106+
var source = "C:\\packages";
107+
configuration.Sources = source;
108+
109+
because();
110+
111+
packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
112+
packageRepositories.First().PackageSource.SourceUri.to_string()
113+
.ShouldEqual(("file:///" + source).Replace("\\","/"));
114+
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
115+
}
116+
117+
[Fact]
118+
public void should_parse_relative_path_source()
119+
{
120+
Context();
121+
var source = "choco";
122+
var fullsource = "C:\\packages\\choco";
123+
configuration.Sources = source;
124+
125+
because();
126+
127+
packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
128+
packageRepositories.First().PackageSource.SourceUri.to_string()
129+
.ShouldEqual(("file:///" + fullsource).Replace("\\", "/"));
130+
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
131+
}
132+
133+
[Fact]
134+
public void should_parse_dot_relative_path_source()
135+
{
136+
Context();
137+
var source = ".";
138+
var fullsource = "C:\\packages";
139+
configuration.Sources = source;
140+
141+
because();
142+
143+
packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
144+
packageRepositories.First().PackageSource.SourceUri.to_string()
145+
.ShouldEqual(("file:///" + fullsource + "/").Replace("\\", "/"));
146+
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
147+
}
148+
149+
[Fact]
150+
public void should_parse_unc_source()
151+
{
152+
Context();
153+
var source = "\\\\samba-server\\choco-share";
154+
configuration.Sources = source;
155+
156+
because();
157+
158+
packageRepositories.First().PackageSource.TrySourceAsUri.ShouldNotBeNull();
159+
packageRepositories.First().PackageSource.SourceUri.to_string()
160+
.ShouldEqual(("file:" + source).Replace("\\", "/"));
161+
packageRepositories.First().PackageSource.IsLocal.ShouldBeTrue();
162+
packageRepositories.First().PackageSource.SourceUri.IsUnc.ShouldBeTrue();
163+
}
63164
}
64165
}
65166
}

Diff for: src/chocolatey/infrastructure.app/nuget/NugetCommon.cs

+34-3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ namespace chocolatey.infrastructure.app.nuget
2323
using System.Net;
2424
using System.Net.Http;
2525
using System.Net.Security;
26+
using System.Runtime.CompilerServices;
2627
using System.Security.Cryptography.X509Certificates;
2728
using System.Text;
2829
using System.Threading;
@@ -92,7 +93,7 @@ public static IPackageRepository GetLocalRepository(IPackagePathResolver pathRes
9293
}
9394
*/
9495

95-
public static IEnumerable<SourceRepository> GetRemoteRepositories(ChocolateyConfiguration configuration, ILogger nugetLogger)
96+
public static IEnumerable<SourceRepository> GetRemoteRepositories(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
9697
{
9798

9899
//TODO, fix
@@ -185,9 +186,39 @@ public static IEnumerable<SourceRepository> GetRemoteRepositories(ChocolateyConf
185186
}
186187
}
187188

188-
updatedSources.AppendFormat("{0};", source);
189-
190189
var nugetSource = new PackageSource(source);
190+
191+
// If not parsed as a http(s) or local source, let's try resolving the path
192+
// Since NuGet.Client is not able to parse all relative paths
193+
// Conversion to absolute paths is handled by clients, not by the libraries as per
194+
// https://github.com/NuGet/NuGet.Client/pull/3783
195+
if (nugetSource.TrySourceAsUri is null)
196+
{
197+
string fullsource;
198+
try
199+
{
200+
fullsource = filesystem.get_full_path(source);
201+
}
202+
catch
203+
{
204+
// If an invalid source was passed in, we don't care here, pass it along
205+
fullsource = source;
206+
}
207+
nugetSource = new PackageSource(fullsource);
208+
209+
if (!nugetSource.IsLocal)
210+
{
211+
throw new ApplicationException("Source '{0}' is unable to be parsed".format_with(source));
212+
}
213+
214+
"chocolatey".Log().Debug("Updating Source path from {0} to {1}".format_with(source, fullsource));
215+
updatedSources.AppendFormat("{0};", fullsource);
216+
}
217+
else
218+
{
219+
updatedSources.AppendFormat("{0};", source);
220+
}
221+
191222
nugetSource.ClientCertificates = sourceClientCertificates;
192223
var repo = Repository.Factory.GetCoreV3(nugetSource);
193224

Diff for: src/chocolatey/infrastructure.app/nuget/NugetList.cs

+7-6
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace chocolatey.infrastructure.app.nuget
2626
using System.Threading;
2727
using System.Threading.Tasks;
2828
using configuration;
29+
using filesystem;
2930
using NuGet.Common;
3031
using NuGet.Configuration;
3132
using NuGet.PackageManagement;
@@ -39,19 +40,19 @@ namespace chocolatey.infrastructure.app.nuget
3940

4041
public static class NugetList
4142
{
42-
public static IEnumerable<IPackageSearchMetadata> GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger)
43+
public static IEnumerable<IPackageSearchMetadata> GetPackages(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
4344
{
44-
return execute_package_search(configuration, nugetLogger).GetAwaiter().GetResult();
45+
return execute_package_search(configuration, nugetLogger, filesystem).GetAwaiter().GetResult();
4546
}
4647

47-
public static int GetCount(ChocolateyConfiguration configuration, ILogger nugetLogger)
48+
public static int GetCount(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
4849
{
49-
return execute_package_search(configuration, nugetLogger).GetAwaiter().GetResult().Count();
50+
return execute_package_search(configuration, nugetLogger, filesystem).GetAwaiter().GetResult().Count();
5051
}
5152

52-
private async static Task<IQueryable<IPackageSearchMetadata>> execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger)
53+
private async static Task<IQueryable<IPackageSearchMetadata>> execute_package_search(ChocolateyConfiguration configuration, ILogger nugetLogger, IFileSystem filesystem)
5354
{
54-
var packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger);
55+
var packageRepositories = NugetCommon.GetRemoteRepositories(configuration, nugetLogger, filesystem);
5556
var packageRepositoriesResources = NugetCommon.GetRepositoryResources(packageRepositories);
5657
string searchTermLower = configuration.Input.to_lower();
5758
SearchFilter searchFilter = new SearchFilter(configuration.Prerelease);

Diff for: src/chocolatey/infrastructure.app/nuget/NugetPush.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,15 @@ namespace chocolatey.infrastructure.app.nuget
2222
using System.Collections.Generic;
2323
using System.Linq;
2424
using System.Threading.Tasks;
25+
using filesystem;
2526
using NuGet.Common;
2627
using NuGet.Configuration;
2728
using NuGet.Protocol;
2829
using NuGet.Protocol.Core.Types;
2930

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

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

0 commit comments

Comments
 (0)