diff --git a/src/Cake.NuGet.Tests/Fixtures/NuGetModuleFixture.cs b/src/Cake.NuGet.Tests/Fixtures/NuGetModuleFixture.cs index ec60afe51e..86080e8a91 100644 --- a/src/Cake.NuGet.Tests/Fixtures/NuGetModuleFixture.cs +++ b/src/Cake.NuGet.Tests/Fixtures/NuGetModuleFixture.cs @@ -4,6 +4,8 @@ using System; using Cake.Core.Composition; +using Cake.Core.Configuration; +using Cake.Testing; using NSubstitute; namespace Cake.NuGet.Tests.Fixtures @@ -12,11 +14,13 @@ internal sealed class NuGetModuleFixture { public ICakeContainerRegistrar Registrar { get; } public ICakeRegistrationBuilder Builder { get; } + public FakeConfiguration Configuration { get; } public NuGetModuleFixture() { Registrar = Substitute.For(); Builder = Substitute.For(); + Configuration = new FakeConfiguration(); Registrar.RegisterType().Returns(Builder); Builder.As(Arg.Any()).Returns(Builder); @@ -24,5 +28,10 @@ public NuGetModuleFixture() Builder.Transient().Returns(Builder); Builder.AsSelf().Returns(Builder); } + + public NuGetModule CreateModule() + { + return new NuGetModule(Configuration); + } } } \ No newline at end of file diff --git a/src/Cake.NuGet.Tests/Unit/NuGetLoadDirectiveProviderTests.cs b/src/Cake.NuGet.Tests/Unit/NuGetLoadDirectiveProviderTests.cs index bcd6dc921d..2ecaa0d49e 100644 --- a/src/Cake.NuGet.Tests/Unit/NuGetLoadDirectiveProviderTests.cs +++ b/src/Cake.NuGet.Tests/Unit/NuGetLoadDirectiveProviderTests.cs @@ -31,20 +31,7 @@ public void Should_Return_True_If_Provider_Is_NuGet() public sealed class TheLoadMethod { - [RuntimeFact(TestRuntime.CoreClr)] - public void Should_Throw_On_NET_Core() - { - // Given - var fixture = new NuGetLoadDirectiveProviderFixture(); - - // When - var result = Record.Exception(() => fixture.Load()); - - // Then - AssertEx.IsExceptionWithMessage(result, "The NuGet provider for #load is not supported on .NET Core."); - } - - [RuntimeFact(TestRuntime.Clr)] + [Fact] public void Should_Install_Package() { // Given @@ -57,7 +44,7 @@ public void Should_Install_Package() Assert.Equal("nuget:?package=Cake.Recipe&include=./**/*.cake", result.Package.OriginalString); } - [RuntimeFact(TestRuntime.Clr)] + [Fact] public void Should_Install_Correct_Package_Type() { // Given @@ -70,7 +57,7 @@ public void Should_Install_Correct_Package_Type() Assert.Equal(PackageType.Tool, result.PackageType); } - [RuntimeFact(TestRuntime.Clr)] + [Fact] public void Should_Install_Package_In_The_Tools_Directory() { // Given @@ -83,7 +70,7 @@ public void Should_Install_Package_In_The_Tools_Directory() Assert.Equal("/Working/tools", result.InstallPath.FullPath); } - [RuntimeFact(TestRuntime.Clr)] + [Fact] public void Should_Install_Package_In_Custom_Tools_Directory_If_Specified_In_Configuration() { // Given @@ -97,7 +84,7 @@ public void Should_Install_Package_In_Custom_Tools_Directory_If_Specified_In_Con Assert.Equal("/Working/Bar", result.InstallPath.FullPath); } - [RuntimeFact(TestRuntime.Clr)] + [Fact] public void Should_Analyze_Installed_Cake_Scripts() { // Given @@ -113,7 +100,7 @@ public void Should_Analyze_Installed_Cake_Scripts() Assert.Equal("/Working/tools/Cake.Recipe/file.cake", result.AnalyzedFiles[0].FullPath); } - [RuntimeFact(TestRuntime.Clr)] + [Fact] public void Should_Write_To_Log_If_No_Scripts_Were_Found() { // Given diff --git a/src/Cake.NuGet.Tests/Unit/NuGetModuleTests.cs b/src/Cake.NuGet.Tests/Unit/NuGetModuleTests.cs index f515993a41..aed6627967 100644 --- a/src/Cake.NuGet.Tests/Unit/NuGetModuleTests.cs +++ b/src/Cake.NuGet.Tests/Unit/NuGetModuleTests.cs @@ -6,6 +6,7 @@ using Cake.Core.Packaging; using Cake.Core.Scripting.Processors.Loading; using Cake.NuGet.Tests.Fixtures; +using Cake.Testing.Xunit; using NSubstitute; using Xunit; @@ -20,7 +21,7 @@ public void Should_Register_The_NuGet_Content_Resolver() { // Given var fixture = new NuGetModuleFixture(); - var module = new NuGetModule(); + var module = fixture.CreateModule(); // When module.Register(fixture.Registrar); @@ -31,13 +32,12 @@ public void Should_Register_The_NuGet_Content_Resolver() fixture.Builder.Received(1).Singleton(); } -#if !NETCORE - [Fact] + [RuntimeFact(TestRuntime.Clr)] public void Should_Register_The_NuGet_Load_Directive_Provider() { // Given var fixture = new NuGetModuleFixture(); - var module = new NuGetModule(); + var module = fixture.CreateModule(); // When module.Register(fixture.Registrar); @@ -47,14 +47,47 @@ public void Should_Register_The_NuGet_Load_Directive_Provider() fixture.Builder.Received(1).As(); fixture.Builder.Received(1).Singleton(); } -#endif + + [RuntimeFact(TestRuntime.CoreClr)] + public void Should_Register_The_NuGet_Load_Directive_Provider_When_Using_In_Process_Client() + { + // Given + var fixture = new NuGetModuleFixture(); + fixture.Configuration.SetValue(Constants.NuGet.UseInProcessClient, bool.TrueString); + var module = fixture.CreateModule(); + + // When + module.Register(fixture.Registrar); + + // Then + fixture.Registrar.Received(1).RegisterType(); + fixture.Builder.Received(1).As(); + fixture.Builder.Received(1).Singleton(); + } + + [RuntimeFact(TestRuntime.CoreClr)] + public void Should_Not_Register_The_NuGet_Load_Directive_Provider_When_Not_Using_In_Process_Client() + { + // Given + var fixture = new NuGetModuleFixture(); + fixture.Configuration.SetValue(Constants.NuGet.UseInProcessClient, bool.FalseString); + var module = fixture.CreateModule(); + + // When + module.Register(fixture.Registrar); + + // Then + fixture.Registrar.Received(0).RegisterType(); + fixture.Builder.Received(0).As(); + fixture.Builder.Received(0).Singleton(); + } [Fact] - public void Shouls_Register_The_NuGet_Package_Installer() + public void Should_Register_The_NuGet_Package_Installer() { // Given var fixture = new NuGetModuleFixture(); - var module = new NuGetModule(); + var module = fixture.CreateModule(); // When module.Register(fixture.Registrar); @@ -65,6 +98,24 @@ public void Shouls_Register_The_NuGet_Package_Installer() fixture.Builder.Received(1).As(); fixture.Builder.Received(1).Singleton(); } + + [Fact] + public void Should_Register_The_In_Process_NuGet_Package_Installer_If_Set_In_Configuration() + { + // Given + var fixture = new NuGetModuleFixture(); + fixture.Configuration.SetValue(Constants.NuGet.UseInProcessClient, bool.TrueString); + var module = fixture.CreateModule(); + + // When + module.Register(fixture.Registrar); + + // Then + fixture.Registrar.Received(1).RegisterType(); + fixture.Builder.Received(1).As(); + fixture.Builder.Received(1).As(); + fixture.Builder.Received(1).Singleton(); + } } } } \ No newline at end of file diff --git a/src/Cake.NuGet/Cake.NuGet.csproj b/src/Cake.NuGet/Cake.NuGet.csproj index 24e4d8fa4d..27356eca22 100644 --- a/src/Cake.NuGet/Cake.NuGet.csproj +++ b/src/Cake.NuGet/Cake.NuGet.csproj @@ -25,12 +25,19 @@ + + + + + + + diff --git a/src/Cake.NuGet/Constants.cs b/src/Cake.NuGet/Constants.cs index c8a9c5d024..c5a74d81e7 100644 --- a/src/Cake.NuGet/Constants.cs +++ b/src/Cake.NuGet/Constants.cs @@ -12,6 +12,16 @@ public static class NuGet /// The config key name for overriding the default nuget package source /// public const string Source = "NuGet_Source"; + + /// + /// The config key name for using the in process client for installing packages + /// + public const string UseInProcessClient = "NuGet_UseInProcessClient"; + + /// + /// The config key name for enabling loading of nuget package dependencies + /// + public const string LoadDependencies = "NuGet_LoadDependencies"; } } } \ No newline at end of file diff --git a/src/Cake.NuGet/Install/NuGetFolderProject.cs b/src/Cake.NuGet/Install/NuGetFolderProject.cs new file mode 100644 index 0000000000..64f3b791bc --- /dev/null +++ b/src/Cake.NuGet/Install/NuGetFolderProject.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Cake.Core.Configuration; +using Cake.Core.Diagnostics; +using Cake.Core.IO; +using NuGet.Packaging.Core; +using NuGet.ProjectManagement; +using NuGet.Protocol.Core.Types; +using PackageReference = Cake.Core.Packaging.PackageReference; +using PackageType = Cake.Core.Packaging.PackageType; + +namespace Cake.NuGet.Install +{ + internal sealed class NugetFolderProject : FolderNuGetProject + { + private readonly ISet _installedPackages; + private readonly INuGetContentResolver _contentResolver; + private readonly ICakeConfiguration _config; + private readonly ICakeLog _log; + private static readonly ISet _blackListedPackages = new HashSet(new[] + { + "Cake.Common", + "Cake.Core" + }, StringComparer.OrdinalIgnoreCase); + + public NugetFolderProject(INuGetContentResolver contentResolver, ICakeConfiguration config, ICakeLog log, string root) : base(root) + { + _contentResolver = contentResolver ?? throw new ArgumentNullException(nameof(contentResolver)); + _config = config ?? throw new ArgumentNullException(nameof(config)); + _log = log ?? throw new ArgumentNullException(nameof(log)); + _installedPackages = new HashSet(); + } + + public override Task InstallPackageAsync(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, + INuGetProjectContext nuGetProjectContext, CancellationToken token) + { + _installedPackages.Add(packageIdentity); + return base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token); + } + + public IReadOnlyCollection GetFiles(DirectoryPath directoryPath, PackageReference packageReference, PackageType type) + { + bool loadDependencies; + if (packageReference.Parameters.ContainsKey("LoadDependencies")) + { + bool.TryParse(packageReference.Parameters["LoadDependencies"].FirstOrDefault() ?? bool.TrueString, out loadDependencies); + } + else + { + bool.TryParse(_config.GetValue(Constants.NuGet.LoadDependencies) ?? bool.FalseString, out loadDependencies); + } + + var files = new List(); + var package = _installedPackages.First(p => p.Id.Equals(packageReference.Package, StringComparison.OrdinalIgnoreCase)); + files.AddRange(_contentResolver.GetFiles(new FilePath(GetInstalledManifestFilePath(package)).GetDirectory(), packageReference, type)); + + if (loadDependencies) + { + foreach (var dependency in _installedPackages + .Where(p => !p.Id.Equals(packageReference.Package, StringComparison.OrdinalIgnoreCase))) + { + if (_blackListedPackages.Contains(dependency.Id)) + { + _log.Warning("Package {0} depends on package {1}. Will not load this dependency...", + packageReference.Package, dependency.ToString()); + continue; + } + files.AddRange(_contentResolver.GetFiles(new FilePath(GetInstalledManifestFilePath(dependency)).GetDirectory(), packageReference, type)); + } + } + + return files; + } + } +} diff --git a/src/Cake.NuGet/Install/NuGetLogger.cs b/src/Cake.NuGet/Install/NuGetLogger.cs new file mode 100644 index 0000000000..1691043595 --- /dev/null +++ b/src/Cake.NuGet/Install/NuGetLogger.cs @@ -0,0 +1,84 @@ +using System; +using System.Threading.Tasks; +using Cake.Core.Diagnostics; +using NuGet.Common; +using LogLevel = NuGet.Common.LogLevel; + +namespace Cake.NuGet.Install +{ + internal sealed class NuGetLogger : ILogger + { + private readonly ICakeLog _log; + + private static Core.Diagnostics.LogLevel GetLogLevel(LogLevel logLevel) + { + switch (logLevel) + { + case LogLevel.Minimal: + return Core.Diagnostics.LogLevel.Information; + case LogLevel.Verbose: + return Core.Diagnostics.LogLevel.Verbose; + case LogLevel.Warning: + return Core.Diagnostics.LogLevel.Warning; + case LogLevel.Error: + return Core.Diagnostics.LogLevel.Error; + default: + return Core.Diagnostics.LogLevel.Debug; + } + } + + private static Verbosity GetVerbosity(LogLevel logLevel) + { + switch (logLevel) + { + case LogLevel.Debug: + return Verbosity.Diagnostic; + case LogLevel.Verbose: + return Verbosity.Verbose; + case LogLevel.Warning: + return Verbosity.Minimal; + case LogLevel.Error: + return Verbosity.Quiet; + default: + return Verbosity.Normal; + } + } + + public NuGetLogger(ICakeLog log) + { + _log = log ?? throw new ArgumentNullException(nameof(log)); + } + + public void LogDebug(string data) => _log.Debug(data); + + public void LogVerbose(string data) => _log.Verbose(data); + + public void LogInformation(string data) => _log.Debug(data); + + public void LogMinimal(string data) => _log.Information(data); + + public void LogWarning(string data) => _log.Warning(data); + + public void LogError(string data) => _log.Error(data); + + public void LogInformationSummary(string data) => _log.Information(data); + + public void LogErrorSummary(string data) => _log.Error(data); + + public void Log(LogLevel level, string data) => _log.Write(GetVerbosity(level), GetLogLevel(level), data); + + public Task LogAsync(LogLevel level, string data) + { + Log(level, data); + return Task.CompletedTask; + } + + public void Log(ILogMessage message) => Log(message.Level, message.Message); + + public Task LogAsync(ILogMessage message) + { + Log(message); + return Task.CompletedTask; + } + } +} diff --git a/src/Cake.NuGet/Install/NuGetPackageInstaller.cs b/src/Cake.NuGet/Install/NuGetPackageInstaller.cs new file mode 100644 index 0000000000..d52fd83883 --- /dev/null +++ b/src/Cake.NuGet/Install/NuGetPackageInstaller.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using Cake.Core; +using Cake.Core.Configuration; +using Cake.Core.Diagnostics; +using Cake.Core.IO; +using Cake.Core.Packaging; +using NuGet.Common; +using NuGet.Configuration; +using NuGet.Frameworks; +using NuGet.PackageManagement; +using NuGet.Packaging.Core; +using NuGet.Protocol.Core.Types; +using NuGet.Resolver; +using NuGet.Versioning; +using PackageType = Cake.Core.Packaging.PackageType; + +namespace Cake.NuGet.Install +{ + internal sealed class NuGetPackageInstaller : INuGetPackageInstaller + { + private readonly ICakeEnvironment _environment; + private readonly INuGetContentResolver _contentResolver; + private readonly ICakeLog _log; + private readonly ICakeConfiguration _config; + private readonly ISettings _nugetSettings; + private readonly NuGetFramework _currentFramework; + private readonly ILogger _nugetLogger; + + /// + /// Initializes a new instance of the class. + /// + /// The environment. + /// The content resolver. + /// The log. + /// the configuration + public NuGetPackageInstaller( + ICakeEnvironment environment, + INuGetContentResolver contentResolver, + ICakeLog log, + ICakeConfiguration config) + { + _environment = environment ?? throw new ArgumentNullException(nameof(environment)); + _contentResolver = contentResolver ?? throw new ArgumentNullException(nameof(contentResolver)); + _log = log ?? throw new ArgumentNullException(nameof(log)); + _config = config ?? throw new ArgumentNullException(nameof(config)); + _currentFramework = NuGetFramework.Parse(_environment.Runtime.TargetFramework.FullName, DefaultFrameworkNameProvider.Instance); + _nugetLogger = new NuGetLogger(_log); + _nugetSettings = Settings.LoadDefaultSettings( + _environment.WorkingDirectory.MakeAbsolute(_environment).FullPath, + null, + new XPlatMachineWideSetting()); + } + + public bool CanInstall(PackageReference package, PackageType type) + { + if (package == null) + { + throw new ArgumentNullException(nameof(package)); + } + return package.Scheme.Equals("nuget", StringComparison.OrdinalIgnoreCase); + } + + public IReadOnlyCollection Install(PackageReference package, PackageType type, DirectoryPath path) + { + if (package == null) + { + throw new ArgumentNullException(nameof(package)); + } + if (path == null) + { + throw new ArgumentNullException(nameof(path)); + } + + var sourceRepositoryProvider = new NuGetSourceRepositoryProvider(_nugetSettings, _config, package); + var packageIdentity = GetPackageId(package, sourceRepositoryProvider); + if (packageIdentity == null) + { + return Array.Empty(); + } + + var packageRoot = path.MakeAbsolute(_environment).FullPath; + var nuGetProject = new NugetFolderProject(_contentResolver, _config, _log, packageRoot); + var packageManager = new NuGetPackageManager(sourceRepositoryProvider, _nugetSettings, packageRoot) + { + PackagesFolderNuGetProject = nuGetProject + }; + + var sourceRepositories = !packageManager.PackageExistsInPackagesFolder(packageIdentity) + ? sourceRepositoryProvider.GetRepositories() + : new[] { sourceRepositoryProvider.CreateRepository(packageRoot) }; + var includePrerelease = false; + if (package.Parameters.ContainsKey("prerelease")) + { + bool.TryParse(package.Parameters["prerelease"].FirstOrDefault() ?? bool.TrueString, out includePrerelease); + } + var resolutionContext = new ResolutionContext(DependencyBehavior.Lowest, includePrerelease, false, VersionConstraints.None); + var projectContext = new NuGetProjectContext(_log); + packageManager.InstallPackageAsync(nuGetProject, packageIdentity, resolutionContext, projectContext, + sourceRepositories, Array.Empty(), + CancellationToken.None).Wait(); + + return nuGetProject.GetFiles(path, package, type); + } + + private PackageIdentity GetPackageId(PackageReference package, NuGetSourceRepositoryProvider sourceRepositoryProvider) + { + var version = GetNuGetVersion(package, sourceRepositoryProvider); + return version == null ? null : new PackageIdentity(package.Package, version); + } + + private NuGetVersion GetNuGetVersion(PackageReference package, NuGetSourceRepositoryProvider sourceRepositoryProvider) + { + if (package.Parameters.ContainsKey("version")) + { + return new NuGetVersion(package.Parameters["version"].First()); + } + + var includePrerelease = false; + if (package.Parameters.ContainsKey("prerelease")) + { + bool.TryParse(package.Parameters["prerelease"].FirstOrDefault() ?? bool.TrueString, out includePrerelease); + } + + foreach (var sourceRepository in sourceRepositoryProvider.GetRepositories()) + { + var dependencyInfoResource = sourceRepository.GetResourceAsync().Result; + var dependencyInfo = dependencyInfoResource.ResolvePackages(package.Package, _currentFramework, _nugetLogger, CancellationToken.None).Result; + var version = dependencyInfo + .Where(p => p.Listed && (includePrerelease || !p.Version.IsPrerelease)) + .OrderByDescending(p => p.Version, VersionComparer.Default) + .Select(p => p.Version) + .FirstOrDefault(); + + if (version != null) + { + return version; + } + } + return null; + } + } +} diff --git a/src/Cake.NuGet/Install/NuGetProjectContext.cs b/src/Cake.NuGet/Install/NuGetProjectContext.cs new file mode 100644 index 0000000000..407f951bbc --- /dev/null +++ b/src/Cake.NuGet/Install/NuGetProjectContext.cs @@ -0,0 +1,61 @@ +using System; +using System.Xml.Linq; +using Cake.Core.Diagnostics; +using NuGet.Packaging; +using NuGet.ProjectManagement; + +namespace Cake.NuGet.Install +{ + internal sealed class NuGetProjectContext : INuGetProjectContext + { + private readonly ICakeLog _log; + + public NuGetProjectContext(ICakeLog log) + { + _log = log ?? throw new ArgumentNullException(nameof(log)); + PackageExtractionContext = new PackageExtractionContext(new NuGetLogger(_log)) + { + PackageSaveMode = PackageSaveMode.Nuspec | PackageSaveMode.Files + }; + } + + public void Log(MessageLevel level, string message, params object[] args) + { + switch (level) + { + case MessageLevel.Warning: + _log.Warning(message, args); + break; + case MessageLevel.Error: + _log.Error(message, args); + break; + default: + _log.Debug(message, args); + break; + } + } + + public void ReportError(string message) + { + _log.Error(message); + } + + public FileConflictAction ResolveFileConflict(string message) + { + _log.Debug(message); + return FileConflictAction.Ignore; + } + + public PackageExtractionContext PackageExtractionContext { get; set; } + + public ISourceControlManagerProvider SourceControlManagerProvider => null; + + public ExecutionContext ExecutionContext => null; + + public XDocument OriginalPackagesConfig { get; set; } + + public NuGetActionType ActionType { get; set; } + + public TelemetryServiceHelper TelemetryService { get; set; } + } +} diff --git a/src/Cake.NuGet/Install/NuGetSourceRepositoryProvider.cs b/src/Cake.NuGet/Install/NuGetSourceRepositoryProvider.cs new file mode 100644 index 0000000000..defba058d9 --- /dev/null +++ b/src/Cake.NuGet/Install/NuGetSourceRepositoryProvider.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using Cake.Core.Configuration; +using Cake.Core.Packaging; +using NuGet.Configuration; +using NuGet.Protocol; +using NuGet.Protocol.Core.Types; + +namespace Cake.NuGet.Install +{ + internal sealed class NuGetSourceRepositoryProvider : ISourceRepositoryProvider + { + private readonly List> _resourceProviders; + private readonly List _repositories; + + public NuGetSourceRepositoryProvider(ISettings settings, ICakeConfiguration config, PackageReference package) + { + // Create the package source provider (needed primarily to get default sources) + PackageSourceProvider = new PackageSourceProvider(settings); + + // Create the default v3 resource provider + _resourceProviders = new List>(); + _resourceProviders.AddRange(Repository.Provider.GetCoreV3()); + + // Add repositories + _repositories = new List(); + + if (package.Address != null) + { + CreateRepository(package.Address.AbsoluteUri); + } + var nugetSource = config.GetValue(Constants.NuGet.Source); + if (!string.IsNullOrWhiteSpace(nugetSource)) + { + CreateRepository(nugetSource); + } + foreach (var source in PackageSourceProvider.LoadPackageSources()) + { + CreateRepository(source); + } + } + + public IEnumerable GetRepositories() => _repositories; + + public SourceRepository CreateRepository(string source) => CreateRepository(new PackageSource(source)); + + public SourceRepository CreateRepository(PackageSource source) => CreateRepository(source, FeedType.Undefined); + + public SourceRepository CreateRepository(PackageSource source, FeedType type) + { + var repository = new SourceRepository(source, _resourceProviders); + _repositories.Add(repository); + return repository; + } + + public IPackageSourceProvider PackageSourceProvider { get; } + } +} diff --git a/src/Cake.NuGet/NuGetLoadDirectiveProvider.cs b/src/Cake.NuGet/NuGetLoadDirectiveProvider.cs index 9b221b4187..83537288c7 100644 --- a/src/Cake.NuGet/NuGetLoadDirectiveProvider.cs +++ b/src/Cake.NuGet/NuGetLoadDirectiveProvider.cs @@ -39,9 +39,6 @@ public bool CanLoad(IScriptAnalyzerContext context, LoadReference reference) public void Load(IScriptAnalyzerContext context, LoadReference reference) { -#if NETCORE - throw new NotSupportedException("The NuGet provider for #load is not supported on .NET Core."); -#else // Create a package reference from our load reference. // The package should contain the necessary include parameters to make sure // that .cake files are included as part of the result. @@ -69,7 +66,6 @@ public void Load(IScriptAnalyzerContext context, LoadReference reference) context.Analyze(file.Path); } } -#endif } private DirectoryPath GetToolPath(DirectoryPath root) diff --git a/src/Cake.NuGet/NuGetModule.cs b/src/Cake.NuGet/NuGetModule.cs index 44b8b0d2f1..807cc1564a 100644 --- a/src/Cake.NuGet/NuGetModule.cs +++ b/src/Cake.NuGet/NuGetModule.cs @@ -4,6 +4,7 @@ using System; using Cake.Core.Composition; +using Cake.Core.Configuration; using Cake.Core.Packaging; using Cake.Core.Scripting.Processors.Loading; @@ -15,6 +16,17 @@ namespace Cake.NuGet /// public sealed class NuGetModule : ICakeModule { + private readonly ICakeConfiguration _config; + + /// + /// Initializes a new instance of the class. + /// + /// The config. + public NuGetModule(ICakeConfiguration config) + { + _config = config ?? throw new ArgumentNullException(nameof(config)); + } + /// /// Performs custom registrations in the provided registrar. /// @@ -32,17 +44,34 @@ public void Register(ICakeContainerRegistrar registrar) .Singleton(); #if !NETCORE - // Load directive not available for .NET Core + // Load directive provider. registrar.RegisterType() .As() .Singleton(); #endif // URI resource support. - registrar.RegisterType() - .As() - .As() - .Singleton(); + bool.TryParse(_config.GetValue(Constants.NuGet.UseInProcessClient) ?? bool.FalseString, out bool useInProcessClient); + if (useInProcessClient) + { +#if NETCORE + // Load directive provider. + registrar.RegisterType() + .As() + .Singleton(); +#endif + registrar.RegisterType() + .As() + .As() + .Singleton(); + } + else + { + registrar.RegisterType() + .As() + .As() + .Singleton(); + } } } } \ No newline at end of file diff --git a/src/Cake/Program.cs b/src/Cake/Program.cs index 2911babb3a..abb6e5ad5e 100644 --- a/src/Cake/Program.cs +++ b/src/Cake/Program.cs @@ -9,6 +9,7 @@ using Cake.Common.Modules; using Cake.Composition; using Cake.Core; +using Cake.Core.Composition; using Cake.Core.Configuration; using Cake.Core.Diagnostics; using Cake.Core.Modules; @@ -44,7 +45,6 @@ public static int Main() builder.RegisterModule(new CakeModule()); builder.RegisterModule(new CoreModule()); builder.RegisterModule(new CommonModule()); - builder.RegisterModule(new NuGetModule()); // Build the container. using (var container = builder.Build()) @@ -67,6 +67,12 @@ public static int Main() builder.RegisterModule(new ScriptingModule(options, log)); builder.Update(container); + // Register the NuGetModule + builder = new ContainerRegistrar(); + var configuration = container.Resolve(); + builder.RegisterModule(new NuGetModule(configuration)); + builder.Update(container); + // Load all modules. var loader = container.Resolve(); loader.LoadModules(container, options);