Example #1
0
        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);
            }
        }
Example #2
0
        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);
        }
Example #3
0
        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);
            }
        }
Example #5
0
        // 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());
        }
Example #6
0
        // 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);
        }
Example #8
0
        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());
        }