diff --git a/build/compile/LzmaArchive.targets b/build/compile/LzmaArchive.targets index 27ad0b7d7..02880b6f8 100644 --- a/build/compile/LzmaArchive.targets +++ b/build/compile/LzmaArchive.targets @@ -13,7 +13,8 @@ $(IntermediateDirectory)/NuGetPackagesArchiveProject $(IntermediateDirectory)/NuGetPackagesArchiveFolder - $(NuGetPackagesArchiveProject)/Nuget.config + $(NuGetPackagesArchiveProject)/Nuget.config + $(RepoRoot)/NuGet.Config $(BaseOutputDirectory)/tools $(ToolsOutputDirectory)/Archiver.dll $(SdkOutputDirectory)/nuGetPackagesArchive.lzma @@ -96,10 +97,11 @@ - + diff --git a/src/Microsoft.DotNet.Configurer/CliFallbackFolderPathCalculator.cs b/src/Microsoft.DotNet.Configurer/CliFallbackFolderPathCalculator.cs new file mode 100644 index 000000000..354d23ab4 --- /dev/null +++ b/src/Microsoft.DotNet.Configurer/CliFallbackFolderPathCalculator.cs @@ -0,0 +1,29 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System; +using System.IO; +using System.Runtime.InteropServices; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.PlatformAbstractions; +using NuGet.Common; + +namespace Microsoft.DotNet.Configurer +{ + public class CliFallbackFolderPathCalculator + { + public string CliFallbackFolderPath + { + get + { + string profileDir = Environment.GetEnvironmentVariable( + RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "USERPROFILE" : "HOME"); + + return Path.Combine(profileDir, ".dotnet", "NuGetFallbackFolder"); + } + } + + public string NuGetUserSettingsDirectory => + NuGetEnvironment.GetFolderPath(NuGetFolderPath.UserSettingsDirectory); + } +} diff --git a/src/Microsoft.DotNet.Configurer/INuGetConfig.cs b/src/Microsoft.DotNet.Configurer/INuGetConfig.cs new file mode 100644 index 000000000..a5ba7a531 --- /dev/null +++ b/src/Microsoft.DotNet.Configurer/INuGetConfig.cs @@ -0,0 +1,10 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.DotNet.Configurer +{ + public interface INuGetConfig + { + void AddCliFallbackFolder(string fallbackFolderPath); + } +} diff --git a/src/Microsoft.DotNet.Configurer/INuGetPackagesArchiver.cs b/src/Microsoft.DotNet.Configurer/INuGetPackagesArchiver.cs index 4fc4b5291..421a37584 100644 --- a/src/Microsoft.DotNet.Configurer/INuGetPackagesArchiver.cs +++ b/src/Microsoft.DotNet.Configurer/INuGetPackagesArchiver.cs @@ -5,10 +5,10 @@ using System; namespace Microsoft.DotNet.Configurer { - public interface INuGetPackagesArchiver : IDisposable + public interface INuGetPackagesArchiver { string NuGetPackagesArchive { get; } - string ExtractArchive(); + void ExtractArchive(string archiveDestination); } } diff --git a/src/Microsoft.DotNet.Configurer/Microsoft.DotNet.Configurer.csproj b/src/Microsoft.DotNet.Configurer/Microsoft.DotNet.Configurer.csproj index 645bc4fe1..03775be47 100644 --- a/src/Microsoft.DotNet.Configurer/Microsoft.DotNet.Configurer.csproj +++ b/src/Microsoft.DotNet.Configurer/Microsoft.DotNet.Configurer.csproj @@ -12,6 +12,11 @@ git://github.com/dotnet/cli + + + + + diff --git a/src/Microsoft.DotNet.Configurer/NuGetCachePrimer.cs b/src/Microsoft.DotNet.Configurer/NuGetCachePrimer.cs index d0b531e0e..b3f42fbfd 100644 --- a/src/Microsoft.DotNet.Configurer/NuGetCachePrimer.cs +++ b/src/Microsoft.DotNet.Configurer/NuGetCachePrimer.cs @@ -10,48 +10,44 @@ namespace Microsoft.DotNet.Configurer { public class NuGetCachePrimer : INuGetCachePrimer { - private static IReadOnlyList> _templatesUsedToPrimeCache = new List>() - { - new List() { "console", "--debug:ephemeral-hive" }, - }; - - private readonly ICommandFactory _commandFactory; - - private readonly IDirectory _directory; - private readonly IFile _file; private readonly INuGetPackagesArchiver _nugetPackagesArchiver; private readonly INuGetCacheSentinel _nuGetCacheSentinel; + private readonly INuGetConfig _nuGetConfig; + + private readonly CliFallbackFolderPathCalculator _cliFallbackFolderPathCalculator; + public NuGetCachePrimer( - ICommandFactory commandFactory, INuGetPackagesArchiver nugetPackagesArchiver, - INuGetCacheSentinel nuGetCacheSentinel) - : this(commandFactory, - nugetPackagesArchiver, + INuGetCacheSentinel nuGetCacheSentinel, + INuGetConfig nuGetConfig, + CliFallbackFolderPathCalculator cliFallbackFolderPathCalculator) + : this(nugetPackagesArchiver, nuGetCacheSentinel, - FileSystemWrapper.Default.Directory, + nuGetConfig, + cliFallbackFolderPathCalculator, FileSystemWrapper.Default.File) { } internal NuGetCachePrimer( - ICommandFactory commandFactory, INuGetPackagesArchiver nugetPackagesArchiver, INuGetCacheSentinel nuGetCacheSentinel, - IDirectory directory, + INuGetConfig nuGetConfig, + CliFallbackFolderPathCalculator cliFallbackFolderPathCalculator, IFile file) { - _commandFactory = commandFactory; - - _directory = directory; - _nugetPackagesArchiver = nugetPackagesArchiver; _nuGetCacheSentinel = nuGetCacheSentinel; + _nuGetConfig = nuGetConfig; + + _cliFallbackFolderPathCalculator = cliFallbackFolderPathCalculator; + _file = file; } @@ -62,79 +58,18 @@ namespace Microsoft.DotNet.Configurer return; } - var extractedPackagesArchiveDirectory = _nugetPackagesArchiver.ExtractArchive(); + var nuGetFallbackFolder = _cliFallbackFolderPathCalculator.CliFallbackFolderPath; - PrimeCacheUsingArchive(extractedPackagesArchiveDirectory); + _nuGetConfig.AddCliFallbackFolder(nuGetFallbackFolder); + + _nugetPackagesArchiver.ExtractArchive(nuGetFallbackFolder); + + _nuGetCacheSentinel.CreateIfNotExists(); } private bool SkipPrimingTheCache() { return !_file.Exists(_nugetPackagesArchiver.NuGetPackagesArchive); } - - private void PrimeCacheUsingArchive(string extractedPackagesArchiveDirectory) - { - bool succeeded = true; - - foreach (IReadOnlyList templateInfo in _templatesUsedToPrimeCache) - { - if (succeeded) - { - using (var temporaryDotnetNewDirectory = _directory.CreateTemporaryDirectory()) - { - var workingDirectory = temporaryDotnetNewDirectory.DirectoryPath; - - succeeded &= CreateTemporaryProject(workingDirectory, templateInfo); - - if (succeeded) - { - succeeded &= RestoreTemporaryProject(extractedPackagesArchiveDirectory, workingDirectory); - } - } - } - } - - if (succeeded) - { - _nuGetCacheSentinel.CreateIfNotExists(); - } - } - - private bool CreateTemporaryProject(string workingDirectory, IReadOnlyList templateInfo) - { - return RunCommand( - "new", - templateInfo, - workingDirectory); - } - - private bool RestoreTemporaryProject(string extractedPackagesArchiveDirectory, string workingDirectory) - { - return RunCommand( - "restore", - new[] { "-s", extractedPackagesArchiveDirectory }, - workingDirectory); - } - - private bool RunCommand(string commandToExecute, IEnumerable args, string workingDirectory) - { - var command = _commandFactory - .Create(commandToExecute, args) - .WorkingDirectory(workingDirectory) - .CaptureStdOut() - .CaptureStdErr(); - - var commandResult = command.Execute(); - - if (commandResult.ExitCode != 0) - { - Reporter.Verbose.WriteLine(commandResult.StdErr); - - Reporter.Error.WriteLine( - string.Format(LocalizableStrings.FailedToPrimeCacheError, commandToExecute, commandResult.ExitCode)); - } - - return commandResult.ExitCode == 0; - } } } diff --git a/src/Microsoft.DotNet.Configurer/NuGetCacheSentinel.cs b/src/Microsoft.DotNet.Configurer/NuGetCacheSentinel.cs index a0feea827..fccb50c1e 100644 --- a/src/Microsoft.DotNet.Configurer/NuGetCacheSentinel.cs +++ b/src/Microsoft.DotNet.Configurer/NuGetCacheSentinel.cs @@ -17,25 +17,13 @@ namespace Microsoft.DotNet.Configurer private string _nugetCachePath; - private string NuGetCachePath - { - get - { - if (string.IsNullOrEmpty(_nugetCachePath)) - { - _nugetCachePath = NuGetPathContext.Create(new NullSettings()).UserPackageFolder; - } - - return _nugetCachePath; - } - } - - private string SentinelPath => Path.Combine(NuGetCachePath, SENTINEL); - private string InProgressSentinelPath => Path.Combine(NuGetCachePath, INPROGRESS_SENTINEL); + private string SentinelPath => Path.Combine(_nugetCachePath, SENTINEL); + private string InProgressSentinelPath => Path.Combine(_nugetCachePath, INPROGRESS_SENTINEL); private Stream InProgressSentinel { get; set; } - public NuGetCacheSentinel() : this(string.Empty, FileSystemWrapper.Default.File) + public NuGetCacheSentinel(CliFallbackFolderPathCalculator cliFallbackFolderPathCalculator) : + this(cliFallbackFolderPathCalculator.CliFallbackFolderPath, FileSystemWrapper.Default.File) { } @@ -74,9 +62,9 @@ namespace Microsoft.DotNet.Configurer { try { - if(!Directory.Exists(NuGetCachePath)) + if (!Directory.Exists(_nugetCachePath)) { - Directory.CreateDirectory(NuGetCachePath); + Directory.CreateDirectory(_nugetCachePath); } // open an exclusive handle to the in-progress sentinel and mark it for delete on close. diff --git a/src/Microsoft.DotNet.Configurer/NuGetConfig.cs b/src/Microsoft.DotNet.Configurer/NuGetConfig.cs new file mode 100644 index 000000000..fb7b9292c --- /dev/null +++ b/src/Microsoft.DotNet.Configurer/NuGetConfig.cs @@ -0,0 +1,39 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using NuGet.Common; +using NuGet.Configuration; +using System.Linq; + +namespace Microsoft.DotNet.Configurer +{ + public class NuGetConfig : INuGetConfig + { + public const string FallbackPackageFolders = "fallbackPackageFolders"; + + private ISettings _settings; + + public NuGetConfig(CliFallbackFolderPathCalculator cliFallbackFolderPathCalculator) + { + _settings = new Settings(cliFallbackFolderPathCalculator.NuGetUserSettingsDirectory); + } + + internal NuGetConfig(ISettings settings) + { + _settings = settings; + } + + public void AddCliFallbackFolder(string fallbackFolderPath) + { + if (!IsCliFallbackFolderSet(fallbackFolderPath)) + { + _settings.SetValue(FallbackPackageFolders, "CliFallbackFolder", fallbackFolderPath); + } + } + + private bool IsCliFallbackFolderSet(string fallbackFolderPath) + { + return _settings.GetSettingValues(FallbackPackageFolders).Any(s => s.Value == fallbackFolderPath); + } + } +} diff --git a/src/Microsoft.DotNet.Configurer/NuGetPackagesArchiver.cs b/src/Microsoft.DotNet.Configurer/NuGetPackagesArchiver.cs index c8d509c40..df2993ab4 100644 --- a/src/Microsoft.DotNet.Configurer/NuGetPackagesArchiver.cs +++ b/src/Microsoft.DotNet.Configurer/NuGetPackagesArchiver.cs @@ -10,33 +10,15 @@ namespace Microsoft.DotNet.Configurer { public class NuGetPackagesArchiver : INuGetPackagesArchiver { - private ITemporaryDirectory _temporaryDirectory; - public string NuGetPackagesArchive => Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "nuGetPackagesArchive.lzma")); - public NuGetPackagesArchiver() : this(FileSystemWrapper.Default.Directory) - { - } - - internal NuGetPackagesArchiver(IDirectory directory) - { - _temporaryDirectory = directory.CreateTemporaryDirectory(); - } - - public string ExtractArchive() + public void ExtractArchive(string archiveDestination) { var progress = new ConsoleProgressReport(); var archive = new IndexedArchive(); - archive.Extract(NuGetPackagesArchive, _temporaryDirectory.DirectoryPath, progress); - - return _temporaryDirectory.DirectoryPath; - } - - public void Dispose() - { - _temporaryDirectory.Dispose(); + archive.Extract(NuGetPackagesArchive, archiveDestination, progress); } } } diff --git a/src/Microsoft.DotNet.TestFramework/TestAssetInstance.cs b/src/Microsoft.DotNet.TestFramework/TestAssetInstance.cs index dadbdf01e..bf75f00c2 100644 --- a/src/Microsoft.DotNet.TestFramework/TestAssetInstance.cs +++ b/src/Microsoft.DotNet.TestFramework/TestAssetInstance.cs @@ -110,6 +110,7 @@ namespace Microsoft.DotNet.TestFramework var content = @" + "; diff --git a/src/dotnet/Program.cs b/src/dotnet/Program.cs index 90142296a..42e04517f 100644 --- a/src/dotnet/Program.cs +++ b/src/dotnet/Program.cs @@ -79,7 +79,8 @@ namespace Microsoft.DotNet.Cli var success = true; var command = string.Empty; var lastArg = 0; - using (INuGetCacheSentinel nugetCacheSentinel = new NuGetCacheSentinel()) + var cliFallbackFolderPathCalculator = new CliFallbackFolderPathCalculator(); + using (INuGetCacheSentinel nugetCacheSentinel = new NuGetCacheSentinel(cliFallbackFolderPathCalculator)) { for (; lastArg < args.Length; lastArg++) { @@ -111,7 +112,7 @@ namespace Microsoft.DotNet.Cli } else { - ConfigureDotNetForFirstTimeUse(nugetCacheSentinel); + ConfigureDotNetForFirstTimeUse(nugetCacheSentinel, cliFallbackFolderPathCalculator); // It's the command, and we're done! command = args[lastArg]; @@ -165,23 +166,27 @@ namespace Microsoft.DotNet.Cli } - private static void ConfigureDotNetForFirstTimeUse(INuGetCacheSentinel nugetCacheSentinel) + private static void ConfigureDotNetForFirstTimeUse( + INuGetCacheSentinel nugetCacheSentinel, + CliFallbackFolderPathCalculator cliFallbackFolderPathCalculator) { using (PerfTrace.Current.CaptureTiming()) { - using (var nugetPackagesArchiver = new NuGetPackagesArchiver()) - { - var environmentProvider = new EnvironmentProvider(); - var commandFactory = new DotNetCommandFactory(alwaysRunOutOfProc: true); - var nugetCachePrimer = - new NuGetCachePrimer(commandFactory, nugetPackagesArchiver, nugetCacheSentinel); - var dotnetConfigurer = new DotnetFirstTimeUseConfigurer( - nugetCachePrimer, - nugetCacheSentinel, - environmentProvider); + var nugetPackagesArchiver = new NuGetPackagesArchiver(); + var environmentProvider = new EnvironmentProvider(); + var commandFactory = new DotNetCommandFactory(alwaysRunOutOfProc: true); + var nugetConfig = new NuGetConfig(cliFallbackFolderPathCalculator); + var nugetCachePrimer = new NuGetCachePrimer( + nugetPackagesArchiver, + nugetCacheSentinel, + nugetConfig, + cliFallbackFolderPathCalculator); + var dotnetConfigurer = new DotnetFirstTimeUseConfigurer( + nugetCachePrimer, + nugetCacheSentinel, + environmentProvider); - dotnetConfigurer.Configure(); - } + dotnetConfigurer.Configure(); } } diff --git a/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs b/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs index 88d64a832..a4ccd283a 100644 --- a/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs +++ b/src/dotnet/commands/dotnet-msbuild/MSBuildLogger.cs @@ -11,7 +11,7 @@ namespace Microsoft.DotNet.Tools.MSBuild { public sealed class MSBuildLogger : Logger { - private readonly INuGetCacheSentinel _sentinel = new NuGetCacheSentinel(); + private readonly INuGetCacheSentinel _sentinel = new NuGetCacheSentinel(new CliFallbackFolderPathCalculator()); private readonly ITelemetry _telemetry; public MSBuildLogger() diff --git a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs index 9d9e00539..938ad5075 100644 --- a/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs +++ b/test/Microsoft.DotNet.Cli.Utils.Tests/GivenAProjectToolsCommandResolver.cs @@ -342,7 +342,8 @@ namespace Microsoft.DotNet.Tests var testInstance = TestAssets.Get("AppWithFallbackFolderToolDependency") .CreateInstance() - .WithSourceFiles(); + .WithSourceFiles() + .WithNuGetConfig(new RepoDirectoriesProvider().TestPackages); var testProjectDirectory = testInstance.Root.FullName; var fallbackFolder = Path.Combine(testProjectDirectory, "fallbackFolder"); @@ -378,13 +379,14 @@ namespace Microsoft.DotNet.Tests } [Fact] - public void ItXXXWhenTheToolDllIsNotFound() + public void ItShowsAnErrorWhenTheToolDllIsNotFound() { var projectToolsCommandResolver = SetupProjectToolsCommandResolver(); var testInstance = TestAssets.Get("AppWithFallbackFolderToolDependency") .CreateInstance() - .WithSourceFiles(); + .WithSourceFiles() + .WithNuGetConfig(new RepoDirectoriesProvider().TestPackages); var testProjectDirectory = testInstance.Root.FullName; var fallbackFolder = Path.Combine(testProjectDirectory, "fallbackFolder"); @@ -415,9 +417,10 @@ namespace Microsoft.DotNet.Tests private void PopulateFallbackFolder(string testProjectDirectory, string fallbackFolder) { + var nugetConfigPath = Path.Combine(testProjectDirectory, "NuGet.Config"); new RestoreCommand() .WithWorkingDirectory(testProjectDirectory) - .Execute($"--packages {fallbackFolder}") + .Execute($"--configfile {nugetConfigPath} --packages {fallbackFolder}") .Should() .Pass(); diff --git a/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetCachePrimer.cs b/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetCachePrimer.cs index 52473a77d..ad519e3d7 100644 --- a/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetCachePrimer.cs +++ b/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetCachePrimer.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; using System.Collections.Generic; using System.Linq; using FluentAssertions; @@ -21,13 +22,11 @@ namespace Microsoft.DotNet.Configurer.UnitTests private const string PACKAGES_ARCHIVE_PATH = "some other path"; private IFileSystem _fileSystemMock; - private ITemporaryDirectoryMock _temporaryDirectoryMock; - private Mock _commandFactoryMock; - private Mock _dotnetNewCommandMock; - private Mock _dotnetRestoreCommandMock; private Mock _nugetPackagesArchiverMock; private Mock _nugetCacheSentinel; + private Mock _nugetConfigMock; + private CliFallbackFolderPathCalculator _cliFallbackFolderPathCalculator; public GivenANuGetCachePrimer() { @@ -35,175 +34,61 @@ namespace Microsoft.DotNet.Configurer.UnitTests fileSystemMockBuilder.TemporaryFolder = TEMPORARY_FOLDER_PATH; fileSystemMockBuilder.AddFile(COMPRESSED_ARCHIVE_PATH); _fileSystemMock = fileSystemMockBuilder.Build(); - _temporaryDirectoryMock = (ITemporaryDirectoryMock)_fileSystemMock.Directory.CreateTemporaryDirectory(); - - _commandFactoryMock = SetupCommandFactoryMock(); - + _nugetPackagesArchiverMock = new Mock(); - _nugetPackagesArchiverMock.Setup(n => n.ExtractArchive()).Returns(PACKAGES_ARCHIVE_PATH); _nugetPackagesArchiverMock.Setup(n => n.NuGetPackagesArchive).Returns(COMPRESSED_ARCHIVE_PATH); _nugetCacheSentinel = new Mock(); + _nugetConfigMock = new Mock(); + + _cliFallbackFolderPathCalculator = new CliFallbackFolderPathCalculator(); + var nugetCachePrimer = new NuGetCachePrimer( - _commandFactoryMock.Object, _nugetPackagesArchiverMock.Object, _nugetCacheSentinel.Object, - _fileSystemMock.Directory, + _nugetConfigMock.Object, + _cliFallbackFolderPathCalculator, _fileSystemMock.File); nugetCachePrimer.PrimeCache(); } - private Mock SetupCommandFactoryMock() - { - var commandFactoryMock = new Mock(); - - _dotnetNewCommandMock = new Mock(); - SetupCommandMock(_dotnetNewCommandMock); - - commandFactoryMock - .Setup(c => c.Create("new", new[] { "console", "--debug:ephemeral-hive" }, null, Constants.DefaultConfiguration)) - .Returns(_dotnetNewCommandMock.Object); - - _dotnetRestoreCommandMock = new Mock(); - SetupCommandMock(_dotnetRestoreCommandMock); - commandFactoryMock - .Setup(c => c.Create( - "restore", - It.IsAny>(), - null, - Constants.DefaultConfiguration)) - .Returns(_dotnetRestoreCommandMock.Object); - - return commandFactoryMock; - } - - private void SetupCommandMock(Mock commandMock) - { - commandMock - .Setup(c => c.WorkingDirectory(TEMPORARY_FOLDER_PATH)) - .Returns(commandMock.Object); - commandMock.Setup(c => c.CaptureStdOut()).Returns(commandMock.Object); - commandMock.Setup(c => c.CaptureStdErr()).Returns(commandMock.Object); - } - [Fact] public void It_does_not_prime_the_NuGet_cache_if_the_archive_is_not_found_so_that_we_do_not_need_to_generate_the_archive_for_stage1() { var fileSystemMockBuilder = FileSystemMockBuilder.Create(); var fileSystemMock = fileSystemMockBuilder.Build(); - var commandFactoryMock = SetupCommandFactoryMock(); - var nugetPackagesArchiverMock = new Mock(); nugetPackagesArchiverMock.Setup(n => n.NuGetPackagesArchive).Returns(COMPRESSED_ARCHIVE_PATH); var nugetCachePrimer = new NuGetCachePrimer( - commandFactoryMock.Object, nugetPackagesArchiverMock.Object, _nugetCacheSentinel.Object, - fileSystemMock.Directory, + _nugetConfigMock.Object, + _cliFallbackFolderPathCalculator, fileSystemMock.File); nugetCachePrimer.PrimeCache(); - nugetPackagesArchiverMock.Verify(n => n.ExtractArchive(), Times.Never); - commandFactoryMock.Verify(c => c.Create( - It.IsAny(), - It.IsAny>(), - null, - Constants.DefaultConfiguration), Times.Never); + nugetPackagesArchiverMock.Verify(n => n.ExtractArchive(It.IsAny()), Times.Never); } [Fact] - public void It_disposes_the_temporary_directory_created_for_the_temporary_project_used_to_prime_the_cache() + public void It_adds_the_fallback_folder_to_NuGet_Config() { - _temporaryDirectoryMock.DisposedTemporaryDirectory.Should().BeTrue(); - } - - [Fact] - public void It_runs_dotnet_new_using_the_temporary_folder() - { - _dotnetNewCommandMock.Verify(c => c.WorkingDirectory(TEMPORARY_FOLDER_PATH), Times.Exactly(1)); - } - - [Fact] - public void It_runs_dotnet_new_capturing_stdout() - { - _dotnetNewCommandMock.Verify(c => c.CaptureStdOut(), Times.Exactly(1)); - } - - [Fact] - public void It_runs_dotnet_new_capturing_stderr() - { - _dotnetNewCommandMock.Verify(c => c.CaptureStdErr(), Times.Exactly(1)); - } - - [Fact] - public void It_actually_runs_dotnet_new() - { - _dotnetNewCommandMock.Verify(c => c.Execute(), Times.Exactly(1)); - } - - [Fact] - public void It_uses_the_packages_archive_with_dotnet_restore() - { - _commandFactoryMock.Verify( - c => c.Create( - "restore", - new[] { "-s", $"{PACKAGES_ARCHIVE_PATH}" }, - null, - Constants.DefaultConfiguration), + _nugetConfigMock.Verify(n => + n.AddCliFallbackFolder(_cliFallbackFolderPathCalculator.CliFallbackFolderPath), Times.Exactly(1)); } [Fact] - public void It_does_not_run_restore_if_dotnet_new_fails() + public void It_extracts_the_archive_to_the_fallback_folder() { - var commandFactoryMock = SetupCommandFactoryMock(); - _dotnetNewCommandMock.Setup(c => c.Execute()).Returns(new CommandResult(null, -1, null, null)); - - var nugetCachePrimer = new NuGetCachePrimer( - commandFactoryMock.Object, - _nugetPackagesArchiverMock.Object, - _nugetCacheSentinel.Object, - _fileSystemMock.Directory, - _fileSystemMock.File); - - nugetCachePrimer.PrimeCache(); - - commandFactoryMock.Verify( - c => c.Create( - "restore", - It.IsAny>(), - It.IsAny(), - It.IsAny()), - Times.Never); - } - - [Fact] - public void It_runs_dotnet_restore_using_the_temporary_folder() - { - _dotnetRestoreCommandMock.Verify(c => c.WorkingDirectory(TEMPORARY_FOLDER_PATH), Times.Exactly(1)); - } - - [Fact] - public void It_runs_dotnet_restore_capturing_stdout() - { - _dotnetRestoreCommandMock.Verify(c => c.CaptureStdOut(), Times.Exactly(1)); - } - - [Fact] - public void It_runs_dotnet_restore_capturing_stderr() - { - _dotnetRestoreCommandMock.Verify(c => c.CaptureStdErr(), Times.Exactly(1)); - } - - [Fact] - public void It_actually_runs_dotnet_restore() - { - _dotnetRestoreCommandMock.Verify(c => c.Execute(), Times.Exactly(1)); + _nugetPackagesArchiverMock.Verify(n => + n.ExtractArchive(_cliFallbackFolderPathCalculator.CliFallbackFolderPath), + Times.Exactly(1)); } [Fact] @@ -213,20 +98,22 @@ namespace Microsoft.DotNet.Configurer.UnitTests } [Fact] - public void It_does_not_create_a_sentinel_when_restore_fails() + public void It_does_not_create_a_sentinel_when_extracting_the_archive_fails() { var nugetCacheSentinel = new Mock(); - _dotnetRestoreCommandMock.Setup(c => c.Execute()).Returns(new CommandResult(null, -1, null, null)); + var nugetPackagesArchiveMock = new Mock(); + nugetPackagesArchiveMock.Setup(n => n.ExtractArchive(It.IsAny())).Throws(); var nugetCachePrimer = new NuGetCachePrimer( - _commandFactoryMock.Object, - _nugetPackagesArchiverMock.Object, + nugetPackagesArchiveMock.Object, nugetCacheSentinel.Object, - _fileSystemMock.Directory, + _nugetConfigMock.Object, + _cliFallbackFolderPathCalculator, _fileSystemMock.File); - nugetCachePrimer.PrimeCache(); + Action action = () => nugetCachePrimer.PrimeCache(); + action.ShouldThrow(); nugetCacheSentinel.Verify(n => n.CreateIfNotExists(), Times.Never); } } diff --git a/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetConfig.cs b/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetConfig.cs new file mode 100644 index 000000000..64721c1f4 --- /dev/null +++ b/test/Microsoft.DotNet.Configurer.UnitTests/GivenANuGetConfig.cs @@ -0,0 +1,53 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.Collections.Generic; +using FluentAssertions; +using Moq; +using NuGet.Configuration; +using Xunit; + +namespace Microsoft.DotNet.Configurer.UnitTests +{ + public class GivenANuGetConfig + { + private const string PathToFallbackFolderAlreadySet = "some path to fallback folder"; + + private Mock _settingsMock; + private INuGetConfig _nugetConfig; + + public GivenANuGetConfig() + { + _settingsMock = new Mock(); + _settingsMock + .Setup(s => s.GetSettingValues(NuGetConfig.FallbackPackageFolders, false)) + .Returns(new List() + { + new SettingValue("CliFallbackFolder", PathToFallbackFolderAlreadySet, false) + }); + + _nugetConfig = new NuGetConfig(_settingsMock.Object); + } + + [Fact] + public void ItAddsACliFallbackFolderIfOneIsNotPresentAlready() + { + const string FallbackFolderNotAlreadySet = "some path not already set"; + _nugetConfig.AddCliFallbackFolder(FallbackFolderNotAlreadySet); + + _settingsMock.Verify(s => + s.SetValue(NuGetConfig.FallbackPackageFolders, "CliFallbackFolder", FallbackFolderNotAlreadySet), + Times.Exactly(1)); + } + + [Fact] + public void ItDoesNotAddTheCliFallbackFolderIfItIsAlreadyPresent() + { + _nugetConfig.AddCliFallbackFolder(PathToFallbackFolderAlreadySet); + + _settingsMock.Verify(s => + s.SetValue(NuGetConfig.FallbackPackageFolders, "CliFallbackFolder", PathToFallbackFolderAlreadySet), + Times.Never); + } + } +} \ No newline at end of file diff --git a/test/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj b/test/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj index c37a13777..8febc4df5 100644 --- a/test/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj +++ b/test/Microsoft.DotNet.Tools.Tests.Utilities/Microsoft.DotNet.Tools.Tests.Utilities.csproj @@ -9,6 +9,7 @@ true true $(PackageTargetFallback);dotnet5.4;portable-net451+win8 + 1.6.0 @@ -18,7 +19,6 @@ - diff --git a/test/dotnet-new.Tests/GivenThatIWantANewApp.cs b/test/dotnet-new.Tests/GivenThatIWantANewApp.cs index 005b9c103..fc3fa0d0e 100644 --- a/test/dotnet-new.Tests/GivenThatIWantANewApp.cs +++ b/test/dotnet-new.Tests/GivenThatIWantANewApp.cs @@ -60,6 +60,8 @@ namespace Microsoft.DotNet.New.Tests string projectFolder, string packagesDirectory) { + var repoRootNuGetConfig = Path.Combine(RepoDirectoriesProvider.RepoRoot, "NuGet.Config"); + new NewCommand() .WithWorkingDirectory(projectFolder) .Execute($"{projectType} --debug:ephemeral-hive") @@ -67,7 +69,7 @@ namespace Microsoft.DotNet.New.Tests new RestoreCommand() .WithWorkingDirectory(projectFolder) - .Execute($"--packages {packagesDirectory}") + .Execute($"--configfile {repoRootNuGetConfig} --packages {packagesDirectory}") .Should().Pass(); } @@ -80,6 +82,7 @@ namespace Microsoft.DotNet.New.Tests var packagesDirectory = Path.Combine(rootPath, "packages"); var projectName = "Project"; var expectedVersion = GetFrameworkPackageVersion(); + var repoRootNuGetConfig = Path.Combine(RepoDirectoriesProvider.RepoRoot, "NuGet.Config"); new NewCommand() .WithWorkingDirectory(rootPath) @@ -88,7 +91,7 @@ namespace Microsoft.DotNet.New.Tests new RestoreCommand() .WithWorkingDirectory(rootPath) - .Execute($"--packages {packagesDirectory}") + .Execute($"--configfile {repoRootNuGetConfig} --packages {packagesDirectory}") .Should().Pass(); new DirectoryInfo(Path.Combine(packagesDirectory, packageName)) diff --git a/test/dotnet-restore.Tests/GivenThatIWantToRestoreApp.cs b/test/dotnet-restore.Tests/GivenThatIWantToRestoreApp.cs index fb732f0f1..5e07e5a73 100644 --- a/test/dotnet-restore.Tests/GivenThatIWantToRestoreApp.cs +++ b/test/dotnet-restore.Tests/GivenThatIWantToRestoreApp.cs @@ -14,6 +14,8 @@ namespace Microsoft.DotNet.Restore.Tests { public class GivenThatIWantToRestoreApp : TestBase { + private static string RepoRootNuGetConfig = Path.Combine(RepoDirectoriesProvider.RepoRoot, "NuGet.Config"); + [Fact] public void ItRestoresAppToSpecificDirectory() { @@ -29,7 +31,7 @@ namespace Microsoft.DotNet.Restore.Tests .Should() .Pass(); - string args = $"--packages \"{dir}\""; + string args = $"--configfile {RepoRootNuGetConfig} --packages \"{dir}\""; new RestoreCommand() .WithWorkingDirectory(rootPath) .ExecuteWithCapturedOutput(args) @@ -56,7 +58,7 @@ namespace Microsoft.DotNet.Restore.Tests .Should() .Pass(); - string args = $"--packages \"{dir}\""; + string args = $"--configfile {RepoRootNuGetConfig} --packages \"{dir}\""; new RestoreCommand() .WithWorkingDirectory(rootPath) .ExecuteWithCapturedOutput(args) @@ -76,7 +78,7 @@ namespace Microsoft.DotNet.Restore.Tests string dir = "pkgs"; string fullPath = Path.GetFullPath(Path.Combine(rootPath, dir)); - string args = $"--packages \"{dir}\""; + string args = $"--configfile {RepoRootNuGetConfig} --packages \"{dir}\""; new RestoreCommand() .WithWorkingDirectory(rootPath) .ExecuteWithCapturedOutput(args) diff --git a/test/dotnet.Tests/GivenThatTheUserIsRunningDotNetForTheFirstTime.cs b/test/dotnet.Tests/GivenThatTheUserIsRunningDotNetForTheFirstTime.cs index 871edb5cd..6fb0675d3 100644 --- a/test/dotnet.Tests/GivenThatTheUserIsRunningDotNetForTheFirstTime.cs +++ b/test/dotnet.Tests/GivenThatTheUserIsRunningDotNetForTheFirstTime.cs @@ -19,23 +19,25 @@ namespace Microsoft.DotNet.Tests { private static CommandResult _firstDotnetNonVerbUseCommandResult; private static CommandResult _firstDotnetVerbUseCommandResult; - private static DirectoryInfo _nugetCacheFolder; + private static DirectoryInfo _nugetFallbackFolder; static GivenThatTheUserIsRunningDotNetForTheFirstTime() { var testDirectory = TestAssets.CreateTestDirectory("Dotnet_first_time_experience_tests"); - var testNugetCache = Path.Combine(testDirectory.FullName, "nuget_cache"); + var testNuGetHome = Path.Combine(testDirectory.FullName, "nuget_home"); var command = new DotnetCommand() .WithWorkingDirectory(testDirectory); - command.Environment["NUGET_PACKAGES"] = testNugetCache; + command.Environment["HOME"] = testNuGetHome; + command.Environment["USERPROFILE"] = testNuGetHome; + command.Environment["APPDATA"] = testNuGetHome; command.Environment["DOTNET_SKIP_FIRST_TIME_EXPERIENCE"] = ""; command.Environment["SkipInvalidConfigurations"] = "true"; _firstDotnetNonVerbUseCommandResult = command.ExecuteWithCapturedOutput("--info"); _firstDotnetVerbUseCommandResult = command.ExecuteWithCapturedOutput("new --debug:ephemeral-hive"); - _nugetCacheFolder = new DirectoryInfo(testNugetCache); + _nugetFallbackFolder = new DirectoryInfo(Path.Combine(testNuGetHome, ".dotnet", "NuGetFallbackFolder")); } [Fact] @@ -82,7 +84,7 @@ A command is running to initially populate your local package cache, to improve [Fact] public void ItCreatesASentinelFileUnderTheNuGetCacheFolder() { - _nugetCacheFolder + _nugetFallbackFolder .Should() .HaveFile($"{GetDotnetVersion()}.dotnetSentinel"); } @@ -115,11 +117,11 @@ A command is running to initially populate your local package cache, to improve "microsoft.visualstudio.web.browserlink", }; - _nugetCacheFolder + _nugetFallbackFolder .Should() .HaveDirectories(expectedDirectories); - _nugetCacheFolder + _nugetFallbackFolder .Should() .NotHaveDirectories(unexpectedDirectories); }