public void GetCoreV3_WithCustomFactory_ReturnsCustomResult() { var factory = new CustomProviderFactory(); IEnumerable <Lazy <INuGetResourceProvider> > resourceProviders = FactoryExtensionsV3.GetCoreV3(factory); Assert.Same(factory.ExpectedResult, resourceProviders); }
public Task InitialAsync() { List <Lazy <INuGetResourceProvider> > _resourceProviders = new List <Lazy <INuGetResourceProvider> >(); _resourceProviders.AddRange(FactoryExtensionsV3.GetCoreV3(Repository.Provider)); SolutionDirectory = _solutionDiretoryManager.DiretoryPath; Settings = _nuGetSettingsAccessor.Settings.Value; PackagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(SolutionDirectory, Settings); _packageSourceProvider = new PackageSourceProvider(Settings); _sourceRepositoryProvider = new SourceRepositoryProvider(_packageSourceProvider, _resourceProviders); _packageExtractionContext = new PackageExtractionContext( PackageSaveMode.Defaultv2, PackageExtractionBehavior.XmlDocFileSaveMode, ClientPolicyContext.GetClientPolicy(Settings, _logger), _logger); _packageManager = CreatePackageManager(); return(Task.CompletedTask); }
public CommandLineSourceRepositoryProvider(Configuration.IPackageSourceProvider packageSourceProvider) { _packageSourceProvider = packageSourceProvider; _resourceProviders = new List <Lazy <INuGetResourceProvider> >(); _resourceProviders.AddRange(FactoryExtensionsV3.GetCoreV3(Repository.Provider)); // Create repositories _repositories = _packageSourceProvider.LoadPackageSources() .Where(s => s.IsEnabled) .Select(CreateRepository) .ToList(); }
private List <PSResourceInfo> InstallPackage( IEnumerable <PSResourceInfo> pkgsToInstall, // those found to be required to be installed (includes Dependency packages as well) string repoUrl, PSCredential credential, bool isLocalRepo) { List <PSResourceInfo> pkgsSuccessfullyInstalled = new List <PSResourceInfo>(); int totalPkgs = pkgsToInstall.Count(); // Counters for tracking current package out of total int totalInstalledPkgCount = 0; foreach (PSResourceInfo pkg in pkgsToInstall) { totalInstalledPkgCount++; var tempInstallPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); try { // Create a temp directory to install to var dir = Directory.CreateDirectory(tempInstallPath); // should check it gets created properly // To delete file attributes from the existing ones get the current file attributes first and use AND (&) operator // with a mask (bitwise complement of desired attributes combination). // TODO: check the attributes and if it's read only then set it // attribute may be inherited from the parent // TODO: are there Linux accommodations we need to consider here? dir.Attributes &= ~FileAttributes.ReadOnly; _cmdletPassedIn.WriteVerbose(string.Format("Begin installing package: '{0}'", pkg.Name)); if (!_quiet) { int activityId = 0; int percentComplete = ((totalInstalledPkgCount * 100) / totalPkgs); string activity = string.Format("Installing {0}...", pkg.Name); string statusDescription = string.Format("{0}% Complete", percentComplete); _cmdletPassedIn.WriteProgress( new ProgressRecord(activityId, activity, statusDescription)); } // Create PackageIdentity in order to download string createFullVersion = pkg.Version.ToString(); if (pkg.IsPrerelease) { createFullVersion = pkg.Version.ToString() + "-" + pkg.PrereleaseLabel; } if (!NuGetVersion.TryParse(createFullVersion, out NuGetVersion pkgVersion)) { var message = String.Format("{0} package could not be installed with error: could not parse package '{0}' version '{1} into a NuGetVersion", pkg.Name, pkg.Version.ToString()); var ex = new ArgumentException(message); var packageIdentityVersionParseError = new ErrorRecord(ex, "psdataFileNotExistError", ErrorCategory.ReadError, null); _cmdletPassedIn.WriteError(packageIdentityVersionParseError); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); continue; } var pkgIdentity = new PackageIdentity(pkg.Name, pkgVersion); var cacheContext = new SourceCacheContext(); if (isLocalRepo) { /* Download from a local repository -- this is slightly different process than from a server */ var localResource = new FindLocalPackagesResourceV2(repoUrl); var resource = new LocalDownloadResource(repoUrl, localResource); // Actually downloading the .nupkg from a local repo var result = resource.GetDownloadResourceResultAsync( identity: pkgIdentity, downloadContext: new PackageDownloadContext(cacheContext), globalPackagesFolder: tempInstallPath, logger: NullLogger.Instance, token: _cancellationToken).GetAwaiter().GetResult(); // Create the package extraction context PackageExtractionContext packageExtractionContext = new PackageExtractionContext( packageSaveMode: PackageSaveMode.Nupkg, xmlDocFileSaveMode: PackageExtractionBehavior.XmlDocFileSaveMode, clientPolicyContext: null, logger: NullLogger.Instance); // Extracting from .nupkg and placing files into tempInstallPath result.PackageReader.CopyFiles( destination: tempInstallPath, packageFiles: result.PackageReader.GetFiles(), extractFile: new PackageFileExtractor( result.PackageReader.GetFiles(), packageExtractionContext.XmlDocFileSaveMode).ExtractPackageFile, logger: NullLogger.Instance, token: _cancellationToken); result.Dispose(); } else { /* Download from a non-local repository */ // Set up NuGet API resource for download PackageSource source = new PackageSource(repoUrl); if (credential != null) { string password = new NetworkCredential(string.Empty, credential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repoUrl, credential.UserName, password, true, null); } var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository = new SourceRepository(source, provider); /* Download from a non-local repository -- ie server */ var downloadResource = repository.GetResourceAsync <DownloadResource>().GetAwaiter().GetResult(); DownloadResourceResult result = null; try { result = downloadResource.GetDownloadResourceResultAsync( identity: pkgIdentity, downloadContext: new PackageDownloadContext(cacheContext), globalPackagesFolder: tempInstallPath, logger: NullLogger.Instance, token: _cancellationToken).GetAwaiter().GetResult(); } catch (Exception e) { _cmdletPassedIn.WriteVerbose(string.Format("Error attempting download: '{0}'", e.Message)); } finally { // Need to close the .nupkg if (result != null) { result.Dispose(); } } } _cmdletPassedIn.WriteVerbose(string.Format("Successfully able to download package from source to: '{0}'", tempInstallPath)); // pkgIdentity.Version.Version gets the version without metadata or release labels. string newVersion = pkgIdentity.Version.ToNormalizedString(); string normalizedVersionNoPrereleaseLabel = newVersion; if (pkgIdentity.Version.IsPrerelease) { // eg: 2.0.2 normalizedVersionNoPrereleaseLabel = pkgIdentity.Version.ToNormalizedString().Substring(0, pkgIdentity.Version.ToNormalizedString().IndexOf('-')); } string tempDirNameVersion = isLocalRepo ? tempInstallPath : Path.Combine(tempInstallPath, pkgIdentity.Id.ToLower(), newVersion); var version4digitNoPrerelease = pkgIdentity.Version.Version.ToString(); string moduleManifestVersion = string.Empty; var scriptPath = Path.Combine(tempDirNameVersion, pkg.Name + ".ps1"); var modulePath = Path.Combine(tempDirNameVersion, pkg.Name + ".psd1"); // Check if the package is a module or a script var isModule = File.Exists(modulePath); string installPath; if (_savePkg) { // For save the installation path is what is passed in via -Path installPath = _pathsToInstallPkg.FirstOrDefault(); // If saving as nupkg simply copy the nupkg and move onto next iteration of loop // asNupkg functionality only applies to Save-PSResource if (_asNupkg) { var nupkgFile = pkgIdentity.ToString().ToLower() + ".nupkg"; File.Copy(Path.Combine(tempDirNameVersion, nupkgFile), Path.Combine(installPath, nupkgFile)); _cmdletPassedIn.WriteVerbose(string.Format("'{0}' moved into file path '{1}'", nupkgFile, installPath)); pkgsSuccessfullyInstalled.Add(pkg); continue; } } else { // PSModules: /// ./Modules /// ./Scripts /// _pathsToInstallPkg is sorted by desirability, Find will pick the pick the first Script or Modules path found in the list installPath = isModule ? _pathsToInstallPkg.Find(path => path.EndsWith("Modules", StringComparison.InvariantCultureIgnoreCase)) : _pathsToInstallPkg.Find(path => path.EndsWith("Scripts", StringComparison.InvariantCultureIgnoreCase)); } if (isModule) { var moduleManifest = Path.Combine(tempDirNameVersion, pkgIdentity.Id + ".psd1"); if (!File.Exists(moduleManifest)) { var message = String.Format("{0} package could not be installed with error: Module manifest file: {1} does not exist. This is not a valid PowerShell module.", pkgIdentity.Id, moduleManifest); var ex = new ArgumentException(message); var psdataFileDoesNotExistError = new ErrorRecord(ex, "psdataFileNotExistError", ErrorCategory.ReadError, null); _cmdletPassedIn.WriteError(psdataFileDoesNotExistError); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); continue; } if (!Utils.TryParseModuleManifest(moduleManifest, _cmdletPassedIn, out Hashtable parsedMetadataHashtable)) { // Ran into errors parsing the module manifest file which was found in Utils.ParseModuleManifest() and written. continue; } moduleManifestVersion = parsedMetadataHashtable["ModuleVersion"] as string; // Accept License verification if (!_savePkg && !CallAcceptLicense(pkg, moduleManifest, tempInstallPath, newVersion)) { continue; } // If NoClobber is specified, ensure command clobbering does not happen if (_noClobber && !DetectClobber(pkg.Name, parsedMetadataHashtable)) { continue; } } // Delete the extra nupkg related files that are not needed and not part of the module/script DeleteExtraneousFiles(pkgIdentity, tempDirNameVersion); if (_includeXML) { CreateMetadataXMLFile(tempDirNameVersion, installPath, pkg, isModule); } MoveFilesIntoInstallPath( pkg, isModule, isLocalRepo, tempDirNameVersion, tempInstallPath, installPath, newVersion, moduleManifestVersion, scriptPath); _cmdletPassedIn.WriteVerbose(String.Format("Successfully installed package '{0}' to location '{1}'", pkg.Name, installPath)); pkgsSuccessfullyInstalled.Add(pkg); } catch (Exception e) { _cmdletPassedIn.WriteError( new ErrorRecord( new PSInvalidOperationException( message: $"Unable to successfully install package '{pkg.Name}': '{e.Message}'", innerException: e), "InstallPackageFailed", ErrorCategory.InvalidOperation, _cmdletPassedIn)); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); } finally { // Delete the temp directory and all its contents _cmdletPassedIn.WriteVerbose(string.Format("Attempting to delete '{0}'", tempInstallPath)); if (Directory.Exists(tempInstallPath)) { if (!TryDeleteDirectory(tempInstallPath, out ErrorRecord errorMsg)) { _cmdletPassedIn.WriteError(errorMsg); } else { _cmdletPassedIn.WriteVerbose(String.Format("Successfully deleted '{0}'", tempInstallPath)); } } } } return(pkgsSuccessfullyInstalled); }
public List <string> InstallHelper(string repositoryUrl, List <string> pkgsLeftToInstall, CancellationToken cancellationToken) { PackageSource source = new PackageSource(repositoryUrl); if (_credential != null) { string password = new NetworkCredential(string.Empty, _credential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repositoryUrl, _credential.UserName, password, true, null); } var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository = new SourceRepository(source, provider); SearchFilter filter = new SearchFilter(_prerelease); ////////////////////// packages from source /// PackageSource source2 = new PackageSource(repositoryUrl); if (_credential != null) { string password = new NetworkCredential(string.Empty, _credential.Password).Password; source2.Credentials = PackageSourceCredential.FromUserInput(repositoryUrl, _credential.UserName, password, true, null); } var provider2 = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository2 = new SourceRepository(source2, provider2); // TODO: proper error handling here PackageMetadataResource resourceMetadata2 = null; try { resourceMetadata2 = repository.GetResourceAsync <PackageMetadataResource>().GetAwaiter().GetResult(); } catch { } SearchFilter filter2 = new SearchFilter(_prerelease); SourceCacheContext context2 = new SourceCacheContext(); foreach (var n in _name) { IPackageSearchMetadata filteredFoundPkgs = null; // Check version first to narrow down the number of pkgs before potential searching through tags VersionRange versionRange = null; if (_version == null) { // ensure that the latst version is returned first (the ordering of versions differ // TODO: proper error handling try { filteredFoundPkgs = (resourceMetadata2.GetMetadataAsync(n, _prerelease, false, context2, NullLogger.Instance, cancellationToken).GetAwaiter().GetResult() .OrderByDescending(p => p.Identity.Version, VersionComparer.VersionRelease) .FirstOrDefault()); } catch { } } else { // check if exact version NuGetVersion nugetVersion; //VersionRange versionRange = VersionRange.Parse(version); NuGetVersion.TryParse(_version, out nugetVersion); // throw if (nugetVersion != null) { // exact version versionRange = new VersionRange(nugetVersion, true, nugetVersion, true, null, null); } else { // check if version range versionRange = VersionRange.Parse(_version); } // Search for packages within a version range // ensure that the latst version is returned first (the ordering of versions differ filteredFoundPkgs = (resourceMetadata2.GetMetadataAsync(n, _prerelease, false, context2, NullLogger.Instance, cancellationToken).GetAwaiter().GetResult() .Where(p => versionRange.Satisfies(p.Identity.Version)) .OrderByDescending(p => p.Identity.Version, VersionComparer.VersionRelease) .FirstOrDefault()); } List <IPackageSearchMetadata> foundDependencies = new List <IPackageSearchMetadata>(); // found a package to install and looking for dependencies // Search for dependencies if (filteredFoundPkgs != null) { // need to parse the depenency and version and such // need to improve this later // this function recursively finds all dependencies // might need to do add instead of AddRange foundDependencies.AddRange(FindDependenciesFromSource(filteredFoundPkgs, resourceMetadata2, context2)); } /// end dep conditional // check which pkgs you actually need to install List <IPackageSearchMetadata> pkgsToInstall = new List <IPackageSearchMetadata>(); // install pkg, then install any dependencies to a temp directory pkgsToInstall.Add(filteredFoundPkgs); pkgsToInstall.AddRange(foundDependencies); if (_asNupkg) { // CreateFolderFeedV3Async(_path, PackageSaveMode.Nupkg | PackageSaveMode.Nuspec, packages). var tempInstallPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString()); var dir = Directory.CreateDirectory(tempInstallPath); // should check it gets created properly //dir.SetAccessControl(new DirectorySecurity(dir.FullName, AccessControlSections.Owner)); // To delete file attributes from the existing ones get the current file attributes first and use AND (&) operator // with a mask (bitwise complement of desired attributes combination). dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly; //remove any null pkgs pkgsToInstall.Remove(null); // install everything to a temp path foreach (var p in pkgsToInstall) { var pkgIdentity = new PackageIdentity(p.Identity.Id, p.Identity.Version); var resource = new DownloadResourceV2FeedProvider(); var resource2 = resource.TryCreate(repository, cancellationToken); var cacheContext = new SourceCacheContext(); var downloadResource = repository.GetResourceAsync <DownloadResource>().GetAwaiter().GetResult(); var result = downloadResource.GetDownloadResourceResultAsync( pkgIdentity, new PackageDownloadContext(cacheContext), tempInstallPath, logger: NullLogger.Instance, CancellationToken.None).GetAwaiter().GetResult(); // need to close the .nupkg result.Dispose(); // 4) copy to proper path // TODO: test installing a script when it already exists // or move to script path // check for failures // var newPath = Directory.CreateDirectory(Path.Combine(psModulesPath, p.Identity.Id, p.Identity.Version.ToNormalizedString())); var installPath = SessionState.Path.GetResolvedPSPathFromPSPath(_path).FirstOrDefault().Path; // when we move the directory over, we'll change the casing of the module directory name from lower case to proper casing. // if script, just move the files over, if module, move the version directory overp var tempPkgIdPath = System.IO.Path.Combine(tempInstallPath, p.Identity.Id, p.Identity.Version.ToString()); var tempPkgVersionPath = System.IO.Path.Combine(tempPkgIdPath, p.Identity.Id.ToLower() + "." + p.Identity.Version + ".nupkg"); var newPath = System.IO.Path.Combine(installPath, p.Identity.Id + "." + p.Identity.Version + ".nupkg"); File.Move(tempPkgVersionPath, newPath); // 2) TODO: Verify that all the proper modules installed correctly // remove temp directory recursively Directory.Delete(tempInstallPath, true); pkgsLeftToInstall.Remove(n); } } else { var tempInstallPath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString()); var dir = Directory.CreateDirectory(tempInstallPath); // should check it gets created properly //dir.SetAccessControl(new DirectorySecurity(dir.FullName, AccessControlSections.Owner)); // To delete file attributes from the existing ones get the current file attributes first and use AND (&) operator // with a mask (bitwise complement of desired attributes combination). dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly; //remove any null pkgs pkgsToInstall.Remove(null); // install everything to a temp path foreach (var p in pkgsToInstall) { var pkgIdentity = new PackageIdentity(p.Identity.Id, p.Identity.Version); var resource = new DownloadResourceV2FeedProvider(); var resource2 = resource.TryCreate(repository, cancellationToken); var cacheContext = new SourceCacheContext(); var downloadResource = repository.GetResourceAsync <DownloadResource>().GetAwaiter().GetResult(); var result = downloadResource.GetDownloadResourceResultAsync( pkgIdentity, new PackageDownloadContext(cacheContext), tempInstallPath, logger: NullLogger.Instance, CancellationToken.None).GetAwaiter().GetResult(); // need to close the .nupkg result.Dispose(); // create a download count to see if everything was installed properly // 1) remove the *.nupkg file // may need to modify due to capitalization var dirNameVersion = System.IO.Path.Combine(tempInstallPath, p.Identity.Id, p.Identity.Version.ToNormalizedString()); var nupkgMetadataToDelete = System.IO.Path.Combine(dirNameVersion, ".nupkg.metadata").ToLower(); var nupkgToDelete = System.IO.Path.Combine(dirNameVersion, (p.Identity.ToString() + ".nupkg").ToLower()); var nupkgSHAToDelete = System.IO.Path.Combine(dirNameVersion, (p.Identity.ToString() + ".nupkg.sha512").ToLower()); var nuspecToDelete = System.IO.Path.Combine(dirNameVersion, (p.Identity.Id + ".nuspec").ToLower()); File.Delete(nupkgMetadataToDelete); File.Delete(nupkgSHAToDelete); File.Delete(nuspecToDelete); File.Delete(nupkgToDelete); // if it's not a script, do the following: var scriptPath = System.IO.Path.Combine(dirNameVersion, (p.Identity.Id.ToString() + ".ps1").ToLower()); var isScript = File.Exists(scriptPath) ? true : false; // 3) create xml //Create PSGetModuleInfo.xml //Set attribute as hidden [System.IO.File]::SetAttributes($psgetItemInfopath, [System.IO.FileAttributes]::Hidden) var fullinstallPath = isScript ? System.IO.Path.Combine(dirNameVersion, (p.Identity.Id + "_InstalledScriptInfo.xml")) : System.IO.Path.Combine(dirNameVersion, "PSGetModuleInfo.xml"); if (_includeXML) { // Create XMLs using (StreamWriter sw = new StreamWriter(fullinstallPath)) { var psModule = "PSModule"; var tags = p.Tags.Split(' '); var module = tags.Contains("PSModule") ? "Module" : null; var script = tags.Contains("PSScript") ? "Script" : null; List <string> includesDscResource = new List <string>(); List <string> includesCommand = new List <string>(); List <string> includesFunction = new List <string>(); List <string> includesRoleCapability = new List <string>(); List <string> filteredTags = new List <string>(); var psDscResource = "PSDscResource_"; var psCommand = "PSCommand_"; var psFunction = "PSFunction_"; var psRoleCapability = "PSRoleCapability_"; foreach (var tag in tags) { if (tag.StartsWith(psDscResource)) { includesDscResource.Add(tag.Remove(0, psDscResource.Length)); } else if (tag.StartsWith(psCommand)) { includesCommand.Add(tag.Remove(0, psCommand.Length)); } else if (tag.StartsWith(psFunction)) { includesFunction.Add(tag.Remove(0, psFunction.Length)); } else if (tag.StartsWith(psRoleCapability)) { includesRoleCapability.Add(tag.Remove(0, psRoleCapability.Length)); } else if (!tag.StartsWith("PSWorkflow_") && !tag.StartsWith("PSCmdlet_") && !tag.StartsWith("PSIncludes_") && !tag.Equals("PSModule") && !tag.Equals("PSScript")) { filteredTags.Add(tag); } } Dictionary <string, List <string> > includes = new Dictionary <string, List <string> >() { { "DscResource", includesDscResource }, { "Command", includesCommand }, { "Function", includesFunction }, { "RoleCapability", includesRoleCapability } }; Dictionary <string, VersionRange> dependencies = new Dictionary <string, VersionRange>(); foreach (var depGroup in p.DependencySets) { PackageDependency depPkg = depGroup.Packages.FirstOrDefault(); dependencies.Add(depPkg.Id, depPkg.VersionRange); } var psGetModuleInfoObj = new PSObject(); // TODO: Add release notes psGetModuleInfoObj.Members.Add(new PSNoteProperty("Name", p.Identity.Id)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Version", p.Identity.Version)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Type", module != null ? module : (script != null ? script : null))); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Description", p.Description)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Author", p.Authors)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("CompanyName", p.Owners)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("PublishedDate", p.Published)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("InstalledDate", System.DateTime.Now)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("LicenseUri", p.LicenseUrl)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("ProjectUri", p.ProjectUrl)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("IconUri", p.IconUrl)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Includes", includes.ToList())); // TODO: check if getting deserialized properly psGetModuleInfoObj.Members.Add(new PSNoteProperty("PowerShellGetFormatVersion", "3")); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Dependencies", dependencies.ToList())); psGetModuleInfoObj.Members.Add(new PSNoteProperty("RepositorySourceLocation", repositoryUrl)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("Repository", repositoryUrl)); psGetModuleInfoObj.Members.Add(new PSNoteProperty("InstalledLocation", null)); // TODO: add installation location psGetModuleInfoObj.TypeNames.Add("Microsoft.PowerShell.Commands.PSRepositoryItemInfo"); var serializedObj = PSSerializer.Serialize(psGetModuleInfoObj); sw.Write(serializedObj); // set the xml attribute to hidden //System.IO.File.SetAttributes("c:\\code\\temp\\installtestpath\\PSGetModuleInfo.xml", FileAttributes.Hidden); } } // 4) copy to proper path // TODO: test installing a script when it already exists // or move to script path // check for failures // var newPath = Directory.CreateDirectory(Path.Combine(psModulesPath, p.Identity.Id, p.Identity.Version.ToNormalizedString())); var installPath = SessionState.Path.GetResolvedPSPathFromPSPath(_path).FirstOrDefault().Path; var newPath = isScript ? installPath : System.IO.Path.Combine(installPath, p.Identity.Id.ToString()); // when we move the directory over, we'll change the casing of the module directory name from lower case to proper casing. // if script, just move the files over, if module, move the version directory overp var tempModuleVersionDir = isScript ? System.IO.Path.Combine(tempInstallPath, p.Identity.Id.ToLower(), p.Identity.Version.ToNormalizedString()) : System.IO.Path.Combine(tempInstallPath, p.Identity.Id.ToLower()); if (isScript) { var scriptXML = p.Identity.Id + "_InstalledScriptInfo.xml"; File.Move(System.IO.Path.Combine(tempModuleVersionDir, scriptXML), System.IO.Path.Combine(installPath, "InstalledScriptInfos", scriptXML)); File.Move(System.IO.Path.Combine(tempModuleVersionDir, p.Identity.Id.ToLower() + ".ps1"), System.IO.Path.Combine(newPath, p.Identity.Id + ".ps1")); } else { if (!Directory.Exists(newPath)) { Directory.Move(tempModuleVersionDir, newPath); } else { // If the module directory path already exists, Directory.Move throws an exception, so we'll just move the version directory over instead tempModuleVersionDir = System.IO.Path.Combine(tempModuleVersionDir, p.Identity.Version.ToNormalizedString()); Directory.Move(tempModuleVersionDir, System.IO.Path.Combine(newPath, p.Identity.Version.ToNormalizedString())); } } // 2) TODO: Verify that all the proper modules installed correctly // remove temp directory recursively Directory.Delete(tempInstallPath, true); pkgsLeftToInstall.Remove(n); } } } return(pkgsLeftToInstall); }
private List <string> InstallPackage(IEnumerable <PSResourceInfo> pkgsToInstall, string repoName, string repoUrl, PSCredential credential, bool isLocalRepo) { List <string> pkgsSuccessfullyInstalled = new List <string>(); foreach (PSResourceInfo p in pkgsToInstall) { var tempInstallPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); try { // Create a temp directory to install to var dir = Directory.CreateDirectory(tempInstallPath); // should check it gets created properly // To delete file attributes from the existing ones get the current file attributes first and use AND (&) operator // with a mask (bitwise complement of desired attributes combination). // TODO: check the attributes and if it's read only then set it // attribute may be inherited from the parent // TODO: are there Linux accommodations we need to consider here? dir.Attributes = dir.Attributes & ~FileAttributes.ReadOnly; _cmdletPassedIn.WriteVerbose(string.Format("Begin installing package: '{0}'", p.Name)); // TODO: add progress bar here // Create PackageIdentity in order to download string createFullVersion = p.Version.ToString(); if (p.IsPrerelease) { createFullVersion = p.Version.ToString() + "-" + p.PrereleaseLabel; } if (!NuGetVersion.TryParse(createFullVersion, out NuGetVersion pkgVersion)) { _cmdletPassedIn.WriteDebug(string.Format("Error parsing package '{0}' version '{1}' into a NuGetVersion", p.Name, p.Version.ToString())); continue; } var pkgIdentity = new PackageIdentity(p.Name, pkgVersion); var cacheContext = new SourceCacheContext(); if (isLocalRepo) { /* Download from a local repository -- this is slightly different process than from a server */ var localResource = new FindLocalPackagesResourceV2(repoUrl); var resource = new LocalDownloadResource(repoUrl, localResource); // Actually downloading the .nupkg from a local repo var result = resource.GetDownloadResourceResultAsync( identity: pkgIdentity, downloadContext: new PackageDownloadContext(cacheContext), globalPackagesFolder: tempInstallPath, logger: NullLogger.Instance, token: _cancellationToken).GetAwaiter().GetResult(); if (_asNupkg) // this is Save functionality { DirectoryInfo nupkgPath = new DirectoryInfo(((System.IO.FileStream)result.PackageStream).Name); File.Copy(nupkgPath.FullName, Path.Combine(tempInstallPath, pkgIdentity.Id + pkgIdentity.Version + ".nupkg")); continue; } // Create the package extraction context PackageExtractionContext packageExtractionContext = new PackageExtractionContext( packageSaveMode: PackageSaveMode.Nupkg, xmlDocFileSaveMode: PackageExtractionBehavior.XmlDocFileSaveMode, clientPolicyContext: null, logger: NullLogger.Instance); // Extracting from .nupkg and placing files into tempInstallPath result.PackageReader.CopyFiles( destination: tempInstallPath, packageFiles: result.PackageReader.GetFiles(), extractFile: (new PackageFileExtractor(result.PackageReader.GetFiles(), packageExtractionContext.XmlDocFileSaveMode)).ExtractPackageFile, logger: NullLogger.Instance, token: _cancellationToken); result.Dispose(); } else { /* Download from a non-local repository */ // Set up NuGet API resource for download PackageSource source = new PackageSource(repoUrl); if (credential != null) { string password = new NetworkCredential(string.Empty, credential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repoUrl, credential.UserName, password, true, null); } var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository = new SourceRepository(source, provider); /* Download from a non-local repository -- ie server */ var downloadResource = repository.GetResourceAsync <DownloadResource>().GetAwaiter().GetResult(); DownloadResourceResult result = null; try { result = downloadResource.GetDownloadResourceResultAsync( identity: pkgIdentity, downloadContext: new PackageDownloadContext(cacheContext), globalPackagesFolder: tempInstallPath, logger: NullLogger.Instance, token: _cancellationToken).GetAwaiter().GetResult(); } catch (Exception e) { _cmdletPassedIn.WriteDebug(string.Format("Error attempting download: '{0}'", e.Message)); } finally { // Need to close the .nupkg if (result != null) { result.Dispose(); } } } _cmdletPassedIn.WriteDebug(string.Format("Successfully able to download package from source to: '{0}'", tempInstallPath)); // Prompt if module requires license acceptance (need to read info license acceptance info from the module manifest) // pkgIdentity.Version.Version gets the version without metadata or release labels. string newVersion = pkgIdentity.Version.ToNormalizedString(); // string normalizedVersionNoPrereleaseLabel = newVersion; if (pkgIdentity.Version.IsPrerelease) { // 2.0.2 normalizedVersionNoPrereleaseLabel = pkgIdentity.Version.ToNormalizedString().Substring(0, pkgIdentity.Version.ToNormalizedString().IndexOf('-')); } //p.Version = new System.Version(normalizedVersionNoPrereleaseLabel); string tempDirNameVersion = isLocalRepo ? tempInstallPath : Path.Combine(tempInstallPath, pkgIdentity.Id.ToLower(), newVersion); var version4digitNoPrerelease = pkgIdentity.Version.Version.ToString(); string moduleManifestVersion = string.Empty; var scriptPath = Path.Combine(tempDirNameVersion, (p.Name + ".ps1")); var isScript = File.Exists(scriptPath) ? true : false; if (!isScript) { var moduleManifest = Path.Combine(tempDirNameVersion, pkgIdentity.Id + ".psd1"); var parsedMetadataHashtable = Utils.ParseModuleManifest(moduleManifest, this); moduleManifestVersion = parsedMetadataHashtable["ModuleVersion"] as string; // Accept License verification if (!_savePkg && !CallAcceptLicense(p, moduleManifest, tempInstallPath, newVersion)) { continue; } } // Delete the extra nupkg related files that are not needed and not part of the module/script DeleteExtraneousFiles(tempInstallPath, pkgIdentity, tempDirNameVersion); string installPath; if (_savePkg) { // For save the installation path is what is passed in via -Path installPath = _pathsToInstallPkg.FirstOrDefault(); } else { // PSModules: /// ./Modules /// ./Scripts /// _pathsToInstallPkg is sorted by desirability, Find will pick the pick the first Script or Modules path found in the list installPath = isScript ? _pathsToInstallPkg.Find(path => path.EndsWith("Scripts", StringComparison.InvariantCultureIgnoreCase)) : _pathsToInstallPkg.Find(path => path.EndsWith("Modules", StringComparison.InvariantCultureIgnoreCase)); } if (_includeXML) { CreateMetadataXMLFile(tempDirNameVersion, installPath, repoName, p, isScript); } MoveFilesIntoInstallPath(p, isScript, isLocalRepo, tempDirNameVersion, tempInstallPath, installPath, newVersion, moduleManifestVersion, normalizedVersionNoPrereleaseLabel, version4digitNoPrerelease, scriptPath); _cmdletPassedIn.WriteVerbose(String.Format("Successfully installed package '{0}' to location '{1}'", p.Name, installPath)); pkgsSuccessfullyInstalled.Add(p.Name); } catch (Exception e) { _cmdletPassedIn.WriteDebug(string.Format("Unable to successfully install package '{0}': '{1}'", p.Name, e.Message)); } finally { // Delete the temp directory and all its contents _cmdletPassedIn.WriteDebug(string.Format("Attempting to delete '{0}'", tempInstallPath)); if (Directory.Exists(tempInstallPath)) { Directory.Delete(tempInstallPath, true); } } } return(pkgsSuccessfullyInstalled); }
public IEnumerable <PSResourceInfo> SearchFromRepository( string repositoryName, Uri repositoryUrl) { PackageSearchResource resourceSearch; PackageMetadataResource resourceMetadata; SearchFilter filter; SourceCacheContext context; // file based Uri scheme if (repositoryUrl.Scheme == Uri.UriSchemeFile) { FindLocalPackagesResourceV2 localResource = new FindLocalPackagesResourceV2(repositoryUrl.ToString()); resourceSearch = new LocalPackageSearchResource(localResource); resourceMetadata = new LocalPackageMetadataResource(localResource); filter = new SearchFilter(_prerelease); context = new SourceCacheContext(); foreach (PSResourceInfo pkg in SearchAcrossNamesInRepository( repositoryName: repositoryName, pkgSearchResource: resourceSearch, pkgMetadataResource: resourceMetadata, searchFilter: filter, sourceContext: context)) { yield return(pkg); } yield break; } // check if ADOFeed- for which searching for Name with wildcard has a different logic flow if (repositoryUrl.ToString().Contains("pkgs.visualstudio.com")) { _isADOFeedRepository = true; } // HTTP, HTTPS, FTP Uri schemes (only other Uri schemes allowed by RepositorySettings.Read() API) PackageSource source = new PackageSource(repositoryUrl.ToString()); if (_credential != null) { string password = new NetworkCredential(string.Empty, _credential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repositoryUrl.ToString(), _credential.UserName, password, true, null); _cmdletPassedIn.WriteVerbose("credential successfully set for repository: " + repositoryName); } // GetCoreV3() API is able to handle V2 and V3 repository endpoints var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository = new SourceRepository(source, provider); resourceSearch = null; resourceMetadata = null; try { resourceSearch = repository.GetResourceAsync <PackageSearchResource>().GetAwaiter().GetResult(); resourceMetadata = repository.GetResourceAsync <PackageMetadataResource>().GetAwaiter().GetResult(); } catch (Exception e) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "Error retrieving resource from repository: " + e.Message); } if (resourceSearch == null || resourceMetadata == null) { yield break; } filter = new SearchFilter(_prerelease); context = new SourceCacheContext(); foreach (PSResourceInfo pkg in SearchAcrossNamesInRepository( repositoryName: repositoryName, pkgSearchResource: resourceSearch, pkgMetadataResource: resourceMetadata, searchFilter: filter, sourceContext: context)) { yield return(pkg); } }
private IEnumerable <PSResourceInfo> SearchFromRepository( string repositoryName, Uri repositoryUri, PSCredentialInfo repositoryCredentialInfo) { PackageSearchResource resourceSearch; PackageMetadataResource resourceMetadata; SearchFilter filter; SourceCacheContext context; // File based Uri scheme. if (repositoryUri.Scheme == Uri.UriSchemeFile) { FindLocalPackagesResourceV2 localResource = new FindLocalPackagesResourceV2(repositoryUri.ToString()); resourceSearch = new LocalPackageSearchResource(localResource); resourceMetadata = new LocalPackageMetadataResource(localResource); filter = new SearchFilter(_prerelease); context = new SourceCacheContext(); foreach (PSResourceInfo pkg in SearchAcrossNamesInRepository( repositoryName: repositoryName, pkgSearchResource: resourceSearch, pkgMetadataResource: resourceMetadata, searchFilter: filter, sourceContext: context)) { yield return(pkg); } yield break; } // Check if ADOFeed- for which searching for Name with wildcard has a different logic flow. if (repositoryUri.ToString().Contains("pkgs.")) { _isADOFeedRepository = true; } // HTTP, HTTPS, FTP Uri schemes (only other Uri schemes allowed by RepositorySettings.Read() API). PackageSource source = new PackageSource(repositoryUri.ToString()); // Explicitly passed in Credential takes precedence over repository CredentialInfo. if (_credential != null) { string password = new NetworkCredential(string.Empty, _credential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repositoryUri.ToString(), _credential.UserName, password, true, null); _cmdletPassedIn.WriteVerbose("credential successfully set for repository: " + repositoryName); } else if (repositoryCredentialInfo != null) { PSCredential repoCredential = Utils.GetRepositoryCredentialFromSecretManagement( repositoryName, repositoryCredentialInfo, _cmdletPassedIn); string password = new NetworkCredential(string.Empty, repoCredential.Password).Password; source.Credentials = PackageSourceCredential.FromUserInput(repositoryUri.ToString(), repoCredential.UserName, password, true, null); _cmdletPassedIn.WriteVerbose("credential successfully read from vault and set for repository: " + repositoryName); } // GetCoreV3() API is able to handle V2 and V3 repository endpoints. var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider); SourceRepository repository = new SourceRepository(source, provider); resourceSearch = null; resourceMetadata = null; try { resourceSearch = repository.GetResourceAsync <PackageSearchResource>().GetAwaiter().GetResult(); resourceMetadata = repository.GetResourceAsync <PackageMetadataResource>().GetAwaiter().GetResult(); } catch (Exception e) { Utils.WriteVerboseOnCmdlet(_cmdletPassedIn, "Error retrieving resource from repository: " + e.Message); } if (resourceSearch == null || resourceMetadata == null) { yield break; } filter = new SearchFilter(_prerelease); context = new SourceCacheContext(); foreach (PSResourceInfo pkg in SearchAcrossNamesInRepository( repositoryName: String.Equals(repositoryUri.AbsoluteUri, _psGalleryUri, StringComparison.InvariantCultureIgnoreCase) ? _psGalleryRepoName : (String.Equals(repositoryUri.AbsoluteUri, _poshTestGalleryUri, StringComparison.InvariantCultureIgnoreCase) ? _poshTestGalleryRepoName : repositoryName), pkgSearchResource: resourceSearch, pkgMetadataResource: resourceMetadata, searchFilter: filter, sourceContext: context)) { yield return(pkg); } }
public void GetCoreV3_WithDefaultFactory_ReturnsNonEmptyEnumerable() { IEnumerable <Lazy <INuGetResourceProvider> > resourceProviders = FactoryExtensionsV3.GetCoreV3(Repository.Provider); Assert.NotEmpty(resourceProviders); }
public void GetCoreV3_WhenFactoryIsNull_Throws() { var exception = Assert.Throws <ArgumentNullException>(() => FactoryExtensionsV3.GetCoreV3(factory: null)); Assert.Equal("factory", exception.ParamName); }
private async Task <Uri> GetNugetUri(CancellationToken cancellationToken) { var settings = Settings.LoadDefaultSettings(null); var packageSourceProvider = new PackageSourceProvider(settings); var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, FactoryExtensionsV3.GetCoreV3(Repository.Provider)); var package = new PackageIdentity("PostgreSql.Binaries.Lite", NuGetVersion.Parse(_pgVersion)); using (var cacheContext = new SourceCacheContext()) { var repositories = sourceRepositoryProvider.GetRepositories(); foreach (var sourceRepository in repositories) { var dependencyInfoResource = await sourceRepository.GetResourceAsync <DependencyInfoResource>(); var dependencyInfo = await dependencyInfoResource.ResolvePackage( package, NuGetFramework.AnyFramework, cacheContext, NullLogger.Instance, cancellationToken); if (dependencyInfo != null) { return(dependencyInfo.DownloadUri); } } } throw new Exception("Could not find PostgreSql.Binaries.Lite package"); }
private async Task <Uri> GetNugetUri(CancellationToken cancellationToken) { var settings = Settings.LoadDefaultSettings(null); var packageSourceProvider = new PackageSourceProvider(settings); var sourceRepositoryProvider = new SourceRepositoryProvider(packageSourceProvider, FactoryExtensionsV3.GetCoreV3(Repository.Provider)); var package = new PackageIdentity("PostgreSql.Binaries.Lite", NuGetVersion.Parse(_pgVersion)); var pathContext = NuGetPathContext.Create(settings); var localSources = new List <string>(); localSources.Add(pathContext.UserPackageFolder); localSources.AddRange(pathContext.FallbackPackageFolders); using (var cacheContext = new SourceCacheContext()) { var repositories = localSources .Select(path => sourceRepositoryProvider.CreateRepository(new PackageSource(path), FeedType.FileSystemV3)) .Concat(sourceRepositoryProvider.GetRepositories()); foreach (var sourceRepository in repositories) { var dependencyInfoResource = await sourceRepository.GetResourceAsync <DependencyInfoResource>(); var dependencyInfo = await dependencyInfoResource.ResolvePackage( package, NuGetFramework.AnyFramework, cacheContext, NullLogger.Instance, cancellationToken); if (dependencyInfo != null) { return(dependencyInfo.DownloadUri); } } } throw new Exception("Could not find PostgreSql.Binaries.Lite package"); }