From 9e28771843102db7ede93782864ac45c095d1162 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 00:05:44 -0400 Subject: [PATCH 01/18] add check for isPrerelease to Uninstall --- src/code/UninstallPSResource.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index e38cd7533..1d71c0992 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -110,7 +110,8 @@ protected override void ProcessRecord() break; case InputObjectSet: - // the for loop will use type PSObject in order to pull the properties from the pkg object + WriteVerbose("in inputObject parameter set"); + // the for loop will use type PSResourceInfo in order to pull the properties from the pkg object foreach (PSResourceInfo pkg in InputObject) { if (pkg == null) @@ -118,8 +119,8 @@ protected override void ProcessRecord() continue; } - // attempt to parse version - if (!Utils.TryParseVersionOrVersionRange(pkg.Version.ToString(), out VersionRange _versionRange)) + if (!Utils.TryParseVersionOrVersionRange(pkg.IsPrerelease ? pkg.Version.ToString() + pkg.PrereleaseLabel : pkg.Version.ToString(), + out VersionRange _versionRange)) { var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", pkg.Version.ToString(), pkg.Name); var ex = new ArgumentException(exMessage); @@ -127,6 +128,8 @@ protected override void ProcessRecord() WriteError(ErrorParsingVersion); } + WriteVerbose("Uninstall- version range is: " + _versionRange); + Name = new string[] { pkg.Name }; if (!String.IsNullOrWhiteSpace(pkg.Name) && !UninstallPkgHelper()) { From 082c23ea20c7c5420a09ae39b115e3bea73cc38b Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 14:39:47 -0400 Subject: [PATCH 02/18] add InputObjectParameterSet for Install --- src/code/InstallPSResource.cs | 131 ++++++++++++++++++++++++++------ src/code/UninstallPSResource.cs | 40 +++++----- 2 files changed, 125 insertions(+), 46 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index 78e7ecd62..b6bf8949f 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -1,4 +1,3 @@ -using System.Collections.Specialized; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. using System; @@ -55,43 +54,57 @@ class InstallPSResource : PSCmdlet /// Specifies a user account that has rights to find a resource from a specific repository. /// [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public PSCredential Credential { get; set; } /// /// Specifies the scope of installation. /// [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public ScopeType Scope { get; set; } /// /// Suppresses being prompted for untrusted sources. /// [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public SwitchParameter TrustRepository { get; set; } /// /// Overwrites a previously installed resource with the same name and version. /// [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public SwitchParameter Reinstall { get; set; } /// /// Suppresses progress information. /// [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public SwitchParameter Quiet { get; set; } /// /// For modules that require a license, AcceptLicense automatically accepts the license agreement during installation. /// [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public SwitchParameter AcceptLicense { get; set; } + /// + /// Used for pipeline input. + /// + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectParameterSet)] + [ValidateNotNullOrEmpty] + public PSResourceInfo[] InputObject { get; set; } + #endregion #region Members private const string NameParameterSet = "NameParameterSet"; + private const string InputObjectParameterSet = "InputObjectParameterSet"; private const string RequiredResourceFileParameterSet = "RequiredResourceFileParameterSet"; private const string RequiredResourceParameterSet = "RequiredResourceParameterSet"; List _pathsToInstallPkg; @@ -107,39 +120,30 @@ protected override void BeginProcessing() // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); - // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. - // An exact version will be formatted into a version range. - if (ParameterSetName.Equals(NameParameterSet) && Version != null && !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) - - { - var exMessage = "Argument for -Version parameter is not in the proper format."; - var ex = new ArgumentException(exMessage); - var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); - ThrowTerminatingError(IncorrectVersionFormat); - } - - // if no Version specified, install latest version for the package - if (Version == null) - { - _versionRange = VersionRange.All; - } - _pathsToInstallPkg = Utils.GetAllInstallationPaths(this, Scope); } protected override void ProcessRecord() { - if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", Name)))) - { - WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", Name))); - return; - } - var installHelper = new InstallHelper(updatePkg: false, savePkg: false, cmdletPassedIn: this); switch (ParameterSetName) { case NameParameterSet: + // If no Version specified, install latest version for the package. + // Otherwise validate Version can be parsed out successfully. + if (Version == null) + { + _versionRange = VersionRange.All; + } + else if (!Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) + { + var exMessage = "Argument for -Version parameter is not in the proper format."; + var ex = new ArgumentException(exMessage); + var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); + ThrowTerminatingError(IncorrectVersionFormat); + } + var namesToInstall = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); if (nameContainsWildcard) { @@ -167,6 +171,12 @@ protected override void ProcessRecord() return; } + if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", namesToInstall)))) + { + WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", namesToInstall))); + return; + } + installHelper.InstallPackages( names: namesToInstall, versionRange: _versionRange, @@ -188,6 +198,79 @@ protected override void ProcessRecord() pathsToInstallPkg: _pathsToInstallPkg); break; + case InputObjectParameterSet: + foreach (PSResourceInfo pkg in InputObject) + { + if (pkg == null) + { + continue; + } + + Name = new string[] { pkg.Name }; + var inputNameToInstall = Utils.ProcessNameWildcards(Name, out string[] inputErrorMsgs, out bool inputNameContainsWildcard); + if (inputNameContainsWildcard) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException("Name with wildcards is not supported for Install-PSResource cmdlet"), + "NameContainsWildcard", + ErrorCategory.InvalidArgument, + this)); + return; + } + + foreach (string error in inputErrorMsgs) + { + 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 there are no elements left in namesToInstall + if (inputNameToInstall.Length == 0) + { + return; + } + + string normalizedVersionString = Utils.GetNormalizedVersionString(pkg.Version.ToString(), pkg.PrereleaseLabel); + if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) + { + var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", normalizedVersionString, pkg.Name); + var ex = new ArgumentException(exMessage); + var ErrorParsingVersion = new ErrorRecord(ex, "ErrorParsingVersion", ErrorCategory.ParserError, null); + WriteError(ErrorParsingVersion); + } + + if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", Name)))) + { + WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", Name))); + return; + } + + installHelper.InstallPackages( + names: inputNameToInstall, + versionRange: _versionRange, + prerelease: pkg.IsPrerelease, + repository: new string[] { pkg.Repository }, + acceptLicense: AcceptLicense, + quiet: Quiet, + reinstall: Reinstall, + force: false, + trustRepository: TrustRepository, + noClobber: false, + credential: Credential, + requiredResourceFile: null, + requiredResourceJson: null, + requiredResourceHash: null, + specifiedPath: null, + asNupkg: false, + includeXML: true, + pathsToInstallPkg: _pathsToInstallPkg); + } + break; + case RequiredResourceFileParameterSet: ThrowTerminatingError(new ErrorRecord( new PSNotImplementedException("RequiredResourceFileParameterSet is not yet implemented. Please rerun cmdlet with other parameter set."), diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 1d71c0992..e582c1457 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -60,22 +60,6 @@ public sealed class UninstallPSResource : PSCmdlet #region Methods protected override void BeginProcessing() { - // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. - // an exact version will be formatted into a version range. - if (ParameterSetName.Equals("NameParameterSet") && Version != null && !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) - { - var exMessage = "Argument for -Version parameter is not in the proper format."; - var ex = new ArgumentException(exMessage); - var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); - ThrowTerminatingError(IncorrectVersionFormat); - } - - // if no Version specified, uninstall all versions for the package - if (Version == null) - { - _versionRange = VersionRange.All; - } - _pathsToSearch = Utils.GetAllResourcePaths(this); } @@ -84,6 +68,21 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: + // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. + // an exact version will be formatted into a version range. + if (Version != null && !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) + { + var exMessage = "Argument for -Version parameter is not in the proper format."; + var ex = new ArgumentException(exMessage); + var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); + ThrowTerminatingError(IncorrectVersionFormat); + } + + // if no Version specified, uninstall all versions for the package + if (Version == null) + { + _versionRange = VersionRange.All; + } Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) @@ -110,7 +109,6 @@ protected override void ProcessRecord() break; case InputObjectSet: - WriteVerbose("in inputObject parameter set"); // the for loop will use type PSResourceInfo in order to pull the properties from the pkg object foreach (PSResourceInfo pkg in InputObject) { @@ -119,8 +117,7 @@ protected override void ProcessRecord() continue; } - if (!Utils.TryParseVersionOrVersionRange(pkg.IsPrerelease ? pkg.Version.ToString() + pkg.PrereleaseLabel : pkg.Version.ToString(), - out VersionRange _versionRange)) + if (!Utils.TryParseVersionOrVersionRange(pkg.Version.ToString(), out _versionRange)) { var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", pkg.Version.ToString(), pkg.Name); var ex = new ArgumentException(exMessage); @@ -128,8 +125,6 @@ protected override void ProcessRecord() WriteError(ErrorParsingVersion); } - WriteVerbose("Uninstall- version range is: " + _versionRange); - Name = new string[] { pkg.Name }; if (!String.IsNullOrWhiteSpace(pkg.Name) && !UninstallPkgHelper()) { @@ -165,9 +160,10 @@ private bool UninstallPkgHelper() // note that the xml file is located in ./Scripts/InstalledScriptInfos, eg: ./Scripts/InstalledScriptInfos/TestScript_InstalledScriptInfo.xml string pkgName = string.Empty; - + WriteVerbose("First version range in FilterPkgPathsByVersion:" + _versionRange); foreach (string pkgPath in getHelper.FilterPkgPathsByVersion(_versionRange, dirsToDelete)) { + WriteVerbose("second in loop version range in FilterPkgPathsByVersion:" + _versionRange); pkgName = Utils.GetInstalledPackageName(pkgPath); if (!ShouldProcess(string.Format("Uninstall resource '{0}' from the machine.", pkgName))) From 1408771ba2aa731c610439e3c3b3eeff0ce72a42 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 14:42:08 -0400 Subject: [PATCH 03/18] minor fixes for Uninstall --- src/code/UninstallPSResource.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index e582c1457..065f3aa85 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -68,9 +68,15 @@ protected override void ProcessRecord() switch (ParameterSetName) { case NameParameterSet: + // if no Version specified, uninstall all versions for the package. // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. // an exact version will be formatted into a version range. - if (Version != null && !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) + if (Version == null) + { + _versionRange = VersionRange.All; + } + + else if (!Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) { var exMessage = "Argument for -Version parameter is not in the proper format."; var ex = new ArgumentException(exMessage); @@ -78,11 +84,6 @@ protected override void ProcessRecord() ThrowTerminatingError(IncorrectVersionFormat); } - // if no Version specified, uninstall all versions for the package - if (Version == null) - { - _versionRange = VersionRange.All; - } Name = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool _); foreach (string error in errorMsgs) @@ -109,7 +110,6 @@ protected override void ProcessRecord() break; case InputObjectSet: - // the for loop will use type PSResourceInfo in order to pull the properties from the pkg object foreach (PSResourceInfo pkg in InputObject) { if (pkg == null) From 9524424baf9a5e9f034a3f140da7b47b9b7cdcc5 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 14:44:05 -0400 Subject: [PATCH 04/18] remove Verbose statement --- src/code/UninstallPSResource.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 065f3aa85..154840af6 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -160,7 +160,6 @@ private bool UninstallPkgHelper() // note that the xml file is located in ./Scripts/InstalledScriptInfos, eg: ./Scripts/InstalledScriptInfos/TestScript_InstalledScriptInfo.xml string pkgName = string.Empty; - WriteVerbose("First version range in FilterPkgPathsByVersion:" + _versionRange); foreach (string pkgPath in getHelper.FilterPkgPathsByVersion(_versionRange, dirsToDelete)) { WriteVerbose("second in loop version range in FilterPkgPathsByVersion:" + _versionRange); From 297b9fe767b817f18e7429cb0943ec521e22b80e Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 18:27:56 -0400 Subject: [PATCH 05/18] add inputObject parameter set and tests --- src/code/InstallPSResource.cs | 4 +- src/code/SavePSResource.cs | 138 ++++++++++++++++++++++++----- src/code/UninstallPSResource.cs | 8 +- test/InstallPSResource.Tests.ps1 | 8 ++ test/SavePSResource.Tests.ps1 | 15 ++++ test/UninstallPSResource.Tests.ps1 | 18 ++++ 6 files changed, 161 insertions(+), 30 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index b6bf8949f..de90027aa 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -243,9 +243,9 @@ protected override void ProcessRecord() WriteError(ErrorParsingVersion); } - if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", Name)))) + if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", inputNameToInstall)))) { - WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", Name))); + WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", inputNameToInstall))); return; } diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index d4af1d151..bbe673063 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -22,7 +22,7 @@ public sealed class SavePSResource : PSCmdlet #region Members private const string NameParameterSet = "NameParameterSet"; - private const string InputObjectSet = "InputObjectSet"; + private const string InputObjectParameterSet = "InputObjectParameterSet"; VersionRange _versionRange; #endregion @@ -54,15 +54,15 @@ public sealed class SavePSResource : PSCmdlet /// Specifies the specific repositories to search within. /// [Parameter(ParameterSetName = NameParameterSet)] - // todo: add tab completion (look at get-psresourcerepository at the name parameter) - [ValidateNotNullOrEmpty] [ArgumentCompleter(typeof(RepositoryNameCompleter))] + [ValidateNotNullOrEmpty] public string[] Repository { get; set; } /// /// Specifies a user account that has rights to save a resource from a specific repository. /// [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public PSCredential Credential { get; set; } /* @@ -82,7 +82,8 @@ public sealed class SavePSResource : PSCmdlet /// /// The destination where the resource is to be installed. Works for all resource types. /// - [Parameter(ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "NameParameterSet")] + [Parameter(ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] public string Path { @@ -109,15 +110,16 @@ public string Path /// /// Suppresses being prompted for untrusted sources. /// - [Parameter()] + [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public SwitchParameter TrustRepository { get; set; } /// /// Used for pipeline input. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] - public object[] InputObject { set; get; } + public PSResourceInfo[] InputObject { get; set; } #endregion @@ -129,17 +131,17 @@ protected override void BeginProcessing() // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); - // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. - // an exact version will be formatted into a version range. - if (ParameterSetName.Equals("NameParameterSet") && - Version != null && - !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) - { - var exMessage = "Argument for -Version parameter is not in the proper format."; - var ex = new ArgumentException(exMessage); - var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); - ThrowTerminatingError(IncorrectVersionFormat); - } + // // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. + // // an exact version will be formatted into a version range. + // if (ParameterSetName.Equals("NameParameterSet") && + // Version != null && + // !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) + // { + // var exMessage = "Argument for -Version parameter is not in the proper format."; + // var ex = new ArgumentException(exMessage); + // var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); + // ThrowTerminatingError(IncorrectVersionFormat); + // } // If the user does not specify a path to save to, use the user's current working directory if (string.IsNullOrWhiteSpace(_path)) @@ -150,12 +152,6 @@ protected override void BeginProcessing() protected override void ProcessRecord() { - if (!ShouldProcess(string.Format("Resources to save: '{0}'", String.Join(", ", Name)))) - { - WriteVerbose(string.Format("Save operation cancelled by user for resources: {0}", String.Join(", ", Name))); - return; - } - var installHelper = new InstallHelper(updatePkg: false, savePkg: true, cmdletPassedIn: this); switch (ParameterSetName) @@ -188,6 +184,26 @@ protected override void ProcessRecord() return; } + // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. + // an exact version will be formatted into a version range. + if (Version == null) + { + _versionRange = VersionRange.All; + } + else if (!Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) + { + var exMessage = "Argument for -Version parameter is not in the proper format."; + var ex = new ArgumentException(exMessage); + var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); + ThrowTerminatingError(IncorrectVersionFormat); + } + + if (!ShouldProcess(string.Format("Resources to save: '{0}'", namesToSave))) + { + WriteVerbose(string.Format("Save operation cancelled by user for resources: {0}", namesToSave)); + return; + } + installHelper.InstallPackages( names: namesToSave, versionRange: _versionRange, @@ -209,6 +225,80 @@ protected override void ProcessRecord() pathsToInstallPkg: new List { _path } ); break; + case InputObjectParameterSet: + foreach (PSResourceInfo pkg in InputObject) + { + if (pkg == null) + { + continue; + } + + Name = new string[] { pkg.Name }; + var inputNamesToSave = Utils.ProcessNameWildcards(Name, out string[] inputErrorMsgs, out bool inputNameContainsWildcard); + if (inputNameContainsWildcard) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException("Name with wildcards is not supported for Save-PSResource cmdlet"), + "NameContainsWildcard", + ErrorCategory.InvalidArgument, + this)); + return; + } + + foreach (string error in inputErrorMsgs) + { + 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 there are no elements left in namesToSave + if (inputNamesToSave.Length == 0) + { + return; + } + + string normalizedVersionString = Utils.GetNormalizedVersionString(pkg.Version.ToString(), pkg.PrereleaseLabel); + if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) + { + var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", normalizedVersionString, pkg.Name); + var ex = new ArgumentException(exMessage); + var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); + ThrowTerminatingError(IncorrectVersionFormat); + } + + if (!ShouldProcess(string.Format("Resources to save: '{0}'", inputNamesToSave))) + { + WriteVerbose(string.Format("Save operation cancelled by user for resources: {0}", inputNamesToSave)); + return; + } + + installHelper.InstallPackages( + names: inputNamesToSave, + versionRange: _versionRange, + prerelease: Prerelease, + repository: Repository, + acceptLicense: true, + quiet: true, + reinstall: true, + force: false, + trustRepository: TrustRepository, + noClobber: false, + credential: Credential, + requiredResourceFile: null, + requiredResourceJson: null, + requiredResourceHash: null, + specifiedPath: _path, + asNupkg: false, + includeXML: false, + pathsToInstallPkg: new List { _path } ); + + } + break; + default: Dbg.Assert(false, "Invalid parameter set"); break; diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 154840af6..60a90d34f 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -39,19 +39,20 @@ public sealed class UninstallPSResource : PSCmdlet /// /// Used for pipeline input. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] public PSResourceInfo[] InputObject { get; set; } /// /// [Parameter(ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = InputObjectParameterSet)] public SwitchParameter Force { get; set; } #endregion #region Members private const string NameParameterSet = "NameParameterSet"; - private const string InputObjectSet = "InputObjectSet"; + private const string InputObjectParameterSet = "InputObjectParameterSet"; public static readonly string OsPlatform = System.Runtime.InteropServices.RuntimeInformation.OSDescription; VersionRange _versionRange; List _pathsToSearch = new List(); @@ -109,7 +110,7 @@ protected override void ProcessRecord() } break; - case InputObjectSet: + case InputObjectParameterSet: foreach (PSResourceInfo pkg in InputObject) { if (pkg == null) @@ -162,7 +163,6 @@ private bool UninstallPkgHelper() string pkgName = string.Empty; foreach (string pkgPath in getHelper.FilterPkgPathsByVersion(_versionRange, dirsToDelete)) { - WriteVerbose("second in loop version range in FilterPkgPathsByVersion:" + _versionRange); pkgName = Utils.GetInstalledPackageName(pkgPath); if (!ShouldProcess(string.Format("Uninstall resource '{0}' from the machine.", pkgName))) diff --git a/test/InstallPSResource.Tests.ps1 b/test/InstallPSResource.Tests.ps1 index 9dcfa1f30..fd8be4ba2 100644 --- a/test/InstallPSResource.Tests.ps1 +++ b/test/InstallPSResource.Tests.ps1 @@ -9,6 +9,7 @@ Describe 'Test Install-PSResource for Module' { $TestGalleryName = Get-PoshTestGalleryName $PSGalleryName = Get-PSGalleryName $NuGetGalleryName = Get-NuGetGalleryName + $testModuleName = "TestModule" Get-NewPSResourceRepositoryFile Register-LocalRepos } @@ -251,6 +252,13 @@ Describe 'Test Install-PSResource for Module' { $res = Get-Module "testModuleWithScript" -ListAvailable $res.Path.Contains("Modules") | Should -Be $true } + + It "Install PSResourceInfo object piped in" { + Find-PSResource -Name $testModuleName -Version "1.1.0.0" -Repository $TestGalleryName | Install-PSResource + $res = Get-InstalledPSResource -Name $testModuleName + $res.Name | Should -Be $testModuleName + $res.Version | Should -Be "1.1.0.0" + } } <# Temporarily commented until -Tag is implemented for this Describe block diff --git a/test/SavePSResource.Tests.ps1 b/test/SavePSResource.Tests.ps1 index 7f107b21f..910597f7e 100644 --- a/test/SavePSResource.Tests.ps1 +++ b/test/SavePSResource.Tests.ps1 @@ -9,6 +9,7 @@ Describe 'Test Save-PSResource for PSResources' { $TestGalleryName = Get-PoshTestGalleryName $PSGalleryName = Get-PSGalleryName $NuGetGalleryName = Get-NuGetGalleryName + $testModuleName = "test_module" Get-NewPSResourceRepositoryFile Register-LocalRepos @@ -173,6 +174,20 @@ Describe 'Test Save-PSResource for PSResources' { (Get-ChildItem -Path $pkgDir.FullName).Count | Should -Be 1 } + It "Save PSResourceInfo object piped in" { + Find-PSResource -Name "TestModule" -Version "1.1.0.0" -Repository $TestGalleryName | Save-PSResource -Path $SaveDir + $pkgDir = Get-ChildItem -Path $SaveDir | Where-Object Name -eq "TestModule" + $pkgDir | Should -Not -BeNullOrEmpty + (Get-ChildItem -Path $pkgDir.FullName).Count | Should -Be 1 + } + + It "Save PSResourceInfo object piped in for prerelease version object" { + Find-PSResource -Name $testModuleName -Version "4.5.2-alpha001" -Repository $TestGalleryName | Save-PSResource -Path $SaveDir + $pkgDir = Get-ChildItem -Path $SaveDir | Where-Object Name -eq $testModuleName + $pkgDir | Should -Not -BeNullOrEmpty + (Get-ChildItem -Path $pkgDir.FullName).Count | Should -Be 1 + } + <# # Tests should not write to module directory It "Save specific module resource by name if no -Path param is specifed" { diff --git a/test/UninstallPSResource.Tests.ps1 b/test/UninstallPSResource.Tests.ps1 index f20e967ae..8f5f6a9f9 100644 --- a/test/UninstallPSResource.Tests.ps1 +++ b/test/UninstallPSResource.Tests.ps1 @@ -8,6 +8,7 @@ Describe 'Test Uninstall-PSResource for Modules' { BeforeAll{ $TestGalleryName = Get-PoshTestGalleryName $PSGalleryName = Get-PSGalleryName + $testModuleName = "test_module" Get-NewPSResourceRepositoryFile $res = Uninstall-PSResource -name ContosoServer -Version "*" } @@ -162,4 +163,21 @@ Describe 'Test Uninstall-PSResource for Modules' { $pkg = Get-Module "RequiredModule1" -ListAvailable $pkg | Should -Be $null } + + It "Uninstall PSResourceInfo object piped in" { + Install-PSResource -Name "ContosoServer" -Version "1.5.0.0" -Repository $TestGalleryName + Get-InstalledPSResource -Name "ContosoServer" -Version "1.5.0.0" | Uninstall-PSResource + $res = Get-InstalledPSResource -Name "ContosoServer" -Version "1.5.0.0" + $res | Should -BeNullOrEmpty + } + + It "Uninstall PSResourceInfo object piped in for prerelease version object" { + Install-PSResource -Name $testModuleName -Version "4.5.2-alpha001" -Repository $TestGalleryName + # Powershell cannot create install locations indicating a prerelease version (with prerelease label indicated in install location). + # To test we can uninstall prerelease versions, we must use the numeric part of the prerelease version only and it must be unique + # of all versions installed for that module. + Get-InstalledPSResource -Name $testModuleName -Version "4.5.2" | Uninstall-PSResource + $res = Get-InstalledPSResource -Name $testModuleName -Version "4.5.2" + $res | Should -BeNullOrEmpty + } } From 663c9bffbf25c4b512145c688f7f4807ecc4c9f1 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 18:45:26 -0400 Subject: [PATCH 06/18] remove ValueFromPipeline attributes where not needed --- src/code/SavePSResource.cs | 18 +++--------------- src/code/UninstallPSResource.cs | 2 +- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index bbe673063..a68bf5231 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -33,7 +33,7 @@ public sealed class SavePSResource : PSCmdlet /// Specifies the exact names of resources to save from a repository. /// A comma-separated list of module names is accepted. The resource name must match the resource name in the repository. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = NameParameterSet)] [ValidateNotNullOrEmpty] public string[] Name { get; set; } @@ -61,7 +61,7 @@ public sealed class SavePSResource : PSCmdlet /// /// Specifies a user account that has rights to save a resource from a specific repository. /// - [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] [Parameter(ParameterSetName = InputObjectParameterSet)] public PSCredential Credential { get; set; } @@ -82,7 +82,7 @@ public sealed class SavePSResource : PSCmdlet /// /// The destination where the resource is to be installed. Works for all resource types. /// - [Parameter(ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] [Parameter(ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] public string Path @@ -131,18 +131,6 @@ protected override void BeginProcessing() // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); - // // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. - // // an exact version will be formatted into a version range. - // if (ParameterSetName.Equals("NameParameterSet") && - // Version != null && - // !Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) - // { - // var exMessage = "Argument for -Version parameter is not in the proper format."; - // var ex = new ArgumentException(exMessage); - // var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); - // ThrowTerminatingError(IncorrectVersionFormat); - // } - // If the user does not specify a path to save to, use the user's current working directory if (string.IsNullOrWhiteSpace(_path)) { diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 60a90d34f..fff4c6bf2 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -25,7 +25,7 @@ public sealed class UninstallPSResource : PSCmdlet /// Specifies the exact names of resources to uninstall. /// A comma-separated list of module names is accepted. The resource name must match the resource name in the repository. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = NameParameterSet)] [ValidateNotNullOrEmpty] public string[] Name { get; set; } From 3bd8a53c56481a03a48cb3fdb68f03dccff9549d Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 18:52:08 -0400 Subject: [PATCH 07/18] remove ValueFromPipelineByPropertyName from Install --- src/code/InstallPSResource.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index de90027aa..5c76b5735 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -25,14 +25,14 @@ class InstallPSResource : PSCmdlet /// Specifies the exact names of resources to install from a repository. /// A comma-separated list of module names is accepted. The resource name must match the resource name in the repository. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = NameParameterSet)] [ValidateNotNullOrEmpty] public string[] Name { get; set; } /// /// Specifies the version or version range of the package to be installed /// - [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] [ValidateNotNullOrEmpty] public string Version { get; set; } @@ -53,7 +53,7 @@ class InstallPSResource : PSCmdlet /// /// Specifies a user account that has rights to find a resource from a specific repository. /// - [Parameter(ValueFromPipelineByPropertyName = true, ParameterSetName = NameParameterSet)] + [Parameter(ParameterSetName = NameParameterSet)] [Parameter(ParameterSetName = InputObjectParameterSet)] public PSCredential Credential { get; set; } From 5e1837dfa859d4b023224cd7e2bd55155954aa2f Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 18:53:58 -0400 Subject: [PATCH 08/18] fix spacing --- src/code/UninstallPSResource.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index fff4c6bf2..c0d0dff17 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -76,7 +76,6 @@ protected override void ProcessRecord() { _versionRange = VersionRange.All; } - else if (!Utils.TryParseVersionOrVersionRange(Version, out _versionRange)) { var exMessage = "Argument for -Version parameter is not in the proper format."; From 229d23afe92b1d68774bbb244a95eee129772da9 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 19:01:23 -0400 Subject: [PATCH 09/18] Find Name should only have ValueFromPipeline --- src/code/FindPSResource.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/code/FindPSResource.cs b/src/code/FindPSResource.cs index 464fddc3d..6dea7f3e3 100644 --- a/src/code/FindPSResource.cs +++ b/src/code/FindPSResource.cs @@ -41,7 +41,6 @@ public sealed class FindPSResource : PSCmdlet /// [Parameter(Position = 0, ValueFromPipeline = true, - ValueFromPipelineByPropertyName = true, ParameterSetName = ResourceNameParameterSet)] [ValidateNotNullOrEmpty] public string[] Name { get; set; } From f00d540b480cd98d5049129839f934f5356c85ea Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 19:03:07 -0400 Subject: [PATCH 10/18] Get Name should only have ValueFromPipeline --- src/code/GetInstalledPSResource.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/code/GetInstalledPSResource.cs b/src/code/GetInstalledPSResource.cs index 34ac306d1..dfcd7202b 100644 --- a/src/code/GetInstalledPSResource.cs +++ b/src/code/GetInstalledPSResource.cs @@ -30,7 +30,7 @@ public sealed class GetInstalledPSResource : PSCmdlet /// /// Specifies the desired name for the resource to look for. /// - [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [Parameter(Position = 0, ValueFromPipeline = true)] public string[] Name { get; set; } /// From d39a12777d83db504e4e3ea12994291087f5d462 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 19:08:37 -0400 Subject: [PATCH 11/18] remove ValueFromPipeline for Publish --- src/code/PublishPSResource.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/code/PublishPSResource.cs b/src/code/PublishPSResource.cs index 5684bfc08..c929b2c8f 100644 --- a/src/code/PublishPSResource.cs +++ b/src/code/PublishPSResource.cs @@ -48,7 +48,7 @@ public sealed class PublishPSResource : PSCmdlet /// Specifies the path to the resource that you want to publish. This parameter accepts the path to the folder that contains the resource. /// Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (.). /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathParameterSet")] + [Parameter(Mandatory = true, ParameterSetName = "PathParameterSet")] [ValidateNotNullOrEmpty] public string Path { @@ -80,7 +80,7 @@ public string Path /// No characters are interpreted as wildcards. If the path includes escape characters, enclose them in single quotation marks. /// Single quotation marks tell PowerShell not to interpret any characters as escape sequences. /// - [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathLiteralParameterSet")] + [Parameter(Mandatory = true, ParameterSetName = "PathLiteralParameterSet")] [ValidateNotNullOrEmpty] public string LiteralPath { @@ -118,7 +118,7 @@ public string LiteralPath /// /// Specifies a proxy server for the request, rather than a direct connection to the internet resource. /// - [Parameter(ValueFromPipelineByPropertyName = true)] + [Parameter()] [ValidateNotNullOrEmpty] public Uri Proxy { set @@ -135,7 +135,7 @@ public Uri Proxy { /// /// Specifies a user account that has permission to use the proxy server that is specified by the Proxy parameter. /// - [Parameter(ValueFromPipelineByPropertyName = true)] + [Parameter()] [ValidateNotNullOrEmpty] public PSCredential ProxyCredential { set @@ -163,7 +163,7 @@ public PSCredential ProxyCredential { protected override void BeginProcessing() { // Create a respository story (the PSResourceRepository.xml file) if it does not already exist - // This is to create a better experience for those who have just installed v3 and want to get up and running quickly + // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); } From b053b8190e7e938eddf7190bff45661e257a982f Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 19:11:57 -0400 Subject: [PATCH 12/18] Update should have value from ValueFromPipeline for Name only --- src/code/UpdatePSResource.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/code/UpdatePSResource.cs b/src/code/UpdatePSResource.cs index 0cf0a8fe5..892a99833 100644 --- a/src/code/UpdatePSResource.cs +++ b/src/code/UpdatePSResource.cs @@ -1,4 +1,3 @@ -using System.Collections.Specialized; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -36,7 +35,7 @@ public sealed class UpdatePSResource : PSCmdlet /// Specifies name of a resource or resources to update. /// Accepts wildcard characters. /// - [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] + [Parameter(Position = 0, ValueFromPipeline = true)] [ValidateNotNullOrEmpty] public string[] Name { get; set ; } = new string[] {"*"}; @@ -103,9 +102,9 @@ public sealed class UpdatePSResource : PSCmdlet #region Override Methods protected override void BeginProcessing() - { - // Create a respository story (the PSResourceRepository.xml file) if it does not already exist - // This is to create a better experience for those who have just installed v3 and want to get up and running quickly + { + // Create a respository story (the PSResourceRepository.xml file) if it does not already exist + // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); _pathsToInstallPkg = Utils.GetAllInstallationPaths(this, Scope); From d805de0d30138915e49a3e263b107efd6f7b4fa3 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 19:51:19 -0400 Subject: [PATCH 13/18] refactor SavePSResource --- src/code/SavePSResource.cs | 175 ++++++++++++++----------------------- 1 file changed, 67 insertions(+), 108 deletions(-) diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index a68bf5231..9ba9d334c 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -141,37 +141,9 @@ protected override void BeginProcessing() protected override void ProcessRecord() { var installHelper = new InstallHelper(updatePkg: false, savePkg: true, cmdletPassedIn: this); - switch (ParameterSetName) { case NameParameterSet: - var namesToSave = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); - if (nameContainsWildcard) - { - WriteError(new ErrorRecord( - new PSInvalidOperationException("Name with wildcards is not supported for Save-PSResource cmdlet"), - "NameContainsWildcard", - ErrorCategory.InvalidArgument, - this)); - return; - } - - 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 there are no elements left in namesToSave - if (namesToSave.Length == 0) - { - return; - } - // validate that if a -Version param is passed in that it can be parsed into a NuGet version range. // an exact version will be formatted into a version range. if (Version == null) @@ -186,31 +158,10 @@ protected override void ProcessRecord() ThrowTerminatingError(IncorrectVersionFormat); } - if (!ShouldProcess(string.Format("Resources to save: '{0}'", namesToSave))) - { - WriteVerbose(string.Format("Save operation cancelled by user for resources: {0}", namesToSave)); - return; - } - - installHelper.InstallPackages( - names: namesToSave, - versionRange: _versionRange, - prerelease: Prerelease, - repository: Repository, - acceptLicense: true, - quiet: true, - reinstall: true, - force: false, - trustRepository: TrustRepository, - noClobber: false, - credential: Credential, - requiredResourceFile: null, - requiredResourceJson: null, - requiredResourceHash: null, - specifiedPath: _path, - asNupkg: false, - includeXML: false, - pathsToInstallPkg: new List { _path } ); + ProcessSaveHelper(installHelper: installHelper, + pkgNames: Name, + pkgPrerelease: Prerelease, + pkgRepository: Repository); break; case InputObjectParameterSet: @@ -221,34 +172,6 @@ protected override void ProcessRecord() continue; } - Name = new string[] { pkg.Name }; - var inputNamesToSave = Utils.ProcessNameWildcards(Name, out string[] inputErrorMsgs, out bool inputNameContainsWildcard); - if (inputNameContainsWildcard) - { - WriteError(new ErrorRecord( - new PSInvalidOperationException("Name with wildcards is not supported for Save-PSResource cmdlet"), - "NameContainsWildcard", - ErrorCategory.InvalidArgument, - this)); - return; - } - - foreach (string error in inputErrorMsgs) - { - 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 there are no elements left in namesToSave - if (inputNamesToSave.Length == 0) - { - return; - } - string normalizedVersionString = Utils.GetNormalizedVersionString(pkg.Version.ToString(), pkg.PrereleaseLabel); if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) { @@ -257,33 +180,11 @@ protected override void ProcessRecord() var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); ThrowTerminatingError(IncorrectVersionFormat); } - - if (!ShouldProcess(string.Format("Resources to save: '{0}'", inputNamesToSave))) - { - WriteVerbose(string.Format("Save operation cancelled by user for resources: {0}", inputNamesToSave)); - return; - } - - installHelper.InstallPackages( - names: inputNamesToSave, - versionRange: _versionRange, - prerelease: Prerelease, - repository: Repository, - acceptLicense: true, - quiet: true, - reinstall: true, - force: false, - trustRepository: TrustRepository, - noClobber: false, - credential: Credential, - requiredResourceFile: null, - requiredResourceJson: null, - requiredResourceHash: null, - specifiedPath: _path, - asNupkg: false, - includeXML: false, - pathsToInstallPkg: new List { _path } ); - + + ProcessSaveHelper(installHelper: installHelper, + pkgNames: new string[] { pkg.Name }, + pkgPrerelease: pkg.IsPrerelease, + pkgRepository: new string[] { pkg.Repository }); } break; @@ -294,5 +195,63 @@ protected override void ProcessRecord() } #endregion + + #region Methods + private void ProcessSaveHelper(InstallHelper installHelper, string[] pkgNames, bool pkgPrerelease, string[] pkgRepository) + { + var namesToSave = Utils.ProcessNameWildcards(pkgNames, out string[] errorMsgs, out bool nameContainsWildcard); + if (nameContainsWildcard) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException("Name with wildcards is not supported for Save-PSResource cmdlet"), + "NameContainsWildcard", + ErrorCategory.InvalidArgument, + this)); + return; + } + + 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 there are no elements left in namesToSave + if (namesToSave.Length == 0) + { + return; + } + + if (!ShouldProcess(string.Format("Resources to save: '{0}'", namesToSave))) + { + WriteVerbose(string.Format("Save operation cancelled by user for resources: {0}", namesToSave)); + return; + } + + installHelper.InstallPackages( + names: namesToSave, + versionRange: _versionRange, + prerelease: pkgPrerelease, + repository: pkgRepository, + acceptLicense: true, + quiet: true, + reinstall: true, + force: false, + trustRepository: TrustRepository, + noClobber: false, + credential: Credential, + requiredResourceFile: null, + requiredResourceJson: null, + requiredResourceHash: null, + specifiedPath: _path, + asNupkg: false, + includeXML: false, + pathsToInstallPkg: new List { _path } ); + } + #endregion } } From 988e9e40c2af5b10a3c4394b3ef9e81e81844990 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Tue, 12 Oct 2021 20:15:12 -0400 Subject: [PATCH 14/18] refactor Install-PSResource --- src/code/InstallPSResource.cs | 171 +++++++++++++--------------------- 1 file changed, 66 insertions(+), 105 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index 5c76b5735..825939e89 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -143,59 +143,11 @@ protected override void ProcessRecord() var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); ThrowTerminatingError(IncorrectVersionFormat); } - - var namesToInstall = Utils.ProcessNameWildcards(Name, out string[] errorMsgs, out bool nameContainsWildcard); - if (nameContainsWildcard) - { - WriteError(new ErrorRecord( - new PSInvalidOperationException("Name with wildcards is not supported for Install-PSResource cmdlet"), - "NameContainsWildcard", - ErrorCategory.InvalidArgument, - this)); - return; - } - - 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 there are no elements left in namesToInstall - if (namesToInstall.Length == 0) - { - return; - } - - if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", namesToInstall)))) - { - WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", namesToInstall))); - return; - } - - installHelper.InstallPackages( - names: namesToInstall, - versionRange: _versionRange, - prerelease: Prerelease, - repository: Repository, - acceptLicense: AcceptLicense, - quiet: Quiet, - reinstall: Reinstall, - force: false, - trustRepository: TrustRepository, - noClobber: false, - credential: Credential, - requiredResourceFile: null, - requiredResourceJson: null, - requiredResourceHash: null, - specifiedPath: null, - asNupkg: false, - includeXML: true, - pathsToInstallPkg: _pathsToInstallPkg); + ProcessInstallHelper(installHelper: installHelper, + pkgNames: Name, + pkgPrerelease: Prerelease, + pkgRepository: Repository); break; case InputObjectParameterSet: @@ -206,34 +158,6 @@ protected override void ProcessRecord() continue; } - Name = new string[] { pkg.Name }; - var inputNameToInstall = Utils.ProcessNameWildcards(Name, out string[] inputErrorMsgs, out bool inputNameContainsWildcard); - if (inputNameContainsWildcard) - { - WriteError(new ErrorRecord( - new PSInvalidOperationException("Name with wildcards is not supported for Install-PSResource cmdlet"), - "NameContainsWildcard", - ErrorCategory.InvalidArgument, - this)); - return; - } - - foreach (string error in inputErrorMsgs) - { - 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 there are no elements left in namesToInstall - if (inputNameToInstall.Length == 0) - { - return; - } - string normalizedVersionString = Utils.GetNormalizedVersionString(pkg.Version.ToString(), pkg.PrereleaseLabel); if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) { @@ -243,31 +167,10 @@ protected override void ProcessRecord() WriteError(ErrorParsingVersion); } - if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", inputNameToInstall)))) - { - WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", inputNameToInstall))); - return; - } - - installHelper.InstallPackages( - names: inputNameToInstall, - versionRange: _versionRange, - prerelease: pkg.IsPrerelease, - repository: new string[] { pkg.Repository }, - acceptLicense: AcceptLicense, - quiet: Quiet, - reinstall: Reinstall, - force: false, - trustRepository: TrustRepository, - noClobber: false, - credential: Credential, - requiredResourceFile: null, - requiredResourceJson: null, - requiredResourceHash: null, - specifiedPath: null, - asNupkg: false, - includeXML: true, - pathsToInstallPkg: _pathsToInstallPkg); + ProcessInstallHelper(installHelper: installHelper, + pkgNames: new string[] { pkg.Name }, + pkgPrerelease: pkg.IsPrerelease, + pkgRepository: new string[]{ pkg.Repository }); } break; @@ -294,5 +197,63 @@ protected override void ProcessRecord() } #endregion + + #region Methods + private void ProcessInstallHelper(InstallHelper installHelper, string[] pkgNames, bool pkgPrerelease, string[] pkgRepository) + { + var inputNameToInstall = Utils.ProcessNameWildcards(pkgNames, out string[] errorMsgs, out bool nameContainsWildcard); + if (nameContainsWildcard) + { + WriteError(new ErrorRecord( + new PSInvalidOperationException("Name with wildcards is not supported for Install-PSResource cmdlet"), + "NameContainsWildcard", + ErrorCategory.InvalidArgument, + this)); + return; + } + + 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 there are no elements left in namesToInstall + if (inputNameToInstall.Length == 0) + { + return; + } + + if (!ShouldProcess(string.Format("package to install: '{0}'", String.Join(", ", inputNameToInstall)))) + { + WriteVerbose(string.Format("Install operation cancelled by user for packages: {0}", String.Join(", ", inputNameToInstall))); + return; + } + + installHelper.InstallPackages( + names: pkgNames, + versionRange: _versionRange, + prerelease: pkgPrerelease, + repository: pkgRepository, + acceptLicense: AcceptLicense, + quiet: Quiet, + reinstall: Reinstall, + force: false, + trustRepository: TrustRepository, + noClobber: false, + credential: Credential, + requiredResourceFile: null, + requiredResourceJson: null, + requiredResourceHash: null, + specifiedPath: null, + asNupkg: false, + includeXML: true, + pathsToInstallPkg: _pathsToInstallPkg); + } + #endregion } } From 7d3734a9f870337fac72bf15def83c73b21c82c8 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 13 Oct 2021 11:33:51 -0400 Subject: [PATCH 15/18] restore changes to Find --- src/code/FindPSResource.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/code/FindPSResource.cs b/src/code/FindPSResource.cs index 6dea7f3e3..464fddc3d 100644 --- a/src/code/FindPSResource.cs +++ b/src/code/FindPSResource.cs @@ -41,6 +41,7 @@ public sealed class FindPSResource : PSCmdlet /// [Parameter(Position = 0, ValueFromPipeline = true, + ValueFromPipelineByPropertyName = true, ParameterSetName = ResourceNameParameterSet)] [ValidateNotNullOrEmpty] public string[] Name { get; set; } From b7d43254e5d30825948b68f091d69de2b1e643f7 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 13 Oct 2021 11:38:37 -0400 Subject: [PATCH 16/18] revert changes made to Get, Publish, Update --- src/code/GetInstalledPSResource.cs | 2 +- src/code/PublishPSResource.cs | 10 +++++----- src/code/UpdatePSResource.cs | 9 +++++---- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/code/GetInstalledPSResource.cs b/src/code/GetInstalledPSResource.cs index dfcd7202b..34ac306d1 100644 --- a/src/code/GetInstalledPSResource.cs +++ b/src/code/GetInstalledPSResource.cs @@ -30,7 +30,7 @@ public sealed class GetInstalledPSResource : PSCmdlet /// /// Specifies the desired name for the resource to look for. /// - [Parameter(Position = 0, ValueFromPipeline = true)] + [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] public string[] Name { get; set; } /// diff --git a/src/code/PublishPSResource.cs b/src/code/PublishPSResource.cs index c929b2c8f..5684bfc08 100644 --- a/src/code/PublishPSResource.cs +++ b/src/code/PublishPSResource.cs @@ -48,7 +48,7 @@ public sealed class PublishPSResource : PSCmdlet /// Specifies the path to the resource that you want to publish. This parameter accepts the path to the folder that contains the resource. /// Specifies a path to one or more locations. Wildcards are permitted. The default location is the current directory (.). /// - [Parameter(Mandatory = true, ParameterSetName = "PathParameterSet")] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathParameterSet")] [ValidateNotNullOrEmpty] public string Path { @@ -80,7 +80,7 @@ public string Path /// No characters are interpreted as wildcards. If the path includes escape characters, enclose them in single quotation marks. /// Single quotation marks tell PowerShell not to interpret any characters as escape sequences. /// - [Parameter(Mandatory = true, ParameterSetName = "PathLiteralParameterSet")] + [Parameter(Mandatory = true, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = "PathLiteralParameterSet")] [ValidateNotNullOrEmpty] public string LiteralPath { @@ -118,7 +118,7 @@ public string LiteralPath /// /// Specifies a proxy server for the request, rather than a direct connection to the internet resource. /// - [Parameter()] + [Parameter(ValueFromPipelineByPropertyName = true)] [ValidateNotNullOrEmpty] public Uri Proxy { set @@ -135,7 +135,7 @@ public Uri Proxy { /// /// Specifies a user account that has permission to use the proxy server that is specified by the Proxy parameter. /// - [Parameter()] + [Parameter(ValueFromPipelineByPropertyName = true)] [ValidateNotNullOrEmpty] public PSCredential ProxyCredential { set @@ -163,7 +163,7 @@ public PSCredential ProxyCredential { protected override void BeginProcessing() { // Create a respository story (the PSResourceRepository.xml file) if it does not already exist - // This is to create a better experience for those who have just installed v3 and want to get up and running quickly + // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); } diff --git a/src/code/UpdatePSResource.cs b/src/code/UpdatePSResource.cs index 892a99833..0cf0a8fe5 100644 --- a/src/code/UpdatePSResource.cs +++ b/src/code/UpdatePSResource.cs @@ -1,3 +1,4 @@ +using System.Collections.Specialized; // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. @@ -35,7 +36,7 @@ public sealed class UpdatePSResource : PSCmdlet /// Specifies name of a resource or resources to update. /// Accepts wildcard characters. /// - [Parameter(Position = 0, ValueFromPipeline = true)] + [Parameter(Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] [ValidateNotNullOrEmpty] public string[] Name { get; set ; } = new string[] {"*"}; @@ -102,9 +103,9 @@ public sealed class UpdatePSResource : PSCmdlet #region Override Methods protected override void BeginProcessing() - { - // Create a respository story (the PSResourceRepository.xml file) if it does not already exist - // This is to create a better experience for those who have just installed v3 and want to get up and running quickly + { + // Create a respository story (the PSResourceRepository.xml file) if it does not already exist + // This is to create a better experience for those who have just installed v3 and want to get up and running quickly RepositorySettings.CheckRepositoryStore(); _pathsToInstallPkg = Utils.GetAllInstallationPaths(this, Scope); From 13571c095f62a783452798a9147c2c83f87a4410 Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Wed, 13 Oct 2021 17:03:40 -0400 Subject: [PATCH 17/18] remove ValueFromPipelineByPropertyName for InputObject param --- src/code/InstallPSResource.cs | 2 +- src/code/SavePSResource.cs | 2 +- src/code/UninstallPSResource.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index 825939e89..fedd8381f 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -95,7 +95,7 @@ class InstallPSResource : PSCmdlet /// /// Used for pipeline input. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectParameterSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] public PSResourceInfo[] InputObject { get; set; } diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index 9ba9d334c..19a34baba 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -117,7 +117,7 @@ public string Path /// /// Used for pipeline input. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectParameterSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] public PSResourceInfo[] InputObject { get; set; } diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index c0d0dff17..70aec83b7 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -39,7 +39,7 @@ public sealed class UninstallPSResource : PSCmdlet /// /// Used for pipeline input. /// - [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true, ParameterSetName = InputObjectParameterSet)] + [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] public PSResourceInfo[] InputObject { get; set; } From 22cd4e13505cd93c93c9ac0f4a233caa00b9fc8f Mon Sep 17 00:00:00 2001 From: Anam Navied Date: Mon, 18 Oct 2021 14:53:39 -0400 Subject: [PATCH 18/18] change InputObjectType from PSResourceInfo[] to PSResourceInfo --- src/code/InstallPSResource.cs | 33 ++++++++++---------------- src/code/SavePSResource.cs | 33 +++++++++++--------------- src/code/UninstallPSResource.cs | 41 ++++++++++++++------------------- 3 files changed, 42 insertions(+), 65 deletions(-) diff --git a/src/code/InstallPSResource.cs b/src/code/InstallPSResource.cs index fedd8381f..42be06c52 100644 --- a/src/code/InstallPSResource.cs +++ b/src/code/InstallPSResource.cs @@ -97,7 +97,7 @@ class InstallPSResource : PSCmdlet /// [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] - public PSResourceInfo[] InputObject { get; set; } + public PSResourceInfo InputObject { get; set; } #endregion @@ -126,7 +126,6 @@ protected override void BeginProcessing() protected override void ProcessRecord() { var installHelper = new InstallHelper(updatePkg: false, savePkg: false, cmdletPassedIn: this); - switch (ParameterSetName) { case NameParameterSet: @@ -151,27 +150,19 @@ protected override void ProcessRecord() break; case InputObjectParameterSet: - foreach (PSResourceInfo pkg in InputObject) + string normalizedVersionString = Utils.GetNormalizedVersionString(InputObject.Version.ToString(), InputObject.PrereleaseLabel); + if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) { - if (pkg == null) - { - continue; - } - - string normalizedVersionString = Utils.GetNormalizedVersionString(pkg.Version.ToString(), pkg.PrereleaseLabel); - if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) - { - var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", normalizedVersionString, pkg.Name); - var ex = new ArgumentException(exMessage); - var ErrorParsingVersion = new ErrorRecord(ex, "ErrorParsingVersion", ErrorCategory.ParserError, null); - WriteError(ErrorParsingVersion); - } - - ProcessInstallHelper(installHelper: installHelper, - pkgNames: new string[] { pkg.Name }, - pkgPrerelease: pkg.IsPrerelease, - pkgRepository: new string[]{ pkg.Repository }); + var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", normalizedVersionString, InputObject.Name); + var ex = new ArgumentException(exMessage); + var ErrorParsingVersion = new ErrorRecord(ex, "ErrorParsingVersion", ErrorCategory.ParserError, null); + WriteError(ErrorParsingVersion); } + + ProcessInstallHelper(installHelper: installHelper, + pkgNames: new string[] { InputObject.Name }, + pkgPrerelease: InputObject.IsPrerelease, + pkgRepository: new string[]{ InputObject.Repository }); break; case RequiredResourceFileParameterSet: diff --git a/src/code/SavePSResource.cs b/src/code/SavePSResource.cs index 19a34baba..be5180150 100644 --- a/src/code/SavePSResource.cs +++ b/src/code/SavePSResource.cs @@ -119,7 +119,7 @@ public string Path /// [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] - public PSResourceInfo[] InputObject { get; set; } + public PSResourceInfo InputObject { get; set; } #endregion @@ -165,27 +165,20 @@ protected override void ProcessRecord() break; case InputObjectParameterSet: - foreach (PSResourceInfo pkg in InputObject) + string normalizedVersionString = Utils.GetNormalizedVersionString(InputObject.Version.ToString(), InputObject.PrereleaseLabel); + if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) { - if (pkg == null) - { - continue; - } - - string normalizedVersionString = Utils.GetNormalizedVersionString(pkg.Version.ToString(), pkg.PrereleaseLabel); - if (!Utils.TryParseVersionOrVersionRange(normalizedVersionString, out _versionRange)) - { - var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", normalizedVersionString, pkg.Name); - var ex = new ArgumentException(exMessage); - var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); - ThrowTerminatingError(IncorrectVersionFormat); - } - - ProcessSaveHelper(installHelper: installHelper, - pkgNames: new string[] { pkg.Name }, - pkgPrerelease: pkg.IsPrerelease, - pkgRepository: new string[] { pkg.Repository }); + var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", normalizedVersionString, InputObject.Name); + var ex = new ArgumentException(exMessage); + var IncorrectVersionFormat = new ErrorRecord(ex, "IncorrectVersionFormat", ErrorCategory.InvalidArgument, null); + ThrowTerminatingError(IncorrectVersionFormat); } + + ProcessSaveHelper(installHelper: installHelper, + pkgNames: new string[] { InputObject.Name }, + pkgPrerelease: InputObject.IsPrerelease, + pkgRepository: new string[] { InputObject.Repository }); + break; default: diff --git a/src/code/UninstallPSResource.cs b/src/code/UninstallPSResource.cs index 70aec83b7..36d16a1a0 100644 --- a/src/code/UninstallPSResource.cs +++ b/src/code/UninstallPSResource.cs @@ -41,7 +41,7 @@ public sealed class UninstallPSResource : PSCmdlet /// [Parameter(Mandatory = true, Position = 0, ValueFromPipeline = true, ParameterSetName = InputObjectParameterSet)] [ValidateNotNullOrEmpty] - public PSResourceInfo[] InputObject { get; set; } + public PSResourceInfo InputObject { get; set; } /// /// @@ -110,31 +110,24 @@ protected override void ProcessRecord() break; case InputObjectParameterSet: - foreach (PSResourceInfo pkg in InputObject) + if (!Utils.TryParseVersionOrVersionRange(InputObject.Version.ToString(), out _versionRange)) { - if (pkg == null) - { - continue; - } - - if (!Utils.TryParseVersionOrVersionRange(pkg.Version.ToString(), out _versionRange)) - { - var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", pkg.Version.ToString(), pkg.Name); - var ex = new ArgumentException(exMessage); - var ErrorParsingVersion = new ErrorRecord(ex, "ErrorParsingVersion", ErrorCategory.ParserError, null); - WriteError(ErrorParsingVersion); - } - - Name = new string[] { pkg.Name }; - if (!String.IsNullOrWhiteSpace(pkg.Name) && !UninstallPkgHelper()) - { - // specific errors will be displayed lower in the stack - var exMessage = String.Format(string.Format("Did not successfully uninstall package {0}", pkg.Name)); - var ex = new ArgumentException(exMessage); - var UninstallResourceError = new ErrorRecord(ex, "UninstallResourceError", ErrorCategory.InvalidOperation, null); - WriteError(UninstallResourceError); - } + var exMessage = String.Format("Version '{0}' for resource '{1}' cannot be parsed.", InputObject.Version.ToString(), InputObject.Name); + var ex = new ArgumentException(exMessage); + var ErrorParsingVersion = new ErrorRecord(ex, "ErrorParsingVersion", ErrorCategory.ParserError, null); + WriteError(ErrorParsingVersion); + } + + Name = new string[] { InputObject.Name }; + if (!String.IsNullOrWhiteSpace(InputObject.Name) && !UninstallPkgHelper()) + { + // specific errors will be displayed lower in the stack + var exMessage = String.Format(string.Format("Did not successfully uninstall package {0}", InputObject.Name)); + var ex = new ArgumentException(exMessage); + var UninstallResourceError = new ErrorRecord(ex, "UninstallResourceError", ErrorCategory.InvalidOperation, null); + WriteError(UninstallResourceError); } + break; default: