/// <summary> /// Find the installed package <paramref name="packageId"/> using the version <paramref name="version"/> if not null, otherwise the <paramref name="constraintProvider"/> if specified. /// If no constraints are specified, the first found entry, whatever it means for NuGet, is used. /// </summary> /// <param name="packageId">Name of the package.</param> /// <param name="version">The version.</param> /// <param name="constraintProvider">The package constraint provider.</param> /// <param name="allowPrereleaseVersions">if set to <c>true</c> [allow prelease version].</param> /// <param name="allowUnlisted">if set to <c>true</c> [allow unlisted].</param> /// <returns>A Package matching the search criterion or null if not found.</returns> /// <exception cref="System.ArgumentNullException">packageId</exception> /// <returns></returns> public NugetPackage FindLocalPackage(string packageId, PackageVersion version = null, ConstraintProvider constraintProvider = null, bool allowPrereleaseVersions = true, bool allowUnlisted = false) { var package = manager.LocalRepository.FindPackage(packageId, version?.ToSemanticVersion(), constraintProvider?.Provider(), allowPrereleaseVersions, allowUnlisted); return(package != null ? new NugetPackage(package) : null); }
/// <summary> /// Fetch, if not already downloaded, and install the package represented by /// (<paramref name="packageId"/>, <paramref name="version"/>). /// </summary> /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks> /// <param name="packageId">Name of package to install.</param> /// <param name="version">Version of package to install.</param> /// <param name="progress">Callbacks to report progress of downloads.</param> public async Task InstallPackage(string packageId, PackageVersion version, ProgressReport progress) { using (GetLocalRepositoryLock()) { currentProgressReport = progress; try { var package = manager.LocalRepository.FindPackage(packageId, version.ToSemanticVersion(), null, allowPrereleaseVersions: true, allowUnlisted: true); if (package == null) { // Let's search in our cache try { package = MachineCache.Default.FindPackage(packageId, version.ToSemanticVersion(), allowPrereleaseVersions: true, allowUnlisted: true); } catch (InvalidDataException) { // Package is somehow corrupted. We ignore this and will redownload the file. } // It represents the name of the .nupkg in our cache var sourceName = Path.Combine(CacheDirectory, PathResolver.GetPackageFileName(packageId, version.ToSemanticVersion())); if (package == null) { // Always recreate cache in case it was deleted. if (!Directory.Exists(CacheDirectory)) { Directory.CreateDirectory(CacheDirectory); } package = manager.SourceRepository.FindPackage(packageId, version.ToSemanticVersion(), NullConstraintProvider.Instance, allowPrereleaseVersions: true, allowUnlisted: true); if (package == null) { throw new ApplicationException("Cannot find package"); } // Package has to be downloaded if it is a DataServicePackage which was not found in our cache. if (package is DataServicePackage) { var downloadPackage = (DataServicePackage)package; var url = downloadPackage.DownloadUrl; var client = new WebClient(); var tcs = new TaskCompletionSource <bool>(); progress?.UpdateProgress(ProgressAction.Download, 0); client.DownloadProgressChanged += (o, e) => progress?.UpdateProgress(ProgressAction.Download, e.ProgressPercentage); client.DownloadFileCompleted += (o, e) => tcs.SetResult(true); client.DownloadFileAsync(url, sourceName); await tcs.Task; progress?.UpdateProgress(ProgressAction.Download, 100); } } progress?.UpdateProgress(ProgressAction.Install, -1); manager.InstallPackage(package, ignoreDependencies: false, allowPrereleaseVersions: true); OptimizedZipPackage.PurgeCache(); } // Every time a new package is installed, we are updating the common targets UpdateTargetsHelper(); } finally { currentProgressReport = null; } } }