protected override void ProcessRecord() { WriteVerbose("Entering GetPSResource"); var namesToSearch = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) { WriteError(new ErrorRecord( new PSInvalidOperationException(error), "ErrorFilteringNamesForUnsupportedWildcards", ErrorCategory.InvalidArgument, this)); } // This catches the case where Name wasn't passed in as null or empty, // but after filtering out unsupported wildcard names in BeginProcessing() there are no elements left in Name. if (namesToSearch.Length == 0) { return; } // SelectPrereleaseOnly is false because we want both stable and prerelease versions all the time.. GetHelper getHelper = new GetHelper(this); foreach (PSResourceInfo pkg in getHelper.GetPackagesFromPath( name: namesToSearch, versionRange: _versionRange, pathsToSearch: _pathsToSearch, selectPrereleaseOnly: false)) { WriteObject(pkg); } }
private bool UninstallPkgHelper() { var successfullyUninstalled = false; GetHelper getHelper = new GetHelper(this); List <string> dirsToDelete = getHelper.FilterPkgPathsByName(Name, _pathsToSearch); // Checking if module or script // a module path will look like: // ./Modules/TestModule/0.0.1 // note that the xml file is located in this path, eg: ./Modules/TestModule/0.0.1/PSModuleInfo.xml // a script path will look like: // ./Scripts/TestScript.ps1 // note that the xml file is located in ./Scripts/InstalledScriptInfos, eg: ./Scripts/InstalledScriptInfos/TestScript_InstalledScriptInfo.xml string pkgName; foreach (string pkgPath in getHelper.FilterPkgPathsByVersion(_versionRange, dirsToDelete, selectPrereleaseOnly: Prerelease)) { pkgName = Utils.GetInstalledPackageName(pkgPath); if (!ShouldProcess(string.Format("Uninstall resource '{0}' from the machine.", pkgName))) { WriteVerbose("ShouldProcess is set to false."); continue; } ErrorRecord errRecord = null; if (pkgPath.EndsWith(PSScriptFileExt)) { successfullyUninstalled = UninstallScriptHelper(pkgPath, pkgName, out errRecord); } else { successfullyUninstalled = UninstallModuleHelper(pkgPath, pkgName, out errRecord); } // if we can't find the resource, write non-terminating error and return if (!successfullyUninstalled || errRecord != null) { if (errRecord == null) { string message = Version == null || Version.Trim().Equals("*") ? string.Format("Could not find any version of the resource '{0}' in any path", pkgName) : string.Format("Could not find verison '{0}' of the resource '{1}' in any path", Version, pkgName); errRecord = new ErrorRecord( new PSInvalidOperationException(message), "ErrorRetrievingSpecifiedResource", ErrorCategory.ObjectNotFound, this); } WriteError(errRecord); } } return(successfullyUninstalled); }
private bool DetectClobber(string pkgName, Hashtable parsedMetadataHashtable) { // Get installed modules, then get all possible paths bool foundClobber = false; GetHelper getHelper = new GetHelper(_cmdletPassedIn); // selectPrereleaseOnly is false because even if Prerelease is true we want to include both stable and prerelease, never select prerelease only. IEnumerable <PSResourceInfo> pkgsAlreadyInstalled = getHelper.GetPackagesFromPath( name: new string[] { "*" }, versionRange: VersionRange.All, pathsToSearch: _pathsToSearch, selectPrereleaseOnly: false); // user parsed metadata hash List <string> listOfCmdlets = new List <string>(); foreach (var cmdletName in parsedMetadataHashtable["CmdletsToExport"] as object[]) { listOfCmdlets.Add(cmdletName as string); } foreach (var pkg in pkgsAlreadyInstalled) { List <string> duplicateCmdlets = new List <string>(); List <string> duplicateCmds = new List <string>(); // See if any of the cmdlets or commands in the pkg we're trying to install exist within a package that's already installed if (pkg.Includes.Cmdlet != null && pkg.Includes.Cmdlet.Any()) { duplicateCmdlets = listOfCmdlets.Where(cmdlet => pkg.Includes.Cmdlet.Contains(cmdlet)).ToList(); } if (pkg.Includes.Command != null && pkg.Includes.Command.Any()) { duplicateCmds = listOfCmdlets.Where(commands => pkg.Includes.Command.Contains(commands, StringComparer.InvariantCultureIgnoreCase)).ToList(); } if (duplicateCmdlets.Any() || duplicateCmds.Any()) { duplicateCmdlets.AddRange(duplicateCmds); var errMessage = string.Format( "{1} package could not be installed with error: The following commands are already available on this system: '{0}'. This module '{1}' may override the existing commands. If you still want to install this module '{1}', remove the -NoClobber parameter.", String.Join(", ", duplicateCmdlets), pkgName); var ex = new ArgumentException(errMessage); var noClobberError = new ErrorRecord(ex, "CommandAlreadyExists", ErrorCategory.ResourceExists, null); _cmdletPassedIn.WriteError(noClobberError); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkgName, StringComparison.InvariantCultureIgnoreCase)); foundClobber = true; return(foundClobber); } } return(foundClobber); }
protected override void ProcessRecord() { WriteDebug("Entering GetInstalledPSResource"); GetHelper getHelper = new GetHelper(this); foreach (PSResourceInfo pkg in getHelper.FilterPkgPaths(Name, _versionRange, _pathsToSearch)) { WriteObject(pkg); } }
// Check if any of the pkg versions are already installed, if they are we'll remove them from the list of packages to install private IEnumerable <PSResourceInfo> FilterByInstalledPkgs(IEnumerable <PSResourceInfo> packages) { // Create list of installation paths to search. List <string> _pathsToSearch = new List <string>(); // _pathsToInstallPkg will only contain the paths specified within the -Scope param (if applicable) // _pathsToSearch will contain all resource package subdirectories within _pathsToInstallPkg path locations // e.g.: // ./InstallPackagePath1/PackageA // ./InstallPackagePath1/PackageB // ./InstallPackagePath2/PackageC // ./InstallPackagePath3/PackageD foreach (var path in _pathsToInstallPkg) { _pathsToSearch.AddRange(Utils.GetSubDirectories(path)); } var filteredPackages = new Dictionary <string, PSResourceInfo>(); foreach (var pkg in packages) { filteredPackages.Add(pkg.Name, pkg); } GetHelper getHelper = new GetHelper(_cmdletPassedIn); // Get currently installed packages. // selectPrereleaseOnly is false because even if Prerelease is true we want to include both stable and prerelease, never select prerelease only. IEnumerable <PSResourceInfo> pkgsAlreadyInstalled = getHelper.GetPackagesFromPath( name: filteredPackages.Keys.ToArray(), versionRange: _versionRange, pathsToSearch: _pathsToSearch, selectPrereleaseOnly: false); if (!pkgsAlreadyInstalled.Any()) { return(packages); } // Remove from list package versions that are already installed. foreach (PSResourceInfo pkg in pkgsAlreadyInstalled) { _cmdletPassedIn.WriteWarning( string.Format("Resource '{0}' with version '{1}' is already installed. If you would like to reinstall, please run the cmdlet again with the -Reinstall parameter", pkg.Name, pkg.Version)); filteredPackages.Remove(pkg.Name); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); } return(filteredPackages.Values.ToArray()); }
// Check if any of the pkg versions are already installed, if they are we'll remove them from the list of packages to install private List <PSResourceInfo> FilterByInstalledPkgs(List <PSResourceInfo> packages) { // Package install paths. // _pathsToInstallPkg will only contain the paths specified within the -Scope param (if applicable). // _pathsToSearch will contain all resource package subdirectories within _pathsToInstallPkg path locations. // e.g.: // ./InstallPackagePath1/PackageA // ./InstallPackagePath1/PackageB // ./InstallPackagePath2/PackageC // ./InstallPackagePath3/PackageD // Get currently installed packages. var getHelper = new GetHelper(_cmdletPassedIn); var installedPackageNames = new HashSet <string>(StringComparer.CurrentCultureIgnoreCase); foreach (var installedPkg in getHelper.GetInstalledPackages( pkgs: packages, pathsToSearch: _pathsToSearch)) { installedPackageNames.Add(installedPkg.Name); } if (installedPackageNames.Count is 0) { return(packages); } // Return only packages that are not already installed. var filteredPackages = new List <PSResourceInfo>(); foreach (var pkg in packages) { if (!installedPackageNames.Contains(pkg.Name)) { // Add packages that still need to be installed. filteredPackages.Add(pkg); } else { // Remove from tracking list of packages to install. _cmdletPassedIn.WriteWarning( string.Format("Resource '{0}' with version '{1}' is already installed. If you would like to reinstall, please run the cmdlet again with the -Reinstall parameter", pkg.Name, pkg.Version)); _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase)); } } return(filteredPackages); }
// Check if any of the pkg versions are already installed, if they are we'll remove them from the list of packages to install public IEnumerable <PSResourceInfo> FilterByInstalledPkgs(IEnumerable <PSResourceInfo> packagesToInstall) { List <string> pkgNames = new List <string>(); foreach (var pkg in packagesToInstall) { pkgNames.Add(pkg.Name); } List <string> _pathsToSearch = new List <string>(); GetHelper getHelper = new GetHelper(_cmdletPassedIn); // _pathsToInstallPkg will only contain the paths specified within the -Scope param (if applicable) // _pathsToSearch will contain all resource package subdirectories within _pathsToInstallPkg path locations // e.g.: // ./InstallPackagePath1/PackageA // ./InstallPackagePath1/PackageB // ./InstallPackagePath2/PackageC // ./InstallPackagePath3/PackageD foreach (var path in _pathsToInstallPkg) { _pathsToSearch.AddRange(Utils.GetSubDirectories(path)); } IEnumerable <PSResourceInfo> pkgsAlreadyInstalled = getHelper.FilterPkgPaths(pkgNames.ToArray(), _versionRange, _pathsToSearch); // If any pkg versions are already installed, write a message saying it is already installed and continue processing other pkg names if (pkgsAlreadyInstalled.Any()) { foreach (PSResourceInfo pkg in pkgsAlreadyInstalled) { _cmdletPassedIn.WriteWarning(string.Format("Resource '{0}' with version '{1}' is already installed. If you would like to reinstall, please run the cmdlet again with the -Reinstall parameter", pkg.Name, pkg.Version)); // remove this pkg from the list of pkg names install packagesToInstall.ToList().Remove(pkg); } } return(packagesToInstall); }
protected override void ProcessRecord() { // Define the cancellation token. CancellationTokenSource source = new CancellationTokenSource(); CancellationToken cancellationToken = source.Token; WriteDebug("Entering GetPSResource"); // Flatten returned pkgs before displaying output returnedPkgsFound.Flatten().ToList()[0] GetHelper getHelper = new GetHelper(cancellationToken, this); List <PSObject> flattenedPkgs = getHelper.ProcessGetParams(_name, _version, prerelease: false, _path); foreach (PSObject psObject in flattenedPkgs) { // Temporary PSObject for output purposes PSObject temp = new PSObject(); temp.Members.Add(new PSNoteProperty("Name", psObject.Properties["Name"].Value.ToString())); temp.Members.Add(new PSNoteProperty("Version", psObject.Properties["Version"].Value.ToString())); temp.Members.Add(new PSNoteProperty("Repository", psObject.Properties["Repository"].Value.ToString())); temp.Members.Add(new PSNoteProperty("Description", psObject.Properties["Description"].Value.ToString())); WriteObject(temp); } }
/// <Summary> /// This method performs a number of functions on the list of resource package names to update. /// - Processes the name list for wild card characters. /// - Writes errors for names with unsupported wild characters. /// - Finds installed packages that match the names list. /// - Finds repository packages that match the names list and update version. /// - Compares installed packages and repository search results with name list. /// - Returns a final list of packages for reinstall, that meet update criteria. /// </Summary> private string[] ProcessPackageNames( string[] namesToProcess, VersionRange versionRange) { namesToProcess = Utils.ProcessNameWildcards( pkgNames: namesToProcess, errorMsgs: out string[] errorMsgs, isContainWildcard: out bool _); foreach (string error in errorMsgs) { WriteError(new ErrorRecord( new PSInvalidOperationException(error), "ErrorFilteringNamesForUnsupportedWildcards", ErrorCategory.InvalidArgument, this)); } // This catches the case where namesToProcess wasn't passed in as null or empty, // but after filtering out unsupported wildcard names there are no elements left in namesToProcess. if (namesToProcess.Length == 0) { return(Utils.EmptyStrArray); } if (String.Equals(namesToProcess[0], "*", StringComparison.InvariantCultureIgnoreCase)) { WriteVerbose("Package names were detected to be (or contain an element equal to): '*', so all packages will be updated"); } // Get all installed packages selected for updating. GetHelper getHelper = new GetHelper(cmdletPassedIn: this); var installedPackages = new Dictionary <string, PSResourceInfo>(StringComparer.InvariantCultureIgnoreCase); foreach (var installedPackage in getHelper.GetPackagesFromPath( name: namesToProcess, versionRange: VersionRange.All, pathsToSearch: Utils.GetAllResourcePaths(this, Scope))) { if (!installedPackages.ContainsKey(installedPackage.Name)) { installedPackages.Add(installedPackage.Name, installedPackage); } } if (installedPackages.Count is 0) { WriteWarning($"No installed packages were found with name '{string.Join(",", namesToProcess)}' in scope '{Scope}'. First install package using 'Install-PSResource'."); return(Utils.EmptyStrArray); } // Find all packages selected for updating in provided repositories. var repositoryPackages = new Dictionary <string, PSResourceInfo>(StringComparer.InvariantCultureIgnoreCase); foreach (var foundResource in _findHelper.FindByResourceName( name: installedPackages.Keys.ToArray(), type: ResourceType.None, version: Version, prerelease: Prerelease, tag: null, repository: Repository, credential: Credential, includeDependencies: !SkipDependencyCheck)) { if (!repositoryPackages.ContainsKey(foundResource.Name)) { repositoryPackages.Add(foundResource.Name, foundResource); } } // Check if named package is installed or can be found in the repositories. foreach (var nameToProcess in namesToProcess) { if (!WildcardPattern.ContainsWildcardCharacters(nameToProcess)) { if (!installedPackages.ContainsKey(nameToProcess)) { WriteWarning( $"Package '{nameToProcess}' not installed in scope '{Scope}'. First install package using 'Install-PSResource'."); } else if (!repositoryPackages.ContainsKey(nameToProcess)) { WriteWarning( $"Installed package '{nameToProcess}':'{Version}' was not found in repositories and cannot be updated."); } } } // Create list of packages to update. List <string> namesToUpdate = new List <string>(); foreach (PSResourceInfo repositoryPackage in repositoryPackages.Values) { if (!installedPackages.TryGetValue(repositoryPackage.Name, out PSResourceInfo installedPackage)) { continue; } // If the current package is out of range, install it with the correct version. if (!NuGetVersion.TryParse(installedPackage.Version.ToString(), out NuGetVersion installedVersion)) { WriteWarning($"Cannot parse nuget version in installed package '{installedPackage.Name}'. Cannot update package."); continue; } if ((versionRange == VersionRange.All && repositoryPackage.Version > installedPackage.Version) || !versionRange.Satisfies(installedVersion)) { namesToUpdate.Add(repositoryPackage.Name); } else { WriteVerbose($"Installed package {repositoryPackage.Name} is up to date."); } } return(namesToUpdate.ToArray()); }