Skip to content
This repository has been archived by the owner on Jul 12, 2022. It is now read-only.

Commit

Permalink
Improve NuGet CLI behaviour when running as global tool (#402)
Browse files Browse the repository at this point in the history
* Log error instead of throwing when NuGet cli cannot be found.

This returns to the old behaviour, that was still expected by the consumers of this class.

* Do not run global nuget restore when dealing with a dotnetcore-only project.

* Include NuGet.exe in packaged tool

* Expanded diagnostic output when probing for NuGet.exe location

* NuGetFileRestoreCommand created by IoC

* NuGetUpdatePackageCommand created by IoC

* DotNetUpdateCommand  created by IoC

* UpdateProjectImportsCommand created by IoC

* UpdateNuspecCommand created by IoC

* Extract helper method to improve readability

* Cache the path to NuGet.exe when found

* Delay evaluation of NuGetPath so that it happens after logger is configured
  • Loading branch information
skolima authored Aug 23, 2018
1 parent 809cdcb commit d0610ad
Show file tree
Hide file tree
Showing 18 changed files with 133 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using NuKeeper.Inspection.RepositoryInspection;
using NuKeeper.Inspection.Sources;
using NuKeeper.Update.Process;
using NuKeeper.Update.ProcessRunner;
using NUnit.Framework;

namespace NuKeeper.Integration.Tests.NuGet.Process
Expand Down Expand Up @@ -116,7 +117,7 @@ private async Task ExecuteValidUpdateTest(
var projectPath = Path.Combine(workDirectory, testProject);
await File.WriteAllTextAsync(projectPath, projectContents);

var command = new DotNetUpdatePackageCommand(Substitute.For<INuKeeperLogger>());
var command = new DotNetUpdatePackageCommand(new ExternalProcess(Substitute.For<INuKeeperLogger>()));

var packageToUpdate = new PackageInProject("Microsoft.AspNet.WebApi.Client", oldPackageVersion,
new PackagePath(workDirectory, testProject, packageReferenceType));
Expand Down
4 changes: 3 additions & 1 deletion NuKeeper.Integration.Tests/NuGet/Process/NuGetPathTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using NSubstitute;
using NuKeeper.Inspection.Logging;
using NuKeeper.Update.Process;
using NUnit.Framework;

Expand All @@ -9,7 +11,7 @@ public class NuGetPathTests
[Test]
public void HasNugetPath()
{
var nugetPath = NuGetPath.FindExecutable();
var nugetPath = new NuGetPath(Substitute.For<INuKeeperLogger>()).Executable;

Assert.That(nugetPath, Is.Not.Empty);
FileAssert.Exists(nugetPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using NuKeeper.Inspection.Logging;
using NuKeeper.Inspection.RepositoryInspection;
using NuKeeper.Inspection.Sources;
using NuKeeper.Update.Process;
using NuKeeper.Update.ProcessRunner;

namespace NuKeeper.Integration.Tests.NuGet.Process
{
Expand Down Expand Up @@ -57,7 +59,8 @@ public async Task ShouldUpdateDotnetClassicProject()

await File.WriteAllTextAsync(Path.Combine(workDirectory, "nuget.config"), _nugetConfig);

var command = new Update.Process.NuGetUpdatePackageCommand(Substitute.For<INuKeeperLogger>());
var logger = Substitute.For<INuKeeperLogger>();
var command = new NuGetUpdatePackageCommand(logger, new NuGetPath(logger), new ExternalProcess(logger));

var packageToUpdate = new PackageInProject("Microsoft.AspNet.WebApi.Client", oldPackageVersion,
new PackagePath(workDirectory, testProject, PackageReferenceType.PackagesConfig));
Expand Down
11 changes: 3 additions & 8 deletions NuKeeper.Update/Process/DotNetUpdatePackageCommand.cs
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
using System.Threading.Tasks;
using NuGet.Configuration;
using NuGet.Versioning;
using NuKeeper.Inspection.Logging;
using NuKeeper.Inspection.RepositoryInspection;
using NuKeeper.Inspection.Sources;
using NuKeeper.Update.ProcessRunner;

namespace NuKeeper.Update.Process
{
public class DotNetUpdatePackageCommand : IPackageCommand
public class DotNetUpdatePackageCommand : IDotNetUpdatePackageCommand
{
private readonly IExternalProcess _externalProcess;
private readonly INuKeeperLogger _logger;

public DotNetUpdatePackageCommand(
INuKeeperLogger logger,
IExternalProcess externalProcess = null)
public DotNetUpdatePackageCommand(IExternalProcess externalProcess)
{
_logger = logger;
_externalProcess = externalProcess ?? new ExternalProcess(logger);
_externalProcess = externalProcess;
}

public async Task Invoke(PackageInProject currentPackage,
Expand Down
6 changes: 6 additions & 0 deletions NuKeeper.Update/Process/IDotNetUpdatePackageCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace NuKeeper.Update.Process
{
public interface IDotNetUpdatePackageCommand : IPackageCommand
{
}
}
7 changes: 7 additions & 0 deletions NuKeeper.Update/Process/INuGetPath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace NuKeeper.Update.Process
{
public interface INuGetPath
{
string Executable { get; }
}
}
6 changes: 6 additions & 0 deletions NuKeeper.Update/Process/INuGetUpdatePackageCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace NuKeeper.Update.Process
{
public interface INuGetUpdatePackageCommand : IPackageCommand
{
}
}
6 changes: 6 additions & 0 deletions NuKeeper.Update/Process/IUpdateNuspecCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace NuKeeper.Update.Process
{
public interface IUpdateNuspecCommand : IPackageCommand
{
}
}
6 changes: 6 additions & 0 deletions NuKeeper.Update/Process/IUpdateProjectImportsCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace NuKeeper.Update.Process
{
public interface IUpdateProjectImportsCommand : IPackageCommand
{
}
}
9 changes: 6 additions & 3 deletions NuKeeper.Update/Process/NuGetFileRestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,17 @@ namespace NuKeeper.Update.Process
public class NuGetFileRestoreCommand : IFileRestoreCommand
{
private readonly INuKeeperLogger _logger;
private readonly INuGetPath _nuGetPath;
private readonly IExternalProcess _externalProcess;

public NuGetFileRestoreCommand(
INuKeeperLogger logger,
IExternalProcess externalProcess = null)
INuGetPath nuGetPath,
IExternalProcess externalProcess)
{
_logger = logger;
_externalProcess = externalProcess ?? new ExternalProcess(logger);
_nuGetPath = nuGetPath;
_externalProcess = externalProcess;
}

public async Task Invoke(FileInfo file, NuGetSources sources)
Expand All @@ -33,7 +36,7 @@ public async Task Invoke(FileInfo file, NuGetSources sources)
return;
}

var nuget = NuGetPath.FindExecutable();
var nuget = _nuGetPath.Executable;

if (string.IsNullOrWhiteSpace(nuget))
{
Expand Down
37 changes: 28 additions & 9 deletions NuKeeper.Update/Process/NuGetPath.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,24 @@
using System;
using System.IO;
using System.Linq;
using NuKeeper.Inspection.Logging;

namespace NuKeeper.Update.Process
{
public static class NuGetPath
public class NuGetPath : INuGetPath
{
public static string FindExecutable()
private readonly INuKeeperLogger _logger;
private readonly Lazy<string> _executablePath;

public NuGetPath(INuKeeperLogger logger)
{
_logger = logger;
this._executablePath = new Lazy<string>(FindExecutable);
}

public string Executable => _executablePath.Value;

private string FindExecutable()
{
var localNugetPath = FindLocalNuget();

Expand All @@ -15,36 +27,39 @@ public static string FindExecutable()
return localNugetPath;
}


return FindNugetInPackagesUnderProfile();
}

private static string FindLocalNuget()
private string FindLocalNuget()
{
var appDir = AppDomain.CurrentDomain.BaseDirectory;
var fullPath = Path.Combine(appDir, "NuGet.exe");
if (File.Exists(fullPath))
{
_logger.Detailed("Found NuGet.exe: " + fullPath);
return fullPath;
}

return string.Empty;
}

private static string FindNugetInPackagesUnderProfile()
private string FindNugetInPackagesUnderProfile()
{
var profile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

if (string.IsNullOrWhiteSpace(profile))
{
throw new Exception("Could not find user profile path");
_logger.Error("Could not find user profile path");
return string.Empty;
}

var commandlinePackageDir = Path.Combine(profile, ".nuget", "packages", "nuget.commandline");
_logger.Detailed("Checking for NuGet.exe in packages directory: " + commandlinePackageDir);

if (!Directory.Exists(commandlinePackageDir))
{
throw new Exception("Could not find nuget commandline path: " + commandlinePackageDir);
_logger.Error("Could not find nuget commandline path: " + commandlinePackageDir);
return string.Empty;
}

var highestVersion = Directory.GetDirectories(commandlinePackageDir)
Expand All @@ -53,11 +68,15 @@ private static string FindNugetInPackagesUnderProfile()

if (string.IsNullOrWhiteSpace(highestVersion))
{
throw new Exception("Could not find a version of nuget.commandline");
_logger.Error("Could not find a version of nuget.commandline");
return string.Empty;
}

var nugetProgramPath = Path.Combine(highestVersion, "tools", "NuGet.exe");
return Path.GetFullPath(nugetProgramPath);
var fullPath = Path.GetFullPath(nugetProgramPath);
_logger.Detailed("Found NuGet.exe: " + fullPath);

return fullPath;
}
}
}
11 changes: 7 additions & 4 deletions NuKeeper.Update/Process/NuGetUpdatePackageCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,20 @@

namespace NuKeeper.Update.Process
{
public class NuGetUpdatePackageCommand : IPackageCommand
public class NuGetUpdatePackageCommand : INuGetUpdatePackageCommand
{
private readonly IExternalProcess _externalProcess;
private readonly INuKeeperLogger _logger;
private readonly INuGetPath _nuGetPath;

public NuGetUpdatePackageCommand(
INuKeeperLogger logger,
IExternalProcess externalProcess = null)
INuGetPath nuGetPath,
IExternalProcess externalProcess)
{
_logger = logger;
_externalProcess = externalProcess ?? new ExternalProcess(logger);
_nuGetPath = nuGetPath;
_externalProcess = externalProcess;
}

public async Task Invoke(PackageInProject currentPackage,
Expand All @@ -33,7 +36,7 @@ public async Task Invoke(PackageInProject currentPackage,

var projectPath = currentPackage.Path.Info.DirectoryName;

var nuget = NuGetPath.FindExecutable();
var nuget = _nuGetPath.Executable;
if (string.IsNullOrWhiteSpace(nuget))
{
_logger.Normal("Cannot find NuGet exe for package update");
Expand Down
2 changes: 1 addition & 1 deletion NuKeeper.Update/Process/UpdateNuspecCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace NuKeeper.Update.Process
{
public class UpdateNuspecCommand : IPackageCommand
public class UpdateNuspecCommand : IUpdateNuspecCommand
{
private readonly INuKeeperLogger _logger;

Expand Down
2 changes: 1 addition & 1 deletion NuKeeper.Update/Process/UpdateProjectImportsCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

namespace NuKeeper.Update.Process
{
public class UpdateProjectImportsCommand : IPackageCommand
public class UpdateProjectImportsCommand : IUpdateProjectImportsCommand
{
public async Task Invoke(PackageInProject currentPackage,
NuGetVersion newVersion, PackageSource packageSource, NuGetSources allSources)
Expand Down
32 changes: 24 additions & 8 deletions NuKeeper.Update/UpdateRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,26 @@ namespace NuKeeper.Update
public class UpdateRunner : IUpdateRunner
{
private readonly INuKeeperLogger _logger;
private readonly IFileRestoreCommand _fileRestoreCommand;
private readonly INuGetUpdatePackageCommand _nuGetUpdatePackageCommand;
private readonly IDotNetUpdatePackageCommand _dotNetUpdatePackageCommand;
private readonly IUpdateProjectImportsCommand _updateProjectImportsCommand;
private readonly IUpdateNuspecCommand _updateNuspecCommand;

public UpdateRunner(INuKeeperLogger logger)
public UpdateRunner(
INuKeeperLogger logger,
IFileRestoreCommand fileRestoreCommand,
INuGetUpdatePackageCommand nuGetUpdatePackageCommand,
IDotNetUpdatePackageCommand dotNetUpdatePackageCommand,
IUpdateProjectImportsCommand updateProjectImportsCommand,
IUpdateNuspecCommand updateNuspecCommand)
{
_logger = logger;
_fileRestoreCommand = fileRestoreCommand;
_nuGetUpdatePackageCommand = nuGetUpdatePackageCommand;
_dotNetUpdatePackageCommand = dotNetUpdatePackageCommand;
_updateProjectImportsCommand = updateProjectImportsCommand;
_updateNuspecCommand = updateNuspecCommand;
}

public async Task Update(PackageUpdateSet updateSet, NuGetSources sources)
Expand All @@ -37,23 +53,23 @@ private IReadOnlyCollection<IPackageCommand> GetUpdateCommands(
case PackageReferenceType.PackagesConfig:
return new IPackageCommand[]
{
new NuGetFileRestoreCommand(_logger),
new NuGetUpdatePackageCommand(_logger)
_fileRestoreCommand,
_nuGetUpdatePackageCommand
};

case PackageReferenceType.ProjectFileOldStyle:
return new IPackageCommand[]
{
new UpdateProjectImportsCommand(),
new NuGetFileRestoreCommand(_logger),
new DotNetUpdatePackageCommand(_logger)
_updateProjectImportsCommand,
_fileRestoreCommand,
_dotNetUpdatePackageCommand
};

case PackageReferenceType.ProjectFile:
return new[] {new DotNetUpdatePackageCommand(_logger) };
return new[] { _dotNetUpdatePackageCommand };

case PackageReferenceType.Nuspec:
return new[] { new UpdateNuspecCommand(_logger) };
return new[] { _updateNuspecCommand };

default:
throw new ArgumentOutOfRangeException(nameof(packageReferenceType));
Expand Down
5 changes: 5 additions & 0 deletions NuKeeper/ContainerUpdateRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,13 @@ public static class ContainerUpdateRegistration
public static void Register(Container container)
{
container.Register<IFileRestoreCommand, NuGetFileRestoreCommand>();
container.Register<INuGetUpdatePackageCommand, NuGetUpdatePackageCommand>();
container.Register<IDotNetUpdatePackageCommand, DotNetUpdatePackageCommand>();
container.Register<IUpdateProjectImportsCommand, UpdateProjectImportsCommand>();
container.Register<IUpdateNuspecCommand, UpdateNuspecCommand>();
container.Register<IExternalProcess, ExternalProcess>();
container.Register<IUpdateRunner, UpdateRunner>();
container.Register<INuGetPath, NuGetPath>();
}
}
}
12 changes: 11 additions & 1 deletion NuKeeper/Engine/RepositoryUpdater.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NuKeeper.Configuration;
using NuKeeper.Engine.Packages;
Expand Down Expand Up @@ -97,7 +98,10 @@ private async Task<int> DoTargetUpdates(
return 0;
}

await _solutionsRestore.Restore(git.WorkingFolder, sources);
if (AnyProjectRequiresNuGetRestore(targetUpdates))
{
await _solutionsRestore.Restore(git.WorkingFolder, sources);
}

var updatesDone = await UpdateAllTargets(git, repository, targetUpdates, sources);

Expand All @@ -113,6 +117,12 @@ private async Task<int> DoTargetUpdates(
return updatesDone;
}

private static bool AnyProjectRequiresNuGetRestore(IEnumerable<PackageUpdateSet> targetUpdates)
{
return targetUpdates.SelectMany(u => u.CurrentPackages)
.Any(p => p.Path.PackageReferenceType != PackageReferenceType.ProjectFile);
}

private static void GitInit(IGitDriver git, RepositoryData repository)
{
git.Clone(repository.Pull.Uri);
Expand Down
Loading

0 comments on commit d0610ad

Please sign in to comment.