diff --git a/src/Cake.Core/Packaging/PackageReference.cs b/src/Cake.Core/Packaging/PackageReference.cs index 1b4b681afc..1b393ec583 100644 --- a/src/Cake.Core/Packaging/PackageReference.cs +++ b/src/Cake.Core/Packaging/PackageReference.cs @@ -4,8 +4,8 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; +using System.Text; namespace Cake.Core.Packaging { @@ -44,6 +44,12 @@ public sealed class PackageReference /// The package. public string Package { get; } + /// + /// Gets the package version. + /// + /// The package version. + public string? Version { get; } + /// /// Initializes a new instance of the class. /// @@ -85,11 +91,39 @@ public PackageReference(Uri uri) nameof(uri)); } - Uri address; - if (Uri.TryCreate(uri.AbsolutePath, UriKind.Absolute, out address)) + if (Parameters.TryGetValue("version", out var versionParameters)) + { + if (versionParameters.Count == 1) + { + Version = versionParameters.FirstOrDefault(); + } + else if (versionParameters.Count > 1) + { + throw new ArgumentException( + "Query string contains more than one parameter 'version'.", + nameof(uri)); + } + } + + if (Uri.TryCreate(uri.AbsolutePath, UriKind.Absolute, out var address)) { Address = new Uri(address.AbsoluteUri); } } + + /// + public override string ToString() + { + var stringBuilder = new StringBuilder(); + + stringBuilder.Append(Package); + + if (!string.IsNullOrEmpty(Version)) + { + stringBuilder.Append($" v{Version}"); + } + + return stringBuilder.ToString(); + } } } \ No newline at end of file diff --git a/src/Cake.Core/Scripting/ScriptProcessor.cs b/src/Cake.Core/Scripting/ScriptProcessor.cs index bcc3031fb4..c63377fc53 100644 --- a/src/Cake.Core/Scripting/ScriptProcessor.cs +++ b/src/Cake.Core/Scripting/ScriptProcessor.cs @@ -105,7 +105,7 @@ public IReadOnlyList InstallAddins( if (assemblies.Count == 0) { const string format = "Failed to install addin '{0}'."; - var message = string.Format(CultureInfo.InvariantCulture, format, addin.Package); + var message = string.Format(CultureInfo.InvariantCulture, format, addin); throw new CakeException(message); } @@ -230,8 +230,7 @@ private void InstallPackages( private void CheckPackageVersion(PackageReference packageReference, string directiveName) { - bool existsVersionParameter = packageReference.Parameters.Any(x => x.Key.Equals("version", StringComparison.OrdinalIgnoreCase)); - if (!existsVersionParameter && !_skipPackageVersionCheck) + if (string.IsNullOrWhiteSpace(packageReference.Version) && !_skipPackageVersionCheck) { const string message = "The '{0}' directive is attempting to install the '{1}' package \r\n" + "without specifying a package version number. \r\n" + diff --git a/src/Cake.Core/Scripting/ScriptRunner.cs b/src/Cake.Core/Scripting/ScriptRunner.cs index 37dd842487..e045e52fdd 100644 --- a/src/Cake.Core/Scripting/ScriptRunner.cs +++ b/src/Cake.Core/Scripting/ScriptRunner.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Reflection; using Cake.Core.Configuration; @@ -75,6 +76,8 @@ public void Run(IScriptHost host, FilePath scriptPath) throw new ArgumentNullException(nameof(scriptPath)); } + var preparationStopwatch = Stopwatch.StartNew(); + // Make the script path absolute. scriptPath = scriptPath.MakeAbsolute(_environment); @@ -82,9 +85,14 @@ public void Run(IScriptHost host, FilePath scriptPath) _environment.WorkingDirectory = scriptPath.GetDirectory(); // Analyze the script file. + var analyzeStopwatch = Stopwatch.StartNew(); + _log.Verbose("Analyzing build script..."); var result = _analyzer.Analyze(scriptPath.GetFilename(), new ScriptAnalyzerSettings()); + analyzeStopwatch.Stop(); + _log.Verbose("Analyzed build script in {0}", analyzeStopwatch.Elapsed); + // Log all errors and throw if (!result.Succeeded) { @@ -98,10 +106,19 @@ public void Run(IScriptHost host, FilePath scriptPath) // Install tools. _log.Verbose("Processing build script..."); + + var toolsStopwatch = Stopwatch.StartNew(); + var toolsPath = GetToolPath(scriptPath.GetDirectory()); _processor.InstallTools(result.Tools, toolsPath); + toolsStopwatch.Stop(); + _log.Verbose("Installed tools in {0}", toolsStopwatch.Elapsed); + // Install addins. + + var addingsStopwatch = Stopwatch.StartNew(); + var addinRoot = GetAddinPath(scriptPath.GetDirectory()); var addinReferences = _processor.InstallAddins(result.Addins, addinRoot); foreach (var addinReference in addinReferences) @@ -109,6 +126,9 @@ public void Run(IScriptHost host, FilePath scriptPath) result.References.Add(addinReference.FullPath); } + addingsStopwatch.Stop(); + _log.Verbose("Installed addins in {0}", addingsStopwatch.Elapsed); + // Create and prepare the session. var session = _engine.CreateSession(host); @@ -167,6 +187,9 @@ public void Run(IScriptHost host, FilePath scriptPath) var defines = new HashSet(result.Defines, StringComparer.Ordinal); defines.AddRange(_conventions.GetDefaultDefines()); + preparationStopwatch.Stop(); + _log.Verbose("Preparation took {0}, going to execute the script", preparationStopwatch.Elapsed); + // Execute the script. var script = new Script(result.Namespaces, result.Lines, aliases, result.UsingAliases, result.UsingStaticDirectives, defines); session.Execute(script); diff --git a/src/Cake.NuGet/Installers/InProcessInstaller.cs b/src/Cake.NuGet/Installers/InProcessInstaller.cs index 5d60facb69..508394b8c3 100644 --- a/src/Cake.NuGet/Installers/InProcessInstaller.cs +++ b/src/Cake.NuGet/Installers/InProcessInstaller.cs @@ -211,7 +211,7 @@ public IReadOnlyCollection Install(PackageReference package, PackageType // If the installed package is not the target package, create a new PackageReference // which is passed to the content resolver. This makes logging make more sense. - var installedPackageReference = isTargetPackage ? package : new PackageReference($"nuget:?package={packageToInstall.Id}"); + var installedPackageReference = isTargetPackage ? package : new PackageReference($"nuget:?package={packageToInstall.Id}&version={packageToInstall.Version}"); var assemblies = _contentResolver.GetFiles(installPath, installedPackageReference, type); if (assemblies.Count == 0) {