Skip to content
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
1 change: 1 addition & 0 deletions .teamcity/settings.kts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@ object ChocolateyPosix : BuildType({
params {
param("env.CAKE_NUGET_SOURCE", "") // The Cake version we use has issues with authing to our private source on Linux
param("env.PRIMARY_NUGET_SOURCE", "") // As above there are issues with authing to our private source on Linux
param("env.NUGETDEVRESTORE_SOURCE", "") // As above there are issues with authing to our private source on Linux
param("env.CHOCOLATEY_VERSION", "%dep.Chocolatey.build.number%")
param("env.CHOCOLATEY_OFFICIAL_KEY", "%system.teamcity.build.checkoutDir%/chocolatey.official.snk")
password("env.GITHUB_PAT", "%system.GitHubPAT%", display = ParameterDisplay.HIDDEN, readOnly = true)
Expand Down
Binary file modified docs/legal/CREDITS.pdf
Comment thread
st3phhays marked this conversation as resolved.
Binary file not shown.
18 changes: 12 additions & 6 deletions src/chocolatey.tests.integration/Scenario.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,22 @@ public static void InstallPackage(ChocolateyConfiguration config, string package
NUnitSetup.MockLogger.Messages.Clear();
}

public static void AddFiles(IEnumerable<Tuple<string, string>> files)
public static void AddFiles(IEnumerable<(string name, string content)> files)
{
foreach (var file in files)
{
if (_fileSystem.FileExists(file.Item1))
{
_fileSystem.DeleteFile(file.Item1);
}
_fileSystem.WriteFile(file.Item1, file.Item2);
AddFile(file.name, file.content);
}
}

public static void AddFile(string name, string content)
{
if (_fileSystem.FileExists(name))
{
_fileSystem.DeleteFile(name);
}

_fileSystem.WriteFile(name, content);
}

public static void CreateDirectory(string directoryPath)
Expand Down
73 changes: 73 additions & 0 deletions src/chocolatey.tests.integration/scenarios/InstallScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4208,6 +4208,79 @@ public void Should_have_executed_chocolateyInstall_script()
}
}

public class When_installing_a_package_with_corrupt_local_package_already_on_disk : ScenariosBase
{
private PackageResult _packageResult;

public override void Context()
{
base.Context();

var corruptPackageFolder = Path.Combine(Scenario.GetPackageInstallPath(), Configuration.PackageNames);
Scenario.CreateDirectory(corruptPackageFolder);

// Add a corrupt nuspec (full of null bytes) as an "already installed, but corrupted" package.
// The nupkg is intentionally missing here, since NuGet doesn't recognise the package as being "installed"
// even if files are present at the target install location, so it will blindly attempt to install a package.
var corruptNuspec = Path.Combine(corruptPackageFolder, Configuration.PackageNames + ".nuspec");
Scenario.AddFile(corruptNuspec, new string((char)0, 1024));
}

public override void Because()
{
Results = Service.Install(Configuration);
_packageResult = Results.FirstOrDefault().Value;
}

[Fact]
public void Should_not_install_where_install_location_reports()
{
Assert.That(_packageResult.InstallLocation ?? string.Empty, Is.Not.EqualTo(string.Empty));
Assert.That(_packageResult.InstallLocation, Does.Not.Exist);
}

[Fact]
public void Should_move_the_package_to_lib_bad_directory()
{
var packageDir = Path.Combine(Scenario.GetTopLevel(), "lib-bad", Configuration.PackageNames);

Assert.That(packageDir, Does.Exist);
}


[Fact]
public void Should_contain_a_warning_message_that_it_did_not_install_successfully()
{
MockLogger.Messages.Should().ContainKey(LogLevel.Warn.ToStringSafe())
.WhoseValue.Should().Contain(m => m.Contains("0/1"));
}


[Fact]
public void Should_not_have_a_successful_package_result()
{
_packageResult.Success.Should().BeFalse();
}

[Fact]
public void Should_not_have_inconclusive_package_result()
{
_packageResult.Inconclusive.Should().BeFalse();
}

[Fact]
public void Config_should_match_package_result_name()
{
_packageResult.Name.Should().Be(Configuration.PackageNames);
}

[Fact]
public void Should_have_an_empty_version_string()
{
_packageResult.Version.Should().Be(string.Empty);
}
}

public class When_installing_a_package_with_non_normalized_version : ScenariosBase
{
private PackageResult _packageResult;
Expand Down
6 changes: 3 additions & 3 deletions src/chocolatey.tests.integration/scenarios/PackScenarios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public override void BeforeEachSpec()

protected void AddFile(string fileName, string fileContent)
{
Scenario.AddFiles(new[] { new Tuple<string, string>(fileName, fileContent) });
Scenario.AddFile(fileName, fileContent);
}
}

Expand Down Expand Up @@ -136,7 +136,7 @@ public override void Context()
{
Configuration = Scenario.Pack();
Scenario.Reset(Configuration);
Scenario.AddFiles(new[] { new Tuple<string, string>("myPackage.nuspec", GetNuspecContent()) });
Scenario.AddFile("myPackage.nuspec", GetNuspecContent());

if (!string.IsNullOrEmpty(ExpectedSubDirectory))
{
Expand Down Expand Up @@ -600,7 +600,7 @@ public override void Context()
Scenario.Reset(Configuration);
Configuration.Version = "0.1.0";
Configuration.PackCommand.Properties.Add("commitId", "1234abcd");
Scenario.AddFiles(new[] { new Tuple<string, string>("myPackage.nuspec", NuspecContentWithVariables) });
Scenario.AddFile("myPackage.nuspec", NuspecContentWithVariables);
}

public override void Because()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1823,7 +1823,11 @@ private void MovePackageToFailedPackagesLocation(PackageResult packageResult)

if (!string.IsNullOrWhiteSpace(packageResult.InstallLocation) && _fileSystem.DirectoryExists(packageResult.InstallLocation))
{
var normalizedVersion = new NuGetVersion(packageResult.Version).ToNormalizedStringChecked();
// If there's no version information (certain edge cases on package install errors), fallback to an unknown version with a timestamp
// so this can't fail out unexpectedly.
var normalizedVersion = string.IsNullOrEmpty(packageResult.Version)
? "unknown-{0}".FormatWith(DateTime.UtcNow.ToString("yyyy-MM-dd-HH-mm-ss"))
: new NuGetVersion(packageResult.Version).ToNormalizedStringChecked();
var failuresFolder = _fileSystem.CombinePaths(ApplicationParameters.PackageFailuresLocation, packageResult.Name, normalizedVersion);

if (_filesService.MovePackageUsingBackupStrategy(packageResult.InstallLocation, failuresFolder, restoreSource: false))
Expand All @@ -1835,7 +1839,7 @@ private void MovePackageToFailedPackagesLocation(PackageResult packageResult)

private void RestorePreviousPackageVersion(ChocolateyConfiguration config, PackageResult packageResult)
{
if (packageResult.InstallLocation == null)
if (string.IsNullOrEmpty(packageResult.InstallLocation) || string.IsNullOrEmpty(packageResult.Version))
{
return;
}
Expand Down
49 changes: 35 additions & 14 deletions src/chocolatey/infrastructure.app/services/NugetService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
using NuGet.Resolver;
using NuGet.Versioning;
using static chocolatey.StringResources;
using System.Xml;

namespace chocolatey.infrastructure.app.services
{
Expand Down Expand Up @@ -954,7 +955,6 @@ Version was specified as '{0}'. It is possible that version
}
}


try
{
//TODO, do sanity check here.
Expand All @@ -975,13 +975,18 @@ Version was specified as '{0}'. It is possible that version
_nugetLogger, CancellationToken.None).GetAwaiter().GetResult())
{
ValidatePackageHash(config, packageDependencyInfo, downloadResult);

nugetProject.InstallPackageAsync(
packageDependencyInfo,
downloadResult,
projectContext,
CancellationToken.None).GetAwaiter().GetResult();

try
{
nugetProject.InstallPackageAsync(
packageDependencyInfo,
downloadResult,
projectContext,
CancellationToken.None).GetAwaiter().GetResult();
}
catch (XmlException)
{
throw new ApplicationException("An unexpected error was encountered parsing a malformed nuspec file. This may occur if corrupt files are present in the package's install directory.");
}
}

var installedPath = nugetProject.GetInstalledPath(packageDependencyInfo);
Expand Down Expand Up @@ -1042,7 +1047,16 @@ Version was specified as '{0}'. It is possible that version

var logMessage = "{0} not installed. An error occurred during installation:{1} {2}".FormatWith(packageDependencyInfo.Id, Environment.NewLine, message);
this.Log().Error(ChocolateyLoggers.Important, logMessage);
var errorResult = packageResultsToReturn.GetOrAdd(packageDependencyInfo.Id, new PackageResult(packageDependencyInfo.Id, version.ToFullStringChecked(), null));

// Set this install path if the folder does exist, to ensure otherwise unrecoverable scenarios still move corrupt files
// to lib-bad if they happen to be present, when the continueAction is set up to do so.
var packageInstallPath = _fileSystem.CombinePaths(nugetProject.Root, pathResolver.GetPackageDirectoryName(packageDependencyInfo));
if (!_fileSystem.DirectoryExists(packageInstallPath))
{
packageInstallPath = null;
}

var errorResult = packageResultsToReturn.GetOrAdd(packageDependencyInfo.Id, new PackageResult(packageDependencyInfo.Id, version.ToFullStringChecked(), packageInstallPath));
errorResult.Messages.Add(new ResultMessage(ResultType.Error, logMessage));
if (errorResult.ExitCode == 0)
{
Expand Down Expand Up @@ -1801,11 +1815,18 @@ public virtual ConcurrentDictionary<string, PackageResult> Upgrade(ChocolateyCon
{
ValidatePackageHash(config, packageDependencyInfo, downloadResult);

nugetProject.InstallPackageAsync(
packageDependencyInfo,
downloadResult,
projectContext,
CancellationToken.None).GetAwaiter().GetResult();
try
{
nugetProject.InstallPackageAsync(
packageDependencyInfo,
downloadResult,
projectContext,
CancellationToken.None).GetAwaiter().GetResult();
}
catch (XmlException)
{
throw new ApplicationException("An unexpected error was encountered parsing a malformed nuspec file. This may occur if corrupt files are present in the package's install directory.");
}
}

var installedPath = nugetProject.GetInstalledPath(packageDependencyInfo);
Expand Down
Loading