Skip to content

Commit

Permalink
(GH-198) Remove existing pending packages
Browse files Browse the repository at this point in the history
If any packages are in a pending state, it means the install did not
complete successfully, so those packages should not actually be
considered "installed". Those pending packages should be removed with a
warning.
  • Loading branch information
ferventcoder committed May 28, 2016
1 parent 33f5b05 commit 3f2831e
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/chocolatey/chocolatey.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
<Compile Include="infrastructure.app\events\HandlePackageResultCompletedMessage.cs" />
<Compile Include="infrastructure.app\services\FileTypeDetectorService.cs" />
<Compile Include="infrastructure.app\services\IFileTypeDetectorService.cs" />
<Compile Include="infrastructure.app\tasks\RemovePendingPackagesTask.cs" />
<Compile Include="infrastructure.app\templates\ChocolateyBeforeModifyTemplate.cs" />
<Compile Include="infrastructure.app\templates\ChocolateyLicenseFileTemplate.cs" />
<Compile Include="infrastructure.app\templates\ChocolateyVerificationFileTemplate.cs" />
Expand Down
14 changes: 14 additions & 0 deletions src/chocolatey/infrastructure.app/registration/ContainerBinding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace chocolatey.infrastructure.app.registration
{
using System.Collections.Generic;
using infrastructure.events;
using infrastructure.tasks;
using NuGet;
using SimpleInjector;
using adapters;
Expand All @@ -28,6 +29,7 @@ namespace chocolatey.infrastructure.app.registration
using infrastructure.services;
using nuget;
using services;
using tasks;
using CryptoHashProvider = cryptography.CryptoHashProvider;
using IFileSystem = filesystem.IFileSystem;
using IHashProvider = cryptography.IHashProvider;
Expand Down Expand Up @@ -111,6 +113,18 @@ public void RegisterComponents(Container container)
container.Register<IEventSubscriptionManagerService, EventSubscriptionManagerService>(Lifestyle.Singleton);
EventManager.initialize_with(container.GetInstance<IEventSubscriptionManagerService>);

container.Register<IEnumerable<ITask>>(
() =>
{
var list = new List<ITask>
{
new RemovePendingPackagesTask(container.GetInstance<IFileSystem>())
};

return list.AsReadOnly();
},
Lifestyle.Singleton);

container.Register<IDateTimeService, SystemDateTimeUtcService>(Lifestyle.Singleton);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright © 2011 - Present RealDimensions Software, LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
//
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

namespace chocolatey.infrastructure.app.tasks
{
using System;
using System.IO;
using System.Linq;
using events;
using filesystem;
using infrastructure.events;
using infrastructure.tasks;
using logging;
using tolerance;

public class RemovePendingPackagesTask : ITask
{
private readonly IFileSystem _fileSystem;
private IDisposable _subscription;

public RemovePendingPackagesTask(IFileSystem fileSystem)
{
_fileSystem = fileSystem;
}

public void initialize()
{
_subscription = EventManager.subscribe<PreRunMessage>(handle_message, null, null);
this.Log().Debug(ChocolateyLoggers.Verbose, () => "{0} is now ready and waiting for {1}.".format_with(GetType().Name, typeof(PreRunMessage).Name));
}

public void shutdown()
{
if (_subscription != null) _subscription.Dispose();
}

private void handle_message(PreRunMessage message)
{
this.Log().Debug(ChocolateyLoggers.Verbose, "[Pending] Removing all pending packages that should not be considered installed...");

var pendingFiles = _fileSystem.get_files(ApplicationParameters.PackagesLocation, ApplicationParameters.PackagePendingFileName, SearchOption.AllDirectories).ToList();
foreach (var pendingFile in pendingFiles.or_empty_list_if_null())
{
var packageFolder = _fileSystem.get_directory_name(pendingFile);
this.Log().Warn("[Pending] Removing incomplete install for '{0}'".format_with(_fileSystem.get_directory_info_for(packageFolder).Name));

FaultTolerance.retry(2, () => _fileSystem.delete_directory_if_exists(packageFolder, recursive: true, overrideAttributes: true, isSilent: true), 500, isSilent: true);
}
}
}
}

0 comments on commit 3f2831e

Please sign in to comment.