/// <summary> /// </summary> /// <param name="fastPackageReference"></param> /// <param name="request"> /// An object passed in from the CORE that contains functions that can be used to interact with the /// CORE and HOST /// </param> public void InstallPackage(string fastPackageReference, NuGetRequest request) { // Nice-to-have put a debug message in that tells what's going on. request.Debug("Calling '{0}::InstallPackage' '{1}'", PackageProviderName, fastPackageReference); var pkgRef = request.GetPackageByFastpath(fastPackageReference); if (pkgRef == null) { request.Error(ErrorCategory.InvalidArgument, fastPackageReference, Constants.Messages.UnableToResolvePackage); return; } // need to make sure that the original package's sources list is tried first. request.OriginalSources = pkgRef.Sources; var dependencies = request.GetUninstalledPackageDependencies(pkgRef).Reverse().ToArray(); int progressId = 0; if (dependencies.Length > 0) { progressId = request.StartProgress(0, "Installing package '{0}'", pkgRef.GetCanonicalId(request)); } var n = 0; foreach (var d in dependencies) { request.Progress(progressId, (n*100/(dependencies.Length + 1)) + 1, "Installing dependent package '{0}'", d.GetCanonicalId(request)); if (!request.InstallSinglePackage(d)) { request.Error(ErrorCategory.InvalidResult, pkgRef.GetCanonicalId(request), Constants.Messages.DependentPackageFailedInstall, d.GetCanonicalId(request)); return; } n++; request.Progress(progressId, (n*100/(dependencies.Length + 1)), "Installed dependent package '{0}'", d.GetCanonicalId(request)); } // got this far, let's install the package we came here for. if (!request.InstallSinglePackage(pkgRef)) { // package itself didn't install. // roll that back out everything we did install. // and get out of here. request.Error(ErrorCategory.InvalidResult, pkgRef.GetCanonicalId(request), Constants.Messages.PackageFailedInstall, pkgRef.GetCanonicalId(request)); request.CompleteProgress(progressId, false); } request.CompleteProgress(progressId, true); }
/// <summary> /// Install a single package. Also install any of its dependency if they are available (the dependency will be installed first). /// For dependencies, we will only get those that are not installed. /// Operation is either install or download /// installOrDownloadFunction is a function that takes in a packageitem and performs either install or download on it /// </summary> /// <param name="pkgItem"></param> /// <param name="request"></param> /// <param name="operation"></param> /// <param name="installOrDownloadFunction"></param> /// <returns></returns> internal static bool InstallOrDownloadPackageHelper(PackageItem pkgItem, NuGetRequest request, string operation, Func<PackageItem, bool> installOrDownloadFunction) { // pkgItem.Sources is the source that the user input. The request will try this source. request.OriginalSources = pkgItem.Sources; int progressId = 0; bool hasDependencyLoop = false; // Get the dependencies that are not already installed var dependencies = NuGetClient.GetPackageDependenciesToInstall(request, pkgItem, ref hasDependencyLoop).ToArray(); // If there is a dependency loop. Warn the user and don't install the package if (hasDependencyLoop) { // package itself didn't install. Report error request.WriteError(ErrorCategory.DeadlockDetected, pkgItem.Id, Constants.Messages.DependencyLoopDetected, pkgItem.Id); return false; } // request may get canceled if there is a package dependencies missing if (request.IsCanceled) { return false; } int n = 0; int numberOfDependencies = dependencies.Count(); // Start progress progressId = request.StartProgress(0, string.Format(CultureInfo.InvariantCulture, Messages.InstallingOrDownloadingPackage, operation, pkgItem.Id)); try { // check that this package has dependency and the user didn't want to skip dependencies if (numberOfDependencies > 0) { // let's install dependencies foreach (var dep in dependencies) { request.Progress(progressId, (n * 100 / (numberOfDependencies + 1)) + 1, string.Format(CultureInfo.InvariantCulture, Messages.InstallingOrDownloadingDependencyPackage, operation, dep.Id)); // Check that we successfully installed the dependency if (!installOrDownloadFunction(dep)) { request.WriteError(ErrorCategory.InvalidResult, dep.Id, Constants.Messages.DependentPackageFailedInstallOrDownload, dep.Id, CultureInfo.CurrentCulture.TextInfo.ToLower(operation)); return false; } n++; request.Progress(progressId, (n * 100 / (numberOfDependencies + 1)), string.Format(CultureInfo.InvariantCulture, Messages.InstalledOrDownloadedDependencyPackage, operation, dep.Id)); } } // Now let's install the main package if (installOrDownloadFunction(pkgItem)) { return true; } } catch (Exception ex) { ex.Dump(request); } finally { // Report that we have completed installing the package and its dependency this does not mean there are no errors. // Just that it's completed. request.CompleteProgress(progressId, false); } // package itself didn't install. Report error request.WriteError(ErrorCategory.InvalidResult, pkgItem.Id, Constants.Messages.PackageFailedInstallOrDownload, pkgItem.Id, CultureInfo.CurrentCulture.TextInfo.ToLower(operation)); return false; }